18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Permission to use, copy, modify, and/or distribute this software for any 58c2ecf20Sopenharmony_ci * purpose with or without fee is hereby granted, provided that the above 68c2ecf20Sopenharmony_ci * copyright notice and this permission notice appear in all copies. 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 98c2ecf20Sopenharmony_ci * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 108c2ecf20Sopenharmony_ci * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 118c2ecf20Sopenharmony_ci * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 128c2ecf20Sopenharmony_ci * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 138c2ecf20Sopenharmony_ci * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 148c2ecf20Sopenharmony_ci * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 158c2ecf20Sopenharmony_ci */ 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#ifndef _WCN36XX_H_ 188c2ecf20Sopenharmony_ci#define _WCN36XX_H_ 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#include <linux/completion.h> 218c2ecf20Sopenharmony_ci#include <linux/printk.h> 228c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 238c2ecf20Sopenharmony_ci#include <net/mac80211.h> 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#include "hal.h" 268c2ecf20Sopenharmony_ci#include "smd.h" 278c2ecf20Sopenharmony_ci#include "txrx.h" 288c2ecf20Sopenharmony_ci#include "dxe.h" 298c2ecf20Sopenharmony_ci#include "pmc.h" 308c2ecf20Sopenharmony_ci#include "debug.h" 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#define WLAN_NV_FILE "wlan/prima/WCNSS_qcom_wlan_nv.bin" 338c2ecf20Sopenharmony_ci#define WCN36XX_AGGR_BUFFER_SIZE 64 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ciextern unsigned int wcn36xx_dbg_mask; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cienum wcn36xx_debug_mask { 388c2ecf20Sopenharmony_ci WCN36XX_DBG_DXE = 0x00000001, 398c2ecf20Sopenharmony_ci WCN36XX_DBG_DXE_DUMP = 0x00000002, 408c2ecf20Sopenharmony_ci WCN36XX_DBG_SMD = 0x00000004, 418c2ecf20Sopenharmony_ci WCN36XX_DBG_SMD_DUMP = 0x00000008, 428c2ecf20Sopenharmony_ci WCN36XX_DBG_RX = 0x00000010, 438c2ecf20Sopenharmony_ci WCN36XX_DBG_RX_DUMP = 0x00000020, 448c2ecf20Sopenharmony_ci WCN36XX_DBG_TX = 0x00000040, 458c2ecf20Sopenharmony_ci WCN36XX_DBG_TX_DUMP = 0x00000080, 468c2ecf20Sopenharmony_ci WCN36XX_DBG_HAL = 0x00000100, 478c2ecf20Sopenharmony_ci WCN36XX_DBG_HAL_DUMP = 0x00000200, 488c2ecf20Sopenharmony_ci WCN36XX_DBG_MAC = 0x00000400, 498c2ecf20Sopenharmony_ci WCN36XX_DBG_BEACON = 0x00000800, 508c2ecf20Sopenharmony_ci WCN36XX_DBG_BEACON_DUMP = 0x00001000, 518c2ecf20Sopenharmony_ci WCN36XX_DBG_PMC = 0x00002000, 528c2ecf20Sopenharmony_ci WCN36XX_DBG_PMC_DUMP = 0x00004000, 538c2ecf20Sopenharmony_ci WCN36XX_DBG_TESTMODE = 0x00008000, 548c2ecf20Sopenharmony_ci WCN36XX_DBG_TESTMODE_DUMP = 0x00010000, 558c2ecf20Sopenharmony_ci WCN36XX_DBG_ANY = 0xffffffff, 568c2ecf20Sopenharmony_ci}; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci#define wcn36xx_err(fmt, arg...) \ 598c2ecf20Sopenharmony_ci printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg) 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci#define wcn36xx_warn(fmt, arg...) \ 628c2ecf20Sopenharmony_ci printk(KERN_WARNING pr_fmt("WARNING " fmt), ##arg) 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci#define wcn36xx_info(fmt, arg...) \ 658c2ecf20Sopenharmony_ci printk(KERN_INFO pr_fmt(fmt), ##arg) 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci#define wcn36xx_dbg(mask, fmt, arg...) do { \ 688c2ecf20Sopenharmony_ci if (wcn36xx_dbg_mask & mask) \ 698c2ecf20Sopenharmony_ci printk(KERN_DEBUG pr_fmt(fmt), ##arg); \ 708c2ecf20Sopenharmony_ci} while (0) 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci#define wcn36xx_dbg_dump(mask, prefix_str, buf, len) do { \ 738c2ecf20Sopenharmony_ci if (wcn36xx_dbg_mask & mask) \ 748c2ecf20Sopenharmony_ci print_hex_dump(KERN_DEBUG, pr_fmt(prefix_str), \ 758c2ecf20Sopenharmony_ci DUMP_PREFIX_OFFSET, 32, 1, \ 768c2ecf20Sopenharmony_ci buf, len, false); \ 778c2ecf20Sopenharmony_ci} while (0) 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cienum wcn36xx_ampdu_state { 808c2ecf20Sopenharmony_ci WCN36XX_AMPDU_NONE, 818c2ecf20Sopenharmony_ci WCN36XX_AMPDU_INIT, 828c2ecf20Sopenharmony_ci WCN36XX_AMPDU_START, 838c2ecf20Sopenharmony_ci WCN36XX_AMPDU_OPERATIONAL, 848c2ecf20Sopenharmony_ci}; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci#define HW_VALUE_PHY_SHIFT 8 878c2ecf20Sopenharmony_ci#define HW_VALUE_PHY(hw_value) ((hw_value) >> HW_VALUE_PHY_SHIFT) 888c2ecf20Sopenharmony_ci#define HW_VALUE_CHANNEL(hw_value) ((hw_value) & 0xFF) 898c2ecf20Sopenharmony_ci#define WCN36XX_HW_CHANNEL(__wcn)\ 908c2ecf20Sopenharmony_ci HW_VALUE_CHANNEL(__wcn->hw->conf.chandef.chan->hw_value) 918c2ecf20Sopenharmony_ci#define WCN36XX_BAND(__wcn) (__wcn->hw->conf.chandef.chan->band) 928c2ecf20Sopenharmony_ci#define WCN36XX_CENTER_FREQ(__wcn) (__wcn->hw->conf.chandef.chan->center_freq) 938c2ecf20Sopenharmony_ci#define WCN36XX_LISTEN_INTERVAL(__wcn) (__wcn->hw->conf.listen_interval) 948c2ecf20Sopenharmony_ci#define WCN36XX_FLAGS(__wcn) (__wcn->hw->flags) 958c2ecf20Sopenharmony_ci#define WCN36XX_MAX_POWER(__wcn) (__wcn->hw->conf.chandef.chan->max_power) 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci#define RF_UNKNOWN 0x0000 988c2ecf20Sopenharmony_ci#define RF_IRIS_WCN3620 0x3620 998c2ecf20Sopenharmony_ci#define RF_IRIS_WCN3660 0x3660 1008c2ecf20Sopenharmony_ci#define RF_IRIS_WCN3680 0x3680 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_cistatic inline void buff_to_be(u32 *buf, size_t len) 1038c2ecf20Sopenharmony_ci{ 1048c2ecf20Sopenharmony_ci int i; 1058c2ecf20Sopenharmony_ci for (i = 0; i < len; i++) 1068c2ecf20Sopenharmony_ci buf[i] = cpu_to_be32(buf[i]); 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistruct nv_data { 1108c2ecf20Sopenharmony_ci int is_valid; 1118c2ecf20Sopenharmony_ci u8 table; 1128c2ecf20Sopenharmony_ci}; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci/** 1158c2ecf20Sopenharmony_ci * struct wcn36xx_vif - holds VIF related fields 1168c2ecf20Sopenharmony_ci * 1178c2ecf20Sopenharmony_ci * @bss_index: bss_index is initially set to 0xFF. bss_index is received from 1188c2ecf20Sopenharmony_ci * HW after first config_bss call and must be used in delete_bss and 1198c2ecf20Sopenharmony_ci * enter/exit_bmps. 1208c2ecf20Sopenharmony_ci */ 1218c2ecf20Sopenharmony_cistruct wcn36xx_vif { 1228c2ecf20Sopenharmony_ci struct list_head list; 1238c2ecf20Sopenharmony_ci u8 dtim_period; 1248c2ecf20Sopenharmony_ci enum ani_ed_type encrypt_type; 1258c2ecf20Sopenharmony_ci bool is_joining; 1268c2ecf20Sopenharmony_ci bool sta_assoc; 1278c2ecf20Sopenharmony_ci struct wcn36xx_hal_mac_ssid ssid; 1288c2ecf20Sopenharmony_ci enum wcn36xx_hal_bss_type bss_type; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci /* Power management */ 1318c2ecf20Sopenharmony_ci enum wcn36xx_power_state pw_state; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci u8 bss_index; 1348c2ecf20Sopenharmony_ci /* Returned from WCN36XX_HAL_ADD_STA_SELF_RSP */ 1358c2ecf20Sopenharmony_ci u8 self_sta_index; 1368c2ecf20Sopenharmony_ci u8 self_dpu_desc_index; 1378c2ecf20Sopenharmony_ci u8 self_ucast_dpu_sign; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci struct list_head sta_list; 1408c2ecf20Sopenharmony_ci}; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci/** 1438c2ecf20Sopenharmony_ci * struct wcn36xx_sta - holds STA related fields 1448c2ecf20Sopenharmony_ci * 1458c2ecf20Sopenharmony_ci * @tid: traffic ID that is used during AMPDU and in TX BD. 1468c2ecf20Sopenharmony_ci * @sta_index: STA index is returned from HW after config_sta call and is 1478c2ecf20Sopenharmony_ci * used in both SMD channel and TX BD. 1488c2ecf20Sopenharmony_ci * @dpu_desc_index: DPU descriptor index is returned from HW after config_sta 1498c2ecf20Sopenharmony_ci * call and is used in TX BD. 1508c2ecf20Sopenharmony_ci * @bss_sta_index: STA index is returned from HW after config_bss call and is 1518c2ecf20Sopenharmony_ci * used in both SMD channel and TX BD. See table bellow when it is used. 1528c2ecf20Sopenharmony_ci * @bss_dpu_desc_index: DPU descriptor index is returned from HW after 1538c2ecf20Sopenharmony_ci * config_bss call and is used in TX BD. 1548c2ecf20Sopenharmony_ci * ______________________________________________ 1558c2ecf20Sopenharmony_ci * | | STA | AP | 1568c2ecf20Sopenharmony_ci * |______________|_____________|_______________| 1578c2ecf20Sopenharmony_ci * | TX BD |bss_sta_index| sta_index | 1588c2ecf20Sopenharmony_ci * |______________|_____________|_______________| 1598c2ecf20Sopenharmony_ci * |all SMD calls |bss_sta_index| sta_index | 1608c2ecf20Sopenharmony_ci * |______________|_____________|_______________| 1618c2ecf20Sopenharmony_ci * |smd_delete_sta| sta_index | sta_index | 1628c2ecf20Sopenharmony_ci * |______________|_____________|_______________| 1638c2ecf20Sopenharmony_ci */ 1648c2ecf20Sopenharmony_cistruct wcn36xx_sta { 1658c2ecf20Sopenharmony_ci struct list_head list; 1668c2ecf20Sopenharmony_ci struct wcn36xx_vif *vif; 1678c2ecf20Sopenharmony_ci u16 aid; 1688c2ecf20Sopenharmony_ci u16 tid; 1698c2ecf20Sopenharmony_ci u8 sta_index; 1708c2ecf20Sopenharmony_ci u8 dpu_desc_index; 1718c2ecf20Sopenharmony_ci u8 ucast_dpu_sign; 1728c2ecf20Sopenharmony_ci u8 bss_sta_index; 1738c2ecf20Sopenharmony_ci u8 bss_dpu_desc_index; 1748c2ecf20Sopenharmony_ci bool is_data_encrypted; 1758c2ecf20Sopenharmony_ci /* Rates */ 1768c2ecf20Sopenharmony_ci struct wcn36xx_hal_supported_rates_v1 supported_rates; 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci spinlock_t ampdu_lock; /* protects next two fields */ 1798c2ecf20Sopenharmony_ci enum wcn36xx_ampdu_state ampdu_state[16]; 1808c2ecf20Sopenharmony_ci int non_agg_frame_ct; 1818c2ecf20Sopenharmony_ci}; 1828c2ecf20Sopenharmony_cistruct wcn36xx_dxe_ch; 1838c2ecf20Sopenharmony_cistruct wcn36xx { 1848c2ecf20Sopenharmony_ci struct ieee80211_hw *hw; 1858c2ecf20Sopenharmony_ci struct device *dev; 1868c2ecf20Sopenharmony_ci struct list_head vif_list; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci const struct firmware *nv; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci u8 fw_revision; 1918c2ecf20Sopenharmony_ci u8 fw_version; 1928c2ecf20Sopenharmony_ci u8 fw_minor; 1938c2ecf20Sopenharmony_ci u8 fw_major; 1948c2ecf20Sopenharmony_ci u32 fw_feat_caps[WCN36XX_HAL_CAPS_SIZE]; 1958c2ecf20Sopenharmony_ci bool is_pronto; 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci /* extra byte for the NULL termination */ 1988c2ecf20Sopenharmony_ci u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1]; 1998c2ecf20Sopenharmony_ci u8 wlan_version[WCN36XX_HAL_VERSION_LENGTH + 1]; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci bool first_boot; 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci /* IRQs */ 2048c2ecf20Sopenharmony_ci int tx_irq; 2058c2ecf20Sopenharmony_ci int rx_irq; 2068c2ecf20Sopenharmony_ci void __iomem *ccu_base; 2078c2ecf20Sopenharmony_ci void __iomem *dxe_base; 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci struct rpmsg_endpoint *smd_channel; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci struct qcom_smem_state *tx_enable_state; 2128c2ecf20Sopenharmony_ci unsigned tx_enable_state_bit; 2138c2ecf20Sopenharmony_ci struct qcom_smem_state *tx_rings_empty_state; 2148c2ecf20Sopenharmony_ci unsigned tx_rings_empty_state_bit; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci /* prevents concurrent FW reconfiguration */ 2178c2ecf20Sopenharmony_ci struct mutex conf_mutex; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci /* 2208c2ecf20Sopenharmony_ci * smd_buf must be protected with smd_mutex to garantee 2218c2ecf20Sopenharmony_ci * that all messages are sent one after another 2228c2ecf20Sopenharmony_ci */ 2238c2ecf20Sopenharmony_ci u8 *hal_buf; 2248c2ecf20Sopenharmony_ci size_t hal_rsp_len; 2258c2ecf20Sopenharmony_ci struct mutex hal_mutex; 2268c2ecf20Sopenharmony_ci struct completion hal_rsp_compl; 2278c2ecf20Sopenharmony_ci struct workqueue_struct *hal_ind_wq; 2288c2ecf20Sopenharmony_ci struct work_struct hal_ind_work; 2298c2ecf20Sopenharmony_ci spinlock_t hal_ind_lock; 2308c2ecf20Sopenharmony_ci struct list_head hal_ind_queue; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci struct cfg80211_scan_request *scan_req; 2338c2ecf20Sopenharmony_ci bool sw_scan; 2348c2ecf20Sopenharmony_ci u8 sw_scan_opchannel; 2358c2ecf20Sopenharmony_ci bool sw_scan_init; 2368c2ecf20Sopenharmony_ci u8 sw_scan_channel; 2378c2ecf20Sopenharmony_ci struct ieee80211_vif *sw_scan_vif; 2388c2ecf20Sopenharmony_ci struct mutex scan_lock; 2398c2ecf20Sopenharmony_ci bool scan_aborted; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci /* DXE channels */ 2428c2ecf20Sopenharmony_ci struct wcn36xx_dxe_ch dxe_tx_l_ch; /* TX low */ 2438c2ecf20Sopenharmony_ci struct wcn36xx_dxe_ch dxe_tx_h_ch; /* TX high */ 2448c2ecf20Sopenharmony_ci struct wcn36xx_dxe_ch dxe_rx_l_ch; /* RX low */ 2458c2ecf20Sopenharmony_ci struct wcn36xx_dxe_ch dxe_rx_h_ch; /* RX high */ 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci /* For synchronization of DXE resources from BH, IRQ and WQ contexts */ 2488c2ecf20Sopenharmony_ci spinlock_t dxe_lock; 2498c2ecf20Sopenharmony_ci bool queues_stopped; 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci /* Memory pools */ 2528c2ecf20Sopenharmony_ci struct wcn36xx_dxe_mem_pool mgmt_mem_pool; 2538c2ecf20Sopenharmony_ci struct wcn36xx_dxe_mem_pool data_mem_pool; 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci struct sk_buff *tx_ack_skb; 2568c2ecf20Sopenharmony_ci struct timer_list tx_ack_timer; 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci /* RF module */ 2598c2ecf20Sopenharmony_ci unsigned rf_id; 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci#ifdef CONFIG_WCN36XX_DEBUGFS 2628c2ecf20Sopenharmony_ci /* Debug file system entry */ 2638c2ecf20Sopenharmony_ci struct wcn36xx_dfs_entry dfs; 2648c2ecf20Sopenharmony_ci#endif /* CONFIG_WCN36XX_DEBUGFS */ 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci}; 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_cistatic inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn, 2698c2ecf20Sopenharmony_ci u8 major, 2708c2ecf20Sopenharmony_ci u8 minor, 2718c2ecf20Sopenharmony_ci u8 version, 2728c2ecf20Sopenharmony_ci u8 revision) 2738c2ecf20Sopenharmony_ci{ 2748c2ecf20Sopenharmony_ci return (wcn->fw_major == major && 2758c2ecf20Sopenharmony_ci wcn->fw_minor == minor && 2768c2ecf20Sopenharmony_ci wcn->fw_version == version && 2778c2ecf20Sopenharmony_ci wcn->fw_revision == revision); 2788c2ecf20Sopenharmony_ci} 2798c2ecf20Sopenharmony_civoid wcn36xx_set_default_rates(struct wcn36xx_hal_supported_rates *rates); 2808c2ecf20Sopenharmony_civoid wcn36xx_set_default_rates_v1(struct wcn36xx_hal_supported_rates_v1 *rates); 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_cistatic inline 2838c2ecf20Sopenharmony_cistruct ieee80211_sta *wcn36xx_priv_to_sta(struct wcn36xx_sta *sta_priv) 2848c2ecf20Sopenharmony_ci{ 2858c2ecf20Sopenharmony_ci return container_of((void *)sta_priv, struct ieee80211_sta, drv_priv); 2868c2ecf20Sopenharmony_ci} 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_cistatic inline 2898c2ecf20Sopenharmony_cistruct wcn36xx_vif *wcn36xx_vif_to_priv(struct ieee80211_vif *vif) 2908c2ecf20Sopenharmony_ci{ 2918c2ecf20Sopenharmony_ci return (struct wcn36xx_vif *) vif->drv_priv; 2928c2ecf20Sopenharmony_ci} 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_cistatic inline 2958c2ecf20Sopenharmony_cistruct ieee80211_vif *wcn36xx_priv_to_vif(struct wcn36xx_vif *vif_priv) 2968c2ecf20Sopenharmony_ci{ 2978c2ecf20Sopenharmony_ci return container_of((void *) vif_priv, struct ieee80211_vif, drv_priv); 2988c2ecf20Sopenharmony_ci} 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_cistatic inline 3018c2ecf20Sopenharmony_cistruct wcn36xx_sta *wcn36xx_sta_to_priv(struct ieee80211_sta *sta) 3028c2ecf20Sopenharmony_ci{ 3038c2ecf20Sopenharmony_ci return (struct wcn36xx_sta *)sta->drv_priv; 3048c2ecf20Sopenharmony_ci} 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci#endif /* _WCN36XX_H_ */ 307