wcn36xx.h (9416B)
1/* 2 * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17#ifndef _WCN36XX_H_ 18#define _WCN36XX_H_ 19 20#include <linux/completion.h> 21#include <linux/in6.h> 22#include <linux/printk.h> 23#include <linux/spinlock.h> 24#include <net/mac80211.h> 25 26#include "hal.h" 27#include "smd.h" 28#include "txrx.h" 29#include "dxe.h" 30#include "pmc.h" 31#include "debug.h" 32 33#define WLAN_NV_FILE "wlan/prima/WCNSS_qcom_wlan_nv.bin" 34#define WCN36XX_AGGR_BUFFER_SIZE 64 35 36extern unsigned int wcn36xx_dbg_mask; 37 38enum wcn36xx_debug_mask { 39 WCN36XX_DBG_DXE = 0x00000001, 40 WCN36XX_DBG_DXE_DUMP = 0x00000002, 41 WCN36XX_DBG_SMD = 0x00000004, 42 WCN36XX_DBG_SMD_DUMP = 0x00000008, 43 WCN36XX_DBG_RX = 0x00000010, 44 WCN36XX_DBG_RX_DUMP = 0x00000020, 45 WCN36XX_DBG_TX = 0x00000040, 46 WCN36XX_DBG_TX_DUMP = 0x00000080, 47 WCN36XX_DBG_HAL = 0x00000100, 48 WCN36XX_DBG_HAL_DUMP = 0x00000200, 49 WCN36XX_DBG_MAC = 0x00000400, 50 WCN36XX_DBG_BEACON = 0x00000800, 51 WCN36XX_DBG_BEACON_DUMP = 0x00001000, 52 WCN36XX_DBG_PMC = 0x00002000, 53 WCN36XX_DBG_PMC_DUMP = 0x00004000, 54 WCN36XX_DBG_TESTMODE = 0x00008000, 55 WCN36XX_DBG_TESTMODE_DUMP = 0x00010000, 56 WCN36XX_DBG_ANY = 0xffffffff, 57}; 58 59#define wcn36xx_err(fmt, arg...) \ 60 printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg) 61 62#define wcn36xx_warn(fmt, arg...) \ 63 printk(KERN_WARNING pr_fmt("WARNING " fmt), ##arg) 64 65#define wcn36xx_info(fmt, arg...) \ 66 printk(KERN_INFO pr_fmt(fmt), ##arg) 67 68#define wcn36xx_dbg(mask, fmt, arg...) do { \ 69 if (wcn36xx_dbg_mask & mask) \ 70 printk(KERN_DEBUG pr_fmt(fmt), ##arg); \ 71} while (0) 72 73#define wcn36xx_dbg_dump(mask, prefix_str, buf, len) do { \ 74 if (wcn36xx_dbg_mask & mask) \ 75 print_hex_dump(KERN_DEBUG, pr_fmt(prefix_str), \ 76 DUMP_PREFIX_OFFSET, 32, 1, \ 77 buf, len, false); \ 78} while (0) 79 80enum wcn36xx_ampdu_state { 81 WCN36XX_AMPDU_NONE, 82 WCN36XX_AMPDU_INIT, 83 WCN36XX_AMPDU_START, 84 WCN36XX_AMPDU_OPERATIONAL, 85}; 86 87#define HW_VALUE_PHY_SHIFT 8 88#define HW_VALUE_PHY(hw_value) ((hw_value) >> HW_VALUE_PHY_SHIFT) 89#define HW_VALUE_CHANNEL(hw_value) ((hw_value) & 0xFF) 90#define WCN36XX_HW_CHANNEL(__wcn)\ 91 HW_VALUE_CHANNEL(__wcn->hw->conf.chandef.chan->hw_value) 92#define WCN36XX_BAND(__wcn) (__wcn->hw->conf.chandef.chan->band) 93#define WCN36XX_CENTER_FREQ(__wcn) (__wcn->hw->conf.chandef.chan->center_freq) 94#define WCN36XX_LISTEN_INTERVAL(__wcn) (__wcn->hw->conf.listen_interval) 95#define WCN36XX_FLAGS(__wcn) (__wcn->hw->flags) 96#define WCN36XX_MAX_POWER(__wcn) (__wcn->hw->conf.chandef.chan->max_power) 97 98#define RF_UNKNOWN 0x0000 99#define RF_IRIS_WCN3620 0x3620 100#define RF_IRIS_WCN3660 0x3660 101#define RF_IRIS_WCN3680 0x3680 102 103static inline void buff_to_be(u32 *buf, size_t len) 104{ 105 int i; 106 for (i = 0; i < len; i++) 107 buf[i] = cpu_to_be32(buf[i]); 108} 109 110struct nv_data { 111 int is_valid; 112 u8 table; 113}; 114 115/** 116 * struct wcn36xx_vif - holds VIF related fields 117 * 118 * @bss_index: bss_index is initially set to 0xFF. bss_index is received from 119 * HW after first config_bss call and must be used in delete_bss and 120 * enter/exit_bmps. 121 */ 122struct wcn36xx_vif { 123 struct list_head list; 124 u8 dtim_period; 125 enum ani_ed_type encrypt_type; 126 bool is_joining; 127 bool sta_assoc; 128 struct wcn36xx_hal_mac_ssid ssid; 129 enum wcn36xx_hal_bss_type bss_type; 130 131 /* Power management */ 132 enum wcn36xx_power_state pw_state; 133 134 u8 bss_index; 135 /* Returned from WCN36XX_HAL_ADD_STA_SELF_RSP */ 136 u8 self_sta_index; 137 u8 self_dpu_desc_index; 138 u8 self_ucast_dpu_sign; 139 140#if IS_ENABLED(CONFIG_IPV6) 141 /* IPv6 addresses for WoWLAN */ 142 struct in6_addr target_ipv6_addrs[WCN36XX_HAL_IPV6_OFFLOAD_ADDR_MAX]; 143 unsigned long tentative_addrs[BITS_TO_LONGS(WCN36XX_HAL_IPV6_OFFLOAD_ADDR_MAX)]; 144 int num_target_ipv6_addrs; 145#endif 146 /* WoWLAN GTK rekey data */ 147 struct { 148 u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN]; 149 __le64 replay_ctr; 150 bool valid; 151 } rekey_data; 152 153 struct list_head sta_list; 154 155 int bmps_fail_ct; 156}; 157 158/** 159 * struct wcn36xx_sta - holds STA related fields 160 * 161 * @tid: traffic ID that is used during AMPDU and in TX BD. 162 * @sta_index: STA index is returned from HW after config_sta call and is 163 * used in both SMD channel and TX BD. 164 * @dpu_desc_index: DPU descriptor index is returned from HW after config_sta 165 * call and is used in TX BD. 166 * @bss_sta_index: STA index is returned from HW after config_bss call and is 167 * used in both SMD channel and TX BD. See table bellow when it is used. 168 * @bss_dpu_desc_index: DPU descriptor index is returned from HW after 169 * config_bss call and is used in TX BD. 170 * ______________________________________________ 171 * | | STA | AP | 172 * |______________|_____________|_______________| 173 * | TX BD |bss_sta_index| sta_index | 174 * |______________|_____________|_______________| 175 * |all SMD calls |bss_sta_index| sta_index | 176 * |______________|_____________|_______________| 177 * |smd_delete_sta| sta_index | sta_index | 178 * |______________|_____________|_______________| 179 */ 180struct wcn36xx_sta { 181 struct list_head list; 182 struct wcn36xx_vif *vif; 183 u16 aid; 184 u16 tid; 185 u8 sta_index; 186 u8 dpu_desc_index; 187 u8 ucast_dpu_sign; 188 u8 bss_sta_index; 189 u8 bss_dpu_desc_index; 190 bool is_data_encrypted; 191 /* Rates */ 192 struct wcn36xx_hal_supported_rates_v1 supported_rates; 193 194 spinlock_t ampdu_lock; /* protects next two fields */ 195 enum wcn36xx_ampdu_state ampdu_state[16]; 196 int non_agg_frame_ct; 197}; 198 199struct wcn36xx_dxe_ch; 200 201struct wcn36xx_chan_survey { 202 s8 rssi; 203 u8 snr; 204}; 205 206struct wcn36xx { 207 struct ieee80211_hw *hw; 208 struct device *dev; 209 struct list_head vif_list; 210 211 const char *nv_file; 212 const struct firmware *nv; 213 214 u8 fw_revision; 215 u8 fw_version; 216 u8 fw_minor; 217 u8 fw_major; 218 u32 fw_feat_caps[WCN36XX_HAL_CAPS_SIZE]; 219 bool is_pronto; 220 221 /* extra byte for the NULL termination */ 222 u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1]; 223 u8 wlan_version[WCN36XX_HAL_VERSION_LENGTH + 1]; 224 225 bool first_boot; 226 227 /* IRQs */ 228 int tx_irq; 229 int rx_irq; 230 void __iomem *ccu_base; 231 void __iomem *dxe_base; 232 233 struct rpmsg_endpoint *smd_channel; 234 235 struct qcom_smem_state *tx_enable_state; 236 unsigned tx_enable_state_bit; 237 struct qcom_smem_state *tx_rings_empty_state; 238 unsigned tx_rings_empty_state_bit; 239 240 /* prevents concurrent FW reconfiguration */ 241 struct mutex conf_mutex; 242 243 /* 244 * smd_buf must be protected with smd_mutex to garantee 245 * that all messages are sent one after another 246 */ 247 u8 *hal_buf; 248 size_t hal_rsp_len; 249 struct mutex hal_mutex; 250 struct completion hal_rsp_compl; 251 struct workqueue_struct *hal_ind_wq; 252 struct work_struct hal_ind_work; 253 spinlock_t hal_ind_lock; 254 struct list_head hal_ind_queue; 255 256 struct cfg80211_scan_request *scan_req; 257 bool sw_scan; 258 u8 sw_scan_opchannel; 259 bool sw_scan_init; 260 u8 sw_scan_channel; 261 struct ieee80211_vif *sw_scan_vif; 262 struct mutex scan_lock; 263 bool scan_aborted; 264 265 /* DXE channels */ 266 struct wcn36xx_dxe_ch dxe_tx_l_ch; /* TX low */ 267 struct wcn36xx_dxe_ch dxe_tx_h_ch; /* TX high */ 268 struct wcn36xx_dxe_ch dxe_rx_l_ch; /* RX low */ 269 struct wcn36xx_dxe_ch dxe_rx_h_ch; /* RX high */ 270 271 /* For synchronization of DXE resources from BH, IRQ and WQ contexts */ 272 spinlock_t dxe_lock; 273 bool queues_stopped; 274 275 /* Memory pools */ 276 struct wcn36xx_dxe_mem_pool mgmt_mem_pool; 277 struct wcn36xx_dxe_mem_pool data_mem_pool; 278 279 struct sk_buff *tx_ack_skb; 280 struct timer_list tx_ack_timer; 281 282 /* For A-MSDU re-aggregation */ 283 struct sk_buff_head amsdu; 284 285 /* RF module */ 286 unsigned rf_id; 287 288#ifdef CONFIG_WCN36XX_DEBUGFS 289 /* Debug file system entry */ 290 struct wcn36xx_dfs_entry dfs; 291#endif /* CONFIG_WCN36XX_DEBUGFS */ 292 293 struct ieee80211_supported_band *band; 294 struct ieee80211_channel *channel; 295 296 spinlock_t survey_lock; /* protects chan_survey */ 297 struct wcn36xx_chan_survey *chan_survey; 298}; 299 300static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn, 301 u8 major, 302 u8 minor, 303 u8 version, 304 u8 revision) 305{ 306 return (wcn->fw_major == major && 307 wcn->fw_minor == minor && 308 wcn->fw_version == version && 309 wcn->fw_revision == revision); 310} 311void wcn36xx_set_default_rates(struct wcn36xx_hal_supported_rates *rates); 312void wcn36xx_set_default_rates_v1(struct wcn36xx_hal_supported_rates_v1 *rates); 313 314static inline 315struct ieee80211_sta *wcn36xx_priv_to_sta(struct wcn36xx_sta *sta_priv) 316{ 317 return container_of((void *)sta_priv, struct ieee80211_sta, drv_priv); 318} 319 320static inline 321struct wcn36xx_vif *wcn36xx_vif_to_priv(struct ieee80211_vif *vif) 322{ 323 return (struct wcn36xx_vif *) vif->drv_priv; 324} 325 326static inline 327struct ieee80211_vif *wcn36xx_priv_to_vif(struct wcn36xx_vif *vif_priv) 328{ 329 return container_of((void *) vif_priv, struct ieee80211_vif, drv_priv); 330} 331 332static inline 333struct wcn36xx_sta *wcn36xx_sta_to_priv(struct ieee80211_sta *sta) 334{ 335 return (struct wcn36xx_sta *)sta->drv_priv; 336} 337 338#endif /* _WCN36XX_H_ */