iwlwifi: change struct iwl_fw
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / iwl-testmode.c
index 63868df32263d64476ede7c4fb00765886011dcd..76f7f925143614c351c45bfc0e590809dcc4e638 100644 (file)
@@ -78,6 +78,7 @@
 #include "iwl-testmode.h"
 #include "iwl-trans.h"
 #include "iwl-fh.h"
+#include "iwl-prph.h"
 
 
 /* Periphery registers absolute lower bound. This is used in order to
@@ -124,6 +125,8 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
        [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, },
        [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, },
        [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, },
+
+       [IWL_TM_ATTR_ENABLE_NOTIFICATION] = {.type = NLA_FLAG, },
 };
 
 /*
@@ -182,7 +185,8 @@ static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
                return;
        }
        NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
-       NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data);
+       /* the length doesn't include len_n_flags field, so add it manually */
+       NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length + sizeof(__le32), data);
        cfg80211_testmode_event(skb, GFP_ATOMIC);
        return;
 
@@ -193,7 +197,7 @@ nla_put_failure:
 
 void iwl_testmode_init(struct iwl_priv *priv)
 {
-       priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
+       priv->pre_rx_handler = NULL;
        priv->testmode_trace.trace_enabled = false;
        priv->testmode_mem.read_in_progress = false;
 }
@@ -462,6 +466,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
        unsigned char *rsp_data_ptr = NULL;
        int status = 0, rsp_data_len = 0;
        u32 devid, inst_size = 0, data_size = 0;
+       const struct fw_img *img;
 
        switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
        case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
@@ -490,6 +495,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
 
        case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
                iwl_testmode_cfg_init_calib(priv);
+               priv->ucode_loaded = false;
                iwl_trans_stop_device(trans);
                break;
 
@@ -508,6 +514,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
 
        case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
                iwl_scan_cancel_timeout(priv, 200);
+               priv->ucode_loaded = false;
                iwl_trans_stop_device(trans);
                status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN);
                if (status) {
@@ -587,25 +594,13 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
                        IWL_ERR(priv, "Memory allocation fail\n");
                        return -ENOMEM;
                }
-               switch (priv->shrd->ucode_type) {
-               case IWL_UCODE_REGULAR:
-                       inst_size = priv->fw->ucode_rt.code.len;
-                       data_size = priv->fw->ucode_rt.data.len;
-                       break;
-               case IWL_UCODE_INIT:
-                       inst_size = priv->fw->ucode_init.code.len;
-                       data_size = priv->fw->ucode_init.data.len;
-                       break;
-               case IWL_UCODE_WOWLAN:
-                       inst_size = priv->fw->ucode_wowlan.code.len;
-                       data_size = priv->fw->ucode_wowlan.data.len;
-                       break;
-               case IWL_UCODE_NONE:
+               if (!priv->ucode_loaded) {
                        IWL_ERR(priv, "No uCode has not been loaded\n");
-                       break;
-               default:
-                       IWL_ERR(priv, "Unsupported uCode type\n");
-                       break;
+                       return -EINVAL;
+               } else {
+                       img = &priv->fw->img[priv->shrd->ucode_type];
+                       inst_size = img->sec[IWL_UCODE_SECTION_INST].len;
+                       data_size = img->sec[IWL_UCODE_SECTION_DATA].len;
                }
                NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type);
                NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size);
@@ -712,7 +707,7 @@ nla_put_failure:
        return -EMSGSIZE;
 }
 
-static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb,
+static int iwl_testmode_trace_dump(struct ieee80211_hw *hw,
                                   struct sk_buff *skb,
                                   struct netlink_callback *cb)
 {
@@ -769,9 +764,13 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
        }
 
        owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]);
-       if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM))
+       if (owner == IWL_OWNERSHIP_DRIVER) {
                priv->ucode_owner = owner;
-       else {
+               priv->pre_rx_handler = NULL;
+       } else if (owner == IWL_OWNERSHIP_TM) {
+               priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
+               priv->ucode_owner = owner;
+       } else {
                IWL_ERR(priv, "Invalid owner\n");
                return -EINVAL;
        }
@@ -904,9 +903,9 @@ static int iwl_testmode_indirect_mem(struct ieee80211_hw *hw,
        }
 }
 
-static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, struct nlattr **tb,
-                                  struct sk_buff *skb,
-                                  struct netlink_callback *cb)
+static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw,
+                                   struct sk_buff *skb,
+                                   struct netlink_callback *cb)
 {
        struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        int idx, length;
@@ -936,6 +935,20 @@ static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, struct nlattr **tb,
        return -ENOBUFS;
 }
 
+static int iwl_testmode_notifications(struct ieee80211_hw *hw,
+       struct nlattr **tb)
+{
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
+       bool enable;
+
+       enable = nla_get_flag(tb[IWL_TM_ATTR_ENABLE_NOTIFICATION]);
+       if (enable)
+               priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
+       else
+               priv->pre_rx_handler = NULL;
+       return 0;
+}
+
 
 /* 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
@@ -1021,6 +1034,12 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
                result = iwl_testmode_indirect_mem(hw, tb);
                break;
 
+       case IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
+               IWL_DEBUG_INFO(priv, "testmode notifications cmd "
+                       "to driver\n");
+               result = iwl_testmode_notifications(hw, tb);
+               break;
+
        default:
                IWL_ERR(priv, "Unknown testmode command\n");
                result = -ENOSYS;
@@ -1066,11 +1085,11 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
        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);
+               result = iwl_testmode_trace_dump(hw, skb, cb);
                break;
        case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP:
                IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n");
-               result = iwl_testmode_buffer_dump(hw, tb, skb, cb);
+               result = iwl_testmode_buffer_dump(hw, skb, cb);
                break;
        default:
                result = -EINVAL;
This page took 0.030432 seconds and 5 git commands to generate.