xref: /freebsd/sys/contrib/dev/iwlwifi/pcie/tx.c (revision a4128aad8503277614f2d214011ef60a19447b83)
1bfcc09ddSBjoern A. Zeeb // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2bfcc09ddSBjoern A. Zeeb /*
3*a4128aadSBjoern A. Zeeb  * Copyright (C) 2003-2014, 2018-2021, 2023-2024 Intel Corporation
4bfcc09ddSBjoern A. Zeeb  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
5bfcc09ddSBjoern A. Zeeb  * Copyright (C) 2016-2017 Intel Deutschland GmbH
6bfcc09ddSBjoern A. Zeeb  */
7bfcc09ddSBjoern A. Zeeb #include <linux/etherdevice.h>
8bfcc09ddSBjoern A. Zeeb #include <linux/ieee80211.h>
9*a4128aadSBjoern A. Zeeb #include <linux/dmapool.h>
10bfcc09ddSBjoern A. Zeeb #include <linux/slab.h>
11bfcc09ddSBjoern A. Zeeb #include <linux/sched.h>
12*a4128aadSBjoern A. Zeeb #include <linux/tcp.h>
13bfcc09ddSBjoern A. Zeeb #ifdef CONFIG_INET
14bfcc09ddSBjoern A. Zeeb #include <net/ip6_checksum.h>
15bfcc09ddSBjoern A. Zeeb #include <net/tso.h>
16bfcc09ddSBjoern A. Zeeb #endif
17bfcc09ddSBjoern A. Zeeb #if defined(__FreeBSD__)
18bfcc09ddSBjoern A. Zeeb #include <net/mac80211.h>
19bfcc09ddSBjoern A. Zeeb #endif
20bfcc09ddSBjoern A. Zeeb 
21*a4128aadSBjoern A. Zeeb #include "fw/api/commands.h"
22*a4128aadSBjoern A. Zeeb #include "fw/api/datapath.h"
23*a4128aadSBjoern A. Zeeb #include "fw/api/debug.h"
24*a4128aadSBjoern A. Zeeb #include "iwl-fh.h"
25bfcc09ddSBjoern A. Zeeb #include "iwl-debug.h"
26bfcc09ddSBjoern A. Zeeb #include "iwl-csr.h"
27bfcc09ddSBjoern A. Zeeb #include "iwl-prph.h"
28bfcc09ddSBjoern A. Zeeb #include "iwl-io.h"
29bfcc09ddSBjoern A. Zeeb #include "iwl-scd.h"
30bfcc09ddSBjoern A. Zeeb #include "iwl-op-mode.h"
31bfcc09ddSBjoern A. Zeeb #include "internal.h"
32bfcc09ddSBjoern A. Zeeb #include "fw/api/tx.h"
33bfcc09ddSBjoern A. Zeeb 
34bfcc09ddSBjoern A. Zeeb /*************** DMA-QUEUE-GENERAL-FUNCTIONS  *****
35bfcc09ddSBjoern A. Zeeb  * DMA services
36bfcc09ddSBjoern A. Zeeb  *
37bfcc09ddSBjoern A. Zeeb  * Theory of operation
38bfcc09ddSBjoern A. Zeeb  *
39bfcc09ddSBjoern A. Zeeb  * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer
40bfcc09ddSBjoern A. Zeeb  * of buffer descriptors, each of which points to one or more data buffers for
41bfcc09ddSBjoern A. Zeeb  * the device to read from or fill.  Driver and device exchange status of each
42bfcc09ddSBjoern A. Zeeb  * queue via "read" and "write" pointers.  Driver keeps minimum of 2 empty
43bfcc09ddSBjoern A. Zeeb  * entries in each circular buffer, to protect against confusing empty and full
44bfcc09ddSBjoern A. Zeeb  * queue states.
45bfcc09ddSBjoern A. Zeeb  *
46bfcc09ddSBjoern A. Zeeb  * The device reads or writes the data in the queues via the device's several
47bfcc09ddSBjoern A. Zeeb  * DMA/FIFO channels.  Each queue is mapped to a single DMA channel.
48bfcc09ddSBjoern A. Zeeb  *
49bfcc09ddSBjoern A. Zeeb  * For Tx queue, there are low mark and high mark limits. If, after queuing
50bfcc09ddSBjoern A. Zeeb  * the packet for Tx, free space become < low mark, Tx queue stopped. When
51bfcc09ddSBjoern A. Zeeb  * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
52bfcc09ddSBjoern A. Zeeb  * Tx queue resumed.
53bfcc09ddSBjoern A. Zeeb  *
54bfcc09ddSBjoern A. Zeeb  ***************************************************/
55bfcc09ddSBjoern A. Zeeb 
56bfcc09ddSBjoern A. Zeeb 
57bfcc09ddSBjoern A. Zeeb int iwl_pcie_alloc_dma_ptr(struct iwl_trans *trans,
58bfcc09ddSBjoern A. Zeeb 			   struct iwl_dma_ptr *ptr, size_t size)
59bfcc09ddSBjoern A. Zeeb {
60bfcc09ddSBjoern A. Zeeb 	if (WARN_ON(ptr->addr))
61bfcc09ddSBjoern A. Zeeb 		return -EINVAL;
62bfcc09ddSBjoern A. Zeeb 
63bfcc09ddSBjoern A. Zeeb 	ptr->addr = dma_alloc_coherent(trans->dev, size,
64bfcc09ddSBjoern A. Zeeb 				       &ptr->dma, GFP_KERNEL);
65bfcc09ddSBjoern A. Zeeb 	if (!ptr->addr)
66bfcc09ddSBjoern A. Zeeb 		return -ENOMEM;
67bfcc09ddSBjoern A. Zeeb 	ptr->size = size;
68bfcc09ddSBjoern A. Zeeb 	return 0;
69bfcc09ddSBjoern A. Zeeb }
70bfcc09ddSBjoern A. Zeeb 
71bfcc09ddSBjoern A. Zeeb void iwl_pcie_free_dma_ptr(struct iwl_trans *trans, struct iwl_dma_ptr *ptr)
72bfcc09ddSBjoern A. Zeeb {
73bfcc09ddSBjoern A. Zeeb 	if (unlikely(!ptr->addr))
74bfcc09ddSBjoern A. Zeeb 		return;
75bfcc09ddSBjoern A. Zeeb 
76bfcc09ddSBjoern A. Zeeb 	dma_free_coherent(trans->dev, ptr->size, ptr->addr, ptr->dma);
77bfcc09ddSBjoern A. Zeeb 	memset(ptr, 0, sizeof(*ptr));
78bfcc09ddSBjoern A. Zeeb }
79bfcc09ddSBjoern A. Zeeb 
80bfcc09ddSBjoern A. Zeeb /*
81bfcc09ddSBjoern A. Zeeb  * iwl_pcie_txq_inc_wr_ptr - Send new write index to hardware
82bfcc09ddSBjoern A. Zeeb  */
83bfcc09ddSBjoern A. Zeeb static void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans,
84bfcc09ddSBjoern A. Zeeb 				    struct iwl_txq *txq)
85bfcc09ddSBjoern A. Zeeb {
86*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
87bfcc09ddSBjoern A. Zeeb 	u32 reg = 0;
88bfcc09ddSBjoern A. Zeeb 	int txq_id = txq->id;
89bfcc09ddSBjoern A. Zeeb 
90bfcc09ddSBjoern A. Zeeb 	lockdep_assert_held(&txq->lock);
91bfcc09ddSBjoern A. Zeeb 
92bfcc09ddSBjoern A. Zeeb 	/*
93bfcc09ddSBjoern A. Zeeb 	 * explicitly wake up the NIC if:
94bfcc09ddSBjoern A. Zeeb 	 * 1. shadow registers aren't enabled
95bfcc09ddSBjoern A. Zeeb 	 * 2. NIC is woken up for CMD regardless of shadow outside this function
96bfcc09ddSBjoern A. Zeeb 	 * 3. there is a chance that the NIC is asleep
97bfcc09ddSBjoern A. Zeeb 	 */
98bfcc09ddSBjoern A. Zeeb 	if (!trans->trans_cfg->base_params->shadow_reg_enable &&
99*a4128aadSBjoern A. Zeeb 	    txq_id != trans_pcie->txqs.cmd.q_id &&
100bfcc09ddSBjoern A. Zeeb 	    test_bit(STATUS_TPOWER_PMI, &trans->status)) {
101bfcc09ddSBjoern A. Zeeb 		/*
102bfcc09ddSBjoern A. Zeeb 		 * wake up nic if it's powered down ...
103bfcc09ddSBjoern A. Zeeb 		 * uCode will wake up, and interrupt us again, so next
104bfcc09ddSBjoern A. Zeeb 		 * time we'll skip this part.
105bfcc09ddSBjoern A. Zeeb 		 */
106bfcc09ddSBjoern A. Zeeb 		reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
107bfcc09ddSBjoern A. Zeeb 
108bfcc09ddSBjoern A. Zeeb 		if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
109bfcc09ddSBjoern A. Zeeb 			IWL_DEBUG_INFO(trans, "Tx queue %d requesting wakeup, GP1 = 0x%x\n",
110bfcc09ddSBjoern A. Zeeb 				       txq_id, reg);
111bfcc09ddSBjoern A. Zeeb 			iwl_set_bit(trans, CSR_GP_CNTRL,
112bfcc09ddSBjoern A. Zeeb 				    CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
113bfcc09ddSBjoern A. Zeeb 			txq->need_update = true;
114bfcc09ddSBjoern A. Zeeb 			return;
115bfcc09ddSBjoern A. Zeeb 		}
116bfcc09ddSBjoern A. Zeeb 	}
117bfcc09ddSBjoern A. Zeeb 
118bfcc09ddSBjoern A. Zeeb 	/*
119bfcc09ddSBjoern A. Zeeb 	 * if not in power-save mode, uCode will never sleep when we're
120bfcc09ddSBjoern A. Zeeb 	 * trying to tx (during RFKILL, we're not trying to tx).
121bfcc09ddSBjoern A. Zeeb 	 */
122bfcc09ddSBjoern A. Zeeb 	IWL_DEBUG_TX(trans, "Q:%d WR: 0x%x\n", txq_id, txq->write_ptr);
123bfcc09ddSBjoern A. Zeeb 	if (!txq->block)
124bfcc09ddSBjoern A. Zeeb 		iwl_write32(trans, HBUS_TARG_WRPTR,
125bfcc09ddSBjoern A. Zeeb 			    txq->write_ptr | (txq_id << 8));
126bfcc09ddSBjoern A. Zeeb }
127bfcc09ddSBjoern A. Zeeb 
128bfcc09ddSBjoern A. Zeeb void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans)
129bfcc09ddSBjoern A. Zeeb {
130*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
131bfcc09ddSBjoern A. Zeeb 	int i;
132bfcc09ddSBjoern A. Zeeb 
133bfcc09ddSBjoern A. Zeeb 	for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) {
134*a4128aadSBjoern A. Zeeb 		struct iwl_txq *txq = trans_pcie->txqs.txq[i];
135bfcc09ddSBjoern A. Zeeb 
136*a4128aadSBjoern A. Zeeb 		if (!test_bit(i, trans_pcie->txqs.queue_used))
137bfcc09ddSBjoern A. Zeeb 			continue;
138bfcc09ddSBjoern A. Zeeb 
139bfcc09ddSBjoern A. Zeeb 		spin_lock_bh(&txq->lock);
140bfcc09ddSBjoern A. Zeeb 		if (txq->need_update) {
141bfcc09ddSBjoern A. Zeeb 			iwl_pcie_txq_inc_wr_ptr(trans, txq);
142bfcc09ddSBjoern A. Zeeb 			txq->need_update = false;
143bfcc09ddSBjoern A. Zeeb 		}
144bfcc09ddSBjoern A. Zeeb 		spin_unlock_bh(&txq->lock);
145bfcc09ddSBjoern A. Zeeb 	}
146bfcc09ddSBjoern A. Zeeb }
147bfcc09ddSBjoern A. Zeeb 
148*a4128aadSBjoern A. Zeeb static inline void iwl_pcie_gen1_tfd_set_tb(struct iwl_tfd *tfd,
149bfcc09ddSBjoern A. Zeeb 					    u8 idx, dma_addr_t addr, u16 len)
150bfcc09ddSBjoern A. Zeeb {
151*a4128aadSBjoern A. Zeeb 	struct iwl_tfd_tb *tb = &tfd->tbs[idx];
152bfcc09ddSBjoern A. Zeeb 	u16 hi_n_len = len << 4;
153bfcc09ddSBjoern A. Zeeb 
154bfcc09ddSBjoern A. Zeeb 	put_unaligned_le32(addr, &tb->lo);
155bfcc09ddSBjoern A. Zeeb 	hi_n_len |= iwl_get_dma_hi_addr(addr);
156bfcc09ddSBjoern A. Zeeb 
157bfcc09ddSBjoern A. Zeeb 	tb->hi_n_len = cpu_to_le16(hi_n_len);
158bfcc09ddSBjoern A. Zeeb 
159*a4128aadSBjoern A. Zeeb 	tfd->num_tbs = idx + 1;
160*a4128aadSBjoern A. Zeeb }
161*a4128aadSBjoern A. Zeeb 
162*a4128aadSBjoern A. Zeeb static inline u8 iwl_txq_gen1_tfd_get_num_tbs(struct iwl_tfd *tfd)
163*a4128aadSBjoern A. Zeeb {
164*a4128aadSBjoern A. Zeeb 	return tfd->num_tbs & 0x1f;
165bfcc09ddSBjoern A. Zeeb }
166bfcc09ddSBjoern A. Zeeb 
167bfcc09ddSBjoern A. Zeeb static int iwl_pcie_txq_build_tfd(struct iwl_trans *trans, struct iwl_txq *txq,
168bfcc09ddSBjoern A. Zeeb 				  dma_addr_t addr, u16 len, bool reset)
169bfcc09ddSBjoern A. Zeeb {
170*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
171bfcc09ddSBjoern A. Zeeb 	void *tfd;
172bfcc09ddSBjoern A. Zeeb 	u32 num_tbs;
173bfcc09ddSBjoern A. Zeeb 
174*a4128aadSBjoern A. Zeeb 	tfd = (u8 *)txq->tfds + trans_pcie->txqs.tfd.size * txq->write_ptr;
175bfcc09ddSBjoern A. Zeeb 
176bfcc09ddSBjoern A. Zeeb 	if (reset)
177*a4128aadSBjoern A. Zeeb 		memset(tfd, 0, trans_pcie->txqs.tfd.size);
178bfcc09ddSBjoern A. Zeeb 
179*a4128aadSBjoern A. Zeeb 	num_tbs = iwl_txq_gen1_tfd_get_num_tbs(tfd);
180bfcc09ddSBjoern A. Zeeb 
181bfcc09ddSBjoern A. Zeeb 	/* Each TFD can point to a maximum max_tbs Tx buffers */
182*a4128aadSBjoern A. Zeeb 	if (num_tbs >= trans_pcie->txqs.tfd.max_tbs) {
183bfcc09ddSBjoern A. Zeeb 		IWL_ERR(trans, "Error can not send more than %d chunks\n",
184*a4128aadSBjoern A. Zeeb 			trans_pcie->txqs.tfd.max_tbs);
185bfcc09ddSBjoern A. Zeeb 		return -EINVAL;
186bfcc09ddSBjoern A. Zeeb 	}
187bfcc09ddSBjoern A. Zeeb 
188bfcc09ddSBjoern A. Zeeb 	if (WARN(addr & ~IWL_TX_DMA_MASK,
189bfcc09ddSBjoern A. Zeeb 		 "Unaligned address = %llx\n", (unsigned long long)addr))
190bfcc09ddSBjoern A. Zeeb 		return -EINVAL;
191bfcc09ddSBjoern A. Zeeb 
192*a4128aadSBjoern A. Zeeb 	iwl_pcie_gen1_tfd_set_tb(tfd, num_tbs, addr, len);
193bfcc09ddSBjoern A. Zeeb 
194bfcc09ddSBjoern A. Zeeb 	return num_tbs;
195bfcc09ddSBjoern A. Zeeb }
196bfcc09ddSBjoern A. Zeeb 
197bfcc09ddSBjoern A. Zeeb static void iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans)
198bfcc09ddSBjoern A. Zeeb {
199bfcc09ddSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
200bfcc09ddSBjoern A. Zeeb 
201bfcc09ddSBjoern A. Zeeb 	if (!trans->trans_cfg->base_params->apmg_wake_up_wa)
202bfcc09ddSBjoern A. Zeeb 		return;
203bfcc09ddSBjoern A. Zeeb 
204bfcc09ddSBjoern A. Zeeb 	spin_lock(&trans_pcie->reg_lock);
205bfcc09ddSBjoern A. Zeeb 
206bfcc09ddSBjoern A. Zeeb 	if (WARN_ON(!trans_pcie->cmd_hold_nic_awake)) {
207bfcc09ddSBjoern A. Zeeb 		spin_unlock(&trans_pcie->reg_lock);
208bfcc09ddSBjoern A. Zeeb 		return;
209bfcc09ddSBjoern A. Zeeb 	}
210bfcc09ddSBjoern A. Zeeb 
211bfcc09ddSBjoern A. Zeeb 	trans_pcie->cmd_hold_nic_awake = false;
212bfcc09ddSBjoern A. Zeeb 	__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
213bfcc09ddSBjoern A. Zeeb 				   CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
214bfcc09ddSBjoern A. Zeeb 	spin_unlock(&trans_pcie->reg_lock);
215bfcc09ddSBjoern A. Zeeb }
216bfcc09ddSBjoern A. Zeeb 
217*a4128aadSBjoern A. Zeeb static void iwl_pcie_free_and_unmap_tso_page(struct iwl_trans *trans,
218*a4128aadSBjoern A. Zeeb 					     struct page *page)
219*a4128aadSBjoern A. Zeeb {
220*a4128aadSBjoern A. Zeeb 	struct iwl_tso_page_info *info = IWL_TSO_PAGE_INFO(page_address(page));
221*a4128aadSBjoern A. Zeeb 
222*a4128aadSBjoern A. Zeeb 	/* Decrease internal use count and unmap/free page if needed */
223*a4128aadSBjoern A. Zeeb 	if (refcount_dec_and_test(&info->use_count)) {
224*a4128aadSBjoern A. Zeeb 		dma_unmap_page(trans->dev, info->dma_addr, PAGE_SIZE,
225*a4128aadSBjoern A. Zeeb 			       DMA_TO_DEVICE);
226*a4128aadSBjoern A. Zeeb 
227*a4128aadSBjoern A. Zeeb 		__free_page(page);
228*a4128aadSBjoern A. Zeeb 	}
229*a4128aadSBjoern A. Zeeb }
230*a4128aadSBjoern A. Zeeb 
231*a4128aadSBjoern A. Zeeb void iwl_pcie_free_tso_pages(struct iwl_trans *trans, struct sk_buff *skb,
232*a4128aadSBjoern A. Zeeb 			     struct iwl_cmd_meta *cmd_meta)
233*a4128aadSBjoern A. Zeeb {
234*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
235*a4128aadSBjoern A. Zeeb 	struct page **page_ptr;
236*a4128aadSBjoern A. Zeeb 	struct page *next;
237*a4128aadSBjoern A. Zeeb 
238*a4128aadSBjoern A. Zeeb 	page_ptr = (void *)((u8 *)skb->cb + trans_pcie->txqs.page_offs);
239*a4128aadSBjoern A. Zeeb 	next = *page_ptr;
240*a4128aadSBjoern A. Zeeb 	*page_ptr = NULL;
241*a4128aadSBjoern A. Zeeb 
242*a4128aadSBjoern A. Zeeb 	while (next) {
243*a4128aadSBjoern A. Zeeb 		struct iwl_tso_page_info *info;
244*a4128aadSBjoern A. Zeeb 		struct page *tmp = next;
245*a4128aadSBjoern A. Zeeb 
246*a4128aadSBjoern A. Zeeb 		info = IWL_TSO_PAGE_INFO(page_address(next));
247*a4128aadSBjoern A. Zeeb 		next = info->next;
248*a4128aadSBjoern A. Zeeb 
249*a4128aadSBjoern A. Zeeb 		/* Unmap the scatter gather list that is on the last page */
250*a4128aadSBjoern A. Zeeb 		if (!next && cmd_meta->sg_offset) {
251*a4128aadSBjoern A. Zeeb 			struct sg_table *sgt;
252*a4128aadSBjoern A. Zeeb 
253*a4128aadSBjoern A. Zeeb 			sgt = (void *)((u8 *)page_address(tmp) +
254*a4128aadSBjoern A. Zeeb 				       cmd_meta->sg_offset);
255*a4128aadSBjoern A. Zeeb 
256*a4128aadSBjoern A. Zeeb 			dma_unmap_sgtable(trans->dev, sgt, DMA_TO_DEVICE, 0);
257*a4128aadSBjoern A. Zeeb 		}
258*a4128aadSBjoern A. Zeeb 
259*a4128aadSBjoern A. Zeeb 		iwl_pcie_free_and_unmap_tso_page(trans, tmp);
260*a4128aadSBjoern A. Zeeb 	}
261*a4128aadSBjoern A. Zeeb }
262*a4128aadSBjoern A. Zeeb 
263*a4128aadSBjoern A. Zeeb static inline dma_addr_t
264*a4128aadSBjoern A. Zeeb iwl_txq_gen1_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
265*a4128aadSBjoern A. Zeeb {
266*a4128aadSBjoern A. Zeeb 	struct iwl_tfd_tb *tb = &tfd->tbs[idx];
267*a4128aadSBjoern A. Zeeb 	dma_addr_t addr;
268*a4128aadSBjoern A. Zeeb 	dma_addr_t hi_len;
269*a4128aadSBjoern A. Zeeb 
270*a4128aadSBjoern A. Zeeb 	addr = get_unaligned_le32(&tb->lo);
271*a4128aadSBjoern A. Zeeb 
272*a4128aadSBjoern A. Zeeb 	if (sizeof(dma_addr_t) <= sizeof(u32))
273*a4128aadSBjoern A. Zeeb 		return addr;
274*a4128aadSBjoern A. Zeeb 
275*a4128aadSBjoern A. Zeeb 	hi_len = le16_to_cpu(tb->hi_n_len) & 0xF;
276*a4128aadSBjoern A. Zeeb 
277*a4128aadSBjoern A. Zeeb 	/*
278*a4128aadSBjoern A. Zeeb 	 * shift by 16 twice to avoid warnings on 32-bit
279*a4128aadSBjoern A. Zeeb 	 * (where this code never runs anyway due to the
280*a4128aadSBjoern A. Zeeb 	 * if statement above)
281*a4128aadSBjoern A. Zeeb 	 */
282*a4128aadSBjoern A. Zeeb 	return addr | ((hi_len << 16) << 16);
283*a4128aadSBjoern A. Zeeb }
284*a4128aadSBjoern A. Zeeb 
285*a4128aadSBjoern A. Zeeb static void iwl_txq_set_tfd_invalid_gen1(struct iwl_trans *trans,
286*a4128aadSBjoern A. Zeeb 					 struct iwl_tfd *tfd)
287*a4128aadSBjoern A. Zeeb {
288*a4128aadSBjoern A. Zeeb 	tfd->num_tbs = 0;
289*a4128aadSBjoern A. Zeeb 
290*a4128aadSBjoern A. Zeeb 	iwl_pcie_gen1_tfd_set_tb(tfd, 0, trans->invalid_tx_cmd.dma,
291*a4128aadSBjoern A. Zeeb 				 trans->invalid_tx_cmd.size);
292*a4128aadSBjoern A. Zeeb }
293*a4128aadSBjoern A. Zeeb 
294*a4128aadSBjoern A. Zeeb static void iwl_txq_gen1_tfd_unmap(struct iwl_trans *trans,
295*a4128aadSBjoern A. Zeeb 				   struct iwl_cmd_meta *meta,
296*a4128aadSBjoern A. Zeeb 				   struct iwl_txq *txq, int index)
297*a4128aadSBjoern A. Zeeb {
298*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
299*a4128aadSBjoern A. Zeeb 	int i, num_tbs;
300*a4128aadSBjoern A. Zeeb 	struct iwl_tfd *tfd = iwl_txq_get_tfd(trans, txq, index);
301*a4128aadSBjoern A. Zeeb 
302*a4128aadSBjoern A. Zeeb 	/* Sanity check on number of chunks */
303*a4128aadSBjoern A. Zeeb 	num_tbs = iwl_txq_gen1_tfd_get_num_tbs(tfd);
304*a4128aadSBjoern A. Zeeb 
305*a4128aadSBjoern A. Zeeb 	if (num_tbs > trans_pcie->txqs.tfd.max_tbs) {
306*a4128aadSBjoern A. Zeeb 		IWL_ERR(trans, "Too many chunks: %i\n", num_tbs);
307*a4128aadSBjoern A. Zeeb 		/* @todo issue fatal error, it is quite serious situation */
308*a4128aadSBjoern A. Zeeb 		return;
309*a4128aadSBjoern A. Zeeb 	}
310*a4128aadSBjoern A. Zeeb 
311*a4128aadSBjoern A. Zeeb 	/* TB1 is mapped directly, the rest is the TSO page and SG list. */
312*a4128aadSBjoern A. Zeeb 	if (meta->sg_offset)
313*a4128aadSBjoern A. Zeeb 		num_tbs = 2;
314*a4128aadSBjoern A. Zeeb 
315*a4128aadSBjoern A. Zeeb 	/* first TB is never freed - it's the bidirectional DMA data */
316*a4128aadSBjoern A. Zeeb 
317*a4128aadSBjoern A. Zeeb 	for (i = 1; i < num_tbs; i++) {
318*a4128aadSBjoern A. Zeeb 		if (meta->tbs & BIT(i))
319*a4128aadSBjoern A. Zeeb 			dma_unmap_page(trans->dev,
320*a4128aadSBjoern A. Zeeb 				       iwl_txq_gen1_tfd_tb_get_addr(tfd, i),
321*a4128aadSBjoern A. Zeeb 				       iwl_txq_gen1_tfd_tb_get_len(trans,
322*a4128aadSBjoern A. Zeeb 								   tfd, i),
323*a4128aadSBjoern A. Zeeb 				       DMA_TO_DEVICE);
324*a4128aadSBjoern A. Zeeb 		else
325*a4128aadSBjoern A. Zeeb 			dma_unmap_single(trans->dev,
326*a4128aadSBjoern A. Zeeb 					 iwl_txq_gen1_tfd_tb_get_addr(tfd, i),
327*a4128aadSBjoern A. Zeeb 					 iwl_txq_gen1_tfd_tb_get_len(trans,
328*a4128aadSBjoern A. Zeeb 								     tfd, i),
329*a4128aadSBjoern A. Zeeb 					 DMA_TO_DEVICE);
330*a4128aadSBjoern A. Zeeb 	}
331*a4128aadSBjoern A. Zeeb 
332*a4128aadSBjoern A. Zeeb 	meta->tbs = 0;
333*a4128aadSBjoern A. Zeeb 
334*a4128aadSBjoern A. Zeeb 	iwl_txq_set_tfd_invalid_gen1(trans, tfd);
335*a4128aadSBjoern A. Zeeb }
336*a4128aadSBjoern A. Zeeb 
337*a4128aadSBjoern A. Zeeb /**
338*a4128aadSBjoern A. Zeeb  * iwl_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
339*a4128aadSBjoern A. Zeeb  * @trans: transport private data
340*a4128aadSBjoern A. Zeeb  * @txq: tx queue
341*a4128aadSBjoern A. Zeeb  * @read_ptr: the TXQ read_ptr to free
342*a4128aadSBjoern A. Zeeb  *
343*a4128aadSBjoern A. Zeeb  * Does NOT advance any TFD circular buffer read/write indexes
344*a4128aadSBjoern A. Zeeb  * Does NOT free the TFD itself (which is within circular buffer)
345*a4128aadSBjoern A. Zeeb  */
346*a4128aadSBjoern A. Zeeb static void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq,
347*a4128aadSBjoern A. Zeeb 			     int read_ptr)
348*a4128aadSBjoern A. Zeeb {
349*a4128aadSBjoern A. Zeeb 	/* rd_ptr is bounded by TFD_QUEUE_SIZE_MAX and
350*a4128aadSBjoern A. Zeeb 	 * idx is bounded by n_window
351*a4128aadSBjoern A. Zeeb 	 */
352*a4128aadSBjoern A. Zeeb 	int idx = iwl_txq_get_cmd_index(txq, read_ptr);
353*a4128aadSBjoern A. Zeeb 	struct sk_buff *skb;
354*a4128aadSBjoern A. Zeeb 
355*a4128aadSBjoern A. Zeeb 	lockdep_assert_held(&txq->reclaim_lock);
356*a4128aadSBjoern A. Zeeb 
357*a4128aadSBjoern A. Zeeb 	if (!txq->entries)
358*a4128aadSBjoern A. Zeeb 		return;
359*a4128aadSBjoern A. Zeeb 
360*a4128aadSBjoern A. Zeeb 	/* We have only q->n_window txq->entries, but we use
361*a4128aadSBjoern A. Zeeb 	 * TFD_QUEUE_SIZE_MAX tfds
362*a4128aadSBjoern A. Zeeb 	 */
363*a4128aadSBjoern A. Zeeb 	if (trans->trans_cfg->gen2)
364*a4128aadSBjoern A. Zeeb 		iwl_txq_gen2_tfd_unmap(trans, &txq->entries[idx].meta,
365*a4128aadSBjoern A. Zeeb 				       iwl_txq_get_tfd(trans, txq, read_ptr));
366*a4128aadSBjoern A. Zeeb 	else
367*a4128aadSBjoern A. Zeeb 		iwl_txq_gen1_tfd_unmap(trans, &txq->entries[idx].meta,
368*a4128aadSBjoern A. Zeeb 				       txq, read_ptr);
369*a4128aadSBjoern A. Zeeb 
370*a4128aadSBjoern A. Zeeb 	/* free SKB */
371*a4128aadSBjoern A. Zeeb 	skb = txq->entries[idx].skb;
372*a4128aadSBjoern A. Zeeb 
373*a4128aadSBjoern A. Zeeb 	/* Can be called from irqs-disabled context
374*a4128aadSBjoern A. Zeeb 	 * If skb is not NULL, it means that the whole queue is being
375*a4128aadSBjoern A. Zeeb 	 * freed and that the queue is not empty - free the skb
376*a4128aadSBjoern A. Zeeb 	 */
377*a4128aadSBjoern A. Zeeb 	if (skb) {
378*a4128aadSBjoern A. Zeeb 		iwl_op_mode_free_skb(trans->op_mode, skb);
379*a4128aadSBjoern A. Zeeb 		txq->entries[idx].skb = NULL;
380*a4128aadSBjoern A. Zeeb 	}
381*a4128aadSBjoern A. Zeeb }
382*a4128aadSBjoern A. Zeeb 
383bfcc09ddSBjoern A. Zeeb /*
384bfcc09ddSBjoern A. Zeeb  * iwl_pcie_txq_unmap -  Unmap any remaining DMA mappings and free skb's
385bfcc09ddSBjoern A. Zeeb  */
386bfcc09ddSBjoern A. Zeeb static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
387bfcc09ddSBjoern A. Zeeb {
388*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
389*a4128aadSBjoern A. Zeeb 	struct iwl_txq *txq = trans_pcie->txqs.txq[txq_id];
390bfcc09ddSBjoern A. Zeeb 
391bfcc09ddSBjoern A. Zeeb 	if (!txq) {
392bfcc09ddSBjoern A. Zeeb 		IWL_ERR(trans, "Trying to free a queue that wasn't allocated?\n");
393bfcc09ddSBjoern A. Zeeb 		return;
394bfcc09ddSBjoern A. Zeeb 	}
395bfcc09ddSBjoern A. Zeeb 
396*a4128aadSBjoern A. Zeeb 	spin_lock_bh(&txq->reclaim_lock);
397*a4128aadSBjoern A. Zeeb 	spin_lock(&txq->lock);
398bfcc09ddSBjoern A. Zeeb 	while (txq->write_ptr != txq->read_ptr) {
399bfcc09ddSBjoern A. Zeeb 		IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n",
400bfcc09ddSBjoern A. Zeeb 				   txq_id, txq->read_ptr);
401bfcc09ddSBjoern A. Zeeb 
402*a4128aadSBjoern A. Zeeb 		if (txq_id != trans_pcie->txqs.cmd.q_id) {
403bfcc09ddSBjoern A. Zeeb 			struct sk_buff *skb = txq->entries[txq->read_ptr].skb;
404*a4128aadSBjoern A. Zeeb 			struct iwl_cmd_meta *cmd_meta =
405*a4128aadSBjoern A. Zeeb 				&txq->entries[txq->read_ptr].meta;
406bfcc09ddSBjoern A. Zeeb 
407bfcc09ddSBjoern A. Zeeb 			if (WARN_ON_ONCE(!skb))
408bfcc09ddSBjoern A. Zeeb 				continue;
409bfcc09ddSBjoern A. Zeeb 
410*a4128aadSBjoern A. Zeeb 			iwl_pcie_free_tso_pages(trans, skb, cmd_meta);
411bfcc09ddSBjoern A. Zeeb 		}
412*a4128aadSBjoern A. Zeeb 		iwl_txq_free_tfd(trans, txq, txq->read_ptr);
413bfcc09ddSBjoern A. Zeeb 		txq->read_ptr = iwl_txq_inc_wrap(trans, txq->read_ptr);
414bfcc09ddSBjoern A. Zeeb 
415bfcc09ddSBjoern A. Zeeb 		if (txq->read_ptr == txq->write_ptr &&
416*a4128aadSBjoern A. Zeeb 		    txq_id == trans_pcie->txqs.cmd.q_id)
417bfcc09ddSBjoern A. Zeeb 			iwl_pcie_clear_cmd_in_flight(trans);
418bfcc09ddSBjoern A. Zeeb 	}
419bfcc09ddSBjoern A. Zeeb 
420bfcc09ddSBjoern A. Zeeb 	while (!skb_queue_empty(&txq->overflow_q)) {
421bfcc09ddSBjoern A. Zeeb 		struct sk_buff *skb = __skb_dequeue(&txq->overflow_q);
422bfcc09ddSBjoern A. Zeeb 
423bfcc09ddSBjoern A. Zeeb 		iwl_op_mode_free_skb(trans->op_mode, skb);
424bfcc09ddSBjoern A. Zeeb 	}
425bfcc09ddSBjoern A. Zeeb 
426*a4128aadSBjoern A. Zeeb 	spin_unlock(&txq->lock);
427*a4128aadSBjoern A. Zeeb 	spin_unlock_bh(&txq->reclaim_lock);
428bfcc09ddSBjoern A. Zeeb 
429bfcc09ddSBjoern A. Zeeb 	/* just in case - this queue may have been stopped */
430*a4128aadSBjoern A. Zeeb 	iwl_trans_pcie_wake_queue(trans, txq);
431bfcc09ddSBjoern A. Zeeb }
432bfcc09ddSBjoern A. Zeeb 
433bfcc09ddSBjoern A. Zeeb /*
434bfcc09ddSBjoern A. Zeeb  * iwl_pcie_txq_free - Deallocate DMA queue.
435bfcc09ddSBjoern A. Zeeb  * @txq: Transmit queue to deallocate.
436bfcc09ddSBjoern A. Zeeb  *
437bfcc09ddSBjoern A. Zeeb  * Empty queue by removing and destroying all BD's.
438bfcc09ddSBjoern A. Zeeb  * Free all buffers.
439bfcc09ddSBjoern A. Zeeb  * 0-fill, but do not free "txq" descriptor structure.
440bfcc09ddSBjoern A. Zeeb  */
441bfcc09ddSBjoern A. Zeeb static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
442bfcc09ddSBjoern A. Zeeb {
443*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
444*a4128aadSBjoern A. Zeeb 	struct iwl_txq *txq = trans_pcie->txqs.txq[txq_id];
445bfcc09ddSBjoern A. Zeeb 	struct device *dev = trans->dev;
446bfcc09ddSBjoern A. Zeeb 	int i;
447bfcc09ddSBjoern A. Zeeb 
448bfcc09ddSBjoern A. Zeeb 	if (WARN_ON(!txq))
449bfcc09ddSBjoern A. Zeeb 		return;
450bfcc09ddSBjoern A. Zeeb 
451bfcc09ddSBjoern A. Zeeb 	iwl_pcie_txq_unmap(trans, txq_id);
452bfcc09ddSBjoern A. Zeeb 
453bfcc09ddSBjoern A. Zeeb 	/* De-alloc array of command/tx buffers */
454*a4128aadSBjoern A. Zeeb 	if (txq_id == trans_pcie->txqs.cmd.q_id)
455bfcc09ddSBjoern A. Zeeb 		for (i = 0; i < txq->n_window; i++) {
456bfcc09ddSBjoern A. Zeeb 			kfree_sensitive(txq->entries[i].cmd);
457bfcc09ddSBjoern A. Zeeb 			kfree_sensitive(txq->entries[i].free_buf);
458bfcc09ddSBjoern A. Zeeb 		}
459bfcc09ddSBjoern A. Zeeb 
460bfcc09ddSBjoern A. Zeeb 	/* De-alloc circular buffer of TFDs */
461bfcc09ddSBjoern A. Zeeb 	if (txq->tfds) {
462bfcc09ddSBjoern A. Zeeb 		dma_free_coherent(dev,
463*a4128aadSBjoern A. Zeeb 				  trans_pcie->txqs.tfd.size *
464bfcc09ddSBjoern A. Zeeb 				  trans->trans_cfg->base_params->max_tfd_queue_size,
465bfcc09ddSBjoern A. Zeeb 				  txq->tfds, txq->dma_addr);
466bfcc09ddSBjoern A. Zeeb 		txq->dma_addr = 0;
467bfcc09ddSBjoern A. Zeeb 		txq->tfds = NULL;
468bfcc09ddSBjoern A. Zeeb 
469bfcc09ddSBjoern A. Zeeb 		dma_free_coherent(dev,
470bfcc09ddSBjoern A. Zeeb 				  sizeof(*txq->first_tb_bufs) * txq->n_window,
471bfcc09ddSBjoern A. Zeeb 				  txq->first_tb_bufs, txq->first_tb_dma);
472bfcc09ddSBjoern A. Zeeb 	}
473bfcc09ddSBjoern A. Zeeb 
474bfcc09ddSBjoern A. Zeeb 	kfree(txq->entries);
475bfcc09ddSBjoern A. Zeeb 	txq->entries = NULL;
476bfcc09ddSBjoern A. Zeeb 
477bfcc09ddSBjoern A. Zeeb 	del_timer_sync(&txq->stuck_timer);
478bfcc09ddSBjoern A. Zeeb 
479bfcc09ddSBjoern A. Zeeb 	/* 0-fill queue descriptor structure */
480bfcc09ddSBjoern A. Zeeb 	memset(txq, 0, sizeof(*txq));
481bfcc09ddSBjoern A. Zeeb }
482bfcc09ddSBjoern A. Zeeb 
483bfcc09ddSBjoern A. Zeeb void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
484bfcc09ddSBjoern A. Zeeb {
485bfcc09ddSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
486bfcc09ddSBjoern A. Zeeb 	int nq = trans->trans_cfg->base_params->num_of_queues;
487bfcc09ddSBjoern A. Zeeb 	int chan;
488bfcc09ddSBjoern A. Zeeb 	u32 reg_val;
489bfcc09ddSBjoern A. Zeeb 	int clear_dwords = (SCD_TRANS_TBL_OFFSET_QUEUE(nq) -
490bfcc09ddSBjoern A. Zeeb 				SCD_CONTEXT_MEM_LOWER_BOUND) / sizeof(u32);
491bfcc09ddSBjoern A. Zeeb 
492bfcc09ddSBjoern A. Zeeb 	/* make sure all queue are not stopped/used */
493*a4128aadSBjoern A. Zeeb 	memset(trans_pcie->txqs.queue_stopped, 0,
494*a4128aadSBjoern A. Zeeb 	       sizeof(trans_pcie->txqs.queue_stopped));
495*a4128aadSBjoern A. Zeeb 	memset(trans_pcie->txqs.queue_used, 0,
496*a4128aadSBjoern A. Zeeb 	       sizeof(trans_pcie->txqs.queue_used));
497bfcc09ddSBjoern A. Zeeb 
498bfcc09ddSBjoern A. Zeeb 	trans_pcie->scd_base_addr =
499bfcc09ddSBjoern A. Zeeb 		iwl_read_prph(trans, SCD_SRAM_BASE_ADDR);
500bfcc09ddSBjoern A. Zeeb 
501bfcc09ddSBjoern A. Zeeb 	WARN_ON(scd_base_addr != 0 &&
502bfcc09ddSBjoern A. Zeeb 		scd_base_addr != trans_pcie->scd_base_addr);
503bfcc09ddSBjoern A. Zeeb 
504bfcc09ddSBjoern A. Zeeb 	/* reset context data, TX status and translation data */
505bfcc09ddSBjoern A. Zeeb 	iwl_trans_write_mem(trans, trans_pcie->scd_base_addr +
506bfcc09ddSBjoern A. Zeeb 				   SCD_CONTEXT_MEM_LOWER_BOUND,
507bfcc09ddSBjoern A. Zeeb 			    NULL, clear_dwords);
508bfcc09ddSBjoern A. Zeeb 
509bfcc09ddSBjoern A. Zeeb 	iwl_write_prph(trans, SCD_DRAM_BASE_ADDR,
510*a4128aadSBjoern A. Zeeb 		       trans_pcie->txqs.scd_bc_tbls.dma >> 10);
511bfcc09ddSBjoern A. Zeeb 
512bfcc09ddSBjoern A. Zeeb 	/* The chain extension of the SCD doesn't work well. This feature is
513bfcc09ddSBjoern A. Zeeb 	 * enabled by default by the HW, so we need to disable it manually.
514bfcc09ddSBjoern A. Zeeb 	 */
515bfcc09ddSBjoern A. Zeeb 	if (trans->trans_cfg->base_params->scd_chain_ext_wa)
516bfcc09ddSBjoern A. Zeeb 		iwl_write_prph(trans, SCD_CHAINEXT_EN, 0);
517bfcc09ddSBjoern A. Zeeb 
518*a4128aadSBjoern A. Zeeb 	iwl_trans_ac_txq_enable(trans, trans_pcie->txqs.cmd.q_id,
519*a4128aadSBjoern A. Zeeb 				trans_pcie->txqs.cmd.fifo,
520*a4128aadSBjoern A. Zeeb 				trans_pcie->txqs.cmd.wdg_timeout);
521bfcc09ddSBjoern A. Zeeb 
522bfcc09ddSBjoern A. Zeeb 	/* Activate all Tx DMA/FIFO channels */
523bfcc09ddSBjoern A. Zeeb 	iwl_scd_activate_fifos(trans);
524bfcc09ddSBjoern A. Zeeb 
525bfcc09ddSBjoern A. Zeeb 	/* Enable DMA channel */
526bfcc09ddSBjoern A. Zeeb 	for (chan = 0; chan < FH_TCSR_CHNL_NUM; chan++)
527bfcc09ddSBjoern A. Zeeb 		iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
528bfcc09ddSBjoern A. Zeeb 				   FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
529bfcc09ddSBjoern A. Zeeb 				   FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
530bfcc09ddSBjoern A. Zeeb 
531bfcc09ddSBjoern A. Zeeb 	/* Update FH chicken bits */
532bfcc09ddSBjoern A. Zeeb 	reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG);
533bfcc09ddSBjoern A. Zeeb 	iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG,
534bfcc09ddSBjoern A. Zeeb 			   reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
535bfcc09ddSBjoern A. Zeeb 
536bfcc09ddSBjoern A. Zeeb 	/* Enable L1-Active */
537bfcc09ddSBjoern A. Zeeb 	if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000)
538bfcc09ddSBjoern A. Zeeb 		iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG,
539bfcc09ddSBjoern A. Zeeb 				    APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
540bfcc09ddSBjoern A. Zeeb }
541bfcc09ddSBjoern A. Zeeb 
542bfcc09ddSBjoern A. Zeeb void iwl_trans_pcie_tx_reset(struct iwl_trans *trans)
543bfcc09ddSBjoern A. Zeeb {
544bfcc09ddSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
545bfcc09ddSBjoern A. Zeeb 	int txq_id;
546bfcc09ddSBjoern A. Zeeb 
547bfcc09ddSBjoern A. Zeeb 	/*
548bfcc09ddSBjoern A. Zeeb 	 * we should never get here in gen2 trans mode return early to avoid
549bfcc09ddSBjoern A. Zeeb 	 * having invalid accesses
550bfcc09ddSBjoern A. Zeeb 	 */
551bfcc09ddSBjoern A. Zeeb 	if (WARN_ON_ONCE(trans->trans_cfg->gen2))
552bfcc09ddSBjoern A. Zeeb 		return;
553bfcc09ddSBjoern A. Zeeb 
554bfcc09ddSBjoern A. Zeeb 	for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues;
555bfcc09ddSBjoern A. Zeeb 	     txq_id++) {
556*a4128aadSBjoern A. Zeeb 		struct iwl_txq *txq = trans_pcie->txqs.txq[txq_id];
5579af1bba4SBjoern A. Zeeb 		if (trans->trans_cfg->gen2)
558bfcc09ddSBjoern A. Zeeb 			iwl_write_direct64(trans,
559bfcc09ddSBjoern A. Zeeb 					   FH_MEM_CBBC_QUEUE(trans, txq_id),
560bfcc09ddSBjoern A. Zeeb 					   txq->dma_addr);
561bfcc09ddSBjoern A. Zeeb 		else
562bfcc09ddSBjoern A. Zeeb 			iwl_write_direct32(trans,
563bfcc09ddSBjoern A. Zeeb 					   FH_MEM_CBBC_QUEUE(trans, txq_id),
564bfcc09ddSBjoern A. Zeeb 					   txq->dma_addr >> 8);
565bfcc09ddSBjoern A. Zeeb 		iwl_pcie_txq_unmap(trans, txq_id);
566bfcc09ddSBjoern A. Zeeb 		txq->read_ptr = 0;
567bfcc09ddSBjoern A. Zeeb 		txq->write_ptr = 0;
568bfcc09ddSBjoern A. Zeeb 	}
569bfcc09ddSBjoern A. Zeeb 
570bfcc09ddSBjoern A. Zeeb 	/* Tell NIC where to find the "keep warm" buffer */
571bfcc09ddSBjoern A. Zeeb 	iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG,
572bfcc09ddSBjoern A. Zeeb 			   trans_pcie->kw.dma >> 4);
573bfcc09ddSBjoern A. Zeeb 
574bfcc09ddSBjoern A. Zeeb 	/*
575bfcc09ddSBjoern A. Zeeb 	 * Send 0 as the scd_base_addr since the device may have be reset
576bfcc09ddSBjoern A. Zeeb 	 * while we were in WoWLAN in which case SCD_SRAM_BASE_ADDR will
577bfcc09ddSBjoern A. Zeeb 	 * contain garbage.
578bfcc09ddSBjoern A. Zeeb 	 */
579bfcc09ddSBjoern A. Zeeb 	iwl_pcie_tx_start(trans, 0);
580bfcc09ddSBjoern A. Zeeb }
581bfcc09ddSBjoern A. Zeeb 
582bfcc09ddSBjoern A. Zeeb static void iwl_pcie_tx_stop_fh(struct iwl_trans *trans)
583bfcc09ddSBjoern A. Zeeb {
584bfcc09ddSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
585bfcc09ddSBjoern A. Zeeb 	int ch, ret;
586bfcc09ddSBjoern A. Zeeb 	u32 mask = 0;
587bfcc09ddSBjoern A. Zeeb 
588bfcc09ddSBjoern A. Zeeb 	spin_lock_bh(&trans_pcie->irq_lock);
589bfcc09ddSBjoern A. Zeeb 
590bfcc09ddSBjoern A. Zeeb 	if (!iwl_trans_grab_nic_access(trans))
591bfcc09ddSBjoern A. Zeeb 		goto out;
592bfcc09ddSBjoern A. Zeeb 
593bfcc09ddSBjoern A. Zeeb 	/* Stop each Tx DMA channel */
594bfcc09ddSBjoern A. Zeeb 	for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) {
595bfcc09ddSBjoern A. Zeeb 		iwl_write32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
596bfcc09ddSBjoern A. Zeeb 		mask |= FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch);
597bfcc09ddSBjoern A. Zeeb 	}
598bfcc09ddSBjoern A. Zeeb 
599bfcc09ddSBjoern A. Zeeb 	/* Wait for DMA channels to be idle */
600bfcc09ddSBjoern A. Zeeb 	ret = iwl_poll_bit(trans, FH_TSSR_TX_STATUS_REG, mask, mask, 5000);
601bfcc09ddSBjoern A. Zeeb 	if (ret < 0)
602bfcc09ddSBjoern A. Zeeb 		IWL_ERR(trans,
603bfcc09ddSBjoern A. Zeeb 			"Failing on timeout while stopping DMA channel %d [0x%08x]\n",
604bfcc09ddSBjoern A. Zeeb 			ch, iwl_read32(trans, FH_TSSR_TX_STATUS_REG));
605bfcc09ddSBjoern A. Zeeb 
606bfcc09ddSBjoern A. Zeeb 	iwl_trans_release_nic_access(trans);
607bfcc09ddSBjoern A. Zeeb 
608bfcc09ddSBjoern A. Zeeb out:
609bfcc09ddSBjoern A. Zeeb 	spin_unlock_bh(&trans_pcie->irq_lock);
610bfcc09ddSBjoern A. Zeeb }
611bfcc09ddSBjoern A. Zeeb 
612bfcc09ddSBjoern A. Zeeb /*
613bfcc09ddSBjoern A. Zeeb  * iwl_pcie_tx_stop - Stop all Tx DMA channels
614bfcc09ddSBjoern A. Zeeb  */
615bfcc09ddSBjoern A. Zeeb int iwl_pcie_tx_stop(struct iwl_trans *trans)
616bfcc09ddSBjoern A. Zeeb {
617bfcc09ddSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
618bfcc09ddSBjoern A. Zeeb 	int txq_id;
619bfcc09ddSBjoern A. Zeeb 
620bfcc09ddSBjoern A. Zeeb 	/* Turn off all Tx DMA fifos */
621bfcc09ddSBjoern A. Zeeb 	iwl_scd_deactivate_fifos(trans);
622bfcc09ddSBjoern A. Zeeb 
623bfcc09ddSBjoern A. Zeeb 	/* Turn off all Tx DMA channels */
624bfcc09ddSBjoern A. Zeeb 	iwl_pcie_tx_stop_fh(trans);
625bfcc09ddSBjoern A. Zeeb 
626bfcc09ddSBjoern A. Zeeb 	/*
627bfcc09ddSBjoern A. Zeeb 	 * This function can be called before the op_mode disabled the
628bfcc09ddSBjoern A. Zeeb 	 * queues. This happens when we have an rfkill interrupt.
629bfcc09ddSBjoern A. Zeeb 	 * Since we stop Tx altogether - mark the queues as stopped.
630bfcc09ddSBjoern A. Zeeb 	 */
631*a4128aadSBjoern A. Zeeb 	memset(trans_pcie->txqs.queue_stopped, 0,
632*a4128aadSBjoern A. Zeeb 	       sizeof(trans_pcie->txqs.queue_stopped));
633*a4128aadSBjoern A. Zeeb 	memset(trans_pcie->txqs.queue_used, 0,
634*a4128aadSBjoern A. Zeeb 	       sizeof(trans_pcie->txqs.queue_used));
635bfcc09ddSBjoern A. Zeeb 
636bfcc09ddSBjoern A. Zeeb 	/* This can happen: start_hw, stop_device */
637bfcc09ddSBjoern A. Zeeb 	if (!trans_pcie->txq_memory)
638bfcc09ddSBjoern A. Zeeb 		return 0;
639bfcc09ddSBjoern A. Zeeb 
640bfcc09ddSBjoern A. Zeeb 	/* Unmap DMA from host system and free skb's */
641bfcc09ddSBjoern A. Zeeb 	for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues;
642bfcc09ddSBjoern A. Zeeb 	     txq_id++)
643bfcc09ddSBjoern A. Zeeb 		iwl_pcie_txq_unmap(trans, txq_id);
644bfcc09ddSBjoern A. Zeeb 
645bfcc09ddSBjoern A. Zeeb 	return 0;
646bfcc09ddSBjoern A. Zeeb }
647bfcc09ddSBjoern A. Zeeb 
648bfcc09ddSBjoern A. Zeeb /*
649bfcc09ddSBjoern A. Zeeb  * iwl_trans_tx_free - Free TXQ Context
650bfcc09ddSBjoern A. Zeeb  *
651bfcc09ddSBjoern A. Zeeb  * Destroy all TX DMA queues and structures
652bfcc09ddSBjoern A. Zeeb  */
653bfcc09ddSBjoern A. Zeeb void iwl_pcie_tx_free(struct iwl_trans *trans)
654bfcc09ddSBjoern A. Zeeb {
655bfcc09ddSBjoern A. Zeeb 	int txq_id;
656bfcc09ddSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
657bfcc09ddSBjoern A. Zeeb 
658*a4128aadSBjoern A. Zeeb 	memset(trans_pcie->txqs.queue_used, 0,
659*a4128aadSBjoern A. Zeeb 	       sizeof(trans_pcie->txqs.queue_used));
660bfcc09ddSBjoern A. Zeeb 
661bfcc09ddSBjoern A. Zeeb 	/* Tx queues */
662bfcc09ddSBjoern A. Zeeb 	if (trans_pcie->txq_memory) {
663bfcc09ddSBjoern A. Zeeb 		for (txq_id = 0;
664bfcc09ddSBjoern A. Zeeb 		     txq_id < trans->trans_cfg->base_params->num_of_queues;
665bfcc09ddSBjoern A. Zeeb 		     txq_id++) {
666bfcc09ddSBjoern A. Zeeb 			iwl_pcie_txq_free(trans, txq_id);
667*a4128aadSBjoern A. Zeeb 			trans_pcie->txqs.txq[txq_id] = NULL;
668bfcc09ddSBjoern A. Zeeb 		}
669bfcc09ddSBjoern A. Zeeb 	}
670bfcc09ddSBjoern A. Zeeb 
671bfcc09ddSBjoern A. Zeeb 	kfree(trans_pcie->txq_memory);
672bfcc09ddSBjoern A. Zeeb 	trans_pcie->txq_memory = NULL;
673bfcc09ddSBjoern A. Zeeb 
674bfcc09ddSBjoern A. Zeeb 	iwl_pcie_free_dma_ptr(trans, &trans_pcie->kw);
675bfcc09ddSBjoern A. Zeeb 
676*a4128aadSBjoern A. Zeeb 	iwl_pcie_free_dma_ptr(trans, &trans_pcie->txqs.scd_bc_tbls);
677*a4128aadSBjoern A. Zeeb }
678*a4128aadSBjoern A. Zeeb 
679*a4128aadSBjoern A. Zeeb void iwl_txq_log_scd_error(struct iwl_trans *trans, struct iwl_txq *txq)
680*a4128aadSBjoern A. Zeeb {
681*a4128aadSBjoern A. Zeeb 	u32 txq_id = txq->id;
682*a4128aadSBjoern A. Zeeb 	u32 status;
683*a4128aadSBjoern A. Zeeb 	bool active;
684*a4128aadSBjoern A. Zeeb 	u8 fifo;
685*a4128aadSBjoern A. Zeeb 
686*a4128aadSBjoern A. Zeeb 	if (trans->trans_cfg->gen2) {
687*a4128aadSBjoern A. Zeeb 		IWL_ERR(trans, "Queue %d is stuck %d %d\n", txq_id,
688*a4128aadSBjoern A. Zeeb 			txq->read_ptr, txq->write_ptr);
689*a4128aadSBjoern A. Zeeb 		/* TODO: access new SCD registers and dump them */
690*a4128aadSBjoern A. Zeeb 		return;
691*a4128aadSBjoern A. Zeeb 	}
692*a4128aadSBjoern A. Zeeb 
693*a4128aadSBjoern A. Zeeb 	status = iwl_read_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id));
694*a4128aadSBjoern A. Zeeb 	fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7;
695*a4128aadSBjoern A. Zeeb 	active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE));
696*a4128aadSBjoern A. Zeeb 
697*a4128aadSBjoern A. Zeeb 	IWL_ERR(trans,
698*a4128aadSBjoern A. Zeeb 		"Queue %d is %sactive on fifo %d and stuck for %u ms. SW [%d, %d] HW [%d, %d] FH TRB=0x0%x\n",
699*a4128aadSBjoern A. Zeeb 		txq_id, active ? "" : "in", fifo,
700*a4128aadSBjoern A. Zeeb 		jiffies_to_msecs(txq->wd_timeout),
701*a4128aadSBjoern A. Zeeb 		txq->read_ptr, txq->write_ptr,
702*a4128aadSBjoern A. Zeeb 		iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) &
703*a4128aadSBjoern A. Zeeb 			(trans->trans_cfg->base_params->max_tfd_queue_size - 1),
704*a4128aadSBjoern A. Zeeb 			iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)) &
705*a4128aadSBjoern A. Zeeb 			(trans->trans_cfg->base_params->max_tfd_queue_size - 1),
706*a4128aadSBjoern A. Zeeb 			iwl_read_direct32(trans, FH_TX_TRB_REG(fifo)));
707*a4128aadSBjoern A. Zeeb }
708*a4128aadSBjoern A. Zeeb 
709*a4128aadSBjoern A. Zeeb static void iwl_txq_stuck_timer(struct timer_list *t)
710*a4128aadSBjoern A. Zeeb {
711*a4128aadSBjoern A. Zeeb 	struct iwl_txq *txq = from_timer(txq, t, stuck_timer);
712*a4128aadSBjoern A. Zeeb 	struct iwl_trans *trans = txq->trans;
713*a4128aadSBjoern A. Zeeb 
714*a4128aadSBjoern A. Zeeb 	spin_lock(&txq->lock);
715*a4128aadSBjoern A. Zeeb 	/* check if triggered erroneously */
716*a4128aadSBjoern A. Zeeb 	if (txq->read_ptr == txq->write_ptr) {
717*a4128aadSBjoern A. Zeeb 		spin_unlock(&txq->lock);
718*a4128aadSBjoern A. Zeeb 		return;
719*a4128aadSBjoern A. Zeeb 	}
720*a4128aadSBjoern A. Zeeb 	spin_unlock(&txq->lock);
721*a4128aadSBjoern A. Zeeb 
722*a4128aadSBjoern A. Zeeb 	iwl_txq_log_scd_error(trans, txq);
723*a4128aadSBjoern A. Zeeb 
724*a4128aadSBjoern A. Zeeb 	iwl_force_nmi(trans);
725*a4128aadSBjoern A. Zeeb }
726*a4128aadSBjoern A. Zeeb 
727*a4128aadSBjoern A. Zeeb int iwl_pcie_txq_alloc(struct iwl_trans *trans, struct iwl_txq *txq,
728*a4128aadSBjoern A. Zeeb 		       int slots_num, bool cmd_queue)
729*a4128aadSBjoern A. Zeeb {
730*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
731*a4128aadSBjoern A. Zeeb 	size_t num_entries = trans->trans_cfg->gen2 ?
732*a4128aadSBjoern A. Zeeb 		slots_num : trans->trans_cfg->base_params->max_tfd_queue_size;
733*a4128aadSBjoern A. Zeeb 	size_t tfd_sz;
734*a4128aadSBjoern A. Zeeb 	size_t tb0_buf_sz;
735*a4128aadSBjoern A. Zeeb 	int i;
736*a4128aadSBjoern A. Zeeb 
737*a4128aadSBjoern A. Zeeb 	if (WARN_ONCE(slots_num <= 0, "Invalid slots num:%d\n", slots_num))
738*a4128aadSBjoern A. Zeeb 		return -EINVAL;
739*a4128aadSBjoern A. Zeeb 
740*a4128aadSBjoern A. Zeeb 	if (WARN_ON(txq->entries || txq->tfds))
741*a4128aadSBjoern A. Zeeb 		return -EINVAL;
742*a4128aadSBjoern A. Zeeb 
743*a4128aadSBjoern A. Zeeb 	tfd_sz = trans_pcie->txqs.tfd.size * num_entries;
744*a4128aadSBjoern A. Zeeb 
745*a4128aadSBjoern A. Zeeb 	timer_setup(&txq->stuck_timer, iwl_txq_stuck_timer, 0);
746*a4128aadSBjoern A. Zeeb 	txq->trans = trans;
747*a4128aadSBjoern A. Zeeb 
748*a4128aadSBjoern A. Zeeb 	txq->n_window = slots_num;
749*a4128aadSBjoern A. Zeeb 
750*a4128aadSBjoern A. Zeeb 	txq->entries = kcalloc(slots_num,
751*a4128aadSBjoern A. Zeeb 			       sizeof(struct iwl_pcie_txq_entry),
752*a4128aadSBjoern A. Zeeb 			       GFP_KERNEL);
753*a4128aadSBjoern A. Zeeb 
754*a4128aadSBjoern A. Zeeb 	if (!txq->entries)
755*a4128aadSBjoern A. Zeeb 		goto error;
756*a4128aadSBjoern A. Zeeb 
757*a4128aadSBjoern A. Zeeb 	if (cmd_queue)
758*a4128aadSBjoern A. Zeeb 		for (i = 0; i < slots_num; i++) {
759*a4128aadSBjoern A. Zeeb 			txq->entries[i].cmd =
760*a4128aadSBjoern A. Zeeb 				kmalloc(sizeof(struct iwl_device_cmd),
761*a4128aadSBjoern A. Zeeb 					GFP_KERNEL);
762*a4128aadSBjoern A. Zeeb 			if (!txq->entries[i].cmd)
763*a4128aadSBjoern A. Zeeb 				goto error;
764*a4128aadSBjoern A. Zeeb 		}
765*a4128aadSBjoern A. Zeeb 
766*a4128aadSBjoern A. Zeeb 	/* Circular buffer of transmit frame descriptors (TFDs),
767*a4128aadSBjoern A. Zeeb 	 * shared with device
768*a4128aadSBjoern A. Zeeb 	 */
769*a4128aadSBjoern A. Zeeb 	txq->tfds = dma_alloc_coherent(trans->dev, tfd_sz,
770*a4128aadSBjoern A. Zeeb 				       &txq->dma_addr, GFP_KERNEL);
771*a4128aadSBjoern A. Zeeb 	if (!txq->tfds)
772*a4128aadSBjoern A. Zeeb 		goto error;
773*a4128aadSBjoern A. Zeeb 
774*a4128aadSBjoern A. Zeeb 	BUILD_BUG_ON(sizeof(*txq->first_tb_bufs) != IWL_FIRST_TB_SIZE_ALIGN);
775*a4128aadSBjoern A. Zeeb 
776*a4128aadSBjoern A. Zeeb 	tb0_buf_sz = sizeof(*txq->first_tb_bufs) * slots_num;
777*a4128aadSBjoern A. Zeeb 
778*a4128aadSBjoern A. Zeeb 	txq->first_tb_bufs = dma_alloc_coherent(trans->dev, tb0_buf_sz,
779*a4128aadSBjoern A. Zeeb 						&txq->first_tb_dma,
780*a4128aadSBjoern A. Zeeb 						GFP_KERNEL);
781*a4128aadSBjoern A. Zeeb 	if (!txq->first_tb_bufs)
782*a4128aadSBjoern A. Zeeb 		goto err_free_tfds;
783*a4128aadSBjoern A. Zeeb 
784*a4128aadSBjoern A. Zeeb 	for (i = 0; i < num_entries; i++) {
785*a4128aadSBjoern A. Zeeb 		void *tfd = iwl_txq_get_tfd(trans, txq, i);
786*a4128aadSBjoern A. Zeeb 
787*a4128aadSBjoern A. Zeeb 		if (trans->trans_cfg->gen2)
788*a4128aadSBjoern A. Zeeb 			iwl_txq_set_tfd_invalid_gen2(trans, tfd);
789*a4128aadSBjoern A. Zeeb 		else
790*a4128aadSBjoern A. Zeeb 			iwl_txq_set_tfd_invalid_gen1(trans, tfd);
791*a4128aadSBjoern A. Zeeb 	}
792*a4128aadSBjoern A. Zeeb 
793*a4128aadSBjoern A. Zeeb 	return 0;
794*a4128aadSBjoern A. Zeeb err_free_tfds:
795*a4128aadSBjoern A. Zeeb 	dma_free_coherent(trans->dev, tfd_sz, txq->tfds, txq->dma_addr);
796*a4128aadSBjoern A. Zeeb 	txq->tfds = NULL;
797*a4128aadSBjoern A. Zeeb error:
798*a4128aadSBjoern A. Zeeb 	if (txq->entries && cmd_queue)
799*a4128aadSBjoern A. Zeeb 		for (i = 0; i < slots_num; i++)
800*a4128aadSBjoern A. Zeeb 			kfree(txq->entries[i].cmd);
801*a4128aadSBjoern A. Zeeb 	kfree(txq->entries);
802*a4128aadSBjoern A. Zeeb 	txq->entries = NULL;
803*a4128aadSBjoern A. Zeeb 
804*a4128aadSBjoern A. Zeeb 	return -ENOMEM;
805bfcc09ddSBjoern A. Zeeb }
806bfcc09ddSBjoern A. Zeeb 
807bfcc09ddSBjoern A. Zeeb /*
808bfcc09ddSBjoern A. Zeeb  * iwl_pcie_tx_alloc - allocate TX context
809bfcc09ddSBjoern A. Zeeb  * Allocate all Tx DMA structures and initialize them
810bfcc09ddSBjoern A. Zeeb  */
811bfcc09ddSBjoern A. Zeeb static int iwl_pcie_tx_alloc(struct iwl_trans *trans)
812bfcc09ddSBjoern A. Zeeb {
813bfcc09ddSBjoern A. Zeeb 	int ret;
814bfcc09ddSBjoern A. Zeeb 	int txq_id, slots_num;
815bfcc09ddSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
816bfcc09ddSBjoern A. Zeeb 	u16 bc_tbls_size = trans->trans_cfg->base_params->num_of_queues;
817bfcc09ddSBjoern A. Zeeb 
818bfcc09ddSBjoern A. Zeeb 	if (WARN_ON(trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210))
819bfcc09ddSBjoern A. Zeeb 		return -EINVAL;
820bfcc09ddSBjoern A. Zeeb 
821bfcc09ddSBjoern A. Zeeb 	bc_tbls_size *= sizeof(struct iwlagn_scd_bc_tbl);
822bfcc09ddSBjoern A. Zeeb 
823bfcc09ddSBjoern A. Zeeb 	/*It is not allowed to alloc twice, so warn when this happens.
824bfcc09ddSBjoern A. Zeeb 	 * We cannot rely on the previous allocation, so free and fail */
825bfcc09ddSBjoern A. Zeeb 	if (WARN_ON(trans_pcie->txq_memory)) {
826bfcc09ddSBjoern A. Zeeb 		ret = -EINVAL;
827bfcc09ddSBjoern A. Zeeb 		goto error;
828bfcc09ddSBjoern A. Zeeb 	}
829bfcc09ddSBjoern A. Zeeb 
830*a4128aadSBjoern A. Zeeb 	ret = iwl_pcie_alloc_dma_ptr(trans, &trans_pcie->txqs.scd_bc_tbls,
831bfcc09ddSBjoern A. Zeeb 				     bc_tbls_size);
832bfcc09ddSBjoern A. Zeeb 	if (ret) {
833bfcc09ddSBjoern A. Zeeb 		IWL_ERR(trans, "Scheduler BC Table allocation failed\n");
834bfcc09ddSBjoern A. Zeeb 		goto error;
835bfcc09ddSBjoern A. Zeeb 	}
836bfcc09ddSBjoern A. Zeeb 
837bfcc09ddSBjoern A. Zeeb 	/* Alloc keep-warm buffer */
838bfcc09ddSBjoern A. Zeeb 	ret = iwl_pcie_alloc_dma_ptr(trans, &trans_pcie->kw, IWL_KW_SIZE);
839bfcc09ddSBjoern A. Zeeb 	if (ret) {
840bfcc09ddSBjoern A. Zeeb 		IWL_ERR(trans, "Keep Warm allocation failed\n");
841bfcc09ddSBjoern A. Zeeb 		goto error;
842bfcc09ddSBjoern A. Zeeb 	}
843bfcc09ddSBjoern A. Zeeb 
844bfcc09ddSBjoern A. Zeeb 	trans_pcie->txq_memory =
845bfcc09ddSBjoern A. Zeeb 		kcalloc(trans->trans_cfg->base_params->num_of_queues,
846bfcc09ddSBjoern A. Zeeb 			sizeof(struct iwl_txq), GFP_KERNEL);
847bfcc09ddSBjoern A. Zeeb 	if (!trans_pcie->txq_memory) {
848bfcc09ddSBjoern A. Zeeb 		IWL_ERR(trans, "Not enough memory for txq\n");
849bfcc09ddSBjoern A. Zeeb 		ret = -ENOMEM;
850bfcc09ddSBjoern A. Zeeb 		goto error;
851bfcc09ddSBjoern A. Zeeb 	}
852bfcc09ddSBjoern A. Zeeb 
853bfcc09ddSBjoern A. Zeeb 	/* Alloc and init all Tx queues, including the command queue (#4/#9) */
854bfcc09ddSBjoern A. Zeeb 	for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues;
855bfcc09ddSBjoern A. Zeeb 	     txq_id++) {
856*a4128aadSBjoern A. Zeeb 		bool cmd_queue = (txq_id == trans_pcie->txqs.cmd.q_id);
857bfcc09ddSBjoern A. Zeeb 
858bfcc09ddSBjoern A. Zeeb 		if (cmd_queue)
859bfcc09ddSBjoern A. Zeeb 			slots_num = max_t(u32, IWL_CMD_QUEUE_SIZE,
860bfcc09ddSBjoern A. Zeeb 					  trans->cfg->min_txq_size);
861bfcc09ddSBjoern A. Zeeb 		else
862bfcc09ddSBjoern A. Zeeb 			slots_num = max_t(u32, IWL_DEFAULT_QUEUE_SIZE,
863d9836fb4SBjoern A. Zeeb 					  trans->cfg->min_ba_txq_size);
864*a4128aadSBjoern A. Zeeb 		trans_pcie->txqs.txq[txq_id] = &trans_pcie->txq_memory[txq_id];
865*a4128aadSBjoern A. Zeeb 		ret = iwl_pcie_txq_alloc(trans, trans_pcie->txqs.txq[txq_id],
866*a4128aadSBjoern A. Zeeb 					 slots_num, cmd_queue);
867bfcc09ddSBjoern A. Zeeb 		if (ret) {
868bfcc09ddSBjoern A. Zeeb 			IWL_ERR(trans, "Tx %d queue alloc failed\n", txq_id);
869bfcc09ddSBjoern A. Zeeb 			goto error;
870bfcc09ddSBjoern A. Zeeb 		}
871*a4128aadSBjoern A. Zeeb 		trans_pcie->txqs.txq[txq_id]->id = txq_id;
872bfcc09ddSBjoern A. Zeeb 	}
873bfcc09ddSBjoern A. Zeeb 
874bfcc09ddSBjoern A. Zeeb 	return 0;
875bfcc09ddSBjoern A. Zeeb 
876bfcc09ddSBjoern A. Zeeb error:
877bfcc09ddSBjoern A. Zeeb 	iwl_pcie_tx_free(trans);
878bfcc09ddSBjoern A. Zeeb 
879bfcc09ddSBjoern A. Zeeb 	return ret;
880bfcc09ddSBjoern A. Zeeb }
881bfcc09ddSBjoern A. Zeeb 
882*a4128aadSBjoern A. Zeeb /*
883*a4128aadSBjoern A. Zeeb  * iwl_queue_init - Initialize queue's high/low-water and read/write indexes
884*a4128aadSBjoern A. Zeeb  */
885*a4128aadSBjoern A. Zeeb static int iwl_queue_init(struct iwl_txq *q, int slots_num)
886*a4128aadSBjoern A. Zeeb {
887*a4128aadSBjoern A. Zeeb 	q->n_window = slots_num;
888*a4128aadSBjoern A. Zeeb 
889*a4128aadSBjoern A. Zeeb 	/* slots_num must be power-of-two size, otherwise
890*a4128aadSBjoern A. Zeeb 	 * iwl_txq_get_cmd_index is broken.
891*a4128aadSBjoern A. Zeeb 	 */
892*a4128aadSBjoern A. Zeeb 	if (WARN_ON(!is_power_of_2(slots_num)))
893*a4128aadSBjoern A. Zeeb 		return -EINVAL;
894*a4128aadSBjoern A. Zeeb 
895*a4128aadSBjoern A. Zeeb 	q->low_mark = q->n_window / 4;
896*a4128aadSBjoern A. Zeeb 	if (q->low_mark < 4)
897*a4128aadSBjoern A. Zeeb 		q->low_mark = 4;
898*a4128aadSBjoern A. Zeeb 
899*a4128aadSBjoern A. Zeeb 	q->high_mark = q->n_window / 8;
900*a4128aadSBjoern A. Zeeb 	if (q->high_mark < 2)
901*a4128aadSBjoern A. Zeeb 		q->high_mark = 2;
902*a4128aadSBjoern A. Zeeb 
903*a4128aadSBjoern A. Zeeb 	q->write_ptr = 0;
904*a4128aadSBjoern A. Zeeb 	q->read_ptr = 0;
905*a4128aadSBjoern A. Zeeb 
906*a4128aadSBjoern A. Zeeb 	return 0;
907*a4128aadSBjoern A. Zeeb }
908*a4128aadSBjoern A. Zeeb 
909*a4128aadSBjoern A. Zeeb int iwl_txq_init(struct iwl_trans *trans, struct iwl_txq *txq,
910*a4128aadSBjoern A. Zeeb 		 int slots_num, bool cmd_queue)
911*a4128aadSBjoern A. Zeeb {
912*a4128aadSBjoern A. Zeeb 	u32 tfd_queue_max_size =
913*a4128aadSBjoern A. Zeeb 		trans->trans_cfg->base_params->max_tfd_queue_size;
914*a4128aadSBjoern A. Zeeb 	int ret;
915*a4128aadSBjoern A. Zeeb 
916*a4128aadSBjoern A. Zeeb 	txq->need_update = false;
917*a4128aadSBjoern A. Zeeb 
918*a4128aadSBjoern A. Zeeb 	/* max_tfd_queue_size must be power-of-two size, otherwise
919*a4128aadSBjoern A. Zeeb 	 * iwl_txq_inc_wrap and iwl_txq_dec_wrap are broken.
920*a4128aadSBjoern A. Zeeb 	 */
921*a4128aadSBjoern A. Zeeb 	if (WARN_ONCE(tfd_queue_max_size & (tfd_queue_max_size - 1),
922*a4128aadSBjoern A. Zeeb 		      "Max tfd queue size must be a power of two, but is %d",
923*a4128aadSBjoern A. Zeeb 		      tfd_queue_max_size))
924*a4128aadSBjoern A. Zeeb 		return -EINVAL;
925*a4128aadSBjoern A. Zeeb 
926*a4128aadSBjoern A. Zeeb 	/* Initialize queue's high/low-water marks, and head/tail indexes */
927*a4128aadSBjoern A. Zeeb 	ret = iwl_queue_init(txq, slots_num);
928*a4128aadSBjoern A. Zeeb 	if (ret)
929*a4128aadSBjoern A. Zeeb 		return ret;
930*a4128aadSBjoern A. Zeeb 
931*a4128aadSBjoern A. Zeeb 	spin_lock_init(&txq->lock);
932*a4128aadSBjoern A. Zeeb 	spin_lock_init(&txq->reclaim_lock);
933*a4128aadSBjoern A. Zeeb 
934*a4128aadSBjoern A. Zeeb 	if (cmd_queue) {
935*a4128aadSBjoern A. Zeeb #if defined(__linux__)
936*a4128aadSBjoern A. Zeeb 		static struct lock_class_key iwl_txq_cmd_queue_lock_class;
937*a4128aadSBjoern A. Zeeb 
938*a4128aadSBjoern A. Zeeb 		lockdep_set_class(&txq->lock, &iwl_txq_cmd_queue_lock_class);
939*a4128aadSBjoern A. Zeeb #endif
940*a4128aadSBjoern A. Zeeb 	}
941*a4128aadSBjoern A. Zeeb 
942*a4128aadSBjoern A. Zeeb 	__skb_queue_head_init(&txq->overflow_q);
943*a4128aadSBjoern A. Zeeb 
944*a4128aadSBjoern A. Zeeb 	return 0;
945*a4128aadSBjoern A. Zeeb }
946*a4128aadSBjoern A. Zeeb 
947bfcc09ddSBjoern A. Zeeb int iwl_pcie_tx_init(struct iwl_trans *trans)
948bfcc09ddSBjoern A. Zeeb {
949bfcc09ddSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
950bfcc09ddSBjoern A. Zeeb 	int ret;
951bfcc09ddSBjoern A. Zeeb 	int txq_id, slots_num;
952bfcc09ddSBjoern A. Zeeb 	bool alloc = false;
953bfcc09ddSBjoern A. Zeeb 
954bfcc09ddSBjoern A. Zeeb 	if (!trans_pcie->txq_memory) {
955bfcc09ddSBjoern A. Zeeb 		ret = iwl_pcie_tx_alloc(trans);
956bfcc09ddSBjoern A. Zeeb 		if (ret)
957bfcc09ddSBjoern A. Zeeb 			goto error;
958bfcc09ddSBjoern A. Zeeb 		alloc = true;
959bfcc09ddSBjoern A. Zeeb 	}
960bfcc09ddSBjoern A. Zeeb 
961bfcc09ddSBjoern A. Zeeb 	spin_lock_bh(&trans_pcie->irq_lock);
962bfcc09ddSBjoern A. Zeeb 
963bfcc09ddSBjoern A. Zeeb 	/* Turn off all Tx DMA fifos */
964bfcc09ddSBjoern A. Zeeb 	iwl_scd_deactivate_fifos(trans);
965bfcc09ddSBjoern A. Zeeb 
966bfcc09ddSBjoern A. Zeeb 	/* Tell NIC where to find the "keep warm" buffer */
967bfcc09ddSBjoern A. Zeeb 	iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG,
968bfcc09ddSBjoern A. Zeeb 			   trans_pcie->kw.dma >> 4);
969bfcc09ddSBjoern A. Zeeb 
970bfcc09ddSBjoern A. Zeeb 	spin_unlock_bh(&trans_pcie->irq_lock);
971bfcc09ddSBjoern A. Zeeb 
972bfcc09ddSBjoern A. Zeeb 	/* Alloc and init all Tx queues, including the command queue (#4/#9) */
973bfcc09ddSBjoern A. Zeeb 	for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues;
974bfcc09ddSBjoern A. Zeeb 	     txq_id++) {
975*a4128aadSBjoern A. Zeeb 		bool cmd_queue = (txq_id == trans_pcie->txqs.cmd.q_id);
976bfcc09ddSBjoern A. Zeeb 
977bfcc09ddSBjoern A. Zeeb 		if (cmd_queue)
978bfcc09ddSBjoern A. Zeeb 			slots_num = max_t(u32, IWL_CMD_QUEUE_SIZE,
979bfcc09ddSBjoern A. Zeeb 					  trans->cfg->min_txq_size);
980bfcc09ddSBjoern A. Zeeb 		else
981bfcc09ddSBjoern A. Zeeb 			slots_num = max_t(u32, IWL_DEFAULT_QUEUE_SIZE,
982d9836fb4SBjoern A. Zeeb 					  trans->cfg->min_ba_txq_size);
983*a4128aadSBjoern A. Zeeb 		ret = iwl_txq_init(trans, trans_pcie->txqs.txq[txq_id], slots_num,
984bfcc09ddSBjoern A. Zeeb 				   cmd_queue);
985bfcc09ddSBjoern A. Zeeb 		if (ret) {
986bfcc09ddSBjoern A. Zeeb 			IWL_ERR(trans, "Tx %d queue init failed\n", txq_id);
987bfcc09ddSBjoern A. Zeeb 			goto error;
988bfcc09ddSBjoern A. Zeeb 		}
989bfcc09ddSBjoern A. Zeeb 
990bfcc09ddSBjoern A. Zeeb 		/*
991bfcc09ddSBjoern A. Zeeb 		 * Tell nic where to find circular buffer of TFDs for a
992bfcc09ddSBjoern A. Zeeb 		 * given Tx queue, and enable the DMA channel used for that
993bfcc09ddSBjoern A. Zeeb 		 * queue.
994bfcc09ddSBjoern A. Zeeb 		 * Circular buffer (TFD queue in DRAM) physical base address
995bfcc09ddSBjoern A. Zeeb 		 */
996bfcc09ddSBjoern A. Zeeb 		iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(trans, txq_id),
997*a4128aadSBjoern A. Zeeb 				   trans_pcie->txqs.txq[txq_id]->dma_addr >> 8);
998bfcc09ddSBjoern A. Zeeb 	}
999bfcc09ddSBjoern A. Zeeb 
1000bfcc09ddSBjoern A. Zeeb 	iwl_set_bits_prph(trans, SCD_GP_CTRL, SCD_GP_CTRL_AUTO_ACTIVE_MODE);
1001bfcc09ddSBjoern A. Zeeb 	if (trans->trans_cfg->base_params->num_of_queues > 20)
1002bfcc09ddSBjoern A. Zeeb 		iwl_set_bits_prph(trans, SCD_GP_CTRL,
1003bfcc09ddSBjoern A. Zeeb 				  SCD_GP_CTRL_ENABLE_31_QUEUES);
1004bfcc09ddSBjoern A. Zeeb 
1005bfcc09ddSBjoern A. Zeeb 	return 0;
1006bfcc09ddSBjoern A. Zeeb error:
1007bfcc09ddSBjoern A. Zeeb 	/*Upon error, free only if we allocated something */
1008bfcc09ddSBjoern A. Zeeb 	if (alloc)
1009bfcc09ddSBjoern A. Zeeb 		iwl_pcie_tx_free(trans);
1010bfcc09ddSBjoern A. Zeeb 	return ret;
1011bfcc09ddSBjoern A. Zeeb }
1012bfcc09ddSBjoern A. Zeeb 
1013bfcc09ddSBjoern A. Zeeb static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
1014bfcc09ddSBjoern A. Zeeb 				      const struct iwl_host_cmd *cmd)
1015bfcc09ddSBjoern A. Zeeb {
1016bfcc09ddSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1017bfcc09ddSBjoern A. Zeeb 
1018bfcc09ddSBjoern A. Zeeb 	/* Make sure the NIC is still alive in the bus */
1019bfcc09ddSBjoern A. Zeeb 	if (test_bit(STATUS_TRANS_DEAD, &trans->status))
1020bfcc09ddSBjoern A. Zeeb 		return -ENODEV;
1021bfcc09ddSBjoern A. Zeeb 
1022bfcc09ddSBjoern A. Zeeb 	if (!trans->trans_cfg->base_params->apmg_wake_up_wa)
1023bfcc09ddSBjoern A. Zeeb 		return 0;
1024bfcc09ddSBjoern A. Zeeb 
1025bfcc09ddSBjoern A. Zeeb 	/*
1026bfcc09ddSBjoern A. Zeeb 	 * wake up the NIC to make sure that the firmware will see the host
1027bfcc09ddSBjoern A. Zeeb 	 * command - we will let the NIC sleep once all the host commands
1028bfcc09ddSBjoern A. Zeeb 	 * returned. This needs to be done only on NICs that have
1029bfcc09ddSBjoern A. Zeeb 	 * apmg_wake_up_wa set (see above.)
1030bfcc09ddSBjoern A. Zeeb 	 */
1031bfcc09ddSBjoern A. Zeeb 	if (!_iwl_trans_pcie_grab_nic_access(trans))
1032bfcc09ddSBjoern A. Zeeb 		return -EIO;
1033bfcc09ddSBjoern A. Zeeb 
1034bfcc09ddSBjoern A. Zeeb 	/*
1035bfcc09ddSBjoern A. Zeeb 	 * In iwl_trans_grab_nic_access(), we've acquired the reg_lock.
1036bfcc09ddSBjoern A. Zeeb 	 * There, we also returned immediately if cmd_hold_nic_awake is
1037bfcc09ddSBjoern A. Zeeb 	 * already true, so it's OK to unconditionally set it to true.
1038bfcc09ddSBjoern A. Zeeb 	 */
1039bfcc09ddSBjoern A. Zeeb 	trans_pcie->cmd_hold_nic_awake = true;
1040bfcc09ddSBjoern A. Zeeb 	spin_unlock(&trans_pcie->reg_lock);
1041bfcc09ddSBjoern A. Zeeb 
1042bfcc09ddSBjoern A. Zeeb 	return 0;
1043bfcc09ddSBjoern A. Zeeb }
1044bfcc09ddSBjoern A. Zeeb 
1045*a4128aadSBjoern A. Zeeb static void iwl_txq_progress(struct iwl_txq *txq)
1046*a4128aadSBjoern A. Zeeb {
1047*a4128aadSBjoern A. Zeeb 	lockdep_assert_held(&txq->lock);
1048*a4128aadSBjoern A. Zeeb 
1049*a4128aadSBjoern A. Zeeb 	if (!txq->wd_timeout)
1050*a4128aadSBjoern A. Zeeb 		return;
1051*a4128aadSBjoern A. Zeeb 
1052*a4128aadSBjoern A. Zeeb 	/*
1053*a4128aadSBjoern A. Zeeb 	 * station is asleep and we send data - that must
1054*a4128aadSBjoern A. Zeeb 	 * be uAPSD or PS-Poll. Don't rearm the timer.
1055*a4128aadSBjoern A. Zeeb 	 */
1056*a4128aadSBjoern A. Zeeb 	if (txq->frozen)
1057*a4128aadSBjoern A. Zeeb 		return;
1058*a4128aadSBjoern A. Zeeb 
1059*a4128aadSBjoern A. Zeeb 	/*
1060*a4128aadSBjoern A. Zeeb 	 * if empty delete timer, otherwise move timer forward
1061*a4128aadSBjoern A. Zeeb 	 * since we're making progress on this queue
1062*a4128aadSBjoern A. Zeeb 	 */
1063*a4128aadSBjoern A. Zeeb 	if (txq->read_ptr == txq->write_ptr)
1064*a4128aadSBjoern A. Zeeb 		del_timer(&txq->stuck_timer);
1065*a4128aadSBjoern A. Zeeb 	else
1066*a4128aadSBjoern A. Zeeb 		mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
1067*a4128aadSBjoern A. Zeeb }
1068*a4128aadSBjoern A. Zeeb 
1069*a4128aadSBjoern A. Zeeb static inline bool iwl_txq_used(const struct iwl_txq *q, int i,
1070*a4128aadSBjoern A. Zeeb 				int read_ptr, int write_ptr)
1071*a4128aadSBjoern A. Zeeb {
1072*a4128aadSBjoern A. Zeeb 	int index = iwl_txq_get_cmd_index(q, i);
1073*a4128aadSBjoern A. Zeeb 	int r = iwl_txq_get_cmd_index(q, read_ptr);
1074*a4128aadSBjoern A. Zeeb 	int w = iwl_txq_get_cmd_index(q, write_ptr);
1075*a4128aadSBjoern A. Zeeb 
1076*a4128aadSBjoern A. Zeeb 	return w >= r ?
1077*a4128aadSBjoern A. Zeeb 		(index >= r && index < w) :
1078*a4128aadSBjoern A. Zeeb 		!(index < r && index >= w);
1079*a4128aadSBjoern A. Zeeb }
1080*a4128aadSBjoern A. Zeeb 
1081bfcc09ddSBjoern A. Zeeb /*
1082bfcc09ddSBjoern A. Zeeb  * iwl_pcie_cmdq_reclaim - Reclaim TX command queue entries already Tx'd
1083bfcc09ddSBjoern A. Zeeb  *
1084bfcc09ddSBjoern A. Zeeb  * When FW advances 'R' index, all entries between old and new 'R' index
1085bfcc09ddSBjoern A. Zeeb  * need to be reclaimed. As result, some free space forms.  If there is
1086bfcc09ddSBjoern A. Zeeb  * enough free space (> low mark), wake the stack that feeds us.
1087bfcc09ddSBjoern A. Zeeb  */
1088bfcc09ddSBjoern A. Zeeb static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
1089bfcc09ddSBjoern A. Zeeb {
1090*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1091*a4128aadSBjoern A. Zeeb 	struct iwl_txq *txq = trans_pcie->txqs.txq[txq_id];
1092bfcc09ddSBjoern A. Zeeb 	int nfreed = 0;
1093bfcc09ddSBjoern A. Zeeb 	u16 r;
1094bfcc09ddSBjoern A. Zeeb 
1095bfcc09ddSBjoern A. Zeeb 	lockdep_assert_held(&txq->lock);
1096bfcc09ddSBjoern A. Zeeb 
1097bfcc09ddSBjoern A. Zeeb 	idx = iwl_txq_get_cmd_index(txq, idx);
1098bfcc09ddSBjoern A. Zeeb 	r = iwl_txq_get_cmd_index(txq, txq->read_ptr);
1099bfcc09ddSBjoern A. Zeeb 
1100bfcc09ddSBjoern A. Zeeb 	if (idx >= trans->trans_cfg->base_params->max_tfd_queue_size ||
1101*a4128aadSBjoern A. Zeeb 	    (!iwl_txq_used(txq, idx, txq->read_ptr, txq->write_ptr))) {
1102*a4128aadSBjoern A. Zeeb 		WARN_ONCE(test_bit(txq_id, trans_pcie->txqs.queue_used),
1103bfcc09ddSBjoern A. Zeeb 			  "%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n",
1104bfcc09ddSBjoern A. Zeeb 			  __func__, txq_id, idx,
1105bfcc09ddSBjoern A. Zeeb 			  trans->trans_cfg->base_params->max_tfd_queue_size,
1106bfcc09ddSBjoern A. Zeeb 			  txq->write_ptr, txq->read_ptr);
1107bfcc09ddSBjoern A. Zeeb 		return;
1108bfcc09ddSBjoern A. Zeeb 	}
1109bfcc09ddSBjoern A. Zeeb 
1110bfcc09ddSBjoern A. Zeeb 	for (idx = iwl_txq_inc_wrap(trans, idx); r != idx;
1111bfcc09ddSBjoern A. Zeeb 	     r = iwl_txq_inc_wrap(trans, r)) {
1112bfcc09ddSBjoern A. Zeeb 		txq->read_ptr = iwl_txq_inc_wrap(trans, txq->read_ptr);
1113bfcc09ddSBjoern A. Zeeb 
1114bfcc09ddSBjoern A. Zeeb 		if (nfreed++ > 0) {
1115bfcc09ddSBjoern A. Zeeb 			IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n",
1116bfcc09ddSBjoern A. Zeeb 				idx, txq->write_ptr, r);
1117bfcc09ddSBjoern A. Zeeb 			iwl_force_nmi(trans);
1118bfcc09ddSBjoern A. Zeeb 		}
1119bfcc09ddSBjoern A. Zeeb 	}
1120bfcc09ddSBjoern A. Zeeb 
1121bfcc09ddSBjoern A. Zeeb 	if (txq->read_ptr == txq->write_ptr)
1122bfcc09ddSBjoern A. Zeeb 		iwl_pcie_clear_cmd_in_flight(trans);
1123bfcc09ddSBjoern A. Zeeb 
1124bfcc09ddSBjoern A. Zeeb 	iwl_txq_progress(txq);
1125bfcc09ddSBjoern A. Zeeb }
1126bfcc09ddSBjoern A. Zeeb 
1127bfcc09ddSBjoern A. Zeeb static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid,
1128bfcc09ddSBjoern A. Zeeb 				 u16 txq_id)
1129bfcc09ddSBjoern A. Zeeb {
1130bfcc09ddSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1131bfcc09ddSBjoern A. Zeeb 	u32 tbl_dw_addr;
1132bfcc09ddSBjoern A. Zeeb 	u32 tbl_dw;
1133bfcc09ddSBjoern A. Zeeb 	u16 scd_q2ratid;
1134bfcc09ddSBjoern A. Zeeb 
1135bfcc09ddSBjoern A. Zeeb 	scd_q2ratid = ra_tid & SCD_QUEUE_RA_TID_MAP_RATID_MSK;
1136bfcc09ddSBjoern A. Zeeb 
1137bfcc09ddSBjoern A. Zeeb 	tbl_dw_addr = trans_pcie->scd_base_addr +
1138bfcc09ddSBjoern A. Zeeb 			SCD_TRANS_TBL_OFFSET_QUEUE(txq_id);
1139bfcc09ddSBjoern A. Zeeb 
1140bfcc09ddSBjoern A. Zeeb 	tbl_dw = iwl_trans_read_mem32(trans, tbl_dw_addr);
1141bfcc09ddSBjoern A. Zeeb 
1142bfcc09ddSBjoern A. Zeeb 	if (txq_id & 0x1)
1143bfcc09ddSBjoern A. Zeeb 		tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
1144bfcc09ddSBjoern A. Zeeb 	else
1145bfcc09ddSBjoern A. Zeeb 		tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
1146bfcc09ddSBjoern A. Zeeb 
1147bfcc09ddSBjoern A. Zeeb 	iwl_trans_write_mem32(trans, tbl_dw_addr, tbl_dw);
1148bfcc09ddSBjoern A. Zeeb 
1149bfcc09ddSBjoern A. Zeeb 	return 0;
1150bfcc09ddSBjoern A. Zeeb }
1151bfcc09ddSBjoern A. Zeeb 
1152bfcc09ddSBjoern A. Zeeb /* Receiver address (actually, Rx station's index into station table),
1153bfcc09ddSBjoern A. Zeeb  * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
1154bfcc09ddSBjoern A. Zeeb #define BUILD_RAxTID(sta_id, tid)	(((sta_id) << 4) + (tid))
1155bfcc09ddSBjoern A. Zeeb 
1156bfcc09ddSBjoern A. Zeeb bool iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1157bfcc09ddSBjoern A. Zeeb 			       const struct iwl_trans_txq_scd_cfg *cfg,
1158bfcc09ddSBjoern A. Zeeb 			       unsigned int wdg_timeout)
1159bfcc09ddSBjoern A. Zeeb {
1160bfcc09ddSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1161*a4128aadSBjoern A. Zeeb 	struct iwl_txq *txq = trans_pcie->txqs.txq[txq_id];
1162bfcc09ddSBjoern A. Zeeb 	int fifo = -1;
1163bfcc09ddSBjoern A. Zeeb 	bool scd_bug = false;
1164bfcc09ddSBjoern A. Zeeb 
1165*a4128aadSBjoern A. Zeeb 	if (test_and_set_bit(txq_id, trans_pcie->txqs.queue_used))
1166bfcc09ddSBjoern A. Zeeb 		WARN_ONCE(1, "queue %d already used - expect issues", txq_id);
1167bfcc09ddSBjoern A. Zeeb 
1168bfcc09ddSBjoern A. Zeeb 	txq->wd_timeout = msecs_to_jiffies(wdg_timeout);
1169bfcc09ddSBjoern A. Zeeb 
1170bfcc09ddSBjoern A. Zeeb 	if (cfg) {
1171bfcc09ddSBjoern A. Zeeb 		fifo = cfg->fifo;
1172bfcc09ddSBjoern A. Zeeb 
1173bfcc09ddSBjoern A. Zeeb 		/* Disable the scheduler prior configuring the cmd queue */
1174*a4128aadSBjoern A. Zeeb 		if (txq_id == trans_pcie->txqs.cmd.q_id &&
1175bfcc09ddSBjoern A. Zeeb 		    trans_pcie->scd_set_active)
1176bfcc09ddSBjoern A. Zeeb 			iwl_scd_enable_set_active(trans, 0);
1177bfcc09ddSBjoern A. Zeeb 
1178bfcc09ddSBjoern A. Zeeb 		/* Stop this Tx queue before configuring it */
1179bfcc09ddSBjoern A. Zeeb 		iwl_scd_txq_set_inactive(trans, txq_id);
1180bfcc09ddSBjoern A. Zeeb 
1181bfcc09ddSBjoern A. Zeeb 		/* Set this queue as a chain-building queue unless it is CMD */
1182*a4128aadSBjoern A. Zeeb 		if (txq_id != trans_pcie->txqs.cmd.q_id)
1183bfcc09ddSBjoern A. Zeeb 			iwl_scd_txq_set_chain(trans, txq_id);
1184bfcc09ddSBjoern A. Zeeb 
1185bfcc09ddSBjoern A. Zeeb 		if (cfg->aggregate) {
1186bfcc09ddSBjoern A. Zeeb 			u16 ra_tid = BUILD_RAxTID(cfg->sta_id, cfg->tid);
1187bfcc09ddSBjoern A. Zeeb 
1188bfcc09ddSBjoern A. Zeeb 			/* Map receiver-address / traffic-ID to this queue */
1189bfcc09ddSBjoern A. Zeeb 			iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id);
1190bfcc09ddSBjoern A. Zeeb 
1191bfcc09ddSBjoern A. Zeeb 			/* enable aggregations for the queue */
1192bfcc09ddSBjoern A. Zeeb 			iwl_scd_txq_enable_agg(trans, txq_id);
1193bfcc09ddSBjoern A. Zeeb 			txq->ampdu = true;
1194bfcc09ddSBjoern A. Zeeb 		} else {
1195bfcc09ddSBjoern A. Zeeb 			/*
1196bfcc09ddSBjoern A. Zeeb 			 * disable aggregations for the queue, this will also
1197bfcc09ddSBjoern A. Zeeb 			 * make the ra_tid mapping configuration irrelevant
1198bfcc09ddSBjoern A. Zeeb 			 * since it is now a non-AGG queue.
1199bfcc09ddSBjoern A. Zeeb 			 */
1200bfcc09ddSBjoern A. Zeeb 			iwl_scd_txq_disable_agg(trans, txq_id);
1201bfcc09ddSBjoern A. Zeeb 
1202bfcc09ddSBjoern A. Zeeb 			ssn = txq->read_ptr;
1203bfcc09ddSBjoern A. Zeeb 		}
1204bfcc09ddSBjoern A. Zeeb 	} else {
1205bfcc09ddSBjoern A. Zeeb 		/*
1206bfcc09ddSBjoern A. Zeeb 		 * If we need to move the SCD write pointer by steps of
1207bfcc09ddSBjoern A. Zeeb 		 * 0x40, 0x80 or 0xc0, it gets stuck. Avoids this and let
1208bfcc09ddSBjoern A. Zeeb 		 * the op_mode know by returning true later.
1209bfcc09ddSBjoern A. Zeeb 		 * Do this only in case cfg is NULL since this trick can
1210bfcc09ddSBjoern A. Zeeb 		 * be done only if we have DQA enabled which is true for mvm
1211bfcc09ddSBjoern A. Zeeb 		 * only. And mvm never sets a cfg pointer.
1212bfcc09ddSBjoern A. Zeeb 		 * This is really ugly, but this is the easiest way out for
1213bfcc09ddSBjoern A. Zeeb 		 * this sad hardware issue.
1214bfcc09ddSBjoern A. Zeeb 		 * This bug has been fixed on devices 9000 and up.
1215bfcc09ddSBjoern A. Zeeb 		 */
1216bfcc09ddSBjoern A. Zeeb 		scd_bug = !trans->trans_cfg->mq_rx_supported &&
1217bfcc09ddSBjoern A. Zeeb 			!((ssn - txq->write_ptr) & 0x3f) &&
1218bfcc09ddSBjoern A. Zeeb 			(ssn != txq->write_ptr);
1219bfcc09ddSBjoern A. Zeeb 		if (scd_bug)
1220bfcc09ddSBjoern A. Zeeb 			ssn++;
1221bfcc09ddSBjoern A. Zeeb 	}
1222bfcc09ddSBjoern A. Zeeb 
1223bfcc09ddSBjoern A. Zeeb 	/* Place first TFD at index corresponding to start sequence number.
1224bfcc09ddSBjoern A. Zeeb 	 * Assumes that ssn_idx is valid (!= 0xFFF) */
1225bfcc09ddSBjoern A. Zeeb 	txq->read_ptr = (ssn & 0xff);
1226bfcc09ddSBjoern A. Zeeb 	txq->write_ptr = (ssn & 0xff);
1227bfcc09ddSBjoern A. Zeeb 	iwl_write_direct32(trans, HBUS_TARG_WRPTR,
1228bfcc09ddSBjoern A. Zeeb 			   (ssn & 0xff) | (txq_id << 8));
1229bfcc09ddSBjoern A. Zeeb 
1230bfcc09ddSBjoern A. Zeeb 	if (cfg) {
1231bfcc09ddSBjoern A. Zeeb 		u8 frame_limit = cfg->frame_limit;
1232bfcc09ddSBjoern A. Zeeb 
1233bfcc09ddSBjoern A. Zeeb 		iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn);
1234bfcc09ddSBjoern A. Zeeb 
1235bfcc09ddSBjoern A. Zeeb 		/* Set up Tx window size and frame limit for this queue */
1236bfcc09ddSBjoern A. Zeeb 		iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr +
1237bfcc09ddSBjoern A. Zeeb 				SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0);
1238bfcc09ddSBjoern A. Zeeb 		iwl_trans_write_mem32(trans,
1239bfcc09ddSBjoern A. Zeeb 			trans_pcie->scd_base_addr +
1240bfcc09ddSBjoern A. Zeeb 			SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32),
1241bfcc09ddSBjoern A. Zeeb 			SCD_QUEUE_CTX_REG2_VAL(WIN_SIZE, frame_limit) |
1242bfcc09ddSBjoern A. Zeeb 			SCD_QUEUE_CTX_REG2_VAL(FRAME_LIMIT, frame_limit));
1243bfcc09ddSBjoern A. Zeeb 
1244bfcc09ddSBjoern A. Zeeb 		/* Set up status area in SRAM, map to Tx DMA/FIFO, activate */
1245bfcc09ddSBjoern A. Zeeb 		iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id),
1246bfcc09ddSBjoern A. Zeeb 			       (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) |
1247bfcc09ddSBjoern A. Zeeb 			       (cfg->fifo << SCD_QUEUE_STTS_REG_POS_TXF) |
1248bfcc09ddSBjoern A. Zeeb 			       (1 << SCD_QUEUE_STTS_REG_POS_WSL) |
1249bfcc09ddSBjoern A. Zeeb 			       SCD_QUEUE_STTS_REG_MSK);
1250bfcc09ddSBjoern A. Zeeb 
1251bfcc09ddSBjoern A. Zeeb 		/* enable the scheduler for this queue (only) */
1252*a4128aadSBjoern A. Zeeb 		if (txq_id == trans_pcie->txqs.cmd.q_id &&
1253bfcc09ddSBjoern A. Zeeb 		    trans_pcie->scd_set_active)
1254bfcc09ddSBjoern A. Zeeb 			iwl_scd_enable_set_active(trans, BIT(txq_id));
1255bfcc09ddSBjoern A. Zeeb 
1256bfcc09ddSBjoern A. Zeeb 		IWL_DEBUG_TX_QUEUES(trans,
1257bfcc09ddSBjoern A. Zeeb 				    "Activate queue %d on FIFO %d WrPtr: %d\n",
1258bfcc09ddSBjoern A. Zeeb 				    txq_id, fifo, ssn & 0xff);
1259bfcc09ddSBjoern A. Zeeb 	} else {
1260bfcc09ddSBjoern A. Zeeb 		IWL_DEBUG_TX_QUEUES(trans,
1261bfcc09ddSBjoern A. Zeeb 				    "Activate queue %d WrPtr: %d\n",
1262bfcc09ddSBjoern A. Zeeb 				    txq_id, ssn & 0xff);
1263bfcc09ddSBjoern A. Zeeb 	}
1264bfcc09ddSBjoern A. Zeeb 
1265bfcc09ddSBjoern A. Zeeb 	return scd_bug;
1266bfcc09ddSBjoern A. Zeeb }
1267bfcc09ddSBjoern A. Zeeb 
1268bfcc09ddSBjoern A. Zeeb void iwl_trans_pcie_txq_set_shared_mode(struct iwl_trans *trans, u32 txq_id,
1269bfcc09ddSBjoern A. Zeeb 					bool shared_mode)
1270bfcc09ddSBjoern A. Zeeb {
1271*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1272*a4128aadSBjoern A. Zeeb 	struct iwl_txq *txq = trans_pcie->txqs.txq[txq_id];
1273bfcc09ddSBjoern A. Zeeb 
1274bfcc09ddSBjoern A. Zeeb 	txq->ampdu = !shared_mode;
1275bfcc09ddSBjoern A. Zeeb }
1276bfcc09ddSBjoern A. Zeeb 
1277bfcc09ddSBjoern A. Zeeb void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id,
1278bfcc09ddSBjoern A. Zeeb 				bool configure_scd)
1279bfcc09ddSBjoern A. Zeeb {
1280bfcc09ddSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1281bfcc09ddSBjoern A. Zeeb 	u32 stts_addr = trans_pcie->scd_base_addr +
1282bfcc09ddSBjoern A. Zeeb 			SCD_TX_STTS_QUEUE_OFFSET(txq_id);
1283bfcc09ddSBjoern A. Zeeb 	static const u32 zero_val[4] = {};
1284bfcc09ddSBjoern A. Zeeb 
1285*a4128aadSBjoern A. Zeeb 	trans_pcie->txqs.txq[txq_id]->frozen_expiry_remainder = 0;
1286*a4128aadSBjoern A. Zeeb 	trans_pcie->txqs.txq[txq_id]->frozen = false;
1287bfcc09ddSBjoern A. Zeeb 
1288bfcc09ddSBjoern A. Zeeb 	/*
1289bfcc09ddSBjoern A. Zeeb 	 * Upon HW Rfkill - we stop the device, and then stop the queues
1290bfcc09ddSBjoern A. Zeeb 	 * in the op_mode. Just for the sake of the simplicity of the op_mode,
1291bfcc09ddSBjoern A. Zeeb 	 * allow the op_mode to call txq_disable after it already called
1292bfcc09ddSBjoern A. Zeeb 	 * stop_device.
1293bfcc09ddSBjoern A. Zeeb 	 */
1294*a4128aadSBjoern A. Zeeb 	if (!test_and_clear_bit(txq_id, trans_pcie->txqs.queue_used)) {
1295bfcc09ddSBjoern A. Zeeb 		WARN_ONCE(test_bit(STATUS_DEVICE_ENABLED, &trans->status),
1296bfcc09ddSBjoern A. Zeeb 			  "queue %d not used", txq_id);
1297bfcc09ddSBjoern A. Zeeb 		return;
1298bfcc09ddSBjoern A. Zeeb 	}
1299bfcc09ddSBjoern A. Zeeb 
1300bfcc09ddSBjoern A. Zeeb 	if (configure_scd) {
1301bfcc09ddSBjoern A. Zeeb 		iwl_scd_txq_set_inactive(trans, txq_id);
1302bfcc09ddSBjoern A. Zeeb 
1303d9836fb4SBjoern A. Zeeb 		iwl_trans_write_mem(trans, stts_addr, (const void *)zero_val,
1304bfcc09ddSBjoern A. Zeeb 				    ARRAY_SIZE(zero_val));
1305bfcc09ddSBjoern A. Zeeb 	}
1306bfcc09ddSBjoern A. Zeeb 
1307bfcc09ddSBjoern A. Zeeb 	iwl_pcie_txq_unmap(trans, txq_id);
1308*a4128aadSBjoern A. Zeeb 	trans_pcie->txqs.txq[txq_id]->ampdu = false;
1309bfcc09ddSBjoern A. Zeeb 
1310bfcc09ddSBjoern A. Zeeb 	IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id);
1311bfcc09ddSBjoern A. Zeeb }
1312bfcc09ddSBjoern A. Zeeb 
1313bfcc09ddSBjoern A. Zeeb /*************** HOST COMMAND QUEUE FUNCTIONS   *****/
1314bfcc09ddSBjoern A. Zeeb 
1315*a4128aadSBjoern A. Zeeb static void iwl_trans_pcie_block_txq_ptrs(struct iwl_trans *trans, bool block)
1316*a4128aadSBjoern A. Zeeb {
1317*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1318*a4128aadSBjoern A. Zeeb 	int i;
1319*a4128aadSBjoern A. Zeeb 
1320*a4128aadSBjoern A. Zeeb 	for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) {
1321*a4128aadSBjoern A. Zeeb 		struct iwl_txq *txq = trans_pcie->txqs.txq[i];
1322*a4128aadSBjoern A. Zeeb 
1323*a4128aadSBjoern A. Zeeb 		if (i == trans_pcie->txqs.cmd.q_id)
1324*a4128aadSBjoern A. Zeeb 			continue;
1325*a4128aadSBjoern A. Zeeb 
1326*a4128aadSBjoern A. Zeeb 		/* we skip the command queue (obviously) so it's OK to nest */
1327*a4128aadSBjoern A. Zeeb 		spin_lock_nested(&txq->lock, 1);
1328*a4128aadSBjoern A. Zeeb 
1329*a4128aadSBjoern A. Zeeb 		if (!block && !(WARN_ON_ONCE(!txq->block))) {
1330*a4128aadSBjoern A. Zeeb 			txq->block--;
1331*a4128aadSBjoern A. Zeeb 			if (!txq->block) {
1332*a4128aadSBjoern A. Zeeb 				iwl_write32(trans, HBUS_TARG_WRPTR,
1333*a4128aadSBjoern A. Zeeb 					    txq->write_ptr | (i << 8));
1334*a4128aadSBjoern A. Zeeb 			}
1335*a4128aadSBjoern A. Zeeb 		} else if (block) {
1336*a4128aadSBjoern A. Zeeb 			txq->block++;
1337*a4128aadSBjoern A. Zeeb 		}
1338*a4128aadSBjoern A. Zeeb 
1339*a4128aadSBjoern A. Zeeb 		spin_unlock(&txq->lock);
1340*a4128aadSBjoern A. Zeeb 	}
1341*a4128aadSBjoern A. Zeeb }
1342*a4128aadSBjoern A. Zeeb 
1343bfcc09ddSBjoern A. Zeeb /*
1344bfcc09ddSBjoern A. Zeeb  * iwl_pcie_enqueue_hcmd - enqueue a uCode command
1345bfcc09ddSBjoern A. Zeeb  * @priv: device private data point
1346bfcc09ddSBjoern A. Zeeb  * @cmd: a pointer to the ucode command structure
1347bfcc09ddSBjoern A. Zeeb  *
1348bfcc09ddSBjoern A. Zeeb  * The function returns < 0 values to indicate the operation
1349bfcc09ddSBjoern A. Zeeb  * failed. On success, it returns the index (>= 0) of command in the
1350bfcc09ddSBjoern A. Zeeb  * command queue.
1351bfcc09ddSBjoern A. Zeeb  */
1352bfcc09ddSBjoern A. Zeeb int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1353bfcc09ddSBjoern A. Zeeb 			  struct iwl_host_cmd *cmd)
1354bfcc09ddSBjoern A. Zeeb {
1355*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1356*a4128aadSBjoern A. Zeeb 	struct iwl_txq *txq = trans_pcie->txqs.txq[trans_pcie->txqs.cmd.q_id];
1357bfcc09ddSBjoern A. Zeeb 	struct iwl_device_cmd *out_cmd;
1358bfcc09ddSBjoern A. Zeeb 	struct iwl_cmd_meta *out_meta;
1359bfcc09ddSBjoern A. Zeeb 	void *dup_buf = NULL;
1360bfcc09ddSBjoern A. Zeeb 	dma_addr_t phys_addr;
1361bfcc09ddSBjoern A. Zeeb 	int idx;
1362bfcc09ddSBjoern A. Zeeb 	u16 copy_size, cmd_size, tb0_size;
1363bfcc09ddSBjoern A. Zeeb 	bool had_nocopy = false;
1364bfcc09ddSBjoern A. Zeeb 	u8 group_id = iwl_cmd_groupid(cmd->id);
1365bfcc09ddSBjoern A. Zeeb 	int i, ret;
1366bfcc09ddSBjoern A. Zeeb 	u32 cmd_pos;
1367bfcc09ddSBjoern A. Zeeb 	const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD];
1368bfcc09ddSBjoern A. Zeeb 	u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD];
1369bfcc09ddSBjoern A. Zeeb 	unsigned long flags;
1370bfcc09ddSBjoern A. Zeeb 
1371bfcc09ddSBjoern A. Zeeb 	if (WARN(!trans->wide_cmd_header &&
1372bfcc09ddSBjoern A. Zeeb 		 group_id > IWL_ALWAYS_LONG_GROUP,
1373bfcc09ddSBjoern A. Zeeb 		 "unsupported wide command %#x\n", cmd->id))
1374bfcc09ddSBjoern A. Zeeb 		return -EINVAL;
1375bfcc09ddSBjoern A. Zeeb 
1376bfcc09ddSBjoern A. Zeeb 	if (group_id != 0) {
1377bfcc09ddSBjoern A. Zeeb 		copy_size = sizeof(struct iwl_cmd_header_wide);
1378bfcc09ddSBjoern A. Zeeb 		cmd_size = sizeof(struct iwl_cmd_header_wide);
1379bfcc09ddSBjoern A. Zeeb 	} else {
1380bfcc09ddSBjoern A. Zeeb 		copy_size = sizeof(struct iwl_cmd_header);
1381bfcc09ddSBjoern A. Zeeb 		cmd_size = sizeof(struct iwl_cmd_header);
1382bfcc09ddSBjoern A. Zeeb 	}
1383bfcc09ddSBjoern A. Zeeb 
1384bfcc09ddSBjoern A. Zeeb 	/* need one for the header if the first is NOCOPY */
1385bfcc09ddSBjoern A. Zeeb 	BUILD_BUG_ON(IWL_MAX_CMD_TBS_PER_TFD > IWL_NUM_OF_TBS - 1);
1386bfcc09ddSBjoern A. Zeeb 
1387bfcc09ddSBjoern A. Zeeb 	for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
1388bfcc09ddSBjoern A. Zeeb 		cmddata[i] = cmd->data[i];
1389bfcc09ddSBjoern A. Zeeb 		cmdlen[i] = cmd->len[i];
1390bfcc09ddSBjoern A. Zeeb 
1391bfcc09ddSBjoern A. Zeeb 		if (!cmd->len[i])
1392bfcc09ddSBjoern A. Zeeb 			continue;
1393bfcc09ddSBjoern A. Zeeb 
1394bfcc09ddSBjoern A. Zeeb 		/* need at least IWL_FIRST_TB_SIZE copied */
1395bfcc09ddSBjoern A. Zeeb 		if (copy_size < IWL_FIRST_TB_SIZE) {
1396bfcc09ddSBjoern A. Zeeb 			int copy = IWL_FIRST_TB_SIZE - copy_size;
1397bfcc09ddSBjoern A. Zeeb 
1398bfcc09ddSBjoern A. Zeeb 			if (copy > cmdlen[i])
1399bfcc09ddSBjoern A. Zeeb 				copy = cmdlen[i];
1400bfcc09ddSBjoern A. Zeeb 			cmdlen[i] -= copy;
1401bfcc09ddSBjoern A. Zeeb 			cmddata[i] += copy;
1402bfcc09ddSBjoern A. Zeeb 			copy_size += copy;
1403bfcc09ddSBjoern A. Zeeb 		}
1404bfcc09ddSBjoern A. Zeeb 
1405bfcc09ddSBjoern A. Zeeb 		if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) {
1406bfcc09ddSBjoern A. Zeeb 			had_nocopy = true;
1407bfcc09ddSBjoern A. Zeeb 			if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) {
1408bfcc09ddSBjoern A. Zeeb 				idx = -EINVAL;
1409bfcc09ddSBjoern A. Zeeb 				goto free_dup_buf;
1410bfcc09ddSBjoern A. Zeeb 			}
1411bfcc09ddSBjoern A. Zeeb 		} else if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) {
1412bfcc09ddSBjoern A. Zeeb 			/*
1413bfcc09ddSBjoern A. Zeeb 			 * This is also a chunk that isn't copied
1414bfcc09ddSBjoern A. Zeeb 			 * to the static buffer so set had_nocopy.
1415bfcc09ddSBjoern A. Zeeb 			 */
1416bfcc09ddSBjoern A. Zeeb 			had_nocopy = true;
1417bfcc09ddSBjoern A. Zeeb 
1418bfcc09ddSBjoern A. Zeeb 			/* only allowed once */
1419bfcc09ddSBjoern A. Zeeb 			if (WARN_ON(dup_buf)) {
1420bfcc09ddSBjoern A. Zeeb 				idx = -EINVAL;
1421bfcc09ddSBjoern A. Zeeb 				goto free_dup_buf;
1422bfcc09ddSBjoern A. Zeeb 			}
1423bfcc09ddSBjoern A. Zeeb 
1424bfcc09ddSBjoern A. Zeeb 			dup_buf = kmemdup(cmddata[i], cmdlen[i],
1425bfcc09ddSBjoern A. Zeeb 					  GFP_ATOMIC);
1426bfcc09ddSBjoern A. Zeeb 			if (!dup_buf)
1427bfcc09ddSBjoern A. Zeeb 				return -ENOMEM;
1428bfcc09ddSBjoern A. Zeeb 		} else {
1429bfcc09ddSBjoern A. Zeeb 			/* NOCOPY must not be followed by normal! */
1430bfcc09ddSBjoern A. Zeeb 			if (WARN_ON(had_nocopy)) {
1431bfcc09ddSBjoern A. Zeeb 				idx = -EINVAL;
1432bfcc09ddSBjoern A. Zeeb 				goto free_dup_buf;
1433bfcc09ddSBjoern A. Zeeb 			}
1434bfcc09ddSBjoern A. Zeeb 			copy_size += cmdlen[i];
1435bfcc09ddSBjoern A. Zeeb 		}
1436bfcc09ddSBjoern A. Zeeb 		cmd_size += cmd->len[i];
1437bfcc09ddSBjoern A. Zeeb 	}
1438bfcc09ddSBjoern A. Zeeb 
1439bfcc09ddSBjoern A. Zeeb 	/*
1440bfcc09ddSBjoern A. Zeeb 	 * If any of the command structures end up being larger than
1441bfcc09ddSBjoern A. Zeeb 	 * the TFD_MAX_PAYLOAD_SIZE and they aren't dynamically
1442bfcc09ddSBjoern A. Zeeb 	 * allocated into separate TFDs, then we will need to
1443bfcc09ddSBjoern A. Zeeb 	 * increase the size of the buffers.
1444bfcc09ddSBjoern A. Zeeb 	 */
1445bfcc09ddSBjoern A. Zeeb 	if (WARN(copy_size > TFD_MAX_PAYLOAD_SIZE,
1446bfcc09ddSBjoern A. Zeeb 		 "Command %s (%#x) is too large (%d bytes)\n",
1447bfcc09ddSBjoern A. Zeeb 		 iwl_get_cmd_string(trans, cmd->id),
1448bfcc09ddSBjoern A. Zeeb 		 cmd->id, copy_size)) {
1449bfcc09ddSBjoern A. Zeeb 		idx = -EINVAL;
1450bfcc09ddSBjoern A. Zeeb 		goto free_dup_buf;
1451bfcc09ddSBjoern A. Zeeb 	}
1452bfcc09ddSBjoern A. Zeeb 
1453bfcc09ddSBjoern A. Zeeb 	spin_lock_irqsave(&txq->lock, flags);
1454bfcc09ddSBjoern A. Zeeb 
1455bfcc09ddSBjoern A. Zeeb 	if (iwl_txq_space(trans, txq) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
1456bfcc09ddSBjoern A. Zeeb 		spin_unlock_irqrestore(&txq->lock, flags);
1457bfcc09ddSBjoern A. Zeeb 
1458bfcc09ddSBjoern A. Zeeb 		IWL_ERR(trans, "No space in command queue\n");
1459bfcc09ddSBjoern A. Zeeb 		iwl_op_mode_cmd_queue_full(trans->op_mode);
1460bfcc09ddSBjoern A. Zeeb 		idx = -ENOSPC;
1461bfcc09ddSBjoern A. Zeeb 		goto free_dup_buf;
1462bfcc09ddSBjoern A. Zeeb 	}
1463bfcc09ddSBjoern A. Zeeb 
1464bfcc09ddSBjoern A. Zeeb 	idx = iwl_txq_get_cmd_index(txq, txq->write_ptr);
1465bfcc09ddSBjoern A. Zeeb 	out_cmd = txq->entries[idx].cmd;
1466bfcc09ddSBjoern A. Zeeb 	out_meta = &txq->entries[idx].meta;
1467bfcc09ddSBjoern A. Zeeb 
1468*a4128aadSBjoern A. Zeeb 	/* re-initialize, this also marks the SG list as unused */
1469*a4128aadSBjoern A. Zeeb 	memset(out_meta, 0, sizeof(*out_meta));
1470bfcc09ddSBjoern A. Zeeb 	if (cmd->flags & CMD_WANT_SKB)
1471bfcc09ddSBjoern A. Zeeb 		out_meta->source = cmd;
1472bfcc09ddSBjoern A. Zeeb 
1473bfcc09ddSBjoern A. Zeeb 	/* set up the header */
1474bfcc09ddSBjoern A. Zeeb 	if (group_id != 0) {
1475bfcc09ddSBjoern A. Zeeb 		out_cmd->hdr_wide.cmd = iwl_cmd_opcode(cmd->id);
1476bfcc09ddSBjoern A. Zeeb 		out_cmd->hdr_wide.group_id = group_id;
1477bfcc09ddSBjoern A. Zeeb 		out_cmd->hdr_wide.version = iwl_cmd_version(cmd->id);
1478bfcc09ddSBjoern A. Zeeb 		out_cmd->hdr_wide.length =
1479bfcc09ddSBjoern A. Zeeb 			cpu_to_le16(cmd_size -
1480bfcc09ddSBjoern A. Zeeb 				    sizeof(struct iwl_cmd_header_wide));
1481bfcc09ddSBjoern A. Zeeb 		out_cmd->hdr_wide.reserved = 0;
1482bfcc09ddSBjoern A. Zeeb 		out_cmd->hdr_wide.sequence =
1483*a4128aadSBjoern A. Zeeb 			cpu_to_le16(QUEUE_TO_SEQ(trans_pcie->txqs.cmd.q_id) |
1484bfcc09ddSBjoern A. Zeeb 						 INDEX_TO_SEQ(txq->write_ptr));
1485bfcc09ddSBjoern A. Zeeb 
1486bfcc09ddSBjoern A. Zeeb 		cmd_pos = sizeof(struct iwl_cmd_header_wide);
1487bfcc09ddSBjoern A. Zeeb 		copy_size = sizeof(struct iwl_cmd_header_wide);
1488bfcc09ddSBjoern A. Zeeb 	} else {
1489bfcc09ddSBjoern A. Zeeb 		out_cmd->hdr.cmd = iwl_cmd_opcode(cmd->id);
1490bfcc09ddSBjoern A. Zeeb 		out_cmd->hdr.sequence =
1491*a4128aadSBjoern A. Zeeb 			cpu_to_le16(QUEUE_TO_SEQ(trans_pcie->txqs.cmd.q_id) |
1492bfcc09ddSBjoern A. Zeeb 						 INDEX_TO_SEQ(txq->write_ptr));
1493bfcc09ddSBjoern A. Zeeb 		out_cmd->hdr.group_id = 0;
1494bfcc09ddSBjoern A. Zeeb 
1495bfcc09ddSBjoern A. Zeeb 		cmd_pos = sizeof(struct iwl_cmd_header);
1496bfcc09ddSBjoern A. Zeeb 		copy_size = sizeof(struct iwl_cmd_header);
1497bfcc09ddSBjoern A. Zeeb 	}
1498bfcc09ddSBjoern A. Zeeb 
1499bfcc09ddSBjoern A. Zeeb 	/* and copy the data that needs to be copied */
1500bfcc09ddSBjoern A. Zeeb 	for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
1501bfcc09ddSBjoern A. Zeeb 		int copy;
1502bfcc09ddSBjoern A. Zeeb 
1503bfcc09ddSBjoern A. Zeeb 		if (!cmd->len[i])
1504bfcc09ddSBjoern A. Zeeb 			continue;
1505bfcc09ddSBjoern A. Zeeb 
1506bfcc09ddSBjoern A. Zeeb 		/* copy everything if not nocopy/dup */
1507bfcc09ddSBjoern A. Zeeb 		if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
1508bfcc09ddSBjoern A. Zeeb 					   IWL_HCMD_DFL_DUP))) {
1509bfcc09ddSBjoern A. Zeeb 			copy = cmd->len[i];
1510bfcc09ddSBjoern A. Zeeb 
1511bfcc09ddSBjoern A. Zeeb 			memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy);
1512bfcc09ddSBjoern A. Zeeb 			cmd_pos += copy;
1513bfcc09ddSBjoern A. Zeeb 			copy_size += copy;
1514bfcc09ddSBjoern A. Zeeb 			continue;
1515bfcc09ddSBjoern A. Zeeb 		}
1516bfcc09ddSBjoern A. Zeeb 
1517bfcc09ddSBjoern A. Zeeb 		/*
1518bfcc09ddSBjoern A. Zeeb 		 * Otherwise we need at least IWL_FIRST_TB_SIZE copied
1519bfcc09ddSBjoern A. Zeeb 		 * in total (for bi-directional DMA), but copy up to what
1520bfcc09ddSBjoern A. Zeeb 		 * we can fit into the payload for debug dump purposes.
1521bfcc09ddSBjoern A. Zeeb 		 */
1522bfcc09ddSBjoern A. Zeeb 		copy = min_t(int, TFD_MAX_PAYLOAD_SIZE - cmd_pos, cmd->len[i]);
1523bfcc09ddSBjoern A. Zeeb 
1524bfcc09ddSBjoern A. Zeeb 		memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy);
1525bfcc09ddSBjoern A. Zeeb 		cmd_pos += copy;
1526bfcc09ddSBjoern A. Zeeb 
1527bfcc09ddSBjoern A. Zeeb 		/* However, treat copy_size the proper way, we need it below */
1528bfcc09ddSBjoern A. Zeeb 		if (copy_size < IWL_FIRST_TB_SIZE) {
1529bfcc09ddSBjoern A. Zeeb 			copy = IWL_FIRST_TB_SIZE - copy_size;
1530bfcc09ddSBjoern A. Zeeb 
1531bfcc09ddSBjoern A. Zeeb 			if (copy > cmd->len[i])
1532bfcc09ddSBjoern A. Zeeb 				copy = cmd->len[i];
1533bfcc09ddSBjoern A. Zeeb 			copy_size += copy;
1534bfcc09ddSBjoern A. Zeeb 		}
1535bfcc09ddSBjoern A. Zeeb 	}
1536bfcc09ddSBjoern A. Zeeb 
1537bfcc09ddSBjoern A. Zeeb 	IWL_DEBUG_HC(trans,
1538bfcc09ddSBjoern A. Zeeb 		     "Sending command %s (%.2x.%.2x), seq: 0x%04X, %d bytes at %d[%d]:%d\n",
1539bfcc09ddSBjoern A. Zeeb 		     iwl_get_cmd_string(trans, cmd->id),
1540bfcc09ddSBjoern A. Zeeb 		     group_id, out_cmd->hdr.cmd,
1541bfcc09ddSBjoern A. Zeeb 		     le16_to_cpu(out_cmd->hdr.sequence),
1542*a4128aadSBjoern A. Zeeb 		     cmd_size, txq->write_ptr, idx, trans_pcie->txqs.cmd.q_id);
1543bfcc09ddSBjoern A. Zeeb 
1544bfcc09ddSBjoern A. Zeeb 	/* start the TFD with the minimum copy bytes */
1545bfcc09ddSBjoern A. Zeeb 	tb0_size = min_t(int, copy_size, IWL_FIRST_TB_SIZE);
1546bfcc09ddSBjoern A. Zeeb 	memcpy(&txq->first_tb_bufs[idx], &out_cmd->hdr, tb0_size);
1547bfcc09ddSBjoern A. Zeeb 	iwl_pcie_txq_build_tfd(trans, txq,
1548bfcc09ddSBjoern A. Zeeb 			       iwl_txq_get_first_tb_dma(txq, idx),
1549bfcc09ddSBjoern A. Zeeb 			       tb0_size, true);
1550bfcc09ddSBjoern A. Zeeb 
1551bfcc09ddSBjoern A. Zeeb 	/* map first command fragment, if any remains */
1552bfcc09ddSBjoern A. Zeeb 	if (copy_size > tb0_size) {
1553bfcc09ddSBjoern A. Zeeb 		phys_addr = dma_map_single(trans->dev,
1554bfcc09ddSBjoern A. Zeeb 					   ((u8 *)&out_cmd->hdr) + tb0_size,
1555bfcc09ddSBjoern A. Zeeb 					   copy_size - tb0_size,
1556bfcc09ddSBjoern A. Zeeb 					   DMA_TO_DEVICE);
1557bfcc09ddSBjoern A. Zeeb 		if (dma_mapping_error(trans->dev, phys_addr)) {
1558bfcc09ddSBjoern A. Zeeb 			iwl_txq_gen1_tfd_unmap(trans, out_meta, txq,
1559bfcc09ddSBjoern A. Zeeb 					       txq->write_ptr);
1560bfcc09ddSBjoern A. Zeeb 			idx = -ENOMEM;
1561bfcc09ddSBjoern A. Zeeb 			goto out;
1562bfcc09ddSBjoern A. Zeeb 		}
1563bfcc09ddSBjoern A. Zeeb 
1564bfcc09ddSBjoern A. Zeeb 		iwl_pcie_txq_build_tfd(trans, txq, phys_addr,
1565bfcc09ddSBjoern A. Zeeb 				       copy_size - tb0_size, false);
1566bfcc09ddSBjoern A. Zeeb 	}
1567bfcc09ddSBjoern A. Zeeb 
1568bfcc09ddSBjoern A. Zeeb 	/* map the remaining (adjusted) nocopy/dup fragments */
1569bfcc09ddSBjoern A. Zeeb 	for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
1570bfcc09ddSBjoern A. Zeeb 		void *data = (void *)(uintptr_t)cmddata[i];
1571bfcc09ddSBjoern A. Zeeb 
1572bfcc09ddSBjoern A. Zeeb 		if (!cmdlen[i])
1573bfcc09ddSBjoern A. Zeeb 			continue;
1574bfcc09ddSBjoern A. Zeeb 		if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
1575bfcc09ddSBjoern A. Zeeb 					   IWL_HCMD_DFL_DUP)))
1576bfcc09ddSBjoern A. Zeeb 			continue;
1577bfcc09ddSBjoern A. Zeeb 		if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP)
1578bfcc09ddSBjoern A. Zeeb 			data = dup_buf;
1579bfcc09ddSBjoern A. Zeeb 		phys_addr = dma_map_single(trans->dev, data,
1580bfcc09ddSBjoern A. Zeeb 					   cmdlen[i], DMA_TO_DEVICE);
1581bfcc09ddSBjoern A. Zeeb 		if (dma_mapping_error(trans->dev, phys_addr)) {
1582bfcc09ddSBjoern A. Zeeb 			iwl_txq_gen1_tfd_unmap(trans, out_meta, txq,
1583bfcc09ddSBjoern A. Zeeb 					       txq->write_ptr);
1584bfcc09ddSBjoern A. Zeeb 			idx = -ENOMEM;
1585bfcc09ddSBjoern A. Zeeb 			goto out;
1586bfcc09ddSBjoern A. Zeeb 		}
1587bfcc09ddSBjoern A. Zeeb 
1588bfcc09ddSBjoern A. Zeeb 		iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], false);
1589bfcc09ddSBjoern A. Zeeb 	}
1590bfcc09ddSBjoern A. Zeeb 
1591bfcc09ddSBjoern A. Zeeb 	BUILD_BUG_ON(IWL_TFH_NUM_TBS > sizeof(out_meta->tbs) * BITS_PER_BYTE);
1592bfcc09ddSBjoern A. Zeeb 	out_meta->flags = cmd->flags;
1593bfcc09ddSBjoern A. Zeeb 	if (WARN_ON_ONCE(txq->entries[idx].free_buf))
1594bfcc09ddSBjoern A. Zeeb 		kfree_sensitive(txq->entries[idx].free_buf);
1595bfcc09ddSBjoern A. Zeeb 	txq->entries[idx].free_buf = dup_buf;
1596bfcc09ddSBjoern A. Zeeb 
1597bfcc09ddSBjoern A. Zeeb 	trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr_wide);
1598bfcc09ddSBjoern A. Zeeb 
1599bfcc09ddSBjoern A. Zeeb 	/* start timer if queue currently empty */
1600bfcc09ddSBjoern A. Zeeb 	if (txq->read_ptr == txq->write_ptr && txq->wd_timeout)
1601bfcc09ddSBjoern A. Zeeb 		mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
1602bfcc09ddSBjoern A. Zeeb 
1603bfcc09ddSBjoern A. Zeeb 	ret = iwl_pcie_set_cmd_in_flight(trans, cmd);
1604bfcc09ddSBjoern A. Zeeb 	if (ret < 0) {
1605bfcc09ddSBjoern A. Zeeb 		idx = ret;
1606bfcc09ddSBjoern A. Zeeb 		goto out;
1607bfcc09ddSBjoern A. Zeeb 	}
1608bfcc09ddSBjoern A. Zeeb 
1609*a4128aadSBjoern A. Zeeb 	if (cmd->flags & CMD_BLOCK_TXQS)
1610*a4128aadSBjoern A. Zeeb 		iwl_trans_pcie_block_txq_ptrs(trans, true);
1611*a4128aadSBjoern A. Zeeb 
1612bfcc09ddSBjoern A. Zeeb 	/* Increment and update queue's write index */
1613bfcc09ddSBjoern A. Zeeb 	txq->write_ptr = iwl_txq_inc_wrap(trans, txq->write_ptr);
1614bfcc09ddSBjoern A. Zeeb 	iwl_pcie_txq_inc_wr_ptr(trans, txq);
1615bfcc09ddSBjoern A. Zeeb 
1616bfcc09ddSBjoern A. Zeeb  out:
1617bfcc09ddSBjoern A. Zeeb 	spin_unlock_irqrestore(&txq->lock, flags);
1618bfcc09ddSBjoern A. Zeeb  free_dup_buf:
1619bfcc09ddSBjoern A. Zeeb 	if (idx < 0)
1620bfcc09ddSBjoern A. Zeeb 		kfree(dup_buf);
1621bfcc09ddSBjoern A. Zeeb 	return idx;
1622bfcc09ddSBjoern A. Zeeb }
1623bfcc09ddSBjoern A. Zeeb 
1624bfcc09ddSBjoern A. Zeeb /*
1625bfcc09ddSBjoern A. Zeeb  * iwl_pcie_hcmd_complete - Pull unused buffers off the queue and reclaim them
1626bfcc09ddSBjoern A. Zeeb  * @rxb: Rx buffer to reclaim
1627bfcc09ddSBjoern A. Zeeb  */
1628bfcc09ddSBjoern A. Zeeb void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
1629bfcc09ddSBjoern A. Zeeb 			    struct iwl_rx_cmd_buffer *rxb)
1630bfcc09ddSBjoern A. Zeeb {
1631bfcc09ddSBjoern A. Zeeb 	struct iwl_rx_packet *pkt = rxb_addr(rxb);
1632bfcc09ddSBjoern A. Zeeb 	u16 sequence = le16_to_cpu(pkt->hdr.sequence);
1633bfcc09ddSBjoern A. Zeeb 	u8 group_id;
1634bfcc09ddSBjoern A. Zeeb 	u32 cmd_id;
1635bfcc09ddSBjoern A. Zeeb 	int txq_id = SEQ_TO_QUEUE(sequence);
1636bfcc09ddSBjoern A. Zeeb 	int index = SEQ_TO_INDEX(sequence);
1637bfcc09ddSBjoern A. Zeeb 	int cmd_index;
1638bfcc09ddSBjoern A. Zeeb 	struct iwl_device_cmd *cmd;
1639bfcc09ddSBjoern A. Zeeb 	struct iwl_cmd_meta *meta;
1640bfcc09ddSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1641*a4128aadSBjoern A. Zeeb 	struct iwl_txq *txq = trans_pcie->txqs.txq[trans_pcie->txqs.cmd.q_id];
1642bfcc09ddSBjoern A. Zeeb 
1643bfcc09ddSBjoern A. Zeeb 	/* If a Tx command is being handled and it isn't in the actual
1644bfcc09ddSBjoern A. Zeeb 	 * command queue then there a command routing bug has been introduced
1645bfcc09ddSBjoern A. Zeeb 	 * in the queue management code. */
1646*a4128aadSBjoern A. Zeeb 	if (WARN(txq_id != trans_pcie->txqs.cmd.q_id,
1647bfcc09ddSBjoern A. Zeeb 		 "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n",
1648*a4128aadSBjoern A. Zeeb 		 txq_id, trans_pcie->txqs.cmd.q_id, sequence, txq->read_ptr,
1649bfcc09ddSBjoern A. Zeeb 		 txq->write_ptr)) {
1650bfcc09ddSBjoern A. Zeeb 		iwl_print_hex_error(trans, pkt, 32);
1651bfcc09ddSBjoern A. Zeeb 		return;
1652bfcc09ddSBjoern A. Zeeb 	}
1653bfcc09ddSBjoern A. Zeeb 
1654bfcc09ddSBjoern A. Zeeb 	spin_lock_bh(&txq->lock);
1655bfcc09ddSBjoern A. Zeeb 
1656bfcc09ddSBjoern A. Zeeb 	cmd_index = iwl_txq_get_cmd_index(txq, index);
1657bfcc09ddSBjoern A. Zeeb 	cmd = txq->entries[cmd_index].cmd;
1658bfcc09ddSBjoern A. Zeeb 	meta = &txq->entries[cmd_index].meta;
1659bfcc09ddSBjoern A. Zeeb 	group_id = cmd->hdr.group_id;
1660d9836fb4SBjoern A. Zeeb 	cmd_id = WIDE_ID(group_id, cmd->hdr.cmd);
1661bfcc09ddSBjoern A. Zeeb 
1662*a4128aadSBjoern A. Zeeb 	if (trans->trans_cfg->gen2)
1663*a4128aadSBjoern A. Zeeb 		iwl_txq_gen2_tfd_unmap(trans, meta,
1664*a4128aadSBjoern A. Zeeb 				       iwl_txq_get_tfd(trans, txq, index));
1665*a4128aadSBjoern A. Zeeb 	else
1666bfcc09ddSBjoern A. Zeeb 		iwl_txq_gen1_tfd_unmap(trans, meta, txq, index);
1667bfcc09ddSBjoern A. Zeeb 
1668bfcc09ddSBjoern A. Zeeb 	/* Input error checking is done when commands are added to queue. */
1669bfcc09ddSBjoern A. Zeeb 	if (meta->flags & CMD_WANT_SKB) {
1670bfcc09ddSBjoern A. Zeeb 		struct page *p = rxb_steal_page(rxb);
1671bfcc09ddSBjoern A. Zeeb 
1672bfcc09ddSBjoern A. Zeeb 		meta->source->resp_pkt = pkt;
1673bfcc09ddSBjoern A. Zeeb #if defined(__linux__)
1674bfcc09ddSBjoern A. Zeeb 		meta->source->_rx_page_addr = (unsigned long)page_address(p);
1675bfcc09ddSBjoern A. Zeeb #elif defined(__FreeBSD__)
1676bfcc09ddSBjoern A. Zeeb 		meta->source->_page = p;
1677bfcc09ddSBjoern A. Zeeb #endif
1678bfcc09ddSBjoern A. Zeeb 		meta->source->_rx_page_order = trans_pcie->rx_page_order;
1679bfcc09ddSBjoern A. Zeeb 	}
1680bfcc09ddSBjoern A. Zeeb 
1681*a4128aadSBjoern A. Zeeb 	if (meta->flags & CMD_BLOCK_TXQS)
1682*a4128aadSBjoern A. Zeeb 		iwl_trans_pcie_block_txq_ptrs(trans, false);
1683bfcc09ddSBjoern A. Zeeb 
1684bfcc09ddSBjoern A. Zeeb 	iwl_pcie_cmdq_reclaim(trans, txq_id, index);
1685bfcc09ddSBjoern A. Zeeb 
1686bfcc09ddSBjoern A. Zeeb 	if (!(meta->flags & CMD_ASYNC)) {
1687bfcc09ddSBjoern A. Zeeb 		if (!test_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status)) {
1688bfcc09ddSBjoern A. Zeeb 			IWL_WARN(trans,
1689bfcc09ddSBjoern A. Zeeb 				 "HCMD_ACTIVE already clear for command %s\n",
1690bfcc09ddSBjoern A. Zeeb 				 iwl_get_cmd_string(trans, cmd_id));
1691bfcc09ddSBjoern A. Zeeb 		}
1692bfcc09ddSBjoern A. Zeeb 		clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
1693bfcc09ddSBjoern A. Zeeb 		IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n",
1694bfcc09ddSBjoern A. Zeeb 			       iwl_get_cmd_string(trans, cmd_id));
1695bfcc09ddSBjoern A. Zeeb 		wake_up(&trans->wait_command_queue);
1696bfcc09ddSBjoern A. Zeeb 	}
1697bfcc09ddSBjoern A. Zeeb 
1698bfcc09ddSBjoern A. Zeeb 	meta->flags = 0;
1699bfcc09ddSBjoern A. Zeeb 
1700bfcc09ddSBjoern A. Zeeb 	spin_unlock_bh(&txq->lock);
1701bfcc09ddSBjoern A. Zeeb }
1702bfcc09ddSBjoern A. Zeeb 
1703bfcc09ddSBjoern A. Zeeb static int iwl_fill_data_tbs(struct iwl_trans *trans, struct sk_buff *skb,
1704bfcc09ddSBjoern A. Zeeb 			     struct iwl_txq *txq, u8 hdr_len,
1705bfcc09ddSBjoern A. Zeeb 			     struct iwl_cmd_meta *out_meta)
1706bfcc09ddSBjoern A. Zeeb {
1707bfcc09ddSBjoern A. Zeeb 	u16 head_tb_len;
1708bfcc09ddSBjoern A. Zeeb 	int i;
1709bfcc09ddSBjoern A. Zeeb 
1710bfcc09ddSBjoern A. Zeeb 	/*
1711bfcc09ddSBjoern A. Zeeb 	 * Set up TFD's third entry to point directly to remainder
1712bfcc09ddSBjoern A. Zeeb 	 * of skb's head, if any
1713bfcc09ddSBjoern A. Zeeb 	 */
1714bfcc09ddSBjoern A. Zeeb 	head_tb_len = skb_headlen(skb) - hdr_len;
1715bfcc09ddSBjoern A. Zeeb 
1716bfcc09ddSBjoern A. Zeeb 	if (head_tb_len > 0) {
1717bfcc09ddSBjoern A. Zeeb 		dma_addr_t tb_phys = dma_map_single(trans->dev,
1718bfcc09ddSBjoern A. Zeeb 						    skb->data + hdr_len,
1719bfcc09ddSBjoern A. Zeeb 						    head_tb_len, DMA_TO_DEVICE);
1720bfcc09ddSBjoern A. Zeeb 		if (unlikely(dma_mapping_error(trans->dev, tb_phys)))
1721bfcc09ddSBjoern A. Zeeb 			return -EINVAL;
1722bfcc09ddSBjoern A. Zeeb 		trace_iwlwifi_dev_tx_tb(trans->dev, skb, skb->data + hdr_len,
1723bfcc09ddSBjoern A. Zeeb 					tb_phys, head_tb_len);
1724bfcc09ddSBjoern A. Zeeb 		iwl_pcie_txq_build_tfd(trans, txq, tb_phys, head_tb_len, false);
1725bfcc09ddSBjoern A. Zeeb 	}
1726bfcc09ddSBjoern A. Zeeb 
1727bfcc09ddSBjoern A. Zeeb 	/* set up the remaining entries to point to the data */
1728bfcc09ddSBjoern A. Zeeb 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
1729bfcc09ddSBjoern A. Zeeb 		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
1730bfcc09ddSBjoern A. Zeeb 		dma_addr_t tb_phys;
1731bfcc09ddSBjoern A. Zeeb 		int tb_idx;
1732bfcc09ddSBjoern A. Zeeb 
1733bfcc09ddSBjoern A. Zeeb 		if (!skb_frag_size(frag))
1734bfcc09ddSBjoern A. Zeeb 			continue;
1735bfcc09ddSBjoern A. Zeeb 
1736bfcc09ddSBjoern A. Zeeb 		tb_phys = skb_frag_dma_map(trans->dev, frag, 0,
1737bfcc09ddSBjoern A. Zeeb 					   skb_frag_size(frag), DMA_TO_DEVICE);
1738bfcc09ddSBjoern A. Zeeb 
1739bfcc09ddSBjoern A. Zeeb 		if (unlikely(dma_mapping_error(trans->dev, tb_phys)))
1740bfcc09ddSBjoern A. Zeeb 			return -EINVAL;
1741bfcc09ddSBjoern A. Zeeb 		trace_iwlwifi_dev_tx_tb(trans->dev, skb, skb_frag_address(frag),
1742bfcc09ddSBjoern A. Zeeb 					tb_phys, skb_frag_size(frag));
1743bfcc09ddSBjoern A. Zeeb 		tb_idx = iwl_pcie_txq_build_tfd(trans, txq, tb_phys,
1744bfcc09ddSBjoern A. Zeeb 						skb_frag_size(frag), false);
1745bfcc09ddSBjoern A. Zeeb 		if (tb_idx < 0)
1746bfcc09ddSBjoern A. Zeeb 			return tb_idx;
1747bfcc09ddSBjoern A. Zeeb 
1748bfcc09ddSBjoern A. Zeeb 		out_meta->tbs |= BIT(tb_idx);
1749bfcc09ddSBjoern A. Zeeb 	}
1750bfcc09ddSBjoern A. Zeeb 
1751bfcc09ddSBjoern A. Zeeb 	return 0;
1752bfcc09ddSBjoern A. Zeeb }
1753bfcc09ddSBjoern A. Zeeb 
1754bfcc09ddSBjoern A. Zeeb #ifdef CONFIG_INET
1755*a4128aadSBjoern A. Zeeb static void *iwl_pcie_get_page_hdr(struct iwl_trans *trans,
1756*a4128aadSBjoern A. Zeeb 				   size_t len, struct sk_buff *skb)
1757*a4128aadSBjoern A. Zeeb {
1758*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1759*a4128aadSBjoern A. Zeeb 	struct iwl_tso_hdr_page *p = this_cpu_ptr(trans_pcie->txqs.tso_hdr_page);
1760*a4128aadSBjoern A. Zeeb 	struct iwl_tso_page_info *info;
1761*a4128aadSBjoern A. Zeeb 	struct page **page_ptr;
1762*a4128aadSBjoern A. Zeeb 	dma_addr_t phys;
1763*a4128aadSBjoern A. Zeeb 	void *ret;
1764*a4128aadSBjoern A. Zeeb 
1765*a4128aadSBjoern A. Zeeb 	page_ptr = (void *)((u8 *)skb->cb + trans_pcie->txqs.page_offs);
1766*a4128aadSBjoern A. Zeeb 
1767*a4128aadSBjoern A. Zeeb 	if (WARN_ON(*page_ptr))
1768*a4128aadSBjoern A. Zeeb 		return NULL;
1769*a4128aadSBjoern A. Zeeb 
1770*a4128aadSBjoern A. Zeeb 	if (!p->page)
1771*a4128aadSBjoern A. Zeeb 		goto alloc;
1772*a4128aadSBjoern A. Zeeb 
1773*a4128aadSBjoern A. Zeeb 	/*
1774*a4128aadSBjoern A. Zeeb 	 * Check if there's enough room on this page
1775*a4128aadSBjoern A. Zeeb 	 *
1776*a4128aadSBjoern A. Zeeb 	 * Note that we put a page chaining pointer *last* in the
1777*a4128aadSBjoern A. Zeeb 	 * page - we need it somewhere, and if it's there then we
1778*a4128aadSBjoern A. Zeeb 	 * avoid DMA mapping the last bits of the page which may
1779*a4128aadSBjoern A. Zeeb 	 * trigger the 32-bit boundary hardware bug.
1780*a4128aadSBjoern A. Zeeb 	 *
1781*a4128aadSBjoern A. Zeeb 	 * (see also get_workaround_page() in tx-gen2.c)
1782*a4128aadSBjoern A. Zeeb 	 */
1783*a4128aadSBjoern A. Zeeb 	if (((unsigned long)p->pos & ~PAGE_MASK) + len < IWL_TSO_PAGE_DATA_SIZE) {
1784*a4128aadSBjoern A. Zeeb 		info = IWL_TSO_PAGE_INFO(page_address(p->page));
1785*a4128aadSBjoern A. Zeeb 		goto out;
1786*a4128aadSBjoern A. Zeeb 	}
1787*a4128aadSBjoern A. Zeeb 
1788*a4128aadSBjoern A. Zeeb 	/* We don't have enough room on this page, get a new one. */
1789*a4128aadSBjoern A. Zeeb 	iwl_pcie_free_and_unmap_tso_page(trans, p->page);
1790*a4128aadSBjoern A. Zeeb 
1791*a4128aadSBjoern A. Zeeb alloc:
1792*a4128aadSBjoern A. Zeeb 	p->page = alloc_page(GFP_ATOMIC);
1793*a4128aadSBjoern A. Zeeb 	if (!p->page)
1794*a4128aadSBjoern A. Zeeb 		return NULL;
1795*a4128aadSBjoern A. Zeeb 	p->pos = page_address(p->page);
1796*a4128aadSBjoern A. Zeeb 
1797*a4128aadSBjoern A. Zeeb 	info = IWL_TSO_PAGE_INFO(page_address(p->page));
1798*a4128aadSBjoern A. Zeeb 
1799*a4128aadSBjoern A. Zeeb 	/* set the chaining pointer to NULL */
1800*a4128aadSBjoern A. Zeeb 	info->next = NULL;
1801*a4128aadSBjoern A. Zeeb 
1802*a4128aadSBjoern A. Zeeb 	/* Create a DMA mapping for the page */
1803*a4128aadSBjoern A. Zeeb 	phys = dma_map_page_attrs(trans->dev, p->page, 0, PAGE_SIZE,
1804*a4128aadSBjoern A. Zeeb 				  DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
1805*a4128aadSBjoern A. Zeeb 	if (unlikely(dma_mapping_error(trans->dev, phys))) {
1806*a4128aadSBjoern A. Zeeb 		__free_page(p->page);
1807*a4128aadSBjoern A. Zeeb 		p->page = NULL;
1808*a4128aadSBjoern A. Zeeb 
1809*a4128aadSBjoern A. Zeeb 		return NULL;
1810*a4128aadSBjoern A. Zeeb 	}
1811*a4128aadSBjoern A. Zeeb 
1812*a4128aadSBjoern A. Zeeb 	/* Store physical address and set use count */
1813*a4128aadSBjoern A. Zeeb 	info->dma_addr = phys;
1814*a4128aadSBjoern A. Zeeb 	refcount_set(&info->use_count, 1);
1815*a4128aadSBjoern A. Zeeb out:
1816*a4128aadSBjoern A. Zeeb 	*page_ptr = p->page;
1817*a4128aadSBjoern A. Zeeb 	/* Return an internal reference for the caller */
1818*a4128aadSBjoern A. Zeeb 	refcount_inc(&info->use_count);
1819*a4128aadSBjoern A. Zeeb 	ret = p->pos;
1820*a4128aadSBjoern A. Zeeb 	p->pos += len;
1821*a4128aadSBjoern A. Zeeb 
1822*a4128aadSBjoern A. Zeeb 	return ret;
1823*a4128aadSBjoern A. Zeeb }
1824*a4128aadSBjoern A. Zeeb 
1825*a4128aadSBjoern A. Zeeb /**
1826*a4128aadSBjoern A. Zeeb  * iwl_pcie_get_sgt_tb_phys - Find TB address in mapped SG list
1827*a4128aadSBjoern A. Zeeb  * @sgt: scatter gather table
1828*a4128aadSBjoern A. Zeeb  * @offset: Offset into the mapped memory (i.e. SKB payload data)
1829*a4128aadSBjoern A. Zeeb  * @len: Length of the area
1830*a4128aadSBjoern A. Zeeb  *
1831*a4128aadSBjoern A. Zeeb  * Find the DMA address that corresponds to the SKB payload data at the
1832*a4128aadSBjoern A. Zeeb  * position given by @offset.
1833*a4128aadSBjoern A. Zeeb  *
1834*a4128aadSBjoern A. Zeeb  * Returns: Address for TB entry
1835*a4128aadSBjoern A. Zeeb  */
1836*a4128aadSBjoern A. Zeeb dma_addr_t iwl_pcie_get_sgt_tb_phys(struct sg_table *sgt, unsigned int offset,
1837*a4128aadSBjoern A. Zeeb 				    unsigned int len)
1838*a4128aadSBjoern A. Zeeb {
1839*a4128aadSBjoern A. Zeeb 	struct scatterlist *sg;
1840*a4128aadSBjoern A. Zeeb 	unsigned int sg_offset = 0;
1841*a4128aadSBjoern A. Zeeb 	int i;
1842*a4128aadSBjoern A. Zeeb 
1843*a4128aadSBjoern A. Zeeb 	/*
1844*a4128aadSBjoern A. Zeeb 	 * Search the mapped DMA areas in the SG for the area that contains the
1845*a4128aadSBjoern A. Zeeb 	 * data at offset with the given length.
1846*a4128aadSBjoern A. Zeeb 	 */
1847*a4128aadSBjoern A. Zeeb 	for_each_sgtable_dma_sg(sgt, sg, i) {
1848*a4128aadSBjoern A. Zeeb 		if (offset >= sg_offset &&
1849*a4128aadSBjoern A. Zeeb 		    offset + len <= sg_offset + sg_dma_len(sg))
1850*a4128aadSBjoern A. Zeeb 			return sg_dma_address(sg) + offset - sg_offset;
1851*a4128aadSBjoern A. Zeeb 
1852*a4128aadSBjoern A. Zeeb 		sg_offset += sg_dma_len(sg);
1853*a4128aadSBjoern A. Zeeb 	}
1854*a4128aadSBjoern A. Zeeb 
1855*a4128aadSBjoern A. Zeeb 	WARN_ON_ONCE(1);
1856*a4128aadSBjoern A. Zeeb 
1857*a4128aadSBjoern A. Zeeb 	return DMA_MAPPING_ERROR;
1858*a4128aadSBjoern A. Zeeb }
1859*a4128aadSBjoern A. Zeeb 
1860*a4128aadSBjoern A. Zeeb /**
1861*a4128aadSBjoern A. Zeeb  * iwl_pcie_prep_tso - Prepare TSO page and SKB for sending
1862*a4128aadSBjoern A. Zeeb  * @trans: transport private data
1863*a4128aadSBjoern A. Zeeb  * @skb: the SKB to map
1864*a4128aadSBjoern A. Zeeb  * @cmd_meta: command meta to store the scatter list information for unmapping
1865*a4128aadSBjoern A. Zeeb  * @hdr: output argument for TSO headers
1866*a4128aadSBjoern A. Zeeb  * @hdr_room: requested length for TSO headers
1867*a4128aadSBjoern A. Zeeb  *
1868*a4128aadSBjoern A. Zeeb  * Allocate space for a scatter gather list and TSO headers and map the SKB
1869*a4128aadSBjoern A. Zeeb  * using the scatter gather list. The SKB is unmapped again when the page is
1870*a4128aadSBjoern A. Zeeb  * free'ed again at the end of the operation.
1871*a4128aadSBjoern A. Zeeb  *
1872*a4128aadSBjoern A. Zeeb  * Returns: newly allocated and mapped scatter gather table with list
1873*a4128aadSBjoern A. Zeeb  */
1874*a4128aadSBjoern A. Zeeb struct sg_table *iwl_pcie_prep_tso(struct iwl_trans *trans, struct sk_buff *skb,
1875*a4128aadSBjoern A. Zeeb 				   struct iwl_cmd_meta *cmd_meta,
1876*a4128aadSBjoern A. Zeeb 				   u8 **hdr, unsigned int hdr_room)
1877*a4128aadSBjoern A. Zeeb {
1878*a4128aadSBjoern A. Zeeb 	struct sg_table *sgt;
1879*a4128aadSBjoern A. Zeeb 
1880*a4128aadSBjoern A. Zeeb 	if (WARN_ON_ONCE(skb_has_frag_list(skb)))
1881*a4128aadSBjoern A. Zeeb 		return NULL;
1882*a4128aadSBjoern A. Zeeb 
1883*a4128aadSBjoern A. Zeeb 	*hdr = iwl_pcie_get_page_hdr(trans,
1884*a4128aadSBjoern A. Zeeb 				     hdr_room + __alignof__(struct sg_table) +
1885*a4128aadSBjoern A. Zeeb 				     sizeof(struct sg_table) +
1886*a4128aadSBjoern A. Zeeb 				     (skb_shinfo(skb)->nr_frags + 1) *
1887*a4128aadSBjoern A. Zeeb 				     sizeof(struct scatterlist),
1888*a4128aadSBjoern A. Zeeb 				     skb);
1889*a4128aadSBjoern A. Zeeb 	if (!*hdr)
1890*a4128aadSBjoern A. Zeeb 		return NULL;
1891*a4128aadSBjoern A. Zeeb 
1892*a4128aadSBjoern A. Zeeb 	sgt = (void *)PTR_ALIGN(*hdr + hdr_room, __alignof__(struct sg_table));
1893*a4128aadSBjoern A. Zeeb 	sgt->sgl = (void *)(sgt + 1);
1894*a4128aadSBjoern A. Zeeb 
1895*a4128aadSBjoern A. Zeeb 	sg_init_table(sgt->sgl, skb_shinfo(skb)->nr_frags + 1);
1896*a4128aadSBjoern A. Zeeb 
1897*a4128aadSBjoern A. Zeeb 	/* Only map the data, not the header (it is copied to the TSO page) */
1898*a4128aadSBjoern A. Zeeb 	sgt->orig_nents = skb_to_sgvec(skb, sgt->sgl, skb_headlen(skb),
1899*a4128aadSBjoern A. Zeeb 				       skb->data_len);
1900*a4128aadSBjoern A. Zeeb 	if (WARN_ON_ONCE(sgt->orig_nents <= 0))
1901*a4128aadSBjoern A. Zeeb 		return NULL;
1902*a4128aadSBjoern A. Zeeb 
1903*a4128aadSBjoern A. Zeeb 	/* And map the entire SKB */
1904*a4128aadSBjoern A. Zeeb 	if (dma_map_sgtable(trans->dev, sgt, DMA_TO_DEVICE, 0) < 0)
1905*a4128aadSBjoern A. Zeeb 		return NULL;
1906*a4128aadSBjoern A. Zeeb 
1907*a4128aadSBjoern A. Zeeb 	/* Store non-zero (i.e. valid) offset for unmapping */
1908*a4128aadSBjoern A. Zeeb 	cmd_meta->sg_offset = (unsigned long) sgt & ~PAGE_MASK;
1909*a4128aadSBjoern A. Zeeb 
1910*a4128aadSBjoern A. Zeeb 	return sgt;
1911*a4128aadSBjoern A. Zeeb }
1912*a4128aadSBjoern A. Zeeb 
1913bfcc09ddSBjoern A. Zeeb static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb,
1914bfcc09ddSBjoern A. Zeeb 				   struct iwl_txq *txq, u8 hdr_len,
1915bfcc09ddSBjoern A. Zeeb 				   struct iwl_cmd_meta *out_meta,
1916bfcc09ddSBjoern A. Zeeb 				   struct iwl_device_tx_cmd *dev_cmd,
1917bfcc09ddSBjoern A. Zeeb 				   u16 tb1_len)
1918bfcc09ddSBjoern A. Zeeb {
1919*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1920bfcc09ddSBjoern A. Zeeb 	struct iwl_tx_cmd *tx_cmd = (void *)dev_cmd->payload;
1921bfcc09ddSBjoern A. Zeeb 	struct ieee80211_hdr *hdr = (void *)skb->data;
1922bfcc09ddSBjoern A. Zeeb 	unsigned int snap_ip_tcp_hdrlen, ip_hdrlen, total_len, hdr_room;
1923bfcc09ddSBjoern A. Zeeb 	unsigned int mss = skb_shinfo(skb)->gso_size;
1924*a4128aadSBjoern A. Zeeb 	unsigned int data_offset = 0;
1925bfcc09ddSBjoern A. Zeeb 	u16 length, iv_len, amsdu_pad;
1926*a4128aadSBjoern A. Zeeb 	dma_addr_t start_hdr_phys;
1927*a4128aadSBjoern A. Zeeb 	u8 *start_hdr, *pos_hdr;
1928*a4128aadSBjoern A. Zeeb 	struct sg_table *sgt;
1929bfcc09ddSBjoern A. Zeeb 	struct tso_t tso;
1930bfcc09ddSBjoern A. Zeeb 
1931bfcc09ddSBjoern A. Zeeb 	/* if the packet is protected, then it must be CCMP or GCMP */
1932bfcc09ddSBjoern A. Zeeb 	BUILD_BUG_ON(IEEE80211_CCMP_HDR_LEN != IEEE80211_GCMP_HDR_LEN);
1933bfcc09ddSBjoern A. Zeeb 	iv_len = ieee80211_has_protected(hdr->frame_control) ?
1934bfcc09ddSBjoern A. Zeeb 		IEEE80211_CCMP_HDR_LEN : 0;
1935bfcc09ddSBjoern A. Zeeb 
1936bfcc09ddSBjoern A. Zeeb 	trace_iwlwifi_dev_tx(trans->dev, skb,
1937bfcc09ddSBjoern A. Zeeb 			     iwl_txq_get_tfd(trans, txq, txq->write_ptr),
1938*a4128aadSBjoern A. Zeeb 			     trans_pcie->txqs.tfd.size,
1939bfcc09ddSBjoern A. Zeeb 			     &dev_cmd->hdr, IWL_FIRST_TB_SIZE + tb1_len, 0);
1940bfcc09ddSBjoern A. Zeeb 
1941*a4128aadSBjoern A. Zeeb 	ip_hdrlen = skb_network_header_len(skb);
1942bfcc09ddSBjoern A. Zeeb 	snap_ip_tcp_hdrlen = 8 + ip_hdrlen + tcp_hdrlen(skb);
1943bfcc09ddSBjoern A. Zeeb 	total_len = skb->len - snap_ip_tcp_hdrlen - hdr_len - iv_len;
1944bfcc09ddSBjoern A. Zeeb 	amsdu_pad = 0;
1945bfcc09ddSBjoern A. Zeeb 
1946bfcc09ddSBjoern A. Zeeb 	/* total amount of header we may need for this A-MSDU */
1947bfcc09ddSBjoern A. Zeeb 	hdr_room = DIV_ROUND_UP(total_len, mss) *
1948bfcc09ddSBjoern A. Zeeb 		(3 + snap_ip_tcp_hdrlen + sizeof(struct ethhdr)) + iv_len;
1949bfcc09ddSBjoern A. Zeeb 
1950bfcc09ddSBjoern A. Zeeb 	/* Our device supports 9 segments at most, it will fit in 1 page */
1951*a4128aadSBjoern A. Zeeb 	sgt = iwl_pcie_prep_tso(trans, skb, out_meta, &start_hdr, hdr_room);
1952*a4128aadSBjoern A. Zeeb 	if (!sgt)
1953bfcc09ddSBjoern A. Zeeb 		return -ENOMEM;
1954bfcc09ddSBjoern A. Zeeb 
1955*a4128aadSBjoern A. Zeeb 	start_hdr_phys = iwl_pcie_get_tso_page_phys(start_hdr);
1956*a4128aadSBjoern A. Zeeb 	pos_hdr = start_hdr;
1957*a4128aadSBjoern A. Zeeb 	memcpy(pos_hdr, skb->data + hdr_len, iv_len);
1958*a4128aadSBjoern A. Zeeb 	pos_hdr += iv_len;
1959bfcc09ddSBjoern A. Zeeb 
1960bfcc09ddSBjoern A. Zeeb 	/*
1961bfcc09ddSBjoern A. Zeeb 	 * Pull the ieee80211 header + IV to be able to use TSO core,
1962bfcc09ddSBjoern A. Zeeb 	 * we will restore it for the tx_status flow.
1963bfcc09ddSBjoern A. Zeeb 	 */
1964bfcc09ddSBjoern A. Zeeb 	skb_pull(skb, hdr_len + iv_len);
1965bfcc09ddSBjoern A. Zeeb 
1966bfcc09ddSBjoern A. Zeeb 	/*
1967bfcc09ddSBjoern A. Zeeb 	 * Remove the length of all the headers that we don't actually
1968bfcc09ddSBjoern A. Zeeb 	 * have in the MPDU by themselves, but that we duplicate into
1969bfcc09ddSBjoern A. Zeeb 	 * all the different MSDUs inside the A-MSDU.
1970bfcc09ddSBjoern A. Zeeb 	 */
1971bfcc09ddSBjoern A. Zeeb 	le16_add_cpu(&tx_cmd->len, -snap_ip_tcp_hdrlen);
1972bfcc09ddSBjoern A. Zeeb 
1973bfcc09ddSBjoern A. Zeeb 	tso_start(skb, &tso);
1974bfcc09ddSBjoern A. Zeeb 
1975bfcc09ddSBjoern A. Zeeb 	while (total_len) {
1976bfcc09ddSBjoern A. Zeeb 		/* this is the data left for this subframe */
1977bfcc09ddSBjoern A. Zeeb 		unsigned int data_left =
1978bfcc09ddSBjoern A. Zeeb 			min_t(unsigned int, mss, total_len);
1979bfcc09ddSBjoern A. Zeeb 		unsigned int hdr_tb_len;
1980bfcc09ddSBjoern A. Zeeb 		dma_addr_t hdr_tb_phys;
1981*a4128aadSBjoern A. Zeeb 		u8 *subf_hdrs_start = pos_hdr;
1982bfcc09ddSBjoern A. Zeeb 
1983bfcc09ddSBjoern A. Zeeb 		total_len -= data_left;
1984bfcc09ddSBjoern A. Zeeb 
1985*a4128aadSBjoern A. Zeeb 		memset(pos_hdr, 0, amsdu_pad);
1986*a4128aadSBjoern A. Zeeb 		pos_hdr += amsdu_pad;
1987bfcc09ddSBjoern A. Zeeb 		amsdu_pad = (4 - (sizeof(struct ethhdr) + snap_ip_tcp_hdrlen +
1988bfcc09ddSBjoern A. Zeeb 				  data_left)) & 0x3;
1989*a4128aadSBjoern A. Zeeb 		ether_addr_copy(pos_hdr, ieee80211_get_DA(hdr));
1990*a4128aadSBjoern A. Zeeb 		pos_hdr += ETH_ALEN;
1991*a4128aadSBjoern A. Zeeb 		ether_addr_copy(pos_hdr, ieee80211_get_SA(hdr));
1992*a4128aadSBjoern A. Zeeb 		pos_hdr += ETH_ALEN;
1993bfcc09ddSBjoern A. Zeeb 
1994bfcc09ddSBjoern A. Zeeb 		length = snap_ip_tcp_hdrlen + data_left;
1995*a4128aadSBjoern A. Zeeb 		*((__be16 *)pos_hdr) = cpu_to_be16(length);
1996*a4128aadSBjoern A. Zeeb 		pos_hdr += sizeof(length);
1997bfcc09ddSBjoern A. Zeeb 
1998bfcc09ddSBjoern A. Zeeb 		/*
1999bfcc09ddSBjoern A. Zeeb 		 * This will copy the SNAP as well which will be considered
2000bfcc09ddSBjoern A. Zeeb 		 * as MAC header.
2001bfcc09ddSBjoern A. Zeeb 		 */
2002*a4128aadSBjoern A. Zeeb 		tso_build_hdr(skb, pos_hdr, &tso, data_left, !total_len);
2003bfcc09ddSBjoern A. Zeeb 
2004*a4128aadSBjoern A. Zeeb 		pos_hdr += snap_ip_tcp_hdrlen;
2005bfcc09ddSBjoern A. Zeeb 
2006*a4128aadSBjoern A. Zeeb 		hdr_tb_len = pos_hdr - start_hdr;
2007*a4128aadSBjoern A. Zeeb 		hdr_tb_phys = iwl_pcie_get_tso_page_phys(start_hdr);
2008*a4128aadSBjoern A. Zeeb 
2009bfcc09ddSBjoern A. Zeeb 		iwl_pcie_txq_build_tfd(trans, txq, hdr_tb_phys,
2010bfcc09ddSBjoern A. Zeeb 				       hdr_tb_len, false);
2011bfcc09ddSBjoern A. Zeeb 		trace_iwlwifi_dev_tx_tb(trans->dev, skb, start_hdr,
2012bfcc09ddSBjoern A. Zeeb 					hdr_tb_phys, hdr_tb_len);
2013bfcc09ddSBjoern A. Zeeb 		/* add this subframe's headers' length to the tx_cmd */
2014*a4128aadSBjoern A. Zeeb 		le16_add_cpu(&tx_cmd->len, pos_hdr - subf_hdrs_start);
2015bfcc09ddSBjoern A. Zeeb 
2016bfcc09ddSBjoern A. Zeeb 		/* prepare the start_hdr for the next subframe */
2017*a4128aadSBjoern A. Zeeb 		start_hdr = pos_hdr;
2018bfcc09ddSBjoern A. Zeeb 
2019bfcc09ddSBjoern A. Zeeb 		/* put the payload */
2020bfcc09ddSBjoern A. Zeeb 		while (data_left) {
2021bfcc09ddSBjoern A. Zeeb 			unsigned int size = min_t(unsigned int, tso.size,
2022bfcc09ddSBjoern A. Zeeb 						  data_left);
2023bfcc09ddSBjoern A. Zeeb 			dma_addr_t tb_phys;
2024bfcc09ddSBjoern A. Zeeb 
2025*a4128aadSBjoern A. Zeeb 			tb_phys = iwl_pcie_get_sgt_tb_phys(sgt, data_offset, size);
2026*a4128aadSBjoern A. Zeeb 			/* Not a real mapping error, use direct comparison */
2027*a4128aadSBjoern A. Zeeb 			if (unlikely(tb_phys == DMA_MAPPING_ERROR))
2028bfcc09ddSBjoern A. Zeeb 				return -EINVAL;
2029bfcc09ddSBjoern A. Zeeb 
2030bfcc09ddSBjoern A. Zeeb 			iwl_pcie_txq_build_tfd(trans, txq, tb_phys,
2031bfcc09ddSBjoern A. Zeeb 					       size, false);
2032bfcc09ddSBjoern A. Zeeb 			trace_iwlwifi_dev_tx_tb(trans->dev, skb, tso.data,
2033bfcc09ddSBjoern A. Zeeb 						tb_phys, size);
2034bfcc09ddSBjoern A. Zeeb 
2035bfcc09ddSBjoern A. Zeeb 			data_left -= size;
2036*a4128aadSBjoern A. Zeeb 			data_offset += size;
2037bfcc09ddSBjoern A. Zeeb 			tso_build_data(skb, &tso, size);
2038bfcc09ddSBjoern A. Zeeb 		}
2039bfcc09ddSBjoern A. Zeeb 	}
2040bfcc09ddSBjoern A. Zeeb 
2041*a4128aadSBjoern A. Zeeb 	dma_sync_single_for_device(trans->dev, start_hdr_phys, hdr_room,
2042*a4128aadSBjoern A. Zeeb 				   DMA_TO_DEVICE);
2043*a4128aadSBjoern A. Zeeb 
2044bfcc09ddSBjoern A. Zeeb 	/* re -add the WiFi header and IV */
2045bfcc09ddSBjoern A. Zeeb 	skb_push(skb, hdr_len + iv_len);
2046bfcc09ddSBjoern A. Zeeb 
2047bfcc09ddSBjoern A. Zeeb 	return 0;
2048bfcc09ddSBjoern A. Zeeb }
2049bfcc09ddSBjoern A. Zeeb #else /* CONFIG_INET */
2050bfcc09ddSBjoern A. Zeeb static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb,
2051bfcc09ddSBjoern A. Zeeb 				   struct iwl_txq *txq, u8 hdr_len,
2052bfcc09ddSBjoern A. Zeeb 				   struct iwl_cmd_meta *out_meta,
2053bfcc09ddSBjoern A. Zeeb 				   struct iwl_device_tx_cmd *dev_cmd,
2054bfcc09ddSBjoern A. Zeeb 				   u16 tb1_len)
2055bfcc09ddSBjoern A. Zeeb {
2056bfcc09ddSBjoern A. Zeeb 	/* No A-MSDU without CONFIG_INET */
2057bfcc09ddSBjoern A. Zeeb 	WARN_ON(1);
2058bfcc09ddSBjoern A. Zeeb 
2059bfcc09ddSBjoern A. Zeeb 	return -1;
2060bfcc09ddSBjoern A. Zeeb }
2061bfcc09ddSBjoern A. Zeeb #endif /* CONFIG_INET */
2062bfcc09ddSBjoern A. Zeeb 
2063*a4128aadSBjoern A. Zeeb #define IWL_TX_CRC_SIZE 4
2064*a4128aadSBjoern A. Zeeb #define IWL_TX_DELIMITER_SIZE 4
2065*a4128aadSBjoern A. Zeeb 
2066*a4128aadSBjoern A. Zeeb /*
2067*a4128aadSBjoern A. Zeeb  * iwl_txq_gen1_update_byte_cnt_tbl - Set up entry in Tx byte-count array
2068*a4128aadSBjoern A. Zeeb  */
2069*a4128aadSBjoern A. Zeeb static void iwl_txq_gen1_update_byte_cnt_tbl(struct iwl_trans *trans,
2070*a4128aadSBjoern A. Zeeb 					     struct iwl_txq *txq, u16 byte_cnt,
2071*a4128aadSBjoern A. Zeeb 					     int num_tbs)
2072*a4128aadSBjoern A. Zeeb {
2073*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
2074*a4128aadSBjoern A. Zeeb 	struct iwlagn_scd_bc_tbl *scd_bc_tbl;
2075*a4128aadSBjoern A. Zeeb 	int write_ptr = txq->write_ptr;
2076*a4128aadSBjoern A. Zeeb 	int txq_id = txq->id;
2077*a4128aadSBjoern A. Zeeb 	u8 sec_ctl = 0;
2078*a4128aadSBjoern A. Zeeb 	u16 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
2079*a4128aadSBjoern A. Zeeb 	__le16 bc_ent;
2080*a4128aadSBjoern A. Zeeb 	struct iwl_device_tx_cmd *dev_cmd = txq->entries[txq->write_ptr].cmd;
2081*a4128aadSBjoern A. Zeeb 	struct iwl_tx_cmd *tx_cmd = (void *)dev_cmd->payload;
2082*a4128aadSBjoern A. Zeeb 	u8 sta_id = tx_cmd->sta_id;
2083*a4128aadSBjoern A. Zeeb 
2084*a4128aadSBjoern A. Zeeb 	scd_bc_tbl = trans_pcie->txqs.scd_bc_tbls.addr;
2085*a4128aadSBjoern A. Zeeb 
2086*a4128aadSBjoern A. Zeeb 	sec_ctl = tx_cmd->sec_ctl;
2087*a4128aadSBjoern A. Zeeb 
2088*a4128aadSBjoern A. Zeeb 	switch (sec_ctl & TX_CMD_SEC_MSK) {
2089*a4128aadSBjoern A. Zeeb 	case TX_CMD_SEC_CCM:
2090*a4128aadSBjoern A. Zeeb 		len += IEEE80211_CCMP_MIC_LEN;
2091*a4128aadSBjoern A. Zeeb 		break;
2092*a4128aadSBjoern A. Zeeb 	case TX_CMD_SEC_TKIP:
2093*a4128aadSBjoern A. Zeeb 		len += IEEE80211_TKIP_ICV_LEN;
2094*a4128aadSBjoern A. Zeeb 		break;
2095*a4128aadSBjoern A. Zeeb 	case TX_CMD_SEC_WEP:
2096*a4128aadSBjoern A. Zeeb 		len += IEEE80211_WEP_IV_LEN + IEEE80211_WEP_ICV_LEN;
2097*a4128aadSBjoern A. Zeeb 		break;
2098*a4128aadSBjoern A. Zeeb 	}
2099*a4128aadSBjoern A. Zeeb 	if (trans_pcie->txqs.bc_table_dword)
2100*a4128aadSBjoern A. Zeeb 		len = DIV_ROUND_UP(len, 4);
2101*a4128aadSBjoern A. Zeeb 
2102*a4128aadSBjoern A. Zeeb 	if (WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX))
2103*a4128aadSBjoern A. Zeeb 		return;
2104*a4128aadSBjoern A. Zeeb 
2105*a4128aadSBjoern A. Zeeb 	bc_ent = cpu_to_le16(len | (sta_id << 12));
2106*a4128aadSBjoern A. Zeeb 
2107*a4128aadSBjoern A. Zeeb 	scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
2108*a4128aadSBjoern A. Zeeb 
2109*a4128aadSBjoern A. Zeeb 	if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
2110*a4128aadSBjoern A. Zeeb 		scd_bc_tbl[txq_id].tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] =
2111*a4128aadSBjoern A. Zeeb 			bc_ent;
2112*a4128aadSBjoern A. Zeeb }
2113*a4128aadSBjoern A. Zeeb 
2114bfcc09ddSBjoern A. Zeeb int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
2115bfcc09ddSBjoern A. Zeeb 		      struct iwl_device_tx_cmd *dev_cmd, int txq_id)
2116bfcc09ddSBjoern A. Zeeb {
2117*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
2118bfcc09ddSBjoern A. Zeeb 	struct ieee80211_hdr *hdr;
2119bfcc09ddSBjoern A. Zeeb 	struct iwl_tx_cmd *tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload;
2120bfcc09ddSBjoern A. Zeeb 	struct iwl_cmd_meta *out_meta;
2121bfcc09ddSBjoern A. Zeeb 	struct iwl_txq *txq;
2122bfcc09ddSBjoern A. Zeeb 	dma_addr_t tb0_phys, tb1_phys, scratch_phys;
2123bfcc09ddSBjoern A. Zeeb 	void *tb1_addr;
2124bfcc09ddSBjoern A. Zeeb 	void *tfd;
2125bfcc09ddSBjoern A. Zeeb 	u16 len, tb1_len;
2126bfcc09ddSBjoern A. Zeeb 	bool wait_write_ptr;
2127bfcc09ddSBjoern A. Zeeb 	__le16 fc;
2128bfcc09ddSBjoern A. Zeeb 	u8 hdr_len;
2129bfcc09ddSBjoern A. Zeeb 	u16 wifi_seq;
2130bfcc09ddSBjoern A. Zeeb 	bool amsdu;
2131bfcc09ddSBjoern A. Zeeb 
2132*a4128aadSBjoern A. Zeeb 	txq = trans_pcie->txqs.txq[txq_id];
2133bfcc09ddSBjoern A. Zeeb 
2134*a4128aadSBjoern A. Zeeb 	if (WARN_ONCE(!test_bit(txq_id, trans_pcie->txqs.queue_used),
2135bfcc09ddSBjoern A. Zeeb 		      "TX on unused queue %d\n", txq_id))
2136bfcc09ddSBjoern A. Zeeb 		return -EINVAL;
2137bfcc09ddSBjoern A. Zeeb 
2138bfcc09ddSBjoern A. Zeeb 	if (skb_is_nonlinear(skb) &&
2139*a4128aadSBjoern A. Zeeb 	    skb_shinfo(skb)->nr_frags > IWL_TRANS_PCIE_MAX_FRAGS(trans_pcie) &&
2140bfcc09ddSBjoern A. Zeeb 	    __skb_linearize(skb))
2141bfcc09ddSBjoern A. Zeeb 		return -ENOMEM;
2142bfcc09ddSBjoern A. Zeeb 
2143bfcc09ddSBjoern A. Zeeb 	/* mac80211 always puts the full header into the SKB's head,
2144bfcc09ddSBjoern A. Zeeb 	 * so there's no need to check if it's readable there
2145bfcc09ddSBjoern A. Zeeb 	 */
2146bfcc09ddSBjoern A. Zeeb 	hdr = (struct ieee80211_hdr *)skb->data;
2147bfcc09ddSBjoern A. Zeeb 	fc = hdr->frame_control;
2148bfcc09ddSBjoern A. Zeeb 	hdr_len = ieee80211_hdrlen(fc);
2149bfcc09ddSBjoern A. Zeeb 
2150bfcc09ddSBjoern A. Zeeb 	spin_lock(&txq->lock);
2151bfcc09ddSBjoern A. Zeeb 
2152bfcc09ddSBjoern A. Zeeb 	if (iwl_txq_space(trans, txq) < txq->high_mark) {
2153bfcc09ddSBjoern A. Zeeb 		iwl_txq_stop(trans, txq);
2154bfcc09ddSBjoern A. Zeeb 
2155bfcc09ddSBjoern A. Zeeb 		/* don't put the packet on the ring, if there is no room */
2156bfcc09ddSBjoern A. Zeeb 		if (unlikely(iwl_txq_space(trans, txq) < 3)) {
2157bfcc09ddSBjoern A. Zeeb 			struct iwl_device_tx_cmd **dev_cmd_ptr;
2158bfcc09ddSBjoern A. Zeeb 
2159bfcc09ddSBjoern A. Zeeb 			dev_cmd_ptr = (void *)((u8 *)skb->cb +
2160*a4128aadSBjoern A. Zeeb 					       trans_pcie->txqs.dev_cmd_offs);
2161bfcc09ddSBjoern A. Zeeb 
2162bfcc09ddSBjoern A. Zeeb 			*dev_cmd_ptr = dev_cmd;
2163bfcc09ddSBjoern A. Zeeb 			__skb_queue_tail(&txq->overflow_q, skb);
2164bfcc09ddSBjoern A. Zeeb 
2165bfcc09ddSBjoern A. Zeeb 			spin_unlock(&txq->lock);
2166bfcc09ddSBjoern A. Zeeb 			return 0;
2167bfcc09ddSBjoern A. Zeeb 		}
2168bfcc09ddSBjoern A. Zeeb 	}
2169bfcc09ddSBjoern A. Zeeb 
2170bfcc09ddSBjoern A. Zeeb 	/* In AGG mode, the index in the ring must correspond to the WiFi
2171bfcc09ddSBjoern A. Zeeb 	 * sequence number. This is a HW requirements to help the SCD to parse
2172bfcc09ddSBjoern A. Zeeb 	 * the BA.
2173bfcc09ddSBjoern A. Zeeb 	 * Check here that the packets are in the right place on the ring.
2174bfcc09ddSBjoern A. Zeeb 	 */
2175bfcc09ddSBjoern A. Zeeb 	wifi_seq = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
2176bfcc09ddSBjoern A. Zeeb 	WARN_ONCE(txq->ampdu &&
2177bfcc09ddSBjoern A. Zeeb 		  (wifi_seq & 0xff) != txq->write_ptr,
2178bfcc09ddSBjoern A. Zeeb 		  "Q: %d WiFi Seq %d tfdNum %d",
2179bfcc09ddSBjoern A. Zeeb 		  txq_id, wifi_seq, txq->write_ptr);
2180bfcc09ddSBjoern A. Zeeb 
2181bfcc09ddSBjoern A. Zeeb 	/* Set up driver data for this TFD */
2182bfcc09ddSBjoern A. Zeeb 	txq->entries[txq->write_ptr].skb = skb;
2183bfcc09ddSBjoern A. Zeeb 	txq->entries[txq->write_ptr].cmd = dev_cmd;
2184bfcc09ddSBjoern A. Zeeb 
2185bfcc09ddSBjoern A. Zeeb 	dev_cmd->hdr.sequence =
2186bfcc09ddSBjoern A. Zeeb 		cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
2187bfcc09ddSBjoern A. Zeeb 			    INDEX_TO_SEQ(txq->write_ptr)));
2188bfcc09ddSBjoern A. Zeeb 
2189bfcc09ddSBjoern A. Zeeb 	tb0_phys = iwl_txq_get_first_tb_dma(txq, txq->write_ptr);
2190bfcc09ddSBjoern A. Zeeb 	scratch_phys = tb0_phys + sizeof(struct iwl_cmd_header) +
2191bfcc09ddSBjoern A. Zeeb 		       offsetof(struct iwl_tx_cmd, scratch);
2192bfcc09ddSBjoern A. Zeeb 
2193bfcc09ddSBjoern A. Zeeb 	tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
2194bfcc09ddSBjoern A. Zeeb 	tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
2195bfcc09ddSBjoern A. Zeeb 
2196bfcc09ddSBjoern A. Zeeb 	/* Set up first empty entry in queue's array of Tx/cmd buffers */
2197bfcc09ddSBjoern A. Zeeb 	out_meta = &txq->entries[txq->write_ptr].meta;
2198*a4128aadSBjoern A. Zeeb 	memset(out_meta, 0, sizeof(*out_meta));
2199bfcc09ddSBjoern A. Zeeb 
2200bfcc09ddSBjoern A. Zeeb 	/*
2201bfcc09ddSBjoern A. Zeeb 	 * The second TB (tb1) points to the remainder of the TX command
2202bfcc09ddSBjoern A. Zeeb 	 * and the 802.11 header - dword aligned size
2203bfcc09ddSBjoern A. Zeeb 	 * (This calculation modifies the TX command, so do it before the
2204bfcc09ddSBjoern A. Zeeb 	 * setup of the first TB)
2205bfcc09ddSBjoern A. Zeeb 	 */
2206bfcc09ddSBjoern A. Zeeb 	len = sizeof(struct iwl_tx_cmd) + sizeof(struct iwl_cmd_header) +
2207bfcc09ddSBjoern A. Zeeb 	      hdr_len - IWL_FIRST_TB_SIZE;
2208bfcc09ddSBjoern A. Zeeb 	/* do not align A-MSDU to dword as the subframe header aligns it */
2209bfcc09ddSBjoern A. Zeeb 	amsdu = ieee80211_is_data_qos(fc) &&
2210bfcc09ddSBjoern A. Zeeb 		(*ieee80211_get_qos_ctl(hdr) &
2211bfcc09ddSBjoern A. Zeeb 		 IEEE80211_QOS_CTL_A_MSDU_PRESENT);
2212bfcc09ddSBjoern A. Zeeb 	if (!amsdu) {
2213bfcc09ddSBjoern A. Zeeb 		tb1_len = ALIGN(len, 4);
2214bfcc09ddSBjoern A. Zeeb 		/* Tell NIC about any 2-byte padding after MAC header */
2215bfcc09ddSBjoern A. Zeeb 		if (tb1_len != len)
2216bfcc09ddSBjoern A. Zeeb 			tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_MH_PAD);
2217bfcc09ddSBjoern A. Zeeb 	} else {
2218bfcc09ddSBjoern A. Zeeb 		tb1_len = len;
2219bfcc09ddSBjoern A. Zeeb 	}
2220bfcc09ddSBjoern A. Zeeb 
2221bfcc09ddSBjoern A. Zeeb 	/*
2222bfcc09ddSBjoern A. Zeeb 	 * The first TB points to bi-directional DMA data, we'll
2223bfcc09ddSBjoern A. Zeeb 	 * memcpy the data into it later.
2224bfcc09ddSBjoern A. Zeeb 	 */
2225bfcc09ddSBjoern A. Zeeb 	iwl_pcie_txq_build_tfd(trans, txq, tb0_phys,
2226bfcc09ddSBjoern A. Zeeb 			       IWL_FIRST_TB_SIZE, true);
2227bfcc09ddSBjoern A. Zeeb 
2228bfcc09ddSBjoern A. Zeeb 	/* there must be data left over for TB1 or this code must be changed */
2229bfcc09ddSBjoern A. Zeeb 	BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_FIRST_TB_SIZE);
22309af1bba4SBjoern A. Zeeb 	BUILD_BUG_ON(sizeof(struct iwl_cmd_header) +
22319af1bba4SBjoern A. Zeeb 		     offsetofend(struct iwl_tx_cmd, scratch) >
22329af1bba4SBjoern A. Zeeb 		     IWL_FIRST_TB_SIZE);
2233bfcc09ddSBjoern A. Zeeb 
2234bfcc09ddSBjoern A. Zeeb 	/* map the data for TB1 */
2235bfcc09ddSBjoern A. Zeeb 	tb1_addr = ((u8 *)&dev_cmd->hdr) + IWL_FIRST_TB_SIZE;
2236bfcc09ddSBjoern A. Zeeb 	tb1_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE);
2237bfcc09ddSBjoern A. Zeeb 	if (unlikely(dma_mapping_error(trans->dev, tb1_phys)))
2238bfcc09ddSBjoern A. Zeeb 		goto out_err;
2239bfcc09ddSBjoern A. Zeeb 	iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, false);
2240bfcc09ddSBjoern A. Zeeb 
2241bfcc09ddSBjoern A. Zeeb 	trace_iwlwifi_dev_tx(trans->dev, skb,
2242bfcc09ddSBjoern A. Zeeb 			     iwl_txq_get_tfd(trans, txq, txq->write_ptr),
2243*a4128aadSBjoern A. Zeeb 			     trans_pcie->txqs.tfd.size,
2244bfcc09ddSBjoern A. Zeeb 			     &dev_cmd->hdr, IWL_FIRST_TB_SIZE + tb1_len,
2245bfcc09ddSBjoern A. Zeeb 			     hdr_len);
2246bfcc09ddSBjoern A. Zeeb 
2247bfcc09ddSBjoern A. Zeeb 	/*
2248bfcc09ddSBjoern A. Zeeb 	 * If gso_size wasn't set, don't give the frame "amsdu treatment"
2249bfcc09ddSBjoern A. Zeeb 	 * (adding subframes, etc.).
2250bfcc09ddSBjoern A. Zeeb 	 * This can happen in some testing flows when the amsdu was already
2251bfcc09ddSBjoern A. Zeeb 	 * pre-built, and we just need to send the resulting skb.
2252bfcc09ddSBjoern A. Zeeb 	 */
2253bfcc09ddSBjoern A. Zeeb 	if (amsdu && skb_shinfo(skb)->gso_size) {
2254bfcc09ddSBjoern A. Zeeb 		if (unlikely(iwl_fill_data_tbs_amsdu(trans, skb, txq, hdr_len,
2255bfcc09ddSBjoern A. Zeeb 						     out_meta, dev_cmd,
2256bfcc09ddSBjoern A. Zeeb 						     tb1_len)))
2257bfcc09ddSBjoern A. Zeeb 			goto out_err;
2258bfcc09ddSBjoern A. Zeeb 	} else {
2259bfcc09ddSBjoern A. Zeeb 		struct sk_buff *frag;
2260bfcc09ddSBjoern A. Zeeb 
2261bfcc09ddSBjoern A. Zeeb 		if (unlikely(iwl_fill_data_tbs(trans, skb, txq, hdr_len,
2262bfcc09ddSBjoern A. Zeeb 					       out_meta)))
2263bfcc09ddSBjoern A. Zeeb 			goto out_err;
2264bfcc09ddSBjoern A. Zeeb 
2265bfcc09ddSBjoern A. Zeeb 		skb_walk_frags(skb, frag) {
2266bfcc09ddSBjoern A. Zeeb 			if (unlikely(iwl_fill_data_tbs(trans, frag, txq, 0,
2267bfcc09ddSBjoern A. Zeeb 						       out_meta)))
2268bfcc09ddSBjoern A. Zeeb 				goto out_err;
2269bfcc09ddSBjoern A. Zeeb 		}
2270bfcc09ddSBjoern A. Zeeb 	}
2271bfcc09ddSBjoern A. Zeeb 
2272bfcc09ddSBjoern A. Zeeb 	/* building the A-MSDU might have changed this data, so memcpy it now */
2273bfcc09ddSBjoern A. Zeeb 	memcpy(&txq->first_tb_bufs[txq->write_ptr], dev_cmd, IWL_FIRST_TB_SIZE);
2274bfcc09ddSBjoern A. Zeeb 
2275bfcc09ddSBjoern A. Zeeb 	tfd = iwl_txq_get_tfd(trans, txq, txq->write_ptr);
2276bfcc09ddSBjoern A. Zeeb 	/* Set up entry for this TFD in Tx byte-count array */
2277bfcc09ddSBjoern A. Zeeb 	iwl_txq_gen1_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len),
2278*a4128aadSBjoern A. Zeeb 					 iwl_txq_gen1_tfd_get_num_tbs(tfd));
2279bfcc09ddSBjoern A. Zeeb 
2280bfcc09ddSBjoern A. Zeeb 	wait_write_ptr = ieee80211_has_morefrags(fc);
2281bfcc09ddSBjoern A. Zeeb 
2282bfcc09ddSBjoern A. Zeeb 	/* start timer if queue currently empty */
2283bfcc09ddSBjoern A. Zeeb 	if (txq->read_ptr == txq->write_ptr && txq->wd_timeout) {
2284bfcc09ddSBjoern A. Zeeb 		/*
2285bfcc09ddSBjoern A. Zeeb 		 * If the TXQ is active, then set the timer, if not,
2286bfcc09ddSBjoern A. Zeeb 		 * set the timer in remainder so that the timer will
2287bfcc09ddSBjoern A. Zeeb 		 * be armed with the right value when the station will
2288bfcc09ddSBjoern A. Zeeb 		 * wake up.
2289bfcc09ddSBjoern A. Zeeb 		 */
2290bfcc09ddSBjoern A. Zeeb 		if (!txq->frozen)
2291bfcc09ddSBjoern A. Zeeb 			mod_timer(&txq->stuck_timer,
2292bfcc09ddSBjoern A. Zeeb 				  jiffies + txq->wd_timeout);
2293bfcc09ddSBjoern A. Zeeb 		else
2294bfcc09ddSBjoern A. Zeeb 			txq->frozen_expiry_remainder = txq->wd_timeout;
2295bfcc09ddSBjoern A. Zeeb 	}
2296bfcc09ddSBjoern A. Zeeb 
2297bfcc09ddSBjoern A. Zeeb 	/* Tell device the write index *just past* this latest filled TFD */
2298bfcc09ddSBjoern A. Zeeb 	txq->write_ptr = iwl_txq_inc_wrap(trans, txq->write_ptr);
2299bfcc09ddSBjoern A. Zeeb 	if (!wait_write_ptr)
2300bfcc09ddSBjoern A. Zeeb 		iwl_pcie_txq_inc_wr_ptr(trans, txq);
2301bfcc09ddSBjoern A. Zeeb 
2302bfcc09ddSBjoern A. Zeeb 	/*
2303bfcc09ddSBjoern A. Zeeb 	 * At this point the frame is "transmitted" successfully
2304bfcc09ddSBjoern A. Zeeb 	 * and we will get a TX status notification eventually.
2305bfcc09ddSBjoern A. Zeeb 	 */
2306bfcc09ddSBjoern A. Zeeb 	spin_unlock(&txq->lock);
2307bfcc09ddSBjoern A. Zeeb 	return 0;
2308bfcc09ddSBjoern A. Zeeb out_err:
2309bfcc09ddSBjoern A. Zeeb 	iwl_txq_gen1_tfd_unmap(trans, out_meta, txq, txq->write_ptr);
2310bfcc09ddSBjoern A. Zeeb 	spin_unlock(&txq->lock);
2311bfcc09ddSBjoern A. Zeeb 	return -1;
2312bfcc09ddSBjoern A. Zeeb }
2313*a4128aadSBjoern A. Zeeb 
2314*a4128aadSBjoern A. Zeeb static void iwl_txq_gen1_inval_byte_cnt_tbl(struct iwl_trans *trans,
2315*a4128aadSBjoern A. Zeeb 					    struct iwl_txq *txq,
2316*a4128aadSBjoern A. Zeeb 					    int read_ptr)
2317*a4128aadSBjoern A. Zeeb {
2318*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
2319*a4128aadSBjoern A. Zeeb 	struct iwlagn_scd_bc_tbl *scd_bc_tbl = trans_pcie->txqs.scd_bc_tbls.addr;
2320*a4128aadSBjoern A. Zeeb 	int txq_id = txq->id;
2321*a4128aadSBjoern A. Zeeb 	u8 sta_id = 0;
2322*a4128aadSBjoern A. Zeeb 	__le16 bc_ent;
2323*a4128aadSBjoern A. Zeeb 	struct iwl_device_tx_cmd *dev_cmd = txq->entries[read_ptr].cmd;
2324*a4128aadSBjoern A. Zeeb 	struct iwl_tx_cmd *tx_cmd = (void *)dev_cmd->payload;
2325*a4128aadSBjoern A. Zeeb 
2326*a4128aadSBjoern A. Zeeb 	WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);
2327*a4128aadSBjoern A. Zeeb 
2328*a4128aadSBjoern A. Zeeb 	if (txq_id != trans_pcie->txqs.cmd.q_id)
2329*a4128aadSBjoern A. Zeeb 		sta_id = tx_cmd->sta_id;
2330*a4128aadSBjoern A. Zeeb 
2331*a4128aadSBjoern A. Zeeb 	bc_ent = cpu_to_le16(1 | (sta_id << 12));
2332*a4128aadSBjoern A. Zeeb 
2333*a4128aadSBjoern A. Zeeb 	scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
2334*a4128aadSBjoern A. Zeeb 
2335*a4128aadSBjoern A. Zeeb 	if (read_ptr < TFD_QUEUE_SIZE_BC_DUP)
2336*a4128aadSBjoern A. Zeeb 		scd_bc_tbl[txq_id].tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] =
2337*a4128aadSBjoern A. Zeeb 			bc_ent;
2338*a4128aadSBjoern A. Zeeb }
2339*a4128aadSBjoern A. Zeeb 
2340*a4128aadSBjoern A. Zeeb /* Frees buffers until index _not_ inclusive */
2341*a4128aadSBjoern A. Zeeb void iwl_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
2342*a4128aadSBjoern A. Zeeb 		      struct sk_buff_head *skbs, bool is_flush)
2343*a4128aadSBjoern A. Zeeb {
2344*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
2345*a4128aadSBjoern A. Zeeb 	struct iwl_txq *txq = trans_pcie->txqs.txq[txq_id];
2346*a4128aadSBjoern A. Zeeb 	int tfd_num, read_ptr, last_to_free;
2347*a4128aadSBjoern A. Zeeb 	int txq_read_ptr, txq_write_ptr;
2348*a4128aadSBjoern A. Zeeb 
2349*a4128aadSBjoern A. Zeeb 	/* This function is not meant to release cmd queue*/
2350*a4128aadSBjoern A. Zeeb 	if (WARN_ON(txq_id == trans_pcie->txqs.cmd.q_id))
2351*a4128aadSBjoern A. Zeeb 		return;
2352*a4128aadSBjoern A. Zeeb 
2353*a4128aadSBjoern A. Zeeb 	if (WARN_ON(!txq))
2354*a4128aadSBjoern A. Zeeb 		return;
2355*a4128aadSBjoern A. Zeeb 
2356*a4128aadSBjoern A. Zeeb 	tfd_num = iwl_txq_get_cmd_index(txq, ssn);
2357*a4128aadSBjoern A. Zeeb 
2358*a4128aadSBjoern A. Zeeb 	spin_lock_bh(&txq->reclaim_lock);
2359*a4128aadSBjoern A. Zeeb 
2360*a4128aadSBjoern A. Zeeb 	spin_lock(&txq->lock);
2361*a4128aadSBjoern A. Zeeb 	txq_read_ptr = txq->read_ptr;
2362*a4128aadSBjoern A. Zeeb 	txq_write_ptr = txq->write_ptr;
2363*a4128aadSBjoern A. Zeeb 	spin_unlock(&txq->lock);
2364*a4128aadSBjoern A. Zeeb 
2365*a4128aadSBjoern A. Zeeb 	read_ptr = iwl_txq_get_cmd_index(txq, txq_read_ptr);
2366*a4128aadSBjoern A. Zeeb 
2367*a4128aadSBjoern A. Zeeb 	if (!test_bit(txq_id, trans_pcie->txqs.queue_used)) {
2368*a4128aadSBjoern A. Zeeb 		IWL_DEBUG_TX_QUEUES(trans, "Q %d inactive - ignoring idx %d\n",
2369*a4128aadSBjoern A. Zeeb 				    txq_id, ssn);
2370*a4128aadSBjoern A. Zeeb 		goto out;
2371*a4128aadSBjoern A. Zeeb 	}
2372*a4128aadSBjoern A. Zeeb 
2373*a4128aadSBjoern A. Zeeb 	if (read_ptr == tfd_num)
2374*a4128aadSBjoern A. Zeeb 		goto out;
2375*a4128aadSBjoern A. Zeeb 
2376*a4128aadSBjoern A. Zeeb 	IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d (%d) -> %d (%d)\n",
2377*a4128aadSBjoern A. Zeeb 			   txq_id, read_ptr, txq_read_ptr, tfd_num, ssn);
2378*a4128aadSBjoern A. Zeeb 
2379*a4128aadSBjoern A. Zeeb 	/* Since we free until index _not_ inclusive, the one before index is
2380*a4128aadSBjoern A. Zeeb 	 * the last we will free. This one must be used
2381*a4128aadSBjoern A. Zeeb 	 */
2382*a4128aadSBjoern A. Zeeb 	last_to_free = iwl_txq_dec_wrap(trans, tfd_num);
2383*a4128aadSBjoern A. Zeeb 
2384*a4128aadSBjoern A. Zeeb 	if (!iwl_txq_used(txq, last_to_free, txq_read_ptr, txq_write_ptr)) {
2385*a4128aadSBjoern A. Zeeb 		IWL_ERR(trans,
2386*a4128aadSBjoern A. Zeeb 			"%s: Read index for txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n",
2387*a4128aadSBjoern A. Zeeb 			__func__, txq_id, last_to_free,
2388*a4128aadSBjoern A. Zeeb 			trans->trans_cfg->base_params->max_tfd_queue_size,
2389*a4128aadSBjoern A. Zeeb 			txq_write_ptr, txq_read_ptr);
2390*a4128aadSBjoern A. Zeeb 
2391*a4128aadSBjoern A. Zeeb 		iwl_op_mode_time_point(trans->op_mode,
2392*a4128aadSBjoern A. Zeeb 				       IWL_FW_INI_TIME_POINT_FAKE_TX,
2393*a4128aadSBjoern A. Zeeb 				       NULL);
2394*a4128aadSBjoern A. Zeeb 		goto out;
2395*a4128aadSBjoern A. Zeeb 	}
2396*a4128aadSBjoern A. Zeeb 
2397*a4128aadSBjoern A. Zeeb 	if (WARN_ON(!skb_queue_empty(skbs)))
2398*a4128aadSBjoern A. Zeeb 		goto out;
2399*a4128aadSBjoern A. Zeeb 
2400*a4128aadSBjoern A. Zeeb 	for (;
2401*a4128aadSBjoern A. Zeeb 	     read_ptr != tfd_num;
2402*a4128aadSBjoern A. Zeeb 	     txq_read_ptr = iwl_txq_inc_wrap(trans, txq_read_ptr),
2403*a4128aadSBjoern A. Zeeb 	     read_ptr = iwl_txq_get_cmd_index(txq, txq_read_ptr)) {
2404*a4128aadSBjoern A. Zeeb 		struct iwl_cmd_meta *cmd_meta = &txq->entries[read_ptr].meta;
2405*a4128aadSBjoern A. Zeeb 		struct sk_buff *skb = txq->entries[read_ptr].skb;
2406*a4128aadSBjoern A. Zeeb 
2407*a4128aadSBjoern A. Zeeb 		if (WARN_ONCE(!skb, "no SKB at %d (%d) on queue %d\n",
2408*a4128aadSBjoern A. Zeeb 			      read_ptr, txq_read_ptr, txq_id))
2409*a4128aadSBjoern A. Zeeb 			continue;
2410*a4128aadSBjoern A. Zeeb 
2411*a4128aadSBjoern A. Zeeb 		iwl_pcie_free_tso_pages(trans, skb, cmd_meta);
2412*a4128aadSBjoern A. Zeeb 
2413*a4128aadSBjoern A. Zeeb 		__skb_queue_tail(skbs, skb);
2414*a4128aadSBjoern A. Zeeb 
2415*a4128aadSBjoern A. Zeeb 		txq->entries[read_ptr].skb = NULL;
2416*a4128aadSBjoern A. Zeeb 
2417*a4128aadSBjoern A. Zeeb 		if (!trans->trans_cfg->gen2)
2418*a4128aadSBjoern A. Zeeb 			iwl_txq_gen1_inval_byte_cnt_tbl(trans, txq,
2419*a4128aadSBjoern A. Zeeb 							txq_read_ptr);
2420*a4128aadSBjoern A. Zeeb 
2421*a4128aadSBjoern A. Zeeb 		iwl_txq_free_tfd(trans, txq, txq_read_ptr);
2422*a4128aadSBjoern A. Zeeb 	}
2423*a4128aadSBjoern A. Zeeb 
2424*a4128aadSBjoern A. Zeeb 	spin_lock(&txq->lock);
2425*a4128aadSBjoern A. Zeeb 	txq->read_ptr = txq_read_ptr;
2426*a4128aadSBjoern A. Zeeb 
2427*a4128aadSBjoern A. Zeeb 	iwl_txq_progress(txq);
2428*a4128aadSBjoern A. Zeeb 
2429*a4128aadSBjoern A. Zeeb 	if (iwl_txq_space(trans, txq) > txq->low_mark &&
2430*a4128aadSBjoern A. Zeeb 	    test_bit(txq_id, trans_pcie->txqs.queue_stopped)) {
2431*a4128aadSBjoern A. Zeeb 		struct sk_buff_head overflow_skbs;
2432*a4128aadSBjoern A. Zeeb 		struct sk_buff *skb;
2433*a4128aadSBjoern A. Zeeb 
2434*a4128aadSBjoern A. Zeeb 		__skb_queue_head_init(&overflow_skbs);
2435*a4128aadSBjoern A. Zeeb 		skb_queue_splice_init(&txq->overflow_q,
2436*a4128aadSBjoern A. Zeeb 				      is_flush ? skbs : &overflow_skbs);
2437*a4128aadSBjoern A. Zeeb 
2438*a4128aadSBjoern A. Zeeb 		/*
2439*a4128aadSBjoern A. Zeeb 		 * We are going to transmit from the overflow queue.
2440*a4128aadSBjoern A. Zeeb 		 * Remember this state so that wait_for_txq_empty will know we
2441*a4128aadSBjoern A. Zeeb 		 * are adding more packets to the TFD queue. It cannot rely on
2442*a4128aadSBjoern A. Zeeb 		 * the state of &txq->overflow_q, as we just emptied it, but
2443*a4128aadSBjoern A. Zeeb 		 * haven't TXed the content yet.
2444*a4128aadSBjoern A. Zeeb 		 */
2445*a4128aadSBjoern A. Zeeb 		txq->overflow_tx = true;
2446*a4128aadSBjoern A. Zeeb 
2447*a4128aadSBjoern A. Zeeb 		/*
2448*a4128aadSBjoern A. Zeeb 		 * This is tricky: we are in reclaim path and are holding
2449*a4128aadSBjoern A. Zeeb 		 * reclaim_lock, so noone will try to access the txq data
2450*a4128aadSBjoern A. Zeeb 		 * from that path. We stopped tx, so we can't have tx as well.
2451*a4128aadSBjoern A. Zeeb 		 * Bottom line, we can unlock and re-lock later.
2452*a4128aadSBjoern A. Zeeb 		 */
2453*a4128aadSBjoern A. Zeeb 		spin_unlock(&txq->lock);
2454*a4128aadSBjoern A. Zeeb 
2455*a4128aadSBjoern A. Zeeb 		while ((skb = __skb_dequeue(&overflow_skbs))) {
2456*a4128aadSBjoern A. Zeeb 			struct iwl_device_tx_cmd *dev_cmd_ptr;
2457*a4128aadSBjoern A. Zeeb 
2458*a4128aadSBjoern A. Zeeb 			dev_cmd_ptr = *(void **)((u8 *)skb->cb +
2459*a4128aadSBjoern A. Zeeb 						 trans_pcie->txqs.dev_cmd_offs);
2460*a4128aadSBjoern A. Zeeb 
2461*a4128aadSBjoern A. Zeeb 			/*
2462*a4128aadSBjoern A. Zeeb 			 * Note that we can very well be overflowing again.
2463*a4128aadSBjoern A. Zeeb 			 * In that case, iwl_txq_space will be small again
2464*a4128aadSBjoern A. Zeeb 			 * and we won't wake mac80211's queue.
2465*a4128aadSBjoern A. Zeeb 			 */
2466*a4128aadSBjoern A. Zeeb 			iwl_trans_tx(trans, skb, dev_cmd_ptr, txq_id);
2467*a4128aadSBjoern A. Zeeb 		}
2468*a4128aadSBjoern A. Zeeb 
2469*a4128aadSBjoern A. Zeeb 		if (iwl_txq_space(trans, txq) > txq->low_mark)
2470*a4128aadSBjoern A. Zeeb 			iwl_trans_pcie_wake_queue(trans, txq);
2471*a4128aadSBjoern A. Zeeb 
2472*a4128aadSBjoern A. Zeeb 		spin_lock(&txq->lock);
2473*a4128aadSBjoern A. Zeeb 		txq->overflow_tx = false;
2474*a4128aadSBjoern A. Zeeb 	}
2475*a4128aadSBjoern A. Zeeb 
2476*a4128aadSBjoern A. Zeeb 	spin_unlock(&txq->lock);
2477*a4128aadSBjoern A. Zeeb out:
2478*a4128aadSBjoern A. Zeeb 	spin_unlock_bh(&txq->reclaim_lock);
2479*a4128aadSBjoern A. Zeeb }
2480*a4128aadSBjoern A. Zeeb 
2481*a4128aadSBjoern A. Zeeb /* Set wr_ptr of specific device and txq  */
2482*a4128aadSBjoern A. Zeeb void iwl_pcie_set_q_ptrs(struct iwl_trans *trans, int txq_id, int ptr)
2483*a4128aadSBjoern A. Zeeb {
2484*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
2485*a4128aadSBjoern A. Zeeb 	struct iwl_txq *txq = trans_pcie->txqs.txq[txq_id];
2486*a4128aadSBjoern A. Zeeb 
2487*a4128aadSBjoern A. Zeeb 	spin_lock_bh(&txq->lock);
2488*a4128aadSBjoern A. Zeeb 
2489*a4128aadSBjoern A. Zeeb 	txq->write_ptr = ptr;
2490*a4128aadSBjoern A. Zeeb 	txq->read_ptr = txq->write_ptr;
2491*a4128aadSBjoern A. Zeeb 
2492*a4128aadSBjoern A. Zeeb 	spin_unlock_bh(&txq->lock);
2493*a4128aadSBjoern A. Zeeb }
2494*a4128aadSBjoern A. Zeeb 
2495*a4128aadSBjoern A. Zeeb void iwl_pcie_freeze_txq_timer(struct iwl_trans *trans,
2496*a4128aadSBjoern A. Zeeb 			       unsigned long txqs, bool freeze)
2497*a4128aadSBjoern A. Zeeb {
2498*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
2499*a4128aadSBjoern A. Zeeb 	int queue;
2500*a4128aadSBjoern A. Zeeb 
2501*a4128aadSBjoern A. Zeeb 	for_each_set_bit(queue, &txqs, BITS_PER_LONG) {
2502*a4128aadSBjoern A. Zeeb 		struct iwl_txq *txq = trans_pcie->txqs.txq[queue];
2503*a4128aadSBjoern A. Zeeb 		unsigned long now;
2504*a4128aadSBjoern A. Zeeb 
2505*a4128aadSBjoern A. Zeeb 		spin_lock_bh(&txq->lock);
2506*a4128aadSBjoern A. Zeeb 
2507*a4128aadSBjoern A. Zeeb 		now = jiffies;
2508*a4128aadSBjoern A. Zeeb 
2509*a4128aadSBjoern A. Zeeb 		if (txq->frozen == freeze)
2510*a4128aadSBjoern A. Zeeb 			goto next_queue;
2511*a4128aadSBjoern A. Zeeb 
2512*a4128aadSBjoern A. Zeeb 		IWL_DEBUG_TX_QUEUES(trans, "%s TXQ %d\n",
2513*a4128aadSBjoern A. Zeeb 				    freeze ? "Freezing" : "Waking", queue);
2514*a4128aadSBjoern A. Zeeb 
2515*a4128aadSBjoern A. Zeeb 		txq->frozen = freeze;
2516*a4128aadSBjoern A. Zeeb 
2517*a4128aadSBjoern A. Zeeb 		if (txq->read_ptr == txq->write_ptr)
2518*a4128aadSBjoern A. Zeeb 			goto next_queue;
2519*a4128aadSBjoern A. Zeeb 
2520*a4128aadSBjoern A. Zeeb 		if (freeze) {
2521*a4128aadSBjoern A. Zeeb 			if (unlikely(time_after(now,
2522*a4128aadSBjoern A. Zeeb 						txq->stuck_timer.expires))) {
2523*a4128aadSBjoern A. Zeeb 				/*
2524*a4128aadSBjoern A. Zeeb 				 * The timer should have fired, maybe it is
2525*a4128aadSBjoern A. Zeeb 				 * spinning right now on the lock.
2526*a4128aadSBjoern A. Zeeb 				 */
2527*a4128aadSBjoern A. Zeeb 				goto next_queue;
2528*a4128aadSBjoern A. Zeeb 			}
2529*a4128aadSBjoern A. Zeeb 			/* remember how long until the timer fires */
2530*a4128aadSBjoern A. Zeeb 			txq->frozen_expiry_remainder =
2531*a4128aadSBjoern A. Zeeb 				txq->stuck_timer.expires - now;
2532*a4128aadSBjoern A. Zeeb 			del_timer(&txq->stuck_timer);
2533*a4128aadSBjoern A. Zeeb 			goto next_queue;
2534*a4128aadSBjoern A. Zeeb 		}
2535*a4128aadSBjoern A. Zeeb 
2536*a4128aadSBjoern A. Zeeb 		/*
2537*a4128aadSBjoern A. Zeeb 		 * Wake a non-empty queue -> arm timer with the
2538*a4128aadSBjoern A. Zeeb 		 * remainder before it froze
2539*a4128aadSBjoern A. Zeeb 		 */
2540*a4128aadSBjoern A. Zeeb 		mod_timer(&txq->stuck_timer,
2541*a4128aadSBjoern A. Zeeb 			  now + txq->frozen_expiry_remainder);
2542*a4128aadSBjoern A. Zeeb 
2543*a4128aadSBjoern A. Zeeb next_queue:
2544*a4128aadSBjoern A. Zeeb 		spin_unlock_bh(&txq->lock);
2545*a4128aadSBjoern A. Zeeb 	}
2546*a4128aadSBjoern A. Zeeb }
2547*a4128aadSBjoern A. Zeeb 
2548*a4128aadSBjoern A. Zeeb #define HOST_COMPLETE_TIMEOUT	(2 * HZ)
2549*a4128aadSBjoern A. Zeeb 
2550*a4128aadSBjoern A. Zeeb static int iwl_trans_pcie_send_hcmd_sync(struct iwl_trans *trans,
2551*a4128aadSBjoern A. Zeeb 					 struct iwl_host_cmd *cmd)
2552*a4128aadSBjoern A. Zeeb {
2553*a4128aadSBjoern A. Zeeb 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
2554*a4128aadSBjoern A. Zeeb 	const char *cmd_str = iwl_get_cmd_string(trans, cmd->id);
2555*a4128aadSBjoern A. Zeeb 	struct iwl_txq *txq = trans_pcie->txqs.txq[trans_pcie->txqs.cmd.q_id];
2556*a4128aadSBjoern A. Zeeb 	int cmd_idx;
2557*a4128aadSBjoern A. Zeeb 	int ret;
2558*a4128aadSBjoern A. Zeeb 
2559*a4128aadSBjoern A. Zeeb 	IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", cmd_str);
2560*a4128aadSBjoern A. Zeeb 
2561*a4128aadSBjoern A. Zeeb 	if (WARN(test_and_set_bit(STATUS_SYNC_HCMD_ACTIVE,
2562*a4128aadSBjoern A. Zeeb 				  &trans->status),
2563*a4128aadSBjoern A. Zeeb 		 "Command %s: a command is already active!\n", cmd_str))
2564*a4128aadSBjoern A. Zeeb 		return -EIO;
2565*a4128aadSBjoern A. Zeeb 
2566*a4128aadSBjoern A. Zeeb 	IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", cmd_str);
2567*a4128aadSBjoern A. Zeeb 
2568*a4128aadSBjoern A. Zeeb 	if (trans->trans_cfg->gen2)
2569*a4128aadSBjoern A. Zeeb 		cmd_idx = iwl_pcie_gen2_enqueue_hcmd(trans, cmd);
2570*a4128aadSBjoern A. Zeeb 	else
2571*a4128aadSBjoern A. Zeeb 		cmd_idx = iwl_pcie_enqueue_hcmd(trans, cmd);
2572*a4128aadSBjoern A. Zeeb 
2573*a4128aadSBjoern A. Zeeb 	if (cmd_idx < 0) {
2574*a4128aadSBjoern A. Zeeb 		ret = cmd_idx;
2575*a4128aadSBjoern A. Zeeb 		clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
2576*a4128aadSBjoern A. Zeeb 		IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n",
2577*a4128aadSBjoern A. Zeeb 			cmd_str, ret);
2578*a4128aadSBjoern A. Zeeb 		return ret;
2579*a4128aadSBjoern A. Zeeb 	}
2580*a4128aadSBjoern A. Zeeb 
2581*a4128aadSBjoern A. Zeeb 	ret = wait_event_timeout(trans->wait_command_queue,
2582*a4128aadSBjoern A. Zeeb 				 !test_bit(STATUS_SYNC_HCMD_ACTIVE,
2583*a4128aadSBjoern A. Zeeb 					   &trans->status),
2584*a4128aadSBjoern A. Zeeb 				 HOST_COMPLETE_TIMEOUT);
2585*a4128aadSBjoern A. Zeeb 	if (!ret) {
2586*a4128aadSBjoern A. Zeeb 		IWL_ERR(trans, "Error sending %s: time out after %dms.\n",
2587*a4128aadSBjoern A. Zeeb 			cmd_str, jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
2588*a4128aadSBjoern A. Zeeb 
2589*a4128aadSBjoern A. Zeeb 		IWL_ERR(trans, "Current CMD queue read_ptr %d write_ptr %d\n",
2590*a4128aadSBjoern A. Zeeb 			txq->read_ptr, txq->write_ptr);
2591*a4128aadSBjoern A. Zeeb 
2592*a4128aadSBjoern A. Zeeb 		clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
2593*a4128aadSBjoern A. Zeeb 		IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n",
2594*a4128aadSBjoern A. Zeeb 			       cmd_str);
2595*a4128aadSBjoern A. Zeeb 		ret = -ETIMEDOUT;
2596*a4128aadSBjoern A. Zeeb 
2597*a4128aadSBjoern A. Zeeb 		iwl_trans_sync_nmi(trans);
2598*a4128aadSBjoern A. Zeeb 		goto cancel;
2599*a4128aadSBjoern A. Zeeb 	}
2600*a4128aadSBjoern A. Zeeb 
2601*a4128aadSBjoern A. Zeeb 	if (test_bit(STATUS_FW_ERROR, &trans->status)) {
2602*a4128aadSBjoern A. Zeeb 		if (!test_and_clear_bit(STATUS_SUPPRESS_CMD_ERROR_ONCE,
2603*a4128aadSBjoern A. Zeeb 					&trans->status)) {
2604*a4128aadSBjoern A. Zeeb 			IWL_ERR(trans, "FW error in SYNC CMD %s\n", cmd_str);
2605*a4128aadSBjoern A. Zeeb 			dump_stack();
2606*a4128aadSBjoern A. Zeeb 		}
2607*a4128aadSBjoern A. Zeeb 		ret = -EIO;
2608*a4128aadSBjoern A. Zeeb 		goto cancel;
2609*a4128aadSBjoern A. Zeeb 	}
2610*a4128aadSBjoern A. Zeeb 
2611*a4128aadSBjoern A. Zeeb 	if (!(cmd->flags & CMD_SEND_IN_RFKILL) &&
2612*a4128aadSBjoern A. Zeeb 	    test_bit(STATUS_RFKILL_OPMODE, &trans->status)) {
2613*a4128aadSBjoern A. Zeeb 		IWL_DEBUG_RF_KILL(trans, "RFKILL in SYNC CMD... no rsp\n");
2614*a4128aadSBjoern A. Zeeb 		ret = -ERFKILL;
2615*a4128aadSBjoern A. Zeeb 		goto cancel;
2616*a4128aadSBjoern A. Zeeb 	}
2617*a4128aadSBjoern A. Zeeb 
2618*a4128aadSBjoern A. Zeeb 	if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) {
2619*a4128aadSBjoern A. Zeeb 		IWL_ERR(trans, "Error: Response NULL in '%s'\n", cmd_str);
2620*a4128aadSBjoern A. Zeeb 		ret = -EIO;
2621*a4128aadSBjoern A. Zeeb 		goto cancel;
2622*a4128aadSBjoern A. Zeeb 	}
2623*a4128aadSBjoern A. Zeeb 
2624*a4128aadSBjoern A. Zeeb 	return 0;
2625*a4128aadSBjoern A. Zeeb 
2626*a4128aadSBjoern A. Zeeb cancel:
2627*a4128aadSBjoern A. Zeeb 	if (cmd->flags & CMD_WANT_SKB) {
2628*a4128aadSBjoern A. Zeeb 		/*
2629*a4128aadSBjoern A. Zeeb 		 * Cancel the CMD_WANT_SKB flag for the cmd in the
2630*a4128aadSBjoern A. Zeeb 		 * TX cmd queue. Otherwise in case the cmd comes
2631*a4128aadSBjoern A. Zeeb 		 * in later, it will possibly set an invalid
2632*a4128aadSBjoern A. Zeeb 		 * address (cmd->meta.source).
2633*a4128aadSBjoern A. Zeeb 		 */
2634*a4128aadSBjoern A. Zeeb 		txq->entries[cmd_idx].meta.flags &= ~CMD_WANT_SKB;
2635*a4128aadSBjoern A. Zeeb 	}
2636*a4128aadSBjoern A. Zeeb 
2637*a4128aadSBjoern A. Zeeb 	if (cmd->resp_pkt) {
2638*a4128aadSBjoern A. Zeeb 		iwl_free_resp(cmd);
2639*a4128aadSBjoern A. Zeeb 		cmd->resp_pkt = NULL;
2640*a4128aadSBjoern A. Zeeb 	}
2641*a4128aadSBjoern A. Zeeb 
2642*a4128aadSBjoern A. Zeeb 	return ret;
2643*a4128aadSBjoern A. Zeeb }
2644*a4128aadSBjoern A. Zeeb 
2645*a4128aadSBjoern A. Zeeb int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans,
2646*a4128aadSBjoern A. Zeeb 			     struct iwl_host_cmd *cmd)
2647*a4128aadSBjoern A. Zeeb {
2648*a4128aadSBjoern A. Zeeb 	/* Make sure the NIC is still alive in the bus */
2649*a4128aadSBjoern A. Zeeb 	if (test_bit(STATUS_TRANS_DEAD, &trans->status))
2650*a4128aadSBjoern A. Zeeb 		return -ENODEV;
2651*a4128aadSBjoern A. Zeeb 
2652*a4128aadSBjoern A. Zeeb 	if (!(cmd->flags & CMD_SEND_IN_RFKILL) &&
2653*a4128aadSBjoern A. Zeeb 	    test_bit(STATUS_RFKILL_OPMODE, &trans->status)) {
2654*a4128aadSBjoern A. Zeeb 		IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n",
2655*a4128aadSBjoern A. Zeeb 				  cmd->id);
2656*a4128aadSBjoern A. Zeeb 		return -ERFKILL;
2657*a4128aadSBjoern A. Zeeb 	}
2658*a4128aadSBjoern A. Zeeb 
2659*a4128aadSBjoern A. Zeeb 	if (unlikely(trans->system_pm_mode == IWL_PLAT_PM_MODE_D3 &&
2660*a4128aadSBjoern A. Zeeb 		     !(cmd->flags & CMD_SEND_IN_D3))) {
2661*a4128aadSBjoern A. Zeeb 		IWL_DEBUG_WOWLAN(trans, "Dropping CMD 0x%x: D3\n", cmd->id);
2662*a4128aadSBjoern A. Zeeb 		return -EHOSTDOWN;
2663*a4128aadSBjoern A. Zeeb 	}
2664*a4128aadSBjoern A. Zeeb 
2665*a4128aadSBjoern A. Zeeb 	if (cmd->flags & CMD_ASYNC) {
2666*a4128aadSBjoern A. Zeeb 		int ret;
2667*a4128aadSBjoern A. Zeeb 
2668*a4128aadSBjoern A. Zeeb 		/* An asynchronous command can not expect an SKB to be set. */
2669*a4128aadSBjoern A. Zeeb 		if (WARN_ON(cmd->flags & CMD_WANT_SKB))
2670*a4128aadSBjoern A. Zeeb 			return -EINVAL;
2671*a4128aadSBjoern A. Zeeb 
2672*a4128aadSBjoern A. Zeeb 		if (trans->trans_cfg->gen2)
2673*a4128aadSBjoern A. Zeeb 			ret = iwl_pcie_gen2_enqueue_hcmd(trans, cmd);
2674*a4128aadSBjoern A. Zeeb 		else
2675*a4128aadSBjoern A. Zeeb 			ret = iwl_pcie_enqueue_hcmd(trans, cmd);
2676*a4128aadSBjoern A. Zeeb 
2677*a4128aadSBjoern A. Zeeb 		if (ret < 0) {
2678*a4128aadSBjoern A. Zeeb 			IWL_ERR(trans,
2679*a4128aadSBjoern A. Zeeb 				"Error sending %s: enqueue_hcmd failed: %d\n",
2680*a4128aadSBjoern A. Zeeb 				iwl_get_cmd_string(trans, cmd->id), ret);
2681*a4128aadSBjoern A. Zeeb 			return ret;
2682*a4128aadSBjoern A. Zeeb 		}
2683*a4128aadSBjoern A. Zeeb 		return 0;
2684*a4128aadSBjoern A. Zeeb 	}
2685*a4128aadSBjoern A. Zeeb 
2686*a4128aadSBjoern A. Zeeb 	return iwl_trans_pcie_send_hcmd_sync(trans, cmd);
2687*a4128aadSBjoern A. Zeeb }
2688*a4128aadSBjoern A. Zeeb IWL_EXPORT_SYMBOL(iwl_trans_pcie_send_hcmd);
2689