aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-10-19 15:48:17 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-10-19 15:48:17 -0400
commitb0a949b42ba7d6f1b2876045a5e062fdfe8c691f (patch)
treea76ed2231a207a6e3d951acc7fd749bc12173416
parent3cd17638fdf13d2f7fe76465cf74106e612af5eb (diff)
parent4e760f1ab267edcd6e4b232ff732fc9cdc659ebb (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h95
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h8
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c3
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c9
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c18
9 files changed, 121 insertions, 30 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 7ff3f143067..475df45c832 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -1191,8 +1191,6 @@ static void iwl_option_config(struct iwl_priv *priv)
1191 1191
1192static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) 1192static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
1193{ 1193{
1194 u16 radio_cfg;
1195
1196 priv->eeprom_data->sku = priv->eeprom_data->sku; 1194 priv->eeprom_data->sku = priv->eeprom_data->sku;
1197 1195
1198 if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE && 1196 if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE &&
@@ -1208,8 +1206,6 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
1208 1206
1209 IWL_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku); 1207 IWL_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku);
1210 1208
1211 radio_cfg = priv->eeprom_data->radio_cfg;
1212
1213 priv->hw_params.tx_chains_num = 1209 priv->hw_params.tx_chains_num =
1214 num_of_ant(priv->eeprom_data->valid_tx_ant); 1210 num_of_ant(priv->eeprom_data->valid_tx_ant);
1215 if (priv->cfg->rx_with_siso_diversity) 1211 if (priv->cfg->rx_with_siso_diversity)
@@ -1334,6 +1330,9 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1334 /* Configure transport layer */ 1330 /* Configure transport layer */
1335 iwl_trans_configure(priv->trans, &trans_cfg); 1331 iwl_trans_configure(priv->trans, &trans_cfg);
1336 1332
1333 trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD;
1334 trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start);
1335
1337 /* At this point both hw and priv are allocated. */ 1336 /* At this point both hw and priv are allocated. */
1338 1337
1339 SET_IEEE80211_DEV(priv->hw, priv->trans->dev); 1338 SET_IEEE80211_DEV(priv->hw, priv->trans->dev);
@@ -2152,8 +2151,6 @@ static int __init iwl_init(void)
2152{ 2151{
2153 2152
2154 int ret; 2153 int ret;
2155 pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
2156 pr_info(DRV_COPYRIGHT "\n");
2157 2154
2158 ret = iwlagn_rate_control_register(); 2155 ret = iwlagn_rate_control_register();
2159 if (ret) { 2156 if (ret) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 59a5f78402f..678717bf62e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -25,6 +25,39 @@
25 *****************************************************************************/ 25 *****************************************************************************/
26 26
27#if !defined(__IWLWIFI_DEVICE_TRACE) || defined(TRACE_HEADER_MULTI_READ) 27#if !defined(__IWLWIFI_DEVICE_TRACE) || defined(TRACE_HEADER_MULTI_READ)
28#include <linux/skbuff.h>
29#include <linux/ieee80211.h>
30#include <net/cfg80211.h>
31#include "iwl-trans.h"
32#if !defined(__IWLWIFI_DEVICE_TRACE)
33static inline bool iwl_trace_data(struct sk_buff *skb)
34{
35 struct ieee80211_hdr *hdr = (void *)skb->data;
36
37 if (ieee80211_is_data(hdr->frame_control))
38 return skb->protocol != cpu_to_be16(ETH_P_PAE);
39 return false;
40}
41
42static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans,
43 void *rxbuf, size_t len)
44{
45 struct iwl_cmd_header *cmd = (void *)((u8 *)rxbuf + sizeof(__le32));
46 struct ieee80211_hdr *hdr;
47
48 if (cmd->cmd != trans->rx_mpdu_cmd)
49 return len;
50
51 hdr = (void *)((u8 *)cmd + sizeof(struct iwl_cmd_header) +
52 trans->rx_mpdu_cmd_hdr_size);
53 if (!ieee80211_is_data(hdr->frame_control))
54 return len;
55 /* maybe try to identify EAPOL frames? */
56 return sizeof(__le32) + sizeof(*cmd) + trans->rx_mpdu_cmd_hdr_size +
57 ieee80211_hdrlen(hdr->frame_control);
58}
59#endif
60
28#define __IWLWIFI_DEVICE_TRACE 61#define __IWLWIFI_DEVICE_TRACE
29 62
30#include <linux/tracepoint.h> 63#include <linux/tracepoint.h>
@@ -235,6 +268,48 @@ TRACE_EVENT(iwlwifi_dbg,
235); 268);
236 269
237#undef TRACE_SYSTEM 270#undef TRACE_SYSTEM
271#define TRACE_SYSTEM iwlwifi_data
272
273TRACE_EVENT(iwlwifi_dev_tx_data,
274 TP_PROTO(const struct device *dev,
275 struct sk_buff *skb,
276 void *data, size_t data_len),
277 TP_ARGS(dev, skb, data, data_len),
278 TP_STRUCT__entry(
279 DEV_ENTRY
280
281 __dynamic_array(u8, data, iwl_trace_data(skb) ? data_len : 0)
282 ),
283 TP_fast_assign(
284 DEV_ASSIGN;
285 if (iwl_trace_data(skb))
286 memcpy(__get_dynamic_array(data), data, data_len);
287 ),
288 TP_printk("[%s] TX frame data", __get_str(dev))
289);
290
291TRACE_EVENT(iwlwifi_dev_rx_data,
292 TP_PROTO(const struct device *dev,
293 const struct iwl_trans *trans,
294 void *rxbuf, size_t len),
295 TP_ARGS(dev, trans, rxbuf, len),
296 TP_STRUCT__entry(
297 DEV_ENTRY
298
299 __dynamic_array(u8, data,
300 len - iwl_rx_trace_len(trans, rxbuf, len))
301 ),
302 TP_fast_assign(
303 size_t offs = iwl_rx_trace_len(trans, rxbuf, len);
304 DEV_ASSIGN;
305 if (offs < len)
306 memcpy(__get_dynamic_array(data),
307 ((u8 *)rxbuf) + offs, len - offs);
308 ),
309 TP_printk("[%s] TX frame data", __get_str(dev))
310);
311
312#undef TRACE_SYSTEM
238#define TRACE_SYSTEM iwlwifi 313#define TRACE_SYSTEM iwlwifi
239 314
240TRACE_EVENT(iwlwifi_dev_hcmd, 315TRACE_EVENT(iwlwifi_dev_hcmd,
@@ -270,25 +345,28 @@ TRACE_EVENT(iwlwifi_dev_hcmd,
270); 345);
271 346
272TRACE_EVENT(iwlwifi_dev_rx, 347TRACE_EVENT(iwlwifi_dev_rx,
273 TP_PROTO(const struct device *dev, void *rxbuf, size_t len), 348 TP_PROTO(const struct device *dev, const struct iwl_trans *trans,
274 TP_ARGS(dev, rxbuf, len), 349 void *rxbuf, size_t len),
350 TP_ARGS(dev, trans, rxbuf, len),
275 TP_STRUCT__entry( 351 TP_STRUCT__entry(
276 DEV_ENTRY 352 DEV_ENTRY
277 __dynamic_array(u8, rxbuf, len) 353 __dynamic_array(u8, rxbuf, iwl_rx_trace_len(trans, rxbuf, len))
278 ), 354 ),
279 TP_fast_assign( 355 TP_fast_assign(
280 DEV_ASSIGN; 356 DEV_ASSIGN;
281 memcpy(__get_dynamic_array(rxbuf), rxbuf, len); 357 memcpy(__get_dynamic_array(rxbuf), rxbuf,
358 iwl_rx_trace_len(trans, rxbuf, len));
282 ), 359 ),
283 TP_printk("[%s] RX cmd %#.2x", 360 TP_printk("[%s] RX cmd %#.2x",
284 __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4]) 361 __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4])
285); 362);
286 363
287TRACE_EVENT(iwlwifi_dev_tx, 364TRACE_EVENT(iwlwifi_dev_tx,
288 TP_PROTO(const struct device *dev, void *tfd, size_t tfdlen, 365 TP_PROTO(const struct device *dev, struct sk_buff *skb,
366 void *tfd, size_t tfdlen,
289 void *buf0, size_t buf0_len, 367 void *buf0, size_t buf0_len,
290 void *buf1, size_t buf1_len), 368 void *buf1, size_t buf1_len),
291 TP_ARGS(dev, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), 369 TP_ARGS(dev, skb, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len),
292 TP_STRUCT__entry( 370 TP_STRUCT__entry(
293 DEV_ENTRY 371 DEV_ENTRY
294 372
@@ -301,14 +379,15 @@ TRACE_EVENT(iwlwifi_dev_tx,
301 * for the possible padding). 379 * for the possible padding).
302 */ 380 */
303 __dynamic_array(u8, buf0, buf0_len) 381 __dynamic_array(u8, buf0, buf0_len)
304 __dynamic_array(u8, buf1, buf1_len) 382 __dynamic_array(u8, buf1, iwl_trace_data(skb) ? 0 : buf1_len)
305 ), 383 ),
306 TP_fast_assign( 384 TP_fast_assign(
307 DEV_ASSIGN; 385 DEV_ASSIGN;
308 __entry->framelen = buf0_len + buf1_len; 386 __entry->framelen = buf0_len + buf1_len;
309 memcpy(__get_dynamic_array(tfd), tfd, tfdlen); 387 memcpy(__get_dynamic_array(tfd), tfd, tfdlen);
310 memcpy(__get_dynamic_array(buf0), buf0, buf0_len); 388 memcpy(__get_dynamic_array(buf0), buf0, buf0_len);
311 memcpy(__get_dynamic_array(buf1), buf1, buf1_len); 389 if (!iwl_trace_data(skb))
390 memcpy(__get_dynamic_array(buf1), buf1, buf1_len);
312 ), 391 ),
313 TP_printk("[%s] TX %.2x (%zu bytes)", 392 TP_printk("[%s] TX %.2x (%zu bytes)",
314 __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0], 393 __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0],
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
index 3dfebfb8434..54c41b44bff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -327,11 +327,11 @@ u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr)
327EXPORT_SYMBOL_GPL(iwl_read_targ_mem); 327EXPORT_SYMBOL_GPL(iwl_read_targ_mem);
328 328
329int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr, 329int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr,
330 void *buf, int dwords) 330 const void *buf, int dwords)
331{ 331{
332 unsigned long flags; 332 unsigned long flags;
333 int offs, result = 0; 333 int offs, result = 0;
334 u32 *vals = buf; 334 const u32 *vals = buf;
335 335
336 spin_lock_irqsave(&trans->reg_lock, flags); 336 spin_lock_irqsave(&trans->reg_lock, flags);
337 if (likely(iwl_grab_nic_access(trans))) { 337 if (likely(iwl_grab_nic_access(trans))) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 50d3819739d..e1aa69f66de 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -87,7 +87,7 @@ void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr,
87 } while (0) 87 } while (0)
88 88
89int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr, 89int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr,
90 void *buf, int dwords); 90 const void *buf, int dwords);
91 91
92u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr); 92u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr);
93int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val); 93int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val);
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 9253ef1dba7..c3a4bb41e53 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -213,6 +213,9 @@
213#define SCD_CONTEXT_QUEUE_OFFSET(x)\ 213#define SCD_CONTEXT_QUEUE_OFFSET(x)\
214 (SCD_CONTEXT_MEM_LOWER_BOUND + ((x) * 8)) 214 (SCD_CONTEXT_MEM_LOWER_BOUND + ((x) * 8))
215 215
216#define SCD_TX_STTS_QUEUE_OFFSET(x)\
217 (SCD_TX_STTS_MEM_LOWER_BOUND + ((x) * 16))
218
216#define SCD_TRANS_TBL_OFFSET_QUEUE(x) \ 219#define SCD_TRANS_TBL_OFFSET_QUEUE(x) \
217 ((SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc) 220 ((SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc)
218 221
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index ff115423288..f75ea6d73ff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -444,6 +444,10 @@ enum iwl_trans_state {
444 * @dev_cmd_headroom: room needed for the transport's private use before the 444 * @dev_cmd_headroom: room needed for the transport's private use before the
445 * device_cmd for Tx - for internal use only 445 * device_cmd for Tx - for internal use only
446 * The user should use iwl_trans_{alloc,free}_tx_cmd. 446 * The user should use iwl_trans_{alloc,free}_tx_cmd.
447 * @rx_mpdu_cmd: MPDU RX command ID, must be assigned by opmode before
448 * starting the firmware, used for tracing
449 * @rx_mpdu_cmd_hdr_size: used for tracing, amount of data before the
450 * start of the 802.11 header in the @rx_mpdu_cmd
447 */ 451 */
448struct iwl_trans { 452struct iwl_trans {
449 const struct iwl_trans_ops *ops; 453 const struct iwl_trans_ops *ops;
@@ -457,6 +461,8 @@ struct iwl_trans {
457 u32 hw_id; 461 u32 hw_id;
458 char hw_id_str[52]; 462 char hw_id_str[52];
459 463
464 u8 rx_mpdu_cmd, rx_mpdu_cmd_hdr_size;
465
460 bool pm_support; 466 bool pm_support;
461 467
462 wait_queue_head_t wait_command_queue; 468 wait_queue_head_t wait_command_queue;
@@ -516,6 +522,8 @@ static inline int iwl_trans_start_fw(struct iwl_trans *trans,
516{ 522{
517 might_sleep(); 523 might_sleep();
518 524
525 WARN_ON_ONCE(!trans->rx_mpdu_cmd);
526
519 return trans->ops->start_fw(trans, fw); 527 return trans->ops->start_fw(trans, fw);
520} 528}
521 529
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 17c8e5d8268..137af4c46a6 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -411,7 +411,8 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
411 411
412 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 412 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
413 len += sizeof(u32); /* account for status word */ 413 len += sizeof(u32); /* account for status word */
414 trace_iwlwifi_dev_rx(trans->dev, pkt, len); 414 trace_iwlwifi_dev_rx(trans->dev, trans, pkt, len);
415 trace_iwlwifi_dev_rx_data(trans->dev, trans, pkt, len);
415 416
416 /* Reclaim a command buffer only if this packet is a response 417 /* Reclaim a command buffer only if this packet is a response
417 * to a (driver-originated) command. 418 * to a (driver-originated) command.
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index fe0fffd0430..f95d88df777 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -300,7 +300,7 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data)
300 struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; 300 struct iwl_trans_pcie *trans_pcie = txq->trans_pcie;
301 struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie); 301 struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie);
302 u32 scd_sram_addr = trans_pcie->scd_base_addr + 302 u32 scd_sram_addr = trans_pcie->scd_base_addr +
303 SCD_TX_STTS_MEM_LOWER_BOUND + (16 * txq->q.id); 303 SCD_TX_STTS_QUEUE_OFFSET(txq->q.id);
304 u8 buf[16]; 304 u8 buf[16];
305 int i; 305 int i;
306 306
@@ -1385,11 +1385,13 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1385 dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, 1385 dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen,
1386 DMA_BIDIRECTIONAL); 1386 DMA_BIDIRECTIONAL);
1387 1387
1388 trace_iwlwifi_dev_tx(trans->dev, 1388 trace_iwlwifi_dev_tx(trans->dev, skb,
1389 &txq->tfds[txq->q.write_ptr], 1389 &txq->tfds[txq->q.write_ptr],
1390 sizeof(struct iwl_tfd), 1390 sizeof(struct iwl_tfd),
1391 &dev_cmd->hdr, firstlen, 1391 &dev_cmd->hdr, firstlen,
1392 skb->data + hdr_len, secondlen); 1392 skb->data + hdr_len, secondlen);
1393 trace_iwlwifi_dev_tx_data(trans->dev, skb,
1394 skb->data + hdr_len, secondlen);
1393 1395
1394 /* start timer if queue currently empty */ 1396 /* start timer if queue currently empty */
1395 if (txq->need_update && q->read_ptr == q->write_ptr && 1397 if (txq->need_update && q->read_ptr == q->write_ptr &&
@@ -1514,14 +1516,13 @@ static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
1514 struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; 1516 struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
1515 /* n_bd is usually 256 => n_bd - 1 = 0xff */ 1517 /* n_bd is usually 256 => n_bd - 1 = 0xff */
1516 int tfd_num = ssn & (txq->q.n_bd - 1); 1518 int tfd_num = ssn & (txq->q.n_bd - 1);
1517 int freed = 0;
1518 1519
1519 spin_lock(&txq->lock); 1520 spin_lock(&txq->lock);
1520 1521
1521 if (txq->q.read_ptr != tfd_num) { 1522 if (txq->q.read_ptr != tfd_num) {
1522 IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n", 1523 IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n",
1523 txq_id, txq->q.read_ptr, tfd_num, ssn); 1524 txq_id, txq->q.read_ptr, tfd_num, ssn);
1524 freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); 1525 iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs);
1525 if (iwl_queue_space(&txq->q) > txq->q.low_mark) 1526 if (iwl_queue_space(&txq->q) > txq->q.low_mark)
1526 iwl_wake_queue(trans, txq); 1527 iwl_wake_queue(trans, txq);
1527 } 1528 }
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 105e3af3c62..db3efbb84d9 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -480,21 +480,20 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
480void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) 480void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id)
481{ 481{
482 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 482 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
483 u16 rd_ptr, wr_ptr; 483 u32 stts_addr = trans_pcie->scd_base_addr +
484 int n_bd = trans_pcie->txq[txq_id].q.n_bd; 484 SCD_TX_STTS_QUEUE_OFFSET(txq_id);
485 static const u32 zero_val[4] = {};
485 486
486 if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { 487 if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) {
487 WARN_ONCE(1, "queue %d not used", txq_id); 488 WARN_ONCE(1, "queue %d not used", txq_id);
488 return; 489 return;
489 } 490 }
490 491
491 rd_ptr = iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & (n_bd - 1); 492 iwl_txq_set_inactive(trans, txq_id);
492 wr_ptr = iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id));
493 493
494 WARN_ONCE(rd_ptr != wr_ptr, "queue %d isn't empty: [%d,%d]", 494 _iwl_write_targ_mem_dwords(trans, stts_addr,
495 txq_id, rd_ptr, wr_ptr); 495 zero_val, ARRAY_SIZE(zero_val));
496 496
497 iwl_txq_set_inactive(trans, txq_id);
498 IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); 497 IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id);
499} 498}
500 499
@@ -549,7 +548,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
549 * allocated into separate TFDs, then we will need to 548 * allocated into separate TFDs, then we will need to
550 * increase the size of the buffers. 549 * increase the size of the buffers.
551 */ 550 */
552 if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE)) 551 if (WARN(copy_size > TFD_MAX_PAYLOAD_SIZE,
552 "Command %s (%#x) is too large (%d bytes)\n",
553 trans_pcie_get_cmd_string(trans_pcie, cmd->id),
554 cmd->id, copy_size))
553 return -EINVAL; 555 return -EINVAL;
554 556
555 spin_lock_bh(&txq->lock); 557 spin_lock_bh(&txq->lock);