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 /* DXE - DMA transfer engine 18 * we have 2 channels(High prio and Low prio) for TX and 2 channels for RX. 19 * through low channels data packets are transfered 20 * through high channels managment packets are transfered 21 */ 22 23 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 24 25 #include <linux/interrupt.h> 26 #include "wcn36xx.h" 27 #include "txrx.h" 28 29 void *wcn36xx_dxe_get_next_bd(struct wcn36xx *wcn, bool is_low) 30 { 31 struct wcn36xx_dxe_ch *ch = is_low ? 32 &wcn->dxe_tx_l_ch : 33 &wcn->dxe_tx_h_ch; 34 35 return ch->head_blk_ctl->bd_cpu_addr; 36 } 37 38 static void wcn36xx_dxe_write_register(struct wcn36xx *wcn, int addr, int data) 39 { 40 wcn36xx_dbg(WCN36XX_DBG_DXE, 41 "wcn36xx_dxe_write_register: addr=%x, data=%x\n", 42 addr, data); 43 44 writel(data, wcn->mmio + addr); 45 } 46 47 #define wcn36xx_dxe_write_register_x(wcn, reg, reg_data) \ 48 do { \ 49 if (wcn->chip_version == WCN36XX_CHIP_3680) \ 50 wcn36xx_dxe_write_register(wcn, reg ## _3680, reg_data); \ 51 else \ 52 wcn36xx_dxe_write_register(wcn, reg ## _3660, reg_data); \ 53 } while (0) \ 54 55 static void wcn36xx_dxe_read_register(struct wcn36xx *wcn, int addr, int *data) 56 { 57 *data = readl(wcn->mmio + addr); 58 59 wcn36xx_dbg(WCN36XX_DBG_DXE, 60 "wcn36xx_dxe_read_register: addr=%x, data=%x\n", 61 addr, *data); 62 } 63 64 static void wcn36xx_dxe_free_ctl_block(struct wcn36xx_dxe_ch *ch) 65 { 66 struct wcn36xx_dxe_ctl *ctl = ch->head_blk_ctl, *next; 67 int i; 68 69 for (i = 0; i < ch->desc_num && ctl; i++) { 70 next = ctl->next; 71 kfree(ctl); 72 ctl = next; 73 } 74 } 75 76 static int wcn36xx_dxe_allocate_ctl_block(struct wcn36xx_dxe_ch *ch) 77 { 78 struct wcn36xx_dxe_ctl *prev_ctl = NULL; 79 struct wcn36xx_dxe_ctl *cur_ctl = NULL; 80 int i; 81 82 for (i = 0; i < ch->desc_num; i++) { 83 cur_ctl = kzalloc(sizeof(*cur_ctl), GFP_KERNEL); 84 if (!cur_ctl) 85 goto out_fail; 86 87 spin_lock_init(&cur_ctl->skb_lock); 88 cur_ctl->ctl_blk_order = i; 89 if (i == 0) { 90 ch->head_blk_ctl = cur_ctl; 91 ch->tail_blk_ctl = cur_ctl; 92 } else if (ch->desc_num - 1 == i) { 93 prev_ctl->next = cur_ctl; 94 cur_ctl->next = ch->head_blk_ctl; 95 } else { 96 prev_ctl->next = cur_ctl; 97 } 98 prev_ctl = cur_ctl; 99 } 100 101 return 0; 102 103 out_fail: 104 wcn36xx_dxe_free_ctl_block(ch); 105 return -ENOMEM; 106 } 107 108 int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn) 109 { 110 int ret; 111 112 wcn->dxe_tx_l_ch.ch_type = WCN36XX_DXE_CH_TX_L; 113 wcn->dxe_tx_h_ch.ch_type = WCN36XX_DXE_CH_TX_H; 114 wcn->dxe_rx_l_ch.ch_type = WCN36XX_DXE_CH_RX_L; 115 wcn->dxe_rx_h_ch.ch_type = WCN36XX_DXE_CH_RX_H; 116 117 wcn->dxe_tx_l_ch.desc_num = WCN36XX_DXE_CH_DESC_NUMB_TX_L; 118 wcn->dxe_tx_h_ch.desc_num = WCN36XX_DXE_CH_DESC_NUMB_TX_H; 119 wcn->dxe_rx_l_ch.desc_num = WCN36XX_DXE_CH_DESC_NUMB_RX_L; 120 wcn->dxe_rx_h_ch.desc_num = WCN36XX_DXE_CH_DESC_NUMB_RX_H; 121 122 wcn->dxe_tx_l_ch.dxe_wq = WCN36XX_DXE_WQ_TX_L; 123 wcn->dxe_tx_h_ch.dxe_wq = WCN36XX_DXE_WQ_TX_H; 124 125 wcn->dxe_tx_l_ch.ctrl_bd = WCN36XX_DXE_CTRL_TX_L_BD; 126 wcn->dxe_tx_h_ch.ctrl_bd = WCN36XX_DXE_CTRL_TX_H_BD; 127 128 wcn->dxe_tx_l_ch.ctrl_skb = WCN36XX_DXE_CTRL_TX_L_SKB; 129 wcn->dxe_tx_h_ch.ctrl_skb = WCN36XX_DXE_CTRL_TX_H_SKB; 130 131 wcn->dxe_tx_l_ch.reg_ctrl = WCN36XX_DXE_REG_CTL_TX_L; 132 wcn->dxe_tx_h_ch.reg_ctrl = WCN36XX_DXE_REG_CTL_TX_H; 133 134 wcn->dxe_tx_l_ch.def_ctrl = WCN36XX_DXE_CH_DEFAULT_CTL_TX_L; 135 wcn->dxe_tx_h_ch.def_ctrl = WCN36XX_DXE_CH_DEFAULT_CTL_TX_H; 136 137 /* DXE control block allocation */ 138 ret = wcn36xx_dxe_allocate_ctl_block(&wcn->dxe_tx_l_ch); 139 if (ret) 140 goto out_err; 141 ret = wcn36xx_dxe_allocate_ctl_block(&wcn->dxe_tx_h_ch); 142 if (ret) 143 goto out_err; 144 ret = wcn36xx_dxe_allocate_ctl_block(&wcn->dxe_rx_l_ch); 145 if (ret) 146 goto out_err; 147 ret = wcn36xx_dxe_allocate_ctl_block(&wcn->dxe_rx_h_ch); 148 if (ret) 149 goto out_err; 150 151 /* Initialize SMSM state Clear TX Enable RING EMPTY STATE */ 152 ret = wcn->ctrl_ops->smsm_change_state( 153 WCN36XX_SMSM_WLAN_TX_ENABLE, 154 WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY); 155 156 return 0; 157 158 out_err: 159 wcn36xx_err("Failed to allocate DXE control blocks\n"); 160 wcn36xx_dxe_free_ctl_blks(wcn); 161 return -ENOMEM; 162 } 163 164 void wcn36xx_dxe_free_ctl_blks(struct wcn36xx *wcn) 165 { 166 wcn36xx_dxe_free_ctl_block(&wcn->dxe_tx_l_ch); 167 wcn36xx_dxe_free_ctl_block(&wcn->dxe_tx_h_ch); 168 wcn36xx_dxe_free_ctl_block(&wcn->dxe_rx_l_ch); 169 wcn36xx_dxe_free_ctl_block(&wcn->dxe_rx_h_ch); 170 } 171 172 static int wcn36xx_dxe_init_descs(struct wcn36xx_dxe_ch *wcn_ch) 173 { 174 struct wcn36xx_dxe_desc *cur_dxe = NULL; 175 struct wcn36xx_dxe_desc *prev_dxe = NULL; 176 struct wcn36xx_dxe_ctl *cur_ctl = NULL; 177 size_t size; 178 int i; 179 180 size = wcn_ch->desc_num * sizeof(struct wcn36xx_dxe_desc); 181 wcn_ch->cpu_addr = dma_alloc_coherent(NULL, size, &wcn_ch->dma_addr, 182 GFP_KERNEL); 183 if (!wcn_ch->cpu_addr) 184 return -ENOMEM; 185 186 memset(wcn_ch->cpu_addr, 0, size); 187 188 cur_dxe = (struct wcn36xx_dxe_desc *)wcn_ch->cpu_addr; 189 cur_ctl = wcn_ch->head_blk_ctl; 190 191 for (i = 0; i < wcn_ch->desc_num; i++) { 192 cur_ctl->desc = cur_dxe; 193 cur_ctl->desc_phy_addr = wcn_ch->dma_addr + 194 i * sizeof(struct wcn36xx_dxe_desc); 195 196 switch (wcn_ch->ch_type) { 197 case WCN36XX_DXE_CH_TX_L: 198 cur_dxe->ctrl = WCN36XX_DXE_CTRL_TX_L; 199 cur_dxe->dst_addr_l = WCN36XX_DXE_WQ_TX_L; 200 break; 201 case WCN36XX_DXE_CH_TX_H: 202 cur_dxe->ctrl = WCN36XX_DXE_CTRL_TX_H; 203 cur_dxe->dst_addr_l = WCN36XX_DXE_WQ_TX_H; 204 break; 205 case WCN36XX_DXE_CH_RX_L: 206 cur_dxe->ctrl = WCN36XX_DXE_CTRL_RX_L; 207 cur_dxe->src_addr_l = WCN36XX_DXE_WQ_RX_L; 208 break; 209 case WCN36XX_DXE_CH_RX_H: 210 cur_dxe->ctrl = WCN36XX_DXE_CTRL_RX_H; 211 cur_dxe->src_addr_l = WCN36XX_DXE_WQ_RX_H; 212 break; 213 } 214 if (0 == i) { 215 cur_dxe->phy_next_l = 0; 216 } else if ((0 < i) && (i < wcn_ch->desc_num - 1)) { 217 prev_dxe->phy_next_l = 218 cur_ctl->desc_phy_addr; 219 } else if (i == (wcn_ch->desc_num - 1)) { 220 prev_dxe->phy_next_l = 221 cur_ctl->desc_phy_addr; 222 cur_dxe->phy_next_l = 223 wcn_ch->head_blk_ctl->desc_phy_addr; 224 } 225 cur_ctl = cur_ctl->next; 226 prev_dxe = cur_dxe; 227 cur_dxe++; 228 } 229 230 return 0; 231 } 232 233 static void wcn36xx_dxe_init_tx_bd(struct wcn36xx_dxe_ch *ch, 234 struct wcn36xx_dxe_mem_pool *pool) 235 { 236 int i, chunk_size = pool->chunk_size; 237 dma_addr_t bd_phy_addr = pool->phy_addr; 238 void *bd_cpu_addr = pool->virt_addr; 239 struct wcn36xx_dxe_ctl *cur = ch->head_blk_ctl; 240 241 for (i = 0; i < ch->desc_num; i++) { 242 /* Only every second dxe needs a bd pointer, 243 the other will point to the skb data */ 244 if (!(i & 1)) { 245 cur->bd_phy_addr = bd_phy_addr; 246 cur->bd_cpu_addr = bd_cpu_addr; 247 bd_phy_addr += chunk_size; 248 bd_cpu_addr += chunk_size; 249 } else { 250 cur->bd_phy_addr = 0; 251 cur->bd_cpu_addr = NULL; 252 } 253 cur = cur->next; 254 } 255 } 256 257 static int wcn36xx_dxe_enable_ch_int(struct wcn36xx *wcn, u16 wcn_ch) 258 { 259 int reg_data = 0; 260 261 wcn36xx_dxe_read_register(wcn, 262 WCN36XX_DXE_INT_MASK_REG, 263 ®_data); 264 265 reg_data |= wcn_ch; 266 267 wcn36xx_dxe_write_register(wcn, 268 WCN36XX_DXE_INT_MASK_REG, 269 (int)reg_data); 270 return 0; 271 } 272 273 static int wcn36xx_dxe_fill_skb(struct wcn36xx_dxe_ctl *ctl) 274 { 275 struct wcn36xx_dxe_desc *dxe = ctl->desc; 276 struct sk_buff *skb; 277 278 skb = alloc_skb(WCN36XX_PKT_SIZE, GFP_ATOMIC); 279 if (skb == NULL) 280 return -ENOMEM; 281 282 dxe->dst_addr_l = dma_map_single(NULL, 283 skb_tail_pointer(skb), 284 WCN36XX_PKT_SIZE, 285 DMA_FROM_DEVICE); 286 ctl->skb = skb; 287 288 return 0; 289 } 290 291 static int wcn36xx_dxe_ch_alloc_skb(struct wcn36xx *wcn, 292 struct wcn36xx_dxe_ch *wcn_ch) 293 { 294 int i; 295 struct wcn36xx_dxe_ctl *cur_ctl = NULL; 296 297 cur_ctl = wcn_ch->head_blk_ctl; 298 299 for (i = 0; i < wcn_ch->desc_num; i++) { 300 wcn36xx_dxe_fill_skb(cur_ctl); 301 cur_ctl = cur_ctl->next; 302 } 303 304 return 0; 305 } 306 307 static void wcn36xx_dxe_ch_free_skbs(struct wcn36xx *wcn, 308 struct wcn36xx_dxe_ch *wcn_ch) 309 { 310 struct wcn36xx_dxe_ctl *cur = wcn_ch->head_blk_ctl; 311 int i; 312 313 for (i = 0; i < wcn_ch->desc_num; i++) { 314 kfree_skb(cur->skb); 315 cur = cur->next; 316 } 317 } 318 319 void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status) 320 { 321 struct ieee80211_tx_info *info; 322 struct sk_buff *skb; 323 unsigned long flags; 324 325 spin_lock_irqsave(&wcn->dxe_lock, flags); 326 skb = wcn->tx_ack_skb; 327 wcn->tx_ack_skb = NULL; 328 spin_unlock_irqrestore(&wcn->dxe_lock, flags); 329 330 if (!skb) { 331 wcn36xx_warn("Spurious TX complete indication\n"); 332 return; 333 } 334 335 info = IEEE80211_SKB_CB(skb); 336 337 if (status == 1) 338 info->flags |= IEEE80211_TX_STAT_ACK; 339 340 wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ack status: %d\n", status); 341 342 ieee80211_tx_status_irqsafe(wcn->hw, skb); 343 ieee80211_wake_queues(wcn->hw); 344 } 345 346 static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch) 347 { 348 struct wcn36xx_dxe_ctl *ctl = ch->tail_blk_ctl; 349 struct ieee80211_tx_info *info; 350 unsigned long flags; 351 352 /* 353 * Make at least one loop of do-while because in case ring is 354 * completely full head and tail are pointing to the same element 355 * and while-do will not make any cycles. 356 */ 357 do { 358 if (ctl->desc->ctrl & WCN36XX_DXE_CTRL_VALID_MASK) 359 break; 360 if (ctl->skb) { 361 dma_unmap_single(NULL, ctl->desc->src_addr_l, 362 ctl->skb->len, DMA_TO_DEVICE); 363 info = IEEE80211_SKB_CB(ctl->skb); 364 if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) { 365 /* Keep frame until TX status comes */ 366 ieee80211_free_txskb(wcn->hw, ctl->skb); 367 } 368 spin_lock_irqsave(&ctl->skb_lock, flags); 369 if (wcn->queues_stopped) { 370 wcn->queues_stopped = false; 371 ieee80211_wake_queues(wcn->hw); 372 } 373 spin_unlock_irqrestore(&ctl->skb_lock, flags); 374 375 ctl->skb = NULL; 376 } 377 ctl = ctl->next; 378 } while (ctl != ch->head_blk_ctl && 379 !(ctl->desc->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)); 380 381 ch->tail_blk_ctl = ctl; 382 } 383 384 static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev) 385 { 386 struct wcn36xx *wcn = (struct wcn36xx *)dev; 387 int int_src, int_reason; 388 389 wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_INT_SRC_RAW_REG, &int_src); 390 391 if (int_src & WCN36XX_INT_MASK_CHAN_TX_H) { 392 wcn36xx_dxe_read_register(wcn, 393 WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_H, 394 &int_reason); 395 396 /* TODO: Check int_reason */ 397 398 wcn36xx_dxe_write_register(wcn, 399 WCN36XX_DXE_0_INT_CLR, 400 WCN36XX_INT_MASK_CHAN_TX_H); 401 402 wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_ED_CLR, 403 WCN36XX_INT_MASK_CHAN_TX_H); 404 wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready high\n"); 405 reap_tx_dxes(wcn, &wcn->dxe_tx_h_ch); 406 } 407 408 if (int_src & WCN36XX_INT_MASK_CHAN_TX_L) { 409 wcn36xx_dxe_read_register(wcn, 410 WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_L, 411 &int_reason); 412 /* TODO: Check int_reason */ 413 414 wcn36xx_dxe_write_register(wcn, 415 WCN36XX_DXE_0_INT_CLR, 416 WCN36XX_INT_MASK_CHAN_TX_L); 417 418 wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_ED_CLR, 419 WCN36XX_INT_MASK_CHAN_TX_L); 420 wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready low\n"); 421 reap_tx_dxes(wcn, &wcn->dxe_tx_l_ch); 422 } 423 424 return IRQ_HANDLED; 425 } 426 427 static irqreturn_t wcn36xx_irq_rx_ready(int irq, void *dev) 428 { 429 struct wcn36xx *wcn = (struct wcn36xx *)dev; 430 431 disable_irq_nosync(wcn->rx_irq); 432 wcn36xx_dxe_rx_frame(wcn); 433 enable_irq(wcn->rx_irq); 434 return IRQ_HANDLED; 435 } 436 437 static int wcn36xx_dxe_request_irqs(struct wcn36xx *wcn) 438 { 439 int ret; 440 441 ret = request_irq(wcn->tx_irq, wcn36xx_irq_tx_complete, 442 IRQF_TRIGGER_HIGH, "wcn36xx_tx", wcn); 443 if (ret) { 444 wcn36xx_err("failed to alloc tx irq\n"); 445 goto out_err; 446 } 447 448 ret = request_irq(wcn->rx_irq, wcn36xx_irq_rx_ready, IRQF_TRIGGER_HIGH, 449 "wcn36xx_rx", wcn); 450 if (ret) { 451 wcn36xx_err("failed to alloc rx irq\n"); 452 goto out_txirq; 453 } 454 455 enable_irq_wake(wcn->rx_irq); 456 457 return 0; 458 459 out_txirq: 460 free_irq(wcn->tx_irq, wcn); 461 out_err: 462 return ret; 463 464 } 465 466 static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn, 467 struct wcn36xx_dxe_ch *ch) 468 { 469 struct wcn36xx_dxe_ctl *ctl = ch->head_blk_ctl; 470 struct wcn36xx_dxe_desc *dxe = ctl->desc; 471 dma_addr_t dma_addr; 472 struct sk_buff *skb; 473 474 while (!(dxe->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)) { 475 skb = ctl->skb; 476 dma_addr = dxe->dst_addr_l; 477 wcn36xx_dxe_fill_skb(ctl); 478 479 switch (ch->ch_type) { 480 case WCN36XX_DXE_CH_RX_L: 481 dxe->ctrl = WCN36XX_DXE_CTRL_RX_L; 482 wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_ENCH_ADDR, 483 WCN36XX_DXE_INT_CH1_MASK); 484 break; 485 case WCN36XX_DXE_CH_RX_H: 486 dxe->ctrl = WCN36XX_DXE_CTRL_RX_H; 487 wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_ENCH_ADDR, 488 WCN36XX_DXE_INT_CH3_MASK); 489 break; 490 default: 491 wcn36xx_warn("Unknown channel\n"); 492 } 493 494 dma_unmap_single(NULL, dma_addr, WCN36XX_PKT_SIZE, 495 DMA_FROM_DEVICE); 496 wcn36xx_rx_skb(wcn, skb); 497 ctl = ctl->next; 498 dxe = ctl->desc; 499 } 500 501 ch->head_blk_ctl = ctl; 502 503 return 0; 504 } 505 506 void wcn36xx_dxe_rx_frame(struct wcn36xx *wcn) 507 { 508 int int_src; 509 510 wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_INT_SRC_RAW_REG, &int_src); 511 512 /* RX_LOW_PRI */ 513 if (int_src & WCN36XX_DXE_INT_CH1_MASK) { 514 wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_CLR, 515 WCN36XX_DXE_INT_CH1_MASK); 516 wcn36xx_rx_handle_packets(wcn, &(wcn->dxe_rx_l_ch)); 517 } 518 519 /* RX_HIGH_PRI */ 520 if (int_src & WCN36XX_DXE_INT_CH3_MASK) { 521 /* Clean up all the INT within this channel */ 522 wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_CLR, 523 WCN36XX_DXE_INT_CH3_MASK); 524 wcn36xx_rx_handle_packets(wcn, &(wcn->dxe_rx_h_ch)); 525 } 526 527 if (!int_src) 528 wcn36xx_warn("No DXE interrupt pending\n"); 529 } 530 531 int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn) 532 { 533 size_t s; 534 void *cpu_addr; 535 536 /* Allocate BD headers for MGMT frames */ 537 538 /* Where this come from ask QC */ 539 wcn->mgmt_mem_pool.chunk_size = WCN36XX_BD_CHUNK_SIZE + 540 16 - (WCN36XX_BD_CHUNK_SIZE % 8); 541 542 s = wcn->mgmt_mem_pool.chunk_size * WCN36XX_DXE_CH_DESC_NUMB_TX_H; 543 cpu_addr = dma_alloc_coherent(NULL, s, &wcn->mgmt_mem_pool.phy_addr, 544 GFP_KERNEL); 545 if (!cpu_addr) 546 goto out_err; 547 548 wcn->mgmt_mem_pool.virt_addr = cpu_addr; 549 memset(cpu_addr, 0, s); 550 551 /* Allocate BD headers for DATA frames */ 552 553 /* Where this come from ask QC */ 554 wcn->data_mem_pool.chunk_size = WCN36XX_BD_CHUNK_SIZE + 555 16 - (WCN36XX_BD_CHUNK_SIZE % 8); 556 557 s = wcn->data_mem_pool.chunk_size * WCN36XX_DXE_CH_DESC_NUMB_TX_L; 558 cpu_addr = dma_alloc_coherent(NULL, s, &wcn->data_mem_pool.phy_addr, 559 GFP_KERNEL); 560 if (!cpu_addr) 561 goto out_err; 562 563 wcn->data_mem_pool.virt_addr = cpu_addr; 564 memset(cpu_addr, 0, s); 565 566 return 0; 567 568 out_err: 569 wcn36xx_dxe_free_mem_pools(wcn); 570 wcn36xx_err("Failed to allocate BD mempool\n"); 571 return -ENOMEM; 572 } 573 574 void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn) 575 { 576 if (wcn->mgmt_mem_pool.virt_addr) 577 dma_free_coherent(NULL, wcn->mgmt_mem_pool.chunk_size * 578 WCN36XX_DXE_CH_DESC_NUMB_TX_H, 579 wcn->mgmt_mem_pool.virt_addr, 580 wcn->mgmt_mem_pool.phy_addr); 581 582 if (wcn->data_mem_pool.virt_addr) { 583 dma_free_coherent(NULL, wcn->data_mem_pool.chunk_size * 584 WCN36XX_DXE_CH_DESC_NUMB_TX_L, 585 wcn->data_mem_pool.virt_addr, 586 wcn->data_mem_pool.phy_addr); 587 } 588 } 589 590 int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, 591 struct wcn36xx_vif *vif_priv, 592 struct sk_buff *skb, 593 bool is_low) 594 { 595 struct wcn36xx_dxe_ctl *ctl = NULL; 596 struct wcn36xx_dxe_desc *desc = NULL; 597 struct wcn36xx_dxe_ch *ch = NULL; 598 unsigned long flags; 599 600 ch = is_low ? &wcn->dxe_tx_l_ch : &wcn->dxe_tx_h_ch; 601 602 ctl = ch->head_blk_ctl; 603 604 spin_lock_irqsave(&ctl->next->skb_lock, flags); 605 606 /* 607 * If skb is not null that means that we reached the tail of the ring 608 * hence ring is full. Stop queues to let mac80211 back off until ring 609 * has an empty slot again. 610 */ 611 if (NULL != ctl->next->skb) { 612 ieee80211_stop_queues(wcn->hw); 613 wcn->queues_stopped = true; 614 spin_unlock_irqrestore(&ctl->next->skb_lock, flags); 615 return -EBUSY; 616 } 617 spin_unlock_irqrestore(&ctl->next->skb_lock, flags); 618 619 ctl->skb = NULL; 620 desc = ctl->desc; 621 622 /* Set source address of the BD we send */ 623 desc->src_addr_l = ctl->bd_phy_addr; 624 625 desc->dst_addr_l = ch->dxe_wq; 626 desc->fr_len = sizeof(struct wcn36xx_tx_bd); 627 desc->ctrl = ch->ctrl_bd; 628 629 wcn36xx_dbg(WCN36XX_DBG_DXE, "DXE TX\n"); 630 631 wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP, "DESC1 >>> ", 632 (char *)desc, sizeof(*desc)); 633 wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP, 634 "BD >>> ", (char *)ctl->bd_cpu_addr, 635 sizeof(struct wcn36xx_tx_bd)); 636 637 /* Set source address of the SKB we send */ 638 ctl = ctl->next; 639 ctl->skb = skb; 640 desc = ctl->desc; 641 if (ctl->bd_cpu_addr) { 642 wcn36xx_err("bd_cpu_addr cannot be NULL for skb DXE\n"); 643 return -EINVAL; 644 } 645 646 desc->src_addr_l = dma_map_single(NULL, 647 ctl->skb->data, 648 ctl->skb->len, 649 DMA_TO_DEVICE); 650 651 desc->dst_addr_l = ch->dxe_wq; 652 desc->fr_len = ctl->skb->len; 653 654 /* set dxe descriptor to VALID */ 655 desc->ctrl = ch->ctrl_skb; 656 657 wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP, "DESC2 >>> ", 658 (char *)desc, sizeof(*desc)); 659 wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP, "SKB >>> ", 660 (char *)ctl->skb->data, ctl->skb->len); 661 662 /* Move the head of the ring to the next empty descriptor */ 663 ch->head_blk_ctl = ctl->next; 664 665 /* 666 * When connected and trying to send data frame chip can be in sleep 667 * mode and writing to the register will not wake up the chip. Instead 668 * notify chip about new frame through SMSM bus. 669 */ 670 if (is_low && vif_priv->pw_state == WCN36XX_BMPS) { 671 wcn->ctrl_ops->smsm_change_state( 672 0, 673 WCN36XX_SMSM_WLAN_TX_ENABLE); 674 } else { 675 /* indicate End Of Packet and generate interrupt on descriptor 676 * done. 677 */ 678 wcn36xx_dxe_write_register(wcn, 679 ch->reg_ctrl, ch->def_ctrl); 680 } 681 682 return 0; 683 } 684 685 int wcn36xx_dxe_init(struct wcn36xx *wcn) 686 { 687 int reg_data = 0, ret; 688 689 reg_data = WCN36XX_DXE_REG_RESET; 690 wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_REG_CSR_RESET, reg_data); 691 692 /* Setting interrupt path */ 693 reg_data = WCN36XX_DXE_CCU_INT; 694 wcn36xx_dxe_write_register_x(wcn, WCN36XX_DXE_REG_CCU_INT, reg_data); 695 696 /***************************************/ 697 /* Init descriptors for TX LOW channel */ 698 /***************************************/ 699 wcn36xx_dxe_init_descs(&wcn->dxe_tx_l_ch); 700 wcn36xx_dxe_init_tx_bd(&wcn->dxe_tx_l_ch, &wcn->data_mem_pool); 701 702 /* Write channel head to a NEXT register */ 703 wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_L, 704 wcn->dxe_tx_l_ch.head_blk_ctl->desc_phy_addr); 705 706 /* Program DMA destination addr for TX LOW */ 707 wcn36xx_dxe_write_register(wcn, 708 WCN36XX_DXE_CH_DEST_ADDR_TX_L, 709 WCN36XX_DXE_WQ_TX_L); 710 711 wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_REG_CH_EN, ®_data); 712 wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_TX_L); 713 714 /***************************************/ 715 /* Init descriptors for TX HIGH channel */ 716 /***************************************/ 717 wcn36xx_dxe_init_descs(&wcn->dxe_tx_h_ch); 718 wcn36xx_dxe_init_tx_bd(&wcn->dxe_tx_h_ch, &wcn->mgmt_mem_pool); 719 720 /* Write channel head to a NEXT register */ 721 wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_H, 722 wcn->dxe_tx_h_ch.head_blk_ctl->desc_phy_addr); 723 724 /* Program DMA destination addr for TX HIGH */ 725 wcn36xx_dxe_write_register(wcn, 726 WCN36XX_DXE_CH_DEST_ADDR_TX_H, 727 WCN36XX_DXE_WQ_TX_H); 728 729 wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_REG_CH_EN, ®_data); 730 731 /* Enable channel interrupts */ 732 wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_TX_H); 733 734 /***************************************/ 735 /* Init descriptors for RX LOW channel */ 736 /***************************************/ 737 wcn36xx_dxe_init_descs(&wcn->dxe_rx_l_ch); 738 739 /* For RX we need to preallocated buffers */ 740 wcn36xx_dxe_ch_alloc_skb(wcn, &wcn->dxe_rx_l_ch); 741 742 /* Write channel head to a NEXT register */ 743 wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_L, 744 wcn->dxe_rx_l_ch.head_blk_ctl->desc_phy_addr); 745 746 /* Write DMA source address */ 747 wcn36xx_dxe_write_register(wcn, 748 WCN36XX_DXE_CH_SRC_ADDR_RX_L, 749 WCN36XX_DXE_WQ_RX_L); 750 751 /* Program preallocated destination address */ 752 wcn36xx_dxe_write_register(wcn, 753 WCN36XX_DXE_CH_DEST_ADDR_RX_L, 754 wcn->dxe_rx_l_ch.head_blk_ctl->desc->phy_next_l); 755 756 /* Enable default control registers */ 757 wcn36xx_dxe_write_register(wcn, 758 WCN36XX_DXE_REG_CTL_RX_L, 759 WCN36XX_DXE_CH_DEFAULT_CTL_RX_L); 760 761 /* Enable channel interrupts */ 762 wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_RX_L); 763 764 /***************************************/ 765 /* Init descriptors for RX HIGH channel */ 766 /***************************************/ 767 wcn36xx_dxe_init_descs(&wcn->dxe_rx_h_ch); 768 769 /* For RX we need to prealocat buffers */ 770 wcn36xx_dxe_ch_alloc_skb(wcn, &wcn->dxe_rx_h_ch); 771 772 /* Write chanel head to a NEXT register */ 773 wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_H, 774 wcn->dxe_rx_h_ch.head_blk_ctl->desc_phy_addr); 775 776 /* Write DMA source address */ 777 wcn36xx_dxe_write_register(wcn, 778 WCN36XX_DXE_CH_SRC_ADDR_RX_H, 779 WCN36XX_DXE_WQ_RX_H); 780 781 /* Program preallocated destination address */ 782 wcn36xx_dxe_write_register(wcn, 783 WCN36XX_DXE_CH_DEST_ADDR_RX_H, 784 wcn->dxe_rx_h_ch.head_blk_ctl->desc->phy_next_l); 785 786 /* Enable default control registers */ 787 wcn36xx_dxe_write_register(wcn, 788 WCN36XX_DXE_REG_CTL_RX_H, 789 WCN36XX_DXE_CH_DEFAULT_CTL_RX_H); 790 791 /* Enable channel interrupts */ 792 wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_RX_H); 793 794 ret = wcn36xx_dxe_request_irqs(wcn); 795 if (ret < 0) 796 goto out_err; 797 798 return 0; 799 800 out_err: 801 return ret; 802 } 803 804 void wcn36xx_dxe_deinit(struct wcn36xx *wcn) 805 { 806 free_irq(wcn->tx_irq, wcn); 807 free_irq(wcn->rx_irq, wcn); 808 809 if (wcn->tx_ack_skb) { 810 ieee80211_tx_status_irqsafe(wcn->hw, wcn->tx_ack_skb); 811 wcn->tx_ack_skb = NULL; 812 } 813 814 wcn36xx_dxe_ch_free_skbs(wcn, &wcn->dxe_rx_l_ch); 815 wcn36xx_dxe_ch_free_skbs(wcn, &wcn->dxe_rx_h_ch); 816 } 817