Lines Matching +full:system +full:- +full:ctl

17 /* DXE - DMA transfer engine
36 writel(data, wcn->ccu_base + addr); in wcn36xx_ccu_write_register()
45 writel(data, wcn->dxe_base + addr); in wcn36xx_dxe_write_register()
50 *data = readl(wcn->dxe_base + addr); in wcn36xx_dxe_read_register()
59 struct wcn36xx_dxe_ctl *ctl = ch->head_blk_ctl, *next; in wcn36xx_dxe_free_ctl_block() local
62 for (i = 0; i < ch->desc_num && ctl; i++) { in wcn36xx_dxe_free_ctl_block()
63 next = ctl->next; in wcn36xx_dxe_free_ctl_block()
64 kfree(ctl); in wcn36xx_dxe_free_ctl_block()
65 ctl = next; in wcn36xx_dxe_free_ctl_block()
75 spin_lock_init(&ch->lock); in wcn36xx_dxe_allocate_ctl_block()
76 for (i = 0; i < ch->desc_num; i++) { in wcn36xx_dxe_allocate_ctl_block()
81 cur_ctl->ctl_blk_order = i; in wcn36xx_dxe_allocate_ctl_block()
83 ch->head_blk_ctl = cur_ctl; in wcn36xx_dxe_allocate_ctl_block()
84 ch->tail_blk_ctl = cur_ctl; in wcn36xx_dxe_allocate_ctl_block()
85 } else if (ch->desc_num - 1 == i) { in wcn36xx_dxe_allocate_ctl_block()
86 prev_ctl->next = cur_ctl; in wcn36xx_dxe_allocate_ctl_block()
87 cur_ctl->next = ch->head_blk_ctl; in wcn36xx_dxe_allocate_ctl_block()
89 prev_ctl->next = cur_ctl; in wcn36xx_dxe_allocate_ctl_block()
98 return -ENOMEM; in wcn36xx_dxe_allocate_ctl_block()
105 wcn->dxe_tx_l_ch.ch_type = WCN36XX_DXE_CH_TX_L; in wcn36xx_dxe_alloc_ctl_blks()
106 wcn->dxe_tx_h_ch.ch_type = WCN36XX_DXE_CH_TX_H; in wcn36xx_dxe_alloc_ctl_blks()
107 wcn->dxe_rx_l_ch.ch_type = WCN36XX_DXE_CH_RX_L; in wcn36xx_dxe_alloc_ctl_blks()
108 wcn->dxe_rx_h_ch.ch_type = WCN36XX_DXE_CH_RX_H; in wcn36xx_dxe_alloc_ctl_blks()
110 wcn->dxe_tx_l_ch.desc_num = WCN36XX_DXE_CH_DESC_NUMB_TX_L; in wcn36xx_dxe_alloc_ctl_blks()
111 wcn->dxe_tx_h_ch.desc_num = WCN36XX_DXE_CH_DESC_NUMB_TX_H; in wcn36xx_dxe_alloc_ctl_blks()
112 wcn->dxe_rx_l_ch.desc_num = WCN36XX_DXE_CH_DESC_NUMB_RX_L; in wcn36xx_dxe_alloc_ctl_blks()
113 wcn->dxe_rx_h_ch.desc_num = WCN36XX_DXE_CH_DESC_NUMB_RX_H; in wcn36xx_dxe_alloc_ctl_blks()
115 wcn->dxe_tx_l_ch.dxe_wq = WCN36XX_DXE_WQ_TX_L(wcn); in wcn36xx_dxe_alloc_ctl_blks()
116 wcn->dxe_tx_h_ch.dxe_wq = WCN36XX_DXE_WQ_TX_H(wcn); in wcn36xx_dxe_alloc_ctl_blks()
118 wcn->dxe_tx_l_ch.ctrl_bd = WCN36XX_DXE_CTRL_TX_L_BD; in wcn36xx_dxe_alloc_ctl_blks()
119 wcn->dxe_tx_h_ch.ctrl_bd = WCN36XX_DXE_CTRL_TX_H_BD; in wcn36xx_dxe_alloc_ctl_blks()
121 wcn->dxe_tx_l_ch.ctrl_skb = WCN36XX_DXE_CTRL_TX_L_SKB; in wcn36xx_dxe_alloc_ctl_blks()
122 wcn->dxe_tx_h_ch.ctrl_skb = WCN36XX_DXE_CTRL_TX_H_SKB; in wcn36xx_dxe_alloc_ctl_blks()
124 wcn->dxe_tx_l_ch.reg_ctrl = WCN36XX_DXE_REG_CTL_TX_L; in wcn36xx_dxe_alloc_ctl_blks()
125 wcn->dxe_tx_h_ch.reg_ctrl = WCN36XX_DXE_REG_CTL_TX_H; in wcn36xx_dxe_alloc_ctl_blks()
127 wcn->dxe_tx_l_ch.def_ctrl = WCN36XX_DXE_CH_DEFAULT_CTL_TX_L; in wcn36xx_dxe_alloc_ctl_blks()
128 wcn->dxe_tx_h_ch.def_ctrl = WCN36XX_DXE_CH_DEFAULT_CTL_TX_H; in wcn36xx_dxe_alloc_ctl_blks()
131 ret = wcn36xx_dxe_allocate_ctl_block(&wcn->dxe_tx_l_ch); in wcn36xx_dxe_alloc_ctl_blks()
134 ret = wcn36xx_dxe_allocate_ctl_block(&wcn->dxe_tx_h_ch); in wcn36xx_dxe_alloc_ctl_blks()
137 ret = wcn36xx_dxe_allocate_ctl_block(&wcn->dxe_rx_l_ch); in wcn36xx_dxe_alloc_ctl_blks()
140 ret = wcn36xx_dxe_allocate_ctl_block(&wcn->dxe_rx_h_ch); in wcn36xx_dxe_alloc_ctl_blks()
145 ret = qcom_smem_state_update_bits(wcn->tx_enable_state, in wcn36xx_dxe_alloc_ctl_blks()
157 return -ENOMEM; in wcn36xx_dxe_alloc_ctl_blks()
162 wcn36xx_dxe_free_ctl_block(&wcn->dxe_tx_l_ch); in wcn36xx_dxe_free_ctl_blks()
163 wcn36xx_dxe_free_ctl_block(&wcn->dxe_tx_h_ch); in wcn36xx_dxe_free_ctl_blks()
164 wcn36xx_dxe_free_ctl_block(&wcn->dxe_rx_l_ch); in wcn36xx_dxe_free_ctl_blks()
165 wcn36xx_dxe_free_ctl_block(&wcn->dxe_rx_h_ch); in wcn36xx_dxe_free_ctl_blks()
170 struct device *dev = wcn->dev; in wcn36xx_dxe_init_descs()
177 size = wcn_ch->desc_num * sizeof(struct wcn36xx_dxe_desc); in wcn36xx_dxe_init_descs()
178 wcn_ch->cpu_addr = dma_alloc_coherent(dev, size, &wcn_ch->dma_addr, in wcn36xx_dxe_init_descs()
180 if (!wcn_ch->cpu_addr) in wcn36xx_dxe_init_descs()
181 return -ENOMEM; in wcn36xx_dxe_init_descs()
183 cur_dxe = wcn_ch->cpu_addr; in wcn36xx_dxe_init_descs()
184 cur_ctl = wcn_ch->head_blk_ctl; in wcn36xx_dxe_init_descs()
186 for (i = 0; i < wcn_ch->desc_num; i++) { in wcn36xx_dxe_init_descs()
187 cur_ctl->desc = cur_dxe; in wcn36xx_dxe_init_descs()
188 cur_ctl->desc_phy_addr = wcn_ch->dma_addr + in wcn36xx_dxe_init_descs()
191 switch (wcn_ch->ch_type) { in wcn36xx_dxe_init_descs()
193 cur_dxe->ctrl = WCN36XX_DXE_CTRL_TX_L; in wcn36xx_dxe_init_descs()
194 cur_dxe->dst_addr_l = WCN36XX_DXE_WQ_TX_L(wcn); in wcn36xx_dxe_init_descs()
197 cur_dxe->ctrl = WCN36XX_DXE_CTRL_TX_H; in wcn36xx_dxe_init_descs()
198 cur_dxe->dst_addr_l = WCN36XX_DXE_WQ_TX_H(wcn); in wcn36xx_dxe_init_descs()
201 cur_dxe->ctrl = WCN36XX_DXE_CTRL_RX_L; in wcn36xx_dxe_init_descs()
202 cur_dxe->src_addr_l = WCN36XX_DXE_WQ_RX_L; in wcn36xx_dxe_init_descs()
205 cur_dxe->ctrl = WCN36XX_DXE_CTRL_RX_H; in wcn36xx_dxe_init_descs()
206 cur_dxe->src_addr_l = WCN36XX_DXE_WQ_RX_H; in wcn36xx_dxe_init_descs()
210 cur_dxe->phy_next_l = 0; in wcn36xx_dxe_init_descs()
211 } else if ((0 < i) && (i < wcn_ch->desc_num - 1)) { in wcn36xx_dxe_init_descs()
212 prev_dxe->phy_next_l = in wcn36xx_dxe_init_descs()
213 cur_ctl->desc_phy_addr; in wcn36xx_dxe_init_descs()
214 } else if (i == (wcn_ch->desc_num - 1)) { in wcn36xx_dxe_init_descs()
215 prev_dxe->phy_next_l = in wcn36xx_dxe_init_descs()
216 cur_ctl->desc_phy_addr; in wcn36xx_dxe_init_descs()
217 cur_dxe->phy_next_l = in wcn36xx_dxe_init_descs()
218 wcn_ch->head_blk_ctl->desc_phy_addr; in wcn36xx_dxe_init_descs()
220 cur_ctl = cur_ctl->next; in wcn36xx_dxe_init_descs()
232 size = wcn_ch->desc_num * sizeof(struct wcn36xx_dxe_desc); in wcn36xx_dxe_deinit_descs()
233 dma_free_coherent(dev, size,wcn_ch->cpu_addr, wcn_ch->dma_addr); in wcn36xx_dxe_deinit_descs()
239 int i, chunk_size = pool->chunk_size; in wcn36xx_dxe_init_tx_bd()
240 dma_addr_t bd_phy_addr = pool->phy_addr; in wcn36xx_dxe_init_tx_bd()
241 void *bd_cpu_addr = pool->virt_addr; in wcn36xx_dxe_init_tx_bd()
242 struct wcn36xx_dxe_ctl *cur = ch->head_blk_ctl; in wcn36xx_dxe_init_tx_bd()
244 for (i = 0; i < ch->desc_num; i++) { in wcn36xx_dxe_init_tx_bd()
248 cur->bd_phy_addr = bd_phy_addr; in wcn36xx_dxe_init_tx_bd()
249 cur->bd_cpu_addr = bd_cpu_addr; in wcn36xx_dxe_init_tx_bd()
253 cur->bd_phy_addr = 0; in wcn36xx_dxe_init_tx_bd()
254 cur->bd_cpu_addr = NULL; in wcn36xx_dxe_init_tx_bd()
256 cur = cur->next; in wcn36xx_dxe_init_tx_bd()
292 struct wcn36xx_dxe_ctl *ctl, in wcn36xx_dxe_fill_skb() argument
295 struct wcn36xx_dxe_desc *dxe = ctl->desc; in wcn36xx_dxe_fill_skb()
300 return -ENOMEM; in wcn36xx_dxe_fill_skb()
302 dxe->dst_addr_l = dma_map_single(dev, in wcn36xx_dxe_fill_skb()
306 if (dma_mapping_error(dev, dxe->dst_addr_l)) { in wcn36xx_dxe_fill_skb()
309 return -ENOMEM; in wcn36xx_dxe_fill_skb()
311 ctl->skb = skb; in wcn36xx_dxe_fill_skb()
322 cur_ctl = wcn_ch->head_blk_ctl; in wcn36xx_dxe_ch_alloc_skb()
324 for (i = 0; i < wcn_ch->desc_num; i++) { in wcn36xx_dxe_ch_alloc_skb()
325 wcn36xx_dxe_fill_skb(wcn->dev, cur_ctl, GFP_KERNEL); in wcn36xx_dxe_ch_alloc_skb()
326 cur_ctl = cur_ctl->next; in wcn36xx_dxe_ch_alloc_skb()
335 struct wcn36xx_dxe_ctl *cur = wcn_ch->head_blk_ctl; in wcn36xx_dxe_ch_free_skbs()
338 for (i = 0; i < wcn_ch->desc_num; i++) { in wcn36xx_dxe_ch_free_skbs()
339 kfree_skb(cur->skb); in wcn36xx_dxe_ch_free_skbs()
340 cur = cur->next; in wcn36xx_dxe_ch_free_skbs()
350 spin_lock_irqsave(&wcn->dxe_lock, flags); in wcn36xx_dxe_tx_ack_ind()
351 skb = wcn->tx_ack_skb; in wcn36xx_dxe_tx_ack_ind()
352 wcn->tx_ack_skb = NULL; in wcn36xx_dxe_tx_ack_ind()
353 del_timer(&wcn->tx_ack_timer); in wcn36xx_dxe_tx_ack_ind()
354 spin_unlock_irqrestore(&wcn->dxe_lock, flags); in wcn36xx_dxe_tx_ack_ind()
364 info->flags |= IEEE80211_TX_STAT_ACK; in wcn36xx_dxe_tx_ack_ind()
366 info->flags &= ~IEEE80211_TX_STAT_ACK; in wcn36xx_dxe_tx_ack_ind()
370 ieee80211_tx_status_irqsafe(wcn->hw, skb); in wcn36xx_dxe_tx_ack_ind()
371 ieee80211_wake_queues(wcn->hw); in wcn36xx_dxe_tx_ack_ind()
384 spin_lock_irqsave(&wcn->dxe_lock, flags); in wcn36xx_dxe_tx_timer()
385 skb = wcn->tx_ack_skb; in wcn36xx_dxe_tx_timer()
386 wcn->tx_ack_skb = NULL; in wcn36xx_dxe_tx_timer()
387 spin_unlock_irqrestore(&wcn->dxe_lock, flags); in wcn36xx_dxe_tx_timer()
393 info->flags &= ~IEEE80211_TX_STAT_ACK; in wcn36xx_dxe_tx_timer()
394 info->flags &= ~IEEE80211_TX_STAT_NOACK_TRANSMITTED; in wcn36xx_dxe_tx_timer()
396 ieee80211_tx_status_irqsafe(wcn->hw, skb); in wcn36xx_dxe_tx_timer()
397 ieee80211_wake_queues(wcn->hw); in wcn36xx_dxe_tx_timer()
402 struct wcn36xx_dxe_ctl *ctl; in reap_tx_dxes() local
407 * Make at least one loop of do-while because in case ring is in reap_tx_dxes()
409 * and while-do will not make any cycles. in reap_tx_dxes()
411 spin_lock_irqsave(&ch->lock, flags); in reap_tx_dxes()
412 ctl = ch->tail_blk_ctl; in reap_tx_dxes()
414 if (READ_ONCE(ctl->desc->ctrl) & WCN36xx_DXE_CTRL_VLD) in reap_tx_dxes()
417 if (ctl->skb && in reap_tx_dxes()
418 READ_ONCE(ctl->desc->ctrl) & WCN36xx_DXE_CTRL_EOP) { in reap_tx_dxes()
419 dma_unmap_single(wcn->dev, ctl->desc->src_addr_l, in reap_tx_dxes()
420 ctl->skb->len, DMA_TO_DEVICE); in reap_tx_dxes()
421 info = IEEE80211_SKB_CB(ctl->skb); in reap_tx_dxes()
422 if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { in reap_tx_dxes()
423 if (info->flags & IEEE80211_TX_CTL_NO_ACK) { in reap_tx_dxes()
424 info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; in reap_tx_dxes()
425 ieee80211_tx_status_irqsafe(wcn->hw, ctl->skb); in reap_tx_dxes()
428 spin_lock(&wcn->dxe_lock); in reap_tx_dxes()
429 if (WARN_ON(wcn->tx_ack_skb)) in reap_tx_dxes()
430 ieee80211_free_txskb(wcn->hw, wcn->tx_ack_skb); in reap_tx_dxes()
431 wcn->tx_ack_skb = ctl->skb; /* Tracking ref */ in reap_tx_dxes()
432 mod_timer(&wcn->tx_ack_timer, jiffies + HZ / 10); in reap_tx_dxes()
433 spin_unlock(&wcn->dxe_lock); in reap_tx_dxes()
437 ieee80211_free_txskb(wcn->hw, ctl->skb); in reap_tx_dxes()
440 if (wcn->queues_stopped) { in reap_tx_dxes()
441 wcn->queues_stopped = false; in reap_tx_dxes()
442 ieee80211_wake_queues(wcn->hw); in reap_tx_dxes()
445 ctl->skb = NULL; in reap_tx_dxes()
447 ctl = ctl->next; in reap_tx_dxes()
448 } while (ctl != ch->head_blk_ctl); in reap_tx_dxes()
450 ch->tail_blk_ctl = ctl; in reap_tx_dxes()
451 spin_unlock_irqrestore(&ch->lock, flags); in reap_tx_dxes()
496 reap_tx_dxes(wcn, &wcn->dxe_tx_h_ch); in wcn36xx_irq_tx_complete()
535 reap_tx_dxes(wcn, &wcn->dxe_tx_l_ch); in wcn36xx_irq_tx_complete()
555 ret = request_irq(wcn->tx_irq, wcn36xx_irq_tx_complete, in wcn36xx_dxe_request_irqs()
562 ret = request_irq(wcn->rx_irq, wcn36xx_irq_rx_ready, IRQF_TRIGGER_HIGH, in wcn36xx_dxe_request_irqs()
569 enable_irq_wake(wcn->rx_irq); in wcn36xx_dxe_request_irqs()
574 free_irq(wcn->tx_irq, wcn); in wcn36xx_dxe_request_irqs()
588 struct wcn36xx_dxe_ctl *ctl; in wcn36xx_rx_handle_packets() local
619 spin_lock(&ch->lock); in wcn36xx_rx_handle_packets()
621 ctl = ch->head_blk_ctl; in wcn36xx_rx_handle_packets()
622 dxe = ctl->desc; in wcn36xx_rx_handle_packets()
624 while (!(READ_ONCE(dxe->ctrl) & WCN36xx_DXE_CTRL_VLD)) { in wcn36xx_rx_handle_packets()
629 skb = ctl->skb; in wcn36xx_rx_handle_packets()
630 dma_addr = dxe->dst_addr_l; in wcn36xx_rx_handle_packets()
631 ret = wcn36xx_dxe_fill_skb(wcn->dev, ctl, GFP_ATOMIC); in wcn36xx_rx_handle_packets()
634 * the old one to network system. in wcn36xx_rx_handle_packets()
636 dma_unmap_single(wcn->dev, dma_addr, WCN36XX_PKT_SIZE, in wcn36xx_rx_handle_packets()
644 /* flush descriptor changes before re-marking as valid */ in wcn36xx_rx_handle_packets()
646 dxe->ctrl = ctrl; in wcn36xx_rx_handle_packets()
648 ctl = ctl->next; in wcn36xx_rx_handle_packets()
649 dxe = ctl->desc; in wcn36xx_rx_handle_packets()
653 ch->head_blk_ctl = ctl; in wcn36xx_rx_handle_packets()
655 spin_unlock(&ch->lock); in wcn36xx_rx_handle_packets()
668 wcn36xx_rx_handle_packets(wcn, &wcn->dxe_rx_l_ch, in wcn36xx_dxe_rx_frame()
676 wcn36xx_rx_handle_packets(wcn, &wcn->dxe_rx_h_ch, in wcn36xx_dxe_rx_frame()
694 wcn->mgmt_mem_pool.chunk_size = WCN36XX_BD_CHUNK_SIZE + in wcn36xx_dxe_allocate_mem_pools()
695 16 - (WCN36XX_BD_CHUNK_SIZE % 8); in wcn36xx_dxe_allocate_mem_pools()
697 s = wcn->mgmt_mem_pool.chunk_size * WCN36XX_DXE_CH_DESC_NUMB_TX_H; in wcn36xx_dxe_allocate_mem_pools()
698 cpu_addr = dma_alloc_coherent(wcn->dev, s, in wcn36xx_dxe_allocate_mem_pools()
699 &wcn->mgmt_mem_pool.phy_addr, in wcn36xx_dxe_allocate_mem_pools()
704 wcn->mgmt_mem_pool.virt_addr = cpu_addr; in wcn36xx_dxe_allocate_mem_pools()
709 wcn->data_mem_pool.chunk_size = WCN36XX_BD_CHUNK_SIZE + in wcn36xx_dxe_allocate_mem_pools()
710 16 - (WCN36XX_BD_CHUNK_SIZE % 8); in wcn36xx_dxe_allocate_mem_pools()
712 s = wcn->data_mem_pool.chunk_size * WCN36XX_DXE_CH_DESC_NUMB_TX_L; in wcn36xx_dxe_allocate_mem_pools()
713 cpu_addr = dma_alloc_coherent(wcn->dev, s, in wcn36xx_dxe_allocate_mem_pools()
714 &wcn->data_mem_pool.phy_addr, in wcn36xx_dxe_allocate_mem_pools()
719 wcn->data_mem_pool.virt_addr = cpu_addr; in wcn36xx_dxe_allocate_mem_pools()
726 return -ENOMEM; in wcn36xx_dxe_allocate_mem_pools()
731 if (wcn->mgmt_mem_pool.virt_addr) in wcn36xx_dxe_free_mem_pools()
732 dma_free_coherent(wcn->dev, wcn->mgmt_mem_pool.chunk_size * in wcn36xx_dxe_free_mem_pools()
734 wcn->mgmt_mem_pool.virt_addr, in wcn36xx_dxe_free_mem_pools()
735 wcn->mgmt_mem_pool.phy_addr); in wcn36xx_dxe_free_mem_pools()
737 if (wcn->data_mem_pool.virt_addr) { in wcn36xx_dxe_free_mem_pools()
738 dma_free_coherent(wcn->dev, wcn->data_mem_pool.chunk_size * in wcn36xx_dxe_free_mem_pools()
740 wcn->data_mem_pool.virt_addr, in wcn36xx_dxe_free_mem_pools()
741 wcn->data_mem_pool.phy_addr); in wcn36xx_dxe_free_mem_pools()
757 ch = is_low ? &wcn->dxe_tx_l_ch : &wcn->dxe_tx_h_ch; in wcn36xx_dxe_tx_frame()
759 spin_lock_irqsave(&ch->lock, flags); in wcn36xx_dxe_tx_frame()
760 ctl_bd = ch->head_blk_ctl; in wcn36xx_dxe_tx_frame()
761 ctl_skb = ctl_bd->next; in wcn36xx_dxe_tx_frame()
768 if (NULL != ctl_skb->skb) { in wcn36xx_dxe_tx_frame()
769 ieee80211_stop_queues(wcn->hw); in wcn36xx_dxe_tx_frame()
770 wcn->queues_stopped = true; in wcn36xx_dxe_tx_frame()
771 spin_unlock_irqrestore(&ch->lock, flags); in wcn36xx_dxe_tx_frame()
772 return -EBUSY; in wcn36xx_dxe_tx_frame()
775 if (unlikely(ctl_skb->bd_cpu_addr)) { in wcn36xx_dxe_tx_frame()
777 ret = -EINVAL; in wcn36xx_dxe_tx_frame()
781 desc_bd = ctl_bd->desc; in wcn36xx_dxe_tx_frame()
782 desc_skb = ctl_skb->desc; in wcn36xx_dxe_tx_frame()
784 ctl_bd->skb = NULL; in wcn36xx_dxe_tx_frame()
787 memcpy(ctl_bd->bd_cpu_addr, bd, sizeof(*bd)); in wcn36xx_dxe_tx_frame()
790 desc_bd->src_addr_l = ctl_bd->bd_phy_addr; in wcn36xx_dxe_tx_frame()
791 desc_bd->dst_addr_l = ch->dxe_wq; in wcn36xx_dxe_tx_frame()
792 desc_bd->fr_len = sizeof(struct wcn36xx_tx_bd); in wcn36xx_dxe_tx_frame()
799 "BD >>> ", (char *)ctl_bd->bd_cpu_addr, in wcn36xx_dxe_tx_frame()
802 desc_skb->src_addr_l = dma_map_single(wcn->dev, in wcn36xx_dxe_tx_frame()
803 skb->data, in wcn36xx_dxe_tx_frame()
804 skb->len, in wcn36xx_dxe_tx_frame()
806 if (dma_mapping_error(wcn->dev, desc_skb->src_addr_l)) { in wcn36xx_dxe_tx_frame()
807 dev_err(wcn->dev, "unable to DMA map src_addr_l\n"); in wcn36xx_dxe_tx_frame()
808 ret = -ENOMEM; in wcn36xx_dxe_tx_frame()
812 ctl_skb->skb = skb; in wcn36xx_dxe_tx_frame()
813 desc_skb->dst_addr_l = ch->dxe_wq; in wcn36xx_dxe_tx_frame()
814 desc_skb->fr_len = ctl_skb->skb->len; in wcn36xx_dxe_tx_frame()
819 (char *)ctl_skb->skb->data, ctl_skb->skb->len); in wcn36xx_dxe_tx_frame()
822 ch->head_blk_ctl = ctl_skb->next; in wcn36xx_dxe_tx_frame()
826 desc_skb->ctrl = ch->ctrl_skb; in wcn36xx_dxe_tx_frame()
828 desc_bd->ctrl = ch->ctrl_bd; in wcn36xx_dxe_tx_frame()
835 if (is_low && vif_priv->pw_state == WCN36XX_BMPS) { in wcn36xx_dxe_tx_frame()
836 qcom_smem_state_update_bits(wcn->tx_rings_empty_state, in wcn36xx_dxe_tx_frame()
844 ch->reg_ctrl, ch->def_ctrl); in wcn36xx_dxe_tx_frame()
849 spin_unlock_irqrestore(&ch->lock, flags); in wcn36xx_dxe_tx_frame()
860 spin_lock_irqsave(&ch->lock, flags); in _wcn36xx_dxe_tx_channel_is_empty()
863 ctl_bd_start = ch->head_blk_ctl; in _wcn36xx_dxe_tx_channel_is_empty()
865 ctl_skb_start = ctl_bd_start->next; in _wcn36xx_dxe_tx_channel_is_empty()
868 if (ctl_skb->skb) { in _wcn36xx_dxe_tx_channel_is_empty()
872 ctl_bd = ctl_skb->next; in _wcn36xx_dxe_tx_channel_is_empty()
873 ctl_skb = ctl_bd->next; in _wcn36xx_dxe_tx_channel_is_empty()
877 spin_unlock_irqrestore(&ch->lock, flags); in _wcn36xx_dxe_tx_channel_is_empty()
887 if (_wcn36xx_dxe_tx_channel_is_empty(&wcn->dxe_tx_l_ch) && in wcn36xx_dxe_tx_flush()
888 _wcn36xx_dxe_tx_channel_is_empty(&wcn->dxe_tx_h_ch)) { in wcn36xx_dxe_tx_flush()
897 return -EBUSY; in wcn36xx_dxe_tx_flush()
910 if (wcn->is_pronto) in wcn36xx_dxe_init()
918 ret = wcn36xx_dxe_init_descs(wcn, &wcn->dxe_tx_l_ch); in wcn36xx_dxe_init()
920 dev_err(wcn->dev, "Error allocating descriptor\n"); in wcn36xx_dxe_init()
923 wcn36xx_dxe_init_tx_bd(&wcn->dxe_tx_l_ch, &wcn->data_mem_pool); in wcn36xx_dxe_init()
927 wcn->dxe_tx_l_ch.head_blk_ctl->desc_phy_addr); in wcn36xx_dxe_init()
939 ret = wcn36xx_dxe_init_descs(wcn, &wcn->dxe_tx_h_ch); in wcn36xx_dxe_init()
941 dev_err(wcn->dev, "Error allocating descriptor\n"); in wcn36xx_dxe_init()
945 wcn36xx_dxe_init_tx_bd(&wcn->dxe_tx_h_ch, &wcn->mgmt_mem_pool); in wcn36xx_dxe_init()
949 wcn->dxe_tx_h_ch.head_blk_ctl->desc_phy_addr); in wcn36xx_dxe_init()
961 ret = wcn36xx_dxe_init_descs(wcn, &wcn->dxe_rx_l_ch); in wcn36xx_dxe_init()
963 dev_err(wcn->dev, "Error allocating descriptor\n"); in wcn36xx_dxe_init()
968 wcn36xx_dxe_ch_alloc_skb(wcn, &wcn->dxe_rx_l_ch); in wcn36xx_dxe_init()
972 wcn->dxe_rx_l_ch.head_blk_ctl->desc_phy_addr); in wcn36xx_dxe_init()
982 wcn->dxe_rx_l_ch.head_blk_ctl->desc->phy_next_l); in wcn36xx_dxe_init()
992 ret = wcn36xx_dxe_init_descs(wcn, &wcn->dxe_rx_h_ch); in wcn36xx_dxe_init()
994 dev_err(wcn->dev, "Error allocating descriptor\n"); in wcn36xx_dxe_init()
999 wcn36xx_dxe_ch_alloc_skb(wcn, &wcn->dxe_rx_h_ch); in wcn36xx_dxe_init()
1003 wcn->dxe_rx_h_ch.head_blk_ctl->desc_phy_addr); in wcn36xx_dxe_init()
1013 wcn->dxe_rx_h_ch.head_blk_ctl->desc->phy_next_l); in wcn36xx_dxe_init()
1024 timer_setup(&wcn->tx_ack_timer, wcn36xx_dxe_tx_timer, 0); in wcn36xx_dxe_init()
1035 wcn36xx_dxe_deinit_descs(wcn->dev, &wcn->dxe_rx_h_ch); in wcn36xx_dxe_init()
1037 wcn36xx_dxe_deinit_descs(wcn->dev, &wcn->dxe_rx_l_ch); in wcn36xx_dxe_init()
1039 wcn36xx_dxe_deinit_descs(wcn->dev, &wcn->dxe_tx_h_ch); in wcn36xx_dxe_init()
1041 wcn36xx_dxe_deinit_descs(wcn->dev, &wcn->dxe_tx_l_ch); in wcn36xx_dxe_init()
1056 free_irq(wcn->tx_irq, wcn); in wcn36xx_dxe_deinit()
1057 free_irq(wcn->rx_irq, wcn); in wcn36xx_dxe_deinit()
1058 del_timer(&wcn->tx_ack_timer); in wcn36xx_dxe_deinit()
1060 if (wcn->tx_ack_skb) { in wcn36xx_dxe_deinit()
1061 ieee80211_tx_status_irqsafe(wcn->hw, wcn->tx_ack_skb); in wcn36xx_dxe_deinit()
1062 wcn->tx_ack_skb = NULL; in wcn36xx_dxe_deinit()
1069 wcn36xx_dxe_ch_free_skbs(wcn, &wcn->dxe_rx_l_ch); in wcn36xx_dxe_deinit()
1070 wcn36xx_dxe_ch_free_skbs(wcn, &wcn->dxe_rx_h_ch); in wcn36xx_dxe_deinit()
1072 wcn36xx_dxe_deinit_descs(wcn->dev, &wcn->dxe_tx_l_ch); in wcn36xx_dxe_deinit()
1073 wcn36xx_dxe_deinit_descs(wcn->dev, &wcn->dxe_tx_h_ch); in wcn36xx_dxe_deinit()
1074 wcn36xx_dxe_deinit_descs(wcn->dev, &wcn->dxe_rx_l_ch); in wcn36xx_dxe_deinit()
1075 wcn36xx_dxe_deinit_descs(wcn->dev, &wcn->dxe_rx_h_ch); in wcn36xx_dxe_deinit()