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 _DXE_H_ 18#define _DXE_H_ 19 20#include "wcn36xx.h" 21 22/* 23TX_LOW = DMA0 24TX_HIGH = DMA4 25RX_LOW = DMA1 26RX_HIGH = DMA3 27H2H_TEST_RX_TX = DMA2 28*/ 29 30/* DXE registers */ 31#define WCN36XX_DXE_MEM_REG 0x202000 32 33#define WCN36XX_DXE_CCU_INT 0xA0011 34#define WCN36XX_DXE_REG_CCU_INT_3660 0x200b10 35#define WCN36XX_DXE_REG_CCU_INT_3680 0x2050dc 36 37/* TODO This must calculated properly but not hardcoded */ 38#define WCN36XX_DXE_CTRL_TX_L 0x328a44 39#define WCN36XX_DXE_CTRL_TX_H 0x32ce44 40#define WCN36XX_DXE_CTRL_RX_L 0x12ad2f 41#define WCN36XX_DXE_CTRL_RX_H 0x12d12f 42#define WCN36XX_DXE_CTRL_TX_H_BD 0x30ce45 43#define WCN36XX_DXE_CTRL_TX_H_SKB 0x32ce4d 44#define WCN36XX_DXE_CTRL_TX_L_BD 0x308a45 45#define WCN36XX_DXE_CTRL_TX_L_SKB 0x328a4d 46 47/* TODO This must calculated properly but not hardcoded */ 48#define WCN36XX_DXE_WQ_TX_L 0x17 49#define WCN36XX_DXE_WQ_TX_H 0x17 50#define WCN36XX_DXE_WQ_RX_L 0xB 51#define WCN36XX_DXE_WQ_RX_H 0x4 52 53/* DXE descriptor control filed */ 54#define WCN36XX_DXE_CTRL_VALID_MASK (0x00000001) 55 56/* TODO This must calculated properly but not hardcoded */ 57/* DXE default control register values */ 58#define WCN36XX_DXE_CH_DEFAULT_CTL_RX_L 0x847EAD2F 59#define WCN36XX_DXE_CH_DEFAULT_CTL_RX_H 0x84FED12F 60#define WCN36XX_DXE_CH_DEFAULT_CTL_TX_H 0x853ECF4D 61#define WCN36XX_DXE_CH_DEFAULT_CTL_TX_L 0x843e8b4d 62 63/* Common DXE registers */ 64#define WCN36XX_DXE_MEM_CSR (WCN36XX_DXE_MEM_REG + 0x00) 65#define WCN36XX_DXE_REG_CSR_RESET (WCN36XX_DXE_MEM_REG + 0x00) 66#define WCN36XX_DXE_ENCH_ADDR (WCN36XX_DXE_MEM_REG + 0x04) 67#define WCN36XX_DXE_REG_CH_EN (WCN36XX_DXE_MEM_REG + 0x08) 68#define WCN36XX_DXE_REG_CH_DONE (WCN36XX_DXE_MEM_REG + 0x0C) 69#define WCN36XX_DXE_REG_CH_ERR (WCN36XX_DXE_MEM_REG + 0x10) 70#define WCN36XX_DXE_INT_MASK_REG (WCN36XX_DXE_MEM_REG + 0x18) 71#define WCN36XX_DXE_INT_SRC_RAW_REG (WCN36XX_DXE_MEM_REG + 0x20) 72 /* #define WCN36XX_DXE_INT_CH6_MASK 0x00000040 */ 73 /* #define WCN36XX_DXE_INT_CH5_MASK 0x00000020 */ 74 #define WCN36XX_DXE_INT_CH4_MASK 0x00000010 75 #define WCN36XX_DXE_INT_CH3_MASK 0x00000008 76 /* #define WCN36XX_DXE_INT_CH2_MASK 0x00000004 */ 77 #define WCN36XX_DXE_INT_CH1_MASK 0x00000002 78 #define WCN36XX_DXE_INT_CH0_MASK 0x00000001 79#define WCN36XX_DXE_0_INT_CLR (WCN36XX_DXE_MEM_REG + 0x30) 80#define WCN36XX_DXE_0_INT_ED_CLR (WCN36XX_DXE_MEM_REG + 0x34) 81#define WCN36XX_DXE_0_INT_DONE_CLR (WCN36XX_DXE_MEM_REG + 0x38) 82#define WCN36XX_DXE_0_INT_ERR_CLR (WCN36XX_DXE_MEM_REG + 0x3C) 83 84#define WCN36XX_DXE_0_CH0_STATUS (WCN36XX_DXE_MEM_REG + 0x404) 85#define WCN36XX_DXE_0_CH1_STATUS (WCN36XX_DXE_MEM_REG + 0x444) 86#define WCN36XX_DXE_0_CH2_STATUS (WCN36XX_DXE_MEM_REG + 0x484) 87#define WCN36XX_DXE_0_CH3_STATUS (WCN36XX_DXE_MEM_REG + 0x4C4) 88#define WCN36XX_DXE_0_CH4_STATUS (WCN36XX_DXE_MEM_REG + 0x504) 89 90#define WCN36XX_DXE_REG_RESET 0x5c89 91 92/* Temporary BMU Workqueue 4 */ 93#define WCN36XX_DXE_BMU_WQ_RX_LOW 0xB 94#define WCN36XX_DXE_BMU_WQ_RX_HIGH 0x4 95/* DMA channel offset */ 96#define WCN36XX_DXE_TX_LOW_OFFSET 0x400 97#define WCN36XX_DXE_TX_HIGH_OFFSET 0x500 98#define WCN36XX_DXE_RX_LOW_OFFSET 0x440 99#define WCN36XX_DXE_RX_HIGH_OFFSET 0x4C0 100 101/* Address of the next DXE descriptor */ 102#define WCN36XX_DXE_CH_NEXT_DESC_ADDR 0x001C 103#define WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_L (WCN36XX_DXE_MEM_REG + \ 104 WCN36XX_DXE_TX_LOW_OFFSET + \ 105 WCN36XX_DXE_CH_NEXT_DESC_ADDR) 106#define WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_H (WCN36XX_DXE_MEM_REG + \ 107 WCN36XX_DXE_TX_HIGH_OFFSET + \ 108 WCN36XX_DXE_CH_NEXT_DESC_ADDR) 109#define WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_L (WCN36XX_DXE_MEM_REG + \ 110 WCN36XX_DXE_RX_LOW_OFFSET + \ 111 WCN36XX_DXE_CH_NEXT_DESC_ADDR) 112#define WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_H (WCN36XX_DXE_MEM_REG + \ 113 WCN36XX_DXE_RX_HIGH_OFFSET + \ 114 WCN36XX_DXE_CH_NEXT_DESC_ADDR) 115 116/* DXE Descriptor source address */ 117#define WCN36XX_DXE_CH_SRC_ADDR 0x000C 118#define WCN36XX_DXE_CH_SRC_ADDR_RX_L (WCN36XX_DXE_MEM_REG + \ 119 WCN36XX_DXE_RX_LOW_OFFSET + \ 120 WCN36XX_DXE_CH_SRC_ADDR) 121#define WCN36XX_DXE_CH_SRC_ADDR_RX_H (WCN36XX_DXE_MEM_REG + \ 122 WCN36XX_DXE_RX_HIGH_OFFSET + \ 123 WCN36XX_DXE_CH_SRC_ADDR) 124 125/* DXE Descriptor address destination address */ 126#define WCN36XX_DXE_CH_DEST_ADDR 0x0014 127#define WCN36XX_DXE_CH_DEST_ADDR_TX_L (WCN36XX_DXE_MEM_REG + \ 128 WCN36XX_DXE_TX_LOW_OFFSET + \ 129 WCN36XX_DXE_CH_DEST_ADDR) 130#define WCN36XX_DXE_CH_DEST_ADDR_TX_H (WCN36XX_DXE_MEM_REG + \ 131 WCN36XX_DXE_TX_HIGH_OFFSET + \ 132 WCN36XX_DXE_CH_DEST_ADDR) 133#define WCN36XX_DXE_CH_DEST_ADDR_RX_L (WCN36XX_DXE_MEM_REG + \ 134 WCN36XX_DXE_RX_LOW_OFFSET + \ 135 WCN36XX_DXE_CH_DEST_ADDR) 136#define WCN36XX_DXE_CH_DEST_ADDR_RX_H (WCN36XX_DXE_MEM_REG + \ 137 WCN36XX_DXE_RX_HIGH_OFFSET + \ 138 WCN36XX_DXE_CH_DEST_ADDR) 139 140/* Interrupt status */ 141#define WCN36XX_DXE_CH_STATUS_REG_ADDR 0x0004 142#define WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_L (WCN36XX_DXE_MEM_REG + \ 143 WCN36XX_DXE_TX_LOW_OFFSET + \ 144 WCN36XX_DXE_CH_STATUS_REG_ADDR) 145#define WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_H (WCN36XX_DXE_MEM_REG + \ 146 WCN36XX_DXE_TX_HIGH_OFFSET + \ 147 WCN36XX_DXE_CH_STATUS_REG_ADDR) 148#define WCN36XX_DXE_CH_STATUS_REG_ADDR_RX_L (WCN36XX_DXE_MEM_REG + \ 149 WCN36XX_DXE_RX_LOW_OFFSET + \ 150 WCN36XX_DXE_CH_STATUS_REG_ADDR) 151#define WCN36XX_DXE_CH_STATUS_REG_ADDR_RX_H (WCN36XX_DXE_MEM_REG + \ 152 WCN36XX_DXE_RX_HIGH_OFFSET + \ 153 WCN36XX_DXE_CH_STATUS_REG_ADDR) 154 155 156/* DXE default control register */ 157#define WCN36XX_DXE_REG_CTL_RX_L (WCN36XX_DXE_MEM_REG + \ 158 WCN36XX_DXE_RX_LOW_OFFSET) 159#define WCN36XX_DXE_REG_CTL_RX_H (WCN36XX_DXE_MEM_REG + \ 160 WCN36XX_DXE_RX_HIGH_OFFSET) 161#define WCN36XX_DXE_REG_CTL_TX_H (WCN36XX_DXE_MEM_REG + \ 162 WCN36XX_DXE_TX_HIGH_OFFSET) 163#define WCN36XX_DXE_REG_CTL_TX_L (WCN36XX_DXE_MEM_REG + \ 164 WCN36XX_DXE_TX_LOW_OFFSET) 165 166#define WCN36XX_SMSM_WLAN_TX_ENABLE 0x00000400 167#define WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY 0x00000200 168 169 170/* Interrupt control channel mask */ 171#define WCN36XX_INT_MASK_CHAN_TX_L 0x00000001 172#define WCN36XX_INT_MASK_CHAN_RX_L 0x00000002 173#define WCN36XX_INT_MASK_CHAN_RX_H 0x00000008 174#define WCN36XX_INT_MASK_CHAN_TX_H 0x00000010 175 176#define WCN36XX_BD_CHUNK_SIZE 128 177 178#define WCN36XX_PKT_SIZE 0xF20 179enum wcn36xx_dxe_ch_type { 180 WCN36XX_DXE_CH_TX_L, 181 WCN36XX_DXE_CH_TX_H, 182 WCN36XX_DXE_CH_RX_L, 183 WCN36XX_DXE_CH_RX_H 184}; 185 186/* amount of descriptors per channel */ 187enum wcn36xx_dxe_ch_desc_num { 188 WCN36XX_DXE_CH_DESC_NUMB_TX_L = 128, 189 WCN36XX_DXE_CH_DESC_NUMB_TX_H = 10, 190 WCN36XX_DXE_CH_DESC_NUMB_RX_L = 512, 191 WCN36XX_DXE_CH_DESC_NUMB_RX_H = 40 192}; 193 194/** 195 * struct wcn36xx_dxe_desc - describes descriptor of one DXE buffer 196 * 197 * @ctrl: is a union that consists of following bits: 198 * union { 199 * u32 valid :1; //0 = DMA stop, 1 = DMA continue with this 200 * //descriptor 201 * u32 transfer_type :2; //0 = Host to Host space 202 * u32 eop :1; //End of Packet 203 * u32 bd_handling :1; //if transferType = Host to BMU, then 0 204 * // means first 128 bytes contain BD, and 1 205 * // means create new empty BD 206 * u32 siq :1; // SIQ 207 * u32 diq :1; // DIQ 208 * u32 pdu_rel :1; //0 = don't release BD and PDUs when done, 209 * // 1 = release them 210 * u32 bthld_sel :4; //BMU Threshold Select 211 * u32 prio :3; //Specifies the priority level to use for 212 * // the transfer 213 * u32 stop_channel :1; //1 = DMA stops processing further, channel 214 * //requires re-enabling after this 215 * u32 intr :1; //Interrupt on Descriptor Done 216 * u32 rsvd :1; //reserved 217 * u32 size :14;//14 bits used - ignored for BMU transfers, 218 * //only used for host to host transfers? 219 * } ctrl; 220 */ 221struct wcn36xx_dxe_desc { 222 u32 ctrl; 223 u32 fr_len; 224 225 u32 src_addr_l; 226 u32 dst_addr_l; 227 u32 phy_next_l; 228 u32 src_addr_h; 229 u32 dst_addr_h; 230 u32 phy_next_h; 231} __packed; 232 233/* DXE Control block */ 234struct wcn36xx_dxe_ctl { 235 struct wcn36xx_dxe_ctl *next; 236 struct wcn36xx_dxe_desc *desc; 237 unsigned int desc_phy_addr; 238 int ctl_blk_order; 239 struct sk_buff *skb; 240 spinlock_t skb_lock; 241 void *bd_cpu_addr; 242 dma_addr_t bd_phy_addr; 243}; 244 245struct wcn36xx_dxe_ch { 246 enum wcn36xx_dxe_ch_type ch_type; 247 void *cpu_addr; 248 dma_addr_t dma_addr; 249 enum wcn36xx_dxe_ch_desc_num desc_num; 250 /* DXE control block ring */ 251 struct wcn36xx_dxe_ctl *head_blk_ctl; 252 struct wcn36xx_dxe_ctl *tail_blk_ctl; 253 254 /* DXE channel specific configs */ 255 u32 dxe_wq; 256 u32 ctrl_bd; 257 u32 ctrl_skb; 258 u32 reg_ctrl; 259 u32 def_ctrl; 260}; 261 262/* Memory Pool for BD headers */ 263struct wcn36xx_dxe_mem_pool { 264 int chunk_size; 265 void *virt_addr; 266 dma_addr_t phy_addr; 267}; 268 269struct wcn36xx_vif; 270int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn); 271void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn); 272void wcn36xx_dxe_rx_frame(struct wcn36xx *wcn); 273int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn); 274void wcn36xx_dxe_free_ctl_blks(struct wcn36xx *wcn); 275int wcn36xx_dxe_init(struct wcn36xx *wcn); 276void wcn36xx_dxe_deinit(struct wcn36xx *wcn); 277int wcn36xx_dxe_init_channels(struct wcn36xx *wcn); 278int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, 279 struct wcn36xx_vif *vif_priv, 280 struct sk_buff *skb, 281 bool is_low); 282void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status); 283void *wcn36xx_dxe_get_next_bd(struct wcn36xx *wcn, bool is_low); 284#endif /* _DXE_H_ */ 285