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 /* 23 TX_LOW = DMA0 24 TX_HIGH = DMA4 25 RX_LOW = DMA1 26 RX_HIGH = DMA3 27 H2H_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 179 enum 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 */ 187 enum 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 */ 221 struct 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 */ 234 struct 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 245 struct 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 */ 263 struct wcn36xx_dxe_mem_pool { 264 int chunk_size; 265 void *virt_addr; 266 dma_addr_t phy_addr; 267 }; 268 269 struct wcn36xx_vif; 270 int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn); 271 void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn); 272 void wcn36xx_dxe_rx_frame(struct wcn36xx *wcn); 273 int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn); 274 void wcn36xx_dxe_free_ctl_blks(struct wcn36xx *wcn); 275 int wcn36xx_dxe_init(struct wcn36xx *wcn); 276 void wcn36xx_dxe_deinit(struct wcn36xx *wcn); 277 int wcn36xx_dxe_init_channels(struct wcn36xx *wcn); 278 int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, 279 struct wcn36xx_vif *vif_priv, 280 struct sk_buff *skb, 281 bool is_low); 282 void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status); 283 void *wcn36xx_dxe_get_next_bd(struct wcn36xx *wcn, bool is_low); 284 #endif /* _DXE_H_ */ 285