Skip to content

Commit

Permalink
iwlagn: add dumpit support for testmode trace function
Browse files Browse the repository at this point in the history
For testmode trace function, huge amout of data need to pass to userspace.
Use the build-in nl80211 dumpt it function

Require nl80211 testmode dumpit support patch.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
  • Loading branch information
Wey-Yi Guy committed Jun 11, 2011
1 parent 49b7210 commit eb64dca
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 26 deletions.
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -3352,6 +3352,7 @@ struct ieee80211_ops iwlagn_hw_ops = {
.offchannel_tx = iwl_mac_offchannel_tx,
.offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait,
CFG80211_TESTMODE_CMD(iwl_testmode_cmd)
CFG80211_TESTMODE_DUMP(iwl_testmode_dump)
};

static u32 iwl_hw_detect(struct iwl_priv *priv)
Expand Down
10 changes: 10 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-agn.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,9 @@ extern int iwl_alive_start(struct iwl_priv *priv);
/* svtool */
#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
extern int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len);
extern int iwl_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
struct netlink_callback *cb,
void *data, int len);
extern void iwl_testmode_init(struct iwl_priv *priv);
extern void iwl_testmode_cleanup(struct iwl_priv *priv);
#else
Expand All @@ -352,6 +355,13 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
return -ENOSYS;
}
static inline
int iwl_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
struct netlink_callback *cb,
void *data, int len)
{
return -ENOSYS;
}
static inline
void iwl_testmode_init(struct iwl_priv *priv)
{
}
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -1172,6 +1172,7 @@ enum iwl_scan_type {
struct iwl_testmode_trace {
u32 buff_size;
u32 total_size;
u32 num_chunks;
u8 *cpu_addr;
u8 *trace_addr;
dma_addr_t dma_addr;
Expand Down
106 changes: 82 additions & 24 deletions drivers/net/wireless/iwlwifi/iwl-sv-open.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
[IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, },

[IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, },
[IWL_TM_ATTR_TRACE_DATA] = { .type = NLA_UNSPEC, },
[IWL_TM_ATTR_TRACE_DUMP] = { .type = NLA_UNSPEC, },
[IWL_TM_ATTR_TRACE_SIZE] = { .type = NLA_U32, },

[IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, },
Expand Down Expand Up @@ -534,34 +534,14 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
"Error sending msg : %d\n",
status);
}
priv->testmode_trace.num_chunks =
DIV_ROUND_UP(priv->testmode_trace.buff_size,
TRACE_CHUNK_SIZE);
break;

case IWL_TM_CMD_APP2DEV_END_TRACE:
iwl_trace_cleanup(priv);
break;

case IWL_TM_CMD_APP2DEV_READ_TRACE:
if (priv->testmode_trace.trace_enabled &&
priv->testmode_trace.trace_addr) {
skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
20 + priv->testmode_trace.buff_size);
if (skb == NULL) {
IWL_DEBUG_INFO(priv,
"Error allocating memory\n");
return -ENOMEM;
}
NLA_PUT(skb, IWL_TM_ATTR_TRACE_DATA,
priv->testmode_trace.buff_size,
priv->testmode_trace.trace_addr);
status = cfg80211_testmode_reply(skb);
if (status < 0) {
IWL_DEBUG_INFO(priv,
"Error sending msg : %d\n", status);
}
} else
return -EFAULT;
break;

default:
IWL_DEBUG_INFO(priv, "Unknown testmode mem command ID\n");
return -ENOSYS;
Expand All @@ -576,6 +556,37 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
return -EMSGSIZE;
}

static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb,
struct sk_buff *skb,
struct netlink_callback *cb)
{
struct iwl_priv *priv = hw->priv;
int idx, length;

if (priv->testmode_trace.trace_enabled &&
priv->testmode_trace.trace_addr) {
idx = cb->args[4];
if (idx >= priv->testmode_trace.num_chunks)
return -ENOENT;
length = TRACE_CHUNK_SIZE;
if (((idx + 1) == priv->testmode_trace.num_chunks) &&
(priv->testmode_trace.buff_size % TRACE_CHUNK_SIZE))
length = priv->testmode_trace.buff_size %
TRACE_CHUNK_SIZE;

NLA_PUT(skb, IWL_TM_ATTR_TRACE_DUMP, length,
priv->testmode_trace.trace_addr +
(TRACE_CHUNK_SIZE * idx));
idx++;
cb->args[4] = idx;
return 0;
} else
return -EFAULT;

nla_put_failure:
return -ENOBUFS;
}

/* The testmode gnl message handler that takes the gnl message from the
* user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
* invoke the corresponding handlers.
Expand Down Expand Up @@ -654,3 +665,50 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
mutex_unlock(&priv->mutex);
return result;
}

int iwl_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
struct netlink_callback *cb,
void *data, int len)
{
struct nlattr *tb[IWL_TM_ATTR_MAX];
struct iwl_priv *priv = hw->priv;
int result;
u32 cmd;

if (cb->args[3]) {
/* offset by 1 since commands start at 0 */
cmd = cb->args[3] - 1;
} else {
result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
iwl_testmode_gnl_msg_policy);
if (result) {
IWL_DEBUG_INFO(priv,
"Error parsing the gnl message : %d\n", result);
return result;
}

/* IWL_TM_ATTR_COMMAND is absolutely mandatory */
if (!tb[IWL_TM_ATTR_COMMAND]) {
IWL_DEBUG_INFO(priv,
"Error finding testmode command type\n");
return -ENOMSG;
}
cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
cb->args[3] = cmd + 1;
}

/* in case multiple accesses to the device happens */
mutex_lock(&priv->mutex);
switch (cmd) {
case IWL_TM_CMD_APP2DEV_READ_TRACE:
IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n");
result = iwl_testmode_trace_dump(hw, tb, skb, cb);
break;
default:
result = -EINVAL;
break;
}

mutex_unlock(&priv->mutex);
return result;
}
4 changes: 2 additions & 2 deletions drivers/net/wireless/iwlwifi/iwl-testmode.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ enum iwl_tm_attr_t {
* IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address
*/
IWL_TM_ATTR_TRACE_ADDR,
IWL_TM_ATTR_TRACE_DATA,
IWL_TM_ATTR_TRACE_SIZE,
IWL_TM_ATTR_TRACE_DUMP,

/* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ,
* The mandatory fields are:
Expand All @@ -182,7 +182,7 @@ enum iwl_tm_attr_t {
#define TRACE_BUFF_SIZE_MAX 0x200000
#define TRACE_BUFF_SIZE_MIN 0x20000
#define TRACE_BUFF_SIZE_DEF TRACE_BUFF_SIZE_MIN

#define TRACE_BUFF_PADD 0x2000
#define TRACE_CHUNK_SIZE (PAGE_SIZE - 1024)

#endif

0 comments on commit eb64dca

Please sign in to comment.