Commit b0a949b4 authored by John W. Linville's avatar John W. Linville
parents 3cd17638 4e760f1a
...@@ -1191,8 +1191,6 @@ static void iwl_option_config(struct iwl_priv *priv) ...@@ -1191,8 +1191,6 @@ static void iwl_option_config(struct iwl_priv *priv)
static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
{ {
u16 radio_cfg;
priv->eeprom_data->sku = priv->eeprom_data->sku; priv->eeprom_data->sku = priv->eeprom_data->sku;
if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE && 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,8 +1206,6 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
IWL_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku); IWL_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku);
radio_cfg = priv->eeprom_data->radio_cfg;
priv->hw_params.tx_chains_num = priv->hw_params.tx_chains_num =
num_of_ant(priv->eeprom_data->valid_tx_ant); num_of_ant(priv->eeprom_data->valid_tx_ant);
if (priv->cfg->rx_with_siso_diversity) 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,6 +1330,9 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
/* Configure transport layer */ /* Configure transport layer */
iwl_trans_configure(priv->trans, &trans_cfg); iwl_trans_configure(priv->trans, &trans_cfg);
trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD;
trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start);
/* At this point both hw and priv are allocated. */ /* At this point both hw and priv are allocated. */
SET_IEEE80211_DEV(priv->hw, priv->trans->dev); SET_IEEE80211_DEV(priv->hw, priv->trans->dev);
...@@ -2152,8 +2151,6 @@ static int __init iwl_init(void) ...@@ -2152,8 +2151,6 @@ static int __init iwl_init(void)
{ {
int ret; int ret;
pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
pr_info(DRV_COPYRIGHT "\n");
ret = iwlagn_rate_control_register(); ret = iwlagn_rate_control_register();
if (ret) { if (ret) {
......
...@@ -25,6 +25,39 @@ ...@@ -25,6 +25,39 @@
*****************************************************************************/ *****************************************************************************/
#if !defined(__IWLWIFI_DEVICE_TRACE) || defined(TRACE_HEADER_MULTI_READ) #if !defined(__IWLWIFI_DEVICE_TRACE) || defined(TRACE_HEADER_MULTI_READ)
#include <linux/skbuff.h>
#include <linux/ieee80211.h>
#include <net/cfg80211.h>
#include "iwl-trans.h"
#if !defined(__IWLWIFI_DEVICE_TRACE)
static inline bool iwl_trace_data(struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (void *)skb->data;
if (ieee80211_is_data(hdr->frame_control))
return skb->protocol != cpu_to_be16(ETH_P_PAE);
return false;
}
static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans,
void *rxbuf, size_t len)
{
struct iwl_cmd_header *cmd = (void *)((u8 *)rxbuf + sizeof(__le32));
struct ieee80211_hdr *hdr;
if (cmd->cmd != trans->rx_mpdu_cmd)
return len;
hdr = (void *)((u8 *)cmd + sizeof(struct iwl_cmd_header) +
trans->rx_mpdu_cmd_hdr_size);
if (!ieee80211_is_data(hdr->frame_control))
return len;
/* maybe try to identify EAPOL frames? */
return sizeof(__le32) + sizeof(*cmd) + trans->rx_mpdu_cmd_hdr_size +
ieee80211_hdrlen(hdr->frame_control);
}
#endif
#define __IWLWIFI_DEVICE_TRACE #define __IWLWIFI_DEVICE_TRACE
#include <linux/tracepoint.h> #include <linux/tracepoint.h>
...@@ -234,6 +267,48 @@ TRACE_EVENT(iwlwifi_dbg, ...@@ -234,6 +267,48 @@ TRACE_EVENT(iwlwifi_dbg,
TP_printk("%s", (char *)__get_dynamic_array(msg)) TP_printk("%s", (char *)__get_dynamic_array(msg))
); );
#undef TRACE_SYSTEM
#define TRACE_SYSTEM iwlwifi_data
TRACE_EVENT(iwlwifi_dev_tx_data,
TP_PROTO(const struct device *dev,
struct sk_buff *skb,
void *data, size_t data_len),
TP_ARGS(dev, skb, data, data_len),
TP_STRUCT__entry(
DEV_ENTRY
__dynamic_array(u8, data, iwl_trace_data(skb) ? data_len : 0)
),
TP_fast_assign(
DEV_ASSIGN;
if (iwl_trace_data(skb))
memcpy(__get_dynamic_array(data), data, data_len);
),
TP_printk("[%s] TX frame data", __get_str(dev))
);
TRACE_EVENT(iwlwifi_dev_rx_data,
TP_PROTO(const struct device *dev,
const struct iwl_trans *trans,
void *rxbuf, size_t len),
TP_ARGS(dev, trans, rxbuf, len),
TP_STRUCT__entry(
DEV_ENTRY
__dynamic_array(u8, data,
len - iwl_rx_trace_len(trans, rxbuf, len))
),
TP_fast_assign(
size_t offs = iwl_rx_trace_len(trans, rxbuf, len);
DEV_ASSIGN;
if (offs < len)
memcpy(__get_dynamic_array(data),
((u8 *)rxbuf) + offs, len - offs);
),
TP_printk("[%s] TX frame data", __get_str(dev))
);
#undef TRACE_SYSTEM #undef TRACE_SYSTEM
#define TRACE_SYSTEM iwlwifi #define TRACE_SYSTEM iwlwifi
...@@ -270,25 +345,28 @@ TRACE_EVENT(iwlwifi_dev_hcmd, ...@@ -270,25 +345,28 @@ TRACE_EVENT(iwlwifi_dev_hcmd,
); );
TRACE_EVENT(iwlwifi_dev_rx, TRACE_EVENT(iwlwifi_dev_rx,
TP_PROTO(const struct device *dev, void *rxbuf, size_t len), TP_PROTO(const struct device *dev, const struct iwl_trans *trans,
TP_ARGS(dev, rxbuf, len), void *rxbuf, size_t len),
TP_ARGS(dev, trans, rxbuf, len),
TP_STRUCT__entry( TP_STRUCT__entry(
DEV_ENTRY DEV_ENTRY
__dynamic_array(u8, rxbuf, len) __dynamic_array(u8, rxbuf, iwl_rx_trace_len(trans, rxbuf, len))
), ),
TP_fast_assign( TP_fast_assign(
DEV_ASSIGN; DEV_ASSIGN;
memcpy(__get_dynamic_array(rxbuf), rxbuf, len); memcpy(__get_dynamic_array(rxbuf), rxbuf,
iwl_rx_trace_len(trans, rxbuf, len));
), ),
TP_printk("[%s] RX cmd %#.2x", TP_printk("[%s] RX cmd %#.2x",
__get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4]) __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4])
); );
TRACE_EVENT(iwlwifi_dev_tx, TRACE_EVENT(iwlwifi_dev_tx,
TP_PROTO(const struct device *dev, void *tfd, size_t tfdlen, TP_PROTO(const struct device *dev, struct sk_buff *skb,
void *tfd, size_t tfdlen,
void *buf0, size_t buf0_len, void *buf0, size_t buf0_len,
void *buf1, size_t buf1_len), void *buf1, size_t buf1_len),
TP_ARGS(dev, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), TP_ARGS(dev, skb, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len),
TP_STRUCT__entry( TP_STRUCT__entry(
DEV_ENTRY DEV_ENTRY
...@@ -301,14 +379,15 @@ TRACE_EVENT(iwlwifi_dev_tx, ...@@ -301,14 +379,15 @@ TRACE_EVENT(iwlwifi_dev_tx,
* for the possible padding). * for the possible padding).
*/ */
__dynamic_array(u8, buf0, buf0_len) __dynamic_array(u8, buf0, buf0_len)
__dynamic_array(u8, buf1, buf1_len) __dynamic_array(u8, buf1, iwl_trace_data(skb) ? 0 : buf1_len)
), ),
TP_fast_assign( TP_fast_assign(
DEV_ASSIGN; DEV_ASSIGN;
__entry->framelen = buf0_len + buf1_len; __entry->framelen = buf0_len + buf1_len;
memcpy(__get_dynamic_array(tfd), tfd, tfdlen); memcpy(__get_dynamic_array(tfd), tfd, tfdlen);
memcpy(__get_dynamic_array(buf0), buf0, buf0_len); memcpy(__get_dynamic_array(buf0), buf0, buf0_len);
memcpy(__get_dynamic_array(buf1), buf1, buf1_len); if (!iwl_trace_data(skb))
memcpy(__get_dynamic_array(buf1), buf1, buf1_len);
), ),
TP_printk("[%s] TX %.2x (%zu bytes)", TP_printk("[%s] TX %.2x (%zu bytes)",
__get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0], __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0],
......
...@@ -327,11 +327,11 @@ u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) ...@@ -327,11 +327,11 @@ u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr)
EXPORT_SYMBOL_GPL(iwl_read_targ_mem); EXPORT_SYMBOL_GPL(iwl_read_targ_mem);
int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr, int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr,
void *buf, int dwords) const void *buf, int dwords)
{ {
unsigned long flags; unsigned long flags;
int offs, result = 0; int offs, result = 0;
u32 *vals = buf; const u32 *vals = buf;
spin_lock_irqsave(&trans->reg_lock, flags); spin_lock_irqsave(&trans->reg_lock, flags);
if (likely(iwl_grab_nic_access(trans))) { if (likely(iwl_grab_nic_access(trans))) {
......
...@@ -87,7 +87,7 @@ void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr, ...@@ -87,7 +87,7 @@ void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr,
} while (0) } while (0)
int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr, int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr,
void *buf, int dwords); const void *buf, int dwords);
u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr); u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr);
int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val); int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val);
......
...@@ -213,6 +213,9 @@ ...@@ -213,6 +213,9 @@
#define SCD_CONTEXT_QUEUE_OFFSET(x)\ #define SCD_CONTEXT_QUEUE_OFFSET(x)\
(SCD_CONTEXT_MEM_LOWER_BOUND + ((x) * 8)) (SCD_CONTEXT_MEM_LOWER_BOUND + ((x) * 8))
#define SCD_TX_STTS_QUEUE_OFFSET(x)\
(SCD_TX_STTS_MEM_LOWER_BOUND + ((x) * 16))
#define SCD_TRANS_TBL_OFFSET_QUEUE(x) \ #define SCD_TRANS_TBL_OFFSET_QUEUE(x) \
((SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc) ((SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc)
......
...@@ -444,6 +444,10 @@ enum iwl_trans_state { ...@@ -444,6 +444,10 @@ enum iwl_trans_state {
* @dev_cmd_headroom: room needed for the transport's private use before the * @dev_cmd_headroom: room needed for the transport's private use before the
* device_cmd for Tx - for internal use only * device_cmd for Tx - for internal use only
* The user should use iwl_trans_{alloc,free}_tx_cmd. * The user should use iwl_trans_{alloc,free}_tx_cmd.
* @rx_mpdu_cmd: MPDU RX command ID, must be assigned by opmode before
* starting the firmware, used for tracing
* @rx_mpdu_cmd_hdr_size: used for tracing, amount of data before the
* start of the 802.11 header in the @rx_mpdu_cmd
*/ */
struct iwl_trans { struct iwl_trans {
const struct iwl_trans_ops *ops; const struct iwl_trans_ops *ops;
...@@ -457,6 +461,8 @@ struct iwl_trans { ...@@ -457,6 +461,8 @@ struct iwl_trans {
u32 hw_id; u32 hw_id;
char hw_id_str[52]; char hw_id_str[52];
u8 rx_mpdu_cmd, rx_mpdu_cmd_hdr_size;
bool pm_support; bool pm_support;
wait_queue_head_t wait_command_queue; wait_queue_head_t wait_command_queue;
...@@ -516,6 +522,8 @@ static inline int iwl_trans_start_fw(struct iwl_trans *trans, ...@@ -516,6 +522,8 @@ static inline int iwl_trans_start_fw(struct iwl_trans *trans,
{ {
might_sleep(); might_sleep();
WARN_ON_ONCE(!trans->rx_mpdu_cmd);
return trans->ops->start_fw(trans, fw); return trans->ops->start_fw(trans, fw);
} }
......
...@@ -411,7 +411,8 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, ...@@ -411,7 +411,8 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
len += sizeof(u32); /* account for status word */ len += sizeof(u32); /* account for status word */
trace_iwlwifi_dev_rx(trans->dev, pkt, len); trace_iwlwifi_dev_rx(trans->dev, trans, pkt, len);
trace_iwlwifi_dev_rx_data(trans->dev, trans, pkt, len);
/* Reclaim a command buffer only if this packet is a response /* Reclaim a command buffer only if this packet is a response
* to a (driver-originated) command. * to a (driver-originated) command.
......
...@@ -300,7 +300,7 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data) ...@@ -300,7 +300,7 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data)
struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; struct iwl_trans_pcie *trans_pcie = txq->trans_pcie;
struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie); struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie);
u32 scd_sram_addr = trans_pcie->scd_base_addr + u32 scd_sram_addr = trans_pcie->scd_base_addr +
SCD_TX_STTS_MEM_LOWER_BOUND + (16 * txq->q.id); SCD_TX_STTS_QUEUE_OFFSET(txq->q.id);
u8 buf[16]; u8 buf[16];
int i; int i;
...@@ -1385,11 +1385,13 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, ...@@ -1385,11 +1385,13 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen,
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
trace_iwlwifi_dev_tx(trans->dev, trace_iwlwifi_dev_tx(trans->dev, skb,
&txq->tfds[txq->q.write_ptr], &txq->tfds[txq->q.write_ptr],
sizeof(struct iwl_tfd), sizeof(struct iwl_tfd),
&dev_cmd->hdr, firstlen, &dev_cmd->hdr, firstlen,
skb->data + hdr_len, secondlen); skb->data + hdr_len, secondlen);
trace_iwlwifi_dev_tx_data(trans->dev, skb,
skb->data + hdr_len, secondlen);
/* start timer if queue currently empty */ /* start timer if queue currently empty */
if (txq->need_update && q->read_ptr == q->write_ptr && 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,14 +1516,13 @@ static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
/* n_bd is usually 256 => n_bd - 1 = 0xff */ /* n_bd is usually 256 => n_bd - 1 = 0xff */
int tfd_num = ssn & (txq->q.n_bd - 1); int tfd_num = ssn & (txq->q.n_bd - 1);
int freed = 0;
spin_lock(&txq->lock); spin_lock(&txq->lock);
if (txq->q.read_ptr != tfd_num) { if (txq->q.read_ptr != tfd_num) {
IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n", IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n",
txq_id, txq->q.read_ptr, tfd_num, ssn); txq_id, txq->q.read_ptr, tfd_num, ssn);
freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs);
if (iwl_queue_space(&txq->q) > txq->q.low_mark) if (iwl_queue_space(&txq->q) > txq->q.low_mark)
iwl_wake_queue(trans, txq); iwl_wake_queue(trans, txq);
} }
......
...@@ -480,21 +480,20 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, ...@@ -480,21 +480,20 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id)
{ {
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
u16 rd_ptr, wr_ptr; u32 stts_addr = trans_pcie->scd_base_addr +
int n_bd = trans_pcie->txq[txq_id].q.n_bd; SCD_TX_STTS_QUEUE_OFFSET(txq_id);
static const u32 zero_val[4] = {};
if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) {
WARN_ONCE(1, "queue %d not used", txq_id); WARN_ONCE(1, "queue %d not used", txq_id);
return; return;
} }
rd_ptr = iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & (n_bd - 1); iwl_txq_set_inactive(trans, txq_id);
wr_ptr = iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id));
WARN_ONCE(rd_ptr != wr_ptr, "queue %d isn't empty: [%d,%d]", _iwl_write_targ_mem_dwords(trans, stts_addr,
txq_id, rd_ptr, wr_ptr); zero_val, ARRAY_SIZE(zero_val));
iwl_txq_set_inactive(trans, txq_id);
IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id);
} }
...@@ -549,7 +548,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) ...@@ -549,7 +548,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
* allocated into separate TFDs, then we will need to * allocated into separate TFDs, then we will need to
* increase the size of the buffers. * increase the size of the buffers.
*/ */
if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE)) if (WARN(copy_size > TFD_MAX_PAYLOAD_SIZE,
"Command %s (%#x) is too large (%d bytes)\n",
trans_pcie_get_cmd_string(trans_pcie, cmd->id),
cmd->id, copy_size))
return -EINVAL; return -EINVAL;
spin_lock_bh(&txq->lock); spin_lock_bh(&txq->lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment