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