*
*****************************************************************************/
+#include <linux/export.h>
#include <net/netlink.h>
+
#include "iwl-io.h"
#include "iwl-fh.h"
#include "iwl-prph.h"
}
EXPORT_SYMBOL_GPL(iwl_test_free);
+static inline int iwl_test_send_cmd(struct iwl_test *tst,
+ struct iwl_host_cmd *cmd)
+{
+ return tst->ops->send_cmd(tst->trans->op_mode, cmd);
+}
+
+static inline bool iwl_test_valid_hw_addr(struct iwl_test *tst, u32 addr)
+{
+ return tst->ops->valid_hw_addr(addr);
+}
+
+static inline u32 iwl_test_fw_ver(struct iwl_test *tst)
+{
+ return tst->ops->get_fw_ver(tst->trans->op_mode);
+}
+
+static inline struct sk_buff*
+iwl_test_alloc_reply(struct iwl_test *tst, int len)
+{
+ return tst->ops->alloc_reply(tst->trans->op_mode, len);
+}
+
+static inline int iwl_test_reply(struct iwl_test *tst, struct sk_buff *skb)
+{
+ return tst->ops->reply(tst->trans->op_mode, skb);
+}
+
+static inline struct sk_buff*
+iwl_test_alloc_event(struct iwl_test *tst, int len)
+{
+ return tst->ops->alloc_event(tst->trans->op_mode, len);
+}
+
+static inline void
+iwl_test_event(struct iwl_test *tst, struct sk_buff *skb)
+{
+ return tst->ops->event(tst->trans->op_mode, skb);
+}
+
/*
* This function handles the user application commands to the fw. The fw
* commands are sent in a synchronuous manner. In case that the user requested
* to get commands response, it is send to the user.
*/
-static int iwl_test_fw_cmd(struct iwl_test *tst, struct ieee80211_hw *hw,
- struct nlattr **tb)
+static int iwl_test_fw_cmd(struct iwl_test *tst, struct nlattr **tb)
{
struct iwl_host_cmd cmd;
struct iwl_rx_packet *pkt;
IWL_DEBUG_INFO(tst->trans, "test fw cmd=0x%x, flags 0x%x, len %d\n",
cmd.id, cmd.flags, cmd.len[0]);
- ret = tst->ops->send_cmd(tst->trans->op_mode, &cmd);
+ ret = iwl_test_send_cmd(tst, &cmd);
if (ret) {
IWL_ERR(tst->trans, "Failed to send hcmd\n");
return ret;
}
reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
- skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, reply_len + 20);
+ skb = iwl_test_alloc_reply(tst, reply_len + 20);
reply_buf = kmalloc(reply_len, GFP_KERNEL);
if (!skb || !reply_buf) {
kfree_skb(skb);
IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) ||
nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf))
goto nla_put_failure;
- return cfg80211_testmode_reply(skb);
+ return iwl_test_reply(tst, skb);
nla_put_failure:
IWL_DEBUG_INFO(tst->trans, "Failed creating NL attributes\n");
/*
* Handles the user application commands for register access.
*/
-static int iwl_test_reg(struct iwl_test *tst, struct ieee80211_hw *hw,
- struct nlattr **tb)
+static int iwl_test_reg(struct iwl_test *tst, struct nlattr **tb)
{
u32 ofs, val32, cmd;
u8 val8;
val32 = iwl_read_direct32(tst->trans, ofs);
IWL_DEBUG_INFO(trans, "32 value to read 0x%x\n", val32);
- skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
+ skb = iwl_test_alloc_reply(tst, 20);
if (!skb) {
IWL_ERR(trans, "Memory allocation fail\n");
return -ENOMEM;
}
if (nla_put_u32(skb, IWL_TM_ATTR_REG_VALUE32, val32))
goto nla_put_failure;
- status = cfg80211_testmode_reply(skb);
+ status = iwl_test_reply(tst, skb);
if (status < 0)
IWL_ERR(trans, "Error sending msg : %d\n", status);
break;
* Handles the request to start FW tracing. Allocates of the trace buffer
* and sends a reply to user space with the address of the allocated buffer.
*/
-static int iwl_test_trace_begin(struct iwl_test *tst, struct ieee80211_hw *hw,
- struct nlattr **tb)
+static int iwl_test_trace_begin(struct iwl_test *tst, struct nlattr **tb)
{
struct sk_buff *skb;
int status = 0;
memset(tst->trace.trace_addr, 0x03B, tst->trace.size);
- skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
- sizeof(tst->trace.dma_addr) + 20);
-
+ skb = iwl_test_alloc_reply(tst, sizeof(tst->trace.dma_addr) + 20);
if (!skb) {
IWL_ERR(tst->trans, "Memory allocation fail\n");
iwl_test_trace_stop(tst);
(u64 *)&tst->trace.dma_addr))
goto nla_put_failure;
- status = cfg80211_testmode_reply(skb);
+ status = iwl_test_reply(tst, skb);
if (status < 0)
IWL_ERR(tst->trans, "Error sending msg : %d\n", status);
iwl_write_prph(trans, addr+i,
*(u32 *)(buf+i));
}
- } else if (tst->ops->valid_hw_addr(addr)) {
+ } else if (iwl_test_valid_hw_addr(tst, addr)) {
_iwl_write_targ_mem_words(trans, addr, buf, size/4);
} else {
return -EINVAL;
/*
* Handles the request to get the device id
*/
-static int iwl_test_get_dev_id(struct iwl_test *tst, struct ieee80211_hw *hw,
- struct nlattr **tb)
+static int iwl_test_get_dev_id(struct iwl_test *tst, struct nlattr **tb)
{
u32 devid = tst->trans->hw_id;
struct sk_buff *skb;
IWL_DEBUG_INFO(tst->trans, "hw version: 0x%x\n", devid);
- skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
+ skb = iwl_test_alloc_reply(tst, 20);
if (!skb) {
IWL_ERR(tst->trans, "Memory allocation fail\n");
return -ENOMEM;
if (nla_put_u32(skb, IWL_TM_ATTR_DEVICE_ID, devid))
goto nla_put_failure;
- status = cfg80211_testmode_reply(skb);
+ status = iwl_test_reply(tst, skb);
if (status < 0)
IWL_ERR(tst->trans, "Error sending msg : %d\n", status);
/*
* Handles the request to get the FW version
*/
-static int iwl_test_get_fw_ver(struct iwl_test *tst, struct ieee80211_hw *hw,
- struct nlattr **tb)
+static int iwl_test_get_fw_ver(struct iwl_test *tst, struct nlattr **tb)
{
struct sk_buff *skb;
int status;
- u32 ver = tst->ops->get_fw_ver(tst->trans->op_mode);
+ u32 ver = iwl_test_fw_ver(tst);
IWL_DEBUG_INFO(tst->trans, "uCode version raw: 0x%x\n", ver);
- skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
+ skb = iwl_test_alloc_reply(tst, 20);
if (!skb) {
IWL_ERR(tst->trans, "Memory allocation fail\n");
return -ENOMEM;
if (nla_put_u32(skb, IWL_TM_ATTR_FW_VERSION, ver))
goto nla_put_failure;
- status = cfg80211_testmode_reply(skb);
+ status = iwl_test_reply(tst, skb);
if (status < 0)
IWL_ERR(tst->trans, "Error sending msg : %d\n", status);
* Returns 1 for unknown commands (not handled by the test object); negative
* value in case of error.
*/
-int iwl_test_handle_cmd(struct iwl_test *tst, struct ieee80211_hw *hw,
- struct nlattr **tb)
+int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb)
{
int result;
switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
case IWL_TM_CMD_APP2DEV_UCODE:
IWL_DEBUG_INFO(tst->trans, "test cmd to uCode\n");
- result = iwl_test_fw_cmd(tst, hw, tb);
+ result = iwl_test_fw_cmd(tst, tb);
break;
case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
IWL_DEBUG_INFO(tst->trans, "test cmd to register\n");
- result = iwl_test_reg(tst, hw, tb);
+ result = iwl_test_reg(tst, tb);
break;
case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
IWL_DEBUG_INFO(tst->trans, "test uCode trace cmd to driver\n");
- result = iwl_test_trace_begin(tst, hw, tb);
+ result = iwl_test_trace_begin(tst, tb);
break;
case IWL_TM_CMD_APP2DEV_END_TRACE:
case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
IWL_DEBUG_INFO(tst->trans, "test get FW ver cmd\n");
- result = iwl_test_get_fw_ver(tst, hw, tb);
+ result = iwl_test_get_fw_ver(tst, tb);
break;
case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
IWL_DEBUG_INFO(tst->trans, "test Get device ID cmd\n");
- result = iwl_test_get_dev_id(tst, hw, tb);
+ result = iwl_test_get_dev_id(tst, tb);
break;
default:
/*
* Multicast a spontaneous messages from the device to the user space.
*/
-static void iwl_test_send_rx(struct iwl_test *tst, struct ieee80211_hw *hw,
+static void iwl_test_send_rx(struct iwl_test *tst,
struct iwl_rx_cmd_buffer *rxb)
{
struct sk_buff *skb;
/* the length doesn't include len_n_flags field, so add it manually */
length += sizeof(__le32);
- skb = cfg80211_testmode_alloc_event_skb(hw->wiphy, 20 + length,
- GFP_ATOMIC);
+ skb = iwl_test_alloc_event(tst, length + 20);
if (skb == NULL) {
IWL_ERR(tst->trans, "Out of memory for message to user\n");
return;
nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data))
goto nla_put_failure;
- cfg80211_testmode_event(skb, GFP_ATOMIC);
+ iwl_test_event(tst, skb);
return;
nla_put_failure:
* Called whenever a Rx frames is recevied from the device. If notifications to
* the user space are requested, sends the frames to the user.
*/
-void iwl_test_rx(struct iwl_test *tst, struct ieee80211_hw *hw,
- struct iwl_rx_cmd_buffer *rxb)
+void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb)
{
if (tst->notify)
- iwl_test_send_rx(tst, hw, rxb);
+ iwl_test_send_rx(tst, rxb);
}
EXPORT_SYMBOL_GPL(iwl_test_rx);
bool in_read;
};
+/*
+ * struct iwl_test_ops: callback to the op mode
+ *
+ * The structure defines the callbacks that the op_mode should handle,
+ * inorder to handle logic that is out of the scope of iwl_test. The
+ * op_mode must set all the callbacks.
+
+ * @send_cmd: handler that is used by the test object to request the
+ * op_mode to send a command to the fw.
+ *
+ * @valid_hw_addr: handler that is used by the test object to request the
+ * op_mode to check if the given address is a valid address.
+ *
+ * @get_fw_ver: handler used to get the FW version.
+ *
+ * @alloc_reply: handler used by the test object to request the op_mode
+ * to allocate an skb for sending a reply to the user, and initialize
+ * the skb. It is assumed that the test object only fills the required
+ * attributes.
+ *
+ * @reply: handler used by the test object to request the op_mode to reply
+ * to a request. The skb is an skb previously allocated by the the
+ * alloc_reply callback.
+ I
+ * @alloc_event: handler used by the test object to request the op_mode
+ * to allocate an skb for sending an event, and initialize
+ * the skb. It is assumed that the test object only fills the required
+ * attributes.
+ *
+ * @reply: handler used by the test object to request the op_mode to send
+ * an event. The skb is an skb previously allocated by the the
+ * alloc_event callback.
+ */
struct iwl_test_ops {
int (*send_cmd)(struct iwl_op_mode *op_modes,
struct iwl_host_cmd *cmd);
bool (*valid_hw_addr)(u32 addr);
u32 (*get_fw_ver)(struct iwl_op_mode *op_mode);
+
+ struct sk_buff *(*alloc_reply)(struct iwl_op_mode *op_mode, int len);
+ int (*reply)(struct iwl_op_mode *op_mode, struct sk_buff *skb);
+ struct sk_buff* (*alloc_event)(struct iwl_op_mode *op_mode, int len);
+ void (*event)(struct iwl_op_mode *op_mode, struct sk_buff *skb);
};
struct iwl_test {
int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb,
void *data, int len);
-int iwl_test_handle_cmd(struct iwl_test *tst, struct ieee80211_hw *hw,
- struct nlattr **tb);
+int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb);
int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb,
struct netlink_callback *cb);
-void iwl_test_rx(struct iwl_test *tst, struct ieee80211_hw *hw,
- struct iwl_rx_cmd_buffer *rxb);
+void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb);
static inline void iwl_test_enable_notifications(struct iwl_test *tst,
bool enable)