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/printk.h> 22#include <linux/spinlock.h> 23#include <net/mac80211.h> 24 25#include "hal.h" 26#include "smd.h" 27#include "txrx.h" 28#include "dxe.h" 29#include "pmc.h" 30#include "debug.h" 31 32#define WLAN_NV_FILE "wlan/prima/WCNSS_qcom_wlan_nv.bin" 33#define WCN36XX_AGGR_BUFFER_SIZE 64 34 35/* How many frames until we start a-mpdu TX session */ 36#define WCN36XX_AMPDU_START_THRESH 20 37 38extern unsigned int wcn36xx_dbg_mask; 39 40enum wcn36xx_debug_mask { 41 WCN36XX_DBG_DXE = 0x00000001, 42 WCN36XX_DBG_DXE_DUMP = 0x00000002, 43 WCN36XX_DBG_SMD = 0x00000004, 44 WCN36XX_DBG_SMD_DUMP = 0x00000008, 45 WCN36XX_DBG_RX = 0x00000010, 46 WCN36XX_DBG_RX_DUMP = 0x00000020, 47 WCN36XX_DBG_TX = 0x00000040, 48 WCN36XX_DBG_TX_DUMP = 0x00000080, 49 WCN36XX_DBG_HAL = 0x00000100, 50 WCN36XX_DBG_HAL_DUMP = 0x00000200, 51 WCN36XX_DBG_MAC = 0x00000400, 52 WCN36XX_DBG_BEACON = 0x00000800, 53 WCN36XX_DBG_BEACON_DUMP = 0x00001000, 54 WCN36XX_DBG_PMC = 0x00002000, 55 WCN36XX_DBG_PMC_DUMP = 0x00004000, 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 WCN36XX_HW_CHANNEL(__wcn) (__wcn->hw->conf.chandef.chan->hw_value) 88#define WCN36XX_BAND(__wcn) (__wcn->hw->conf.chandef.chan->band) 89#define WCN36XX_CENTER_FREQ(__wcn) (__wcn->hw->conf.chandef.chan->center_freq) 90#define WCN36XX_LISTEN_INTERVAL(__wcn) (__wcn->hw->conf.listen_interval) 91#define WCN36XX_FLAGS(__wcn) (__wcn->hw->flags) 92#define WCN36XX_MAX_POWER(__wcn) (__wcn->hw->conf.chandef.chan->max_power) 93 94static inline void buff_to_be(u32 *buf, size_t len) 95{ 96 int i; 97 for (i = 0; i < len; i++) 98 buf[i] = cpu_to_be32(buf[i]); 99} 100 101struct nv_data { 102 int is_valid; 103 u8 table; 104}; 105 106/* Interface for platform control path 107 * 108 * @open: hook must be called when wcn36xx wants to open control channel. 109 * @tx: sends a buffer. 110 */ 111struct wcn36xx_platform_ctrl_ops { 112 int (*open)(void *drv_priv, void *rsp_cb); 113 void (*close)(void); 114 int (*tx)(char *buf, size_t len); 115 int (*get_hw_mac)(u8 *addr); 116 int (*smsm_change_state)(u32 clear_mask, u32 set_mask); 117}; 118 119/** 120 * struct wcn36xx_vif - holds VIF related fields 121 * 122 * @bss_index: bss_index is initially set to 0xFF. bss_index is received from 123 * HW after first config_bss call and must be used in delete_bss and 124 * enter/exit_bmps. 125 */ 126struct wcn36xx_vif { 127 struct list_head list; 128 struct wcn36xx_sta *sta; 129 u8 dtim_period; 130 enum ani_ed_type encrypt_type; 131 bool is_joining; 132 struct wcn36xx_hal_mac_ssid ssid; 133 134 /* Power management */ 135 enum wcn36xx_power_state pw_state; 136 137 u8 bss_index; 138 /* Returned from WCN36XX_HAL_ADD_STA_SELF_RSP */ 139 u8 self_sta_index; 140 u8 self_dpu_desc_index; 141 u8 self_ucast_dpu_sign; 142}; 143 144/** 145 * struct wcn36xx_sta - holds STA related fields 146 * 147 * @tid: traffic ID that is used during AMPDU and in TX BD. 148 * @sta_index: STA index is returned from HW after config_sta call and is 149 * used in both SMD channel and TX BD. 150 * @dpu_desc_index: DPU descriptor index is returned from HW after config_sta 151 * call and is used in TX BD. 152 * @bss_sta_index: STA index is returned from HW after config_bss call and is 153 * used in both SMD channel and TX BD. See table bellow when it is used. 154 * @bss_dpu_desc_index: DPU descriptor index is returned from HW after 155 * config_bss call and is used in TX BD. 156 * ______________________________________________ 157 * | | STA | AP | 158 * |______________|_____________|_______________| 159 * | TX BD |bss_sta_index| sta_index | 160 * |______________|_____________|_______________| 161 * |all SMD calls |bss_sta_index| sta_index | 162 * |______________|_____________|_______________| 163 * |smd_delete_sta| sta_index | sta_index | 164 * |______________|_____________|_______________| 165 */ 166struct wcn36xx_sta { 167 struct wcn36xx_vif *vif; 168 u16 aid; 169 u16 tid; 170 u8 sta_index; 171 u8 dpu_desc_index; 172 u8 ucast_dpu_sign; 173 u8 bss_sta_index; 174 u8 bss_dpu_desc_index; 175 bool is_data_encrypted; 176 /* Rates */ 177 struct wcn36xx_hal_supported_rates supported_rates; 178 179 spinlock_t ampdu_lock; /* protects next two fields */ 180 enum wcn36xx_ampdu_state ampdu_state[16]; 181 int non_agg_frame_ct; 182}; 183struct wcn36xx_dxe_ch; 184struct wcn36xx { 185 struct ieee80211_hw *hw; 186 struct device *dev; 187 struct list_head vif_list; 188 189 const struct firmware *nv; 190 191 u8 fw_revision; 192 u8 fw_version; 193 u8 fw_minor; 194 u8 fw_major; 195 u32 fw_feat_caps[WCN36XX_HAL_CAPS_SIZE]; 196 u32 chip_version; 197 198 /* extra byte for the NULL termination */ 199 u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1]; 200 u8 wlan_version[WCN36XX_HAL_VERSION_LENGTH + 1]; 201 202 /* IRQs */ 203 int tx_irq; 204 int rx_irq; 205 void __iomem *mmio; 206 207 struct wcn36xx_platform_ctrl_ops *ctrl_ops; 208 /* 209 * smd_buf must be protected with smd_mutex to garantee 210 * that all messages are sent one after another 211 */ 212 u8 *hal_buf; 213 size_t hal_rsp_len; 214 struct mutex hal_mutex; 215 struct completion hal_rsp_compl; 216 struct workqueue_struct *hal_ind_wq; 217 struct work_struct hal_ind_work; 218 struct mutex hal_ind_mutex; 219 struct list_head hal_ind_queue; 220 221 /* DXE channels */ 222 struct wcn36xx_dxe_ch dxe_tx_l_ch; /* TX low */ 223 struct wcn36xx_dxe_ch dxe_tx_h_ch; /* TX high */ 224 struct wcn36xx_dxe_ch dxe_rx_l_ch; /* RX low */ 225 struct wcn36xx_dxe_ch dxe_rx_h_ch; /* RX high */ 226 227 /* For synchronization of DXE resources from BH, IRQ and WQ contexts */ 228 spinlock_t dxe_lock; 229 bool queues_stopped; 230 231 /* Memory pools */ 232 struct wcn36xx_dxe_mem_pool mgmt_mem_pool; 233 struct wcn36xx_dxe_mem_pool data_mem_pool; 234 235 struct sk_buff *tx_ack_skb; 236 237#ifdef CONFIG_WCN36XX_DEBUGFS 238 /* Debug file system entry */ 239 struct wcn36xx_dfs_entry dfs; 240#endif /* CONFIG_WCN36XX_DEBUGFS */ 241 242}; 243 244#define WCN36XX_CHIP_3660 0 245#define WCN36XX_CHIP_3680 1 246 247static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn, 248 u8 major, 249 u8 minor, 250 u8 version, 251 u8 revision) 252{ 253 return (wcn->fw_major == major && 254 wcn->fw_minor == minor && 255 wcn->fw_version == version && 256 wcn->fw_revision == revision); 257} 258void wcn36xx_set_default_rates(struct wcn36xx_hal_supported_rates *rates); 259 260static inline 261struct ieee80211_sta *wcn36xx_priv_to_sta(struct wcn36xx_sta *sta_priv) 262{ 263 return container_of((void *)sta_priv, struct ieee80211_sta, drv_priv); 264} 265 266#endif /* _WCN36XX_H_ */ 267