Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / iwlwifi / iwl-testmode.c
index 4a5cddd2d56bfb867a21c6d00f49cd219743ce2a..a56a77b8f9264ec85041cf1b93e73795fdaf46fc 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -115,6 +115,9 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
 
        [IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, },
        [IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, },
+       [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, },
 };
 
 /*
@@ -299,7 +302,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
 
        switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
        case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
-               val32 = iwl_read32(bus(priv), ofs);
+               val32 = iwl_read_direct32(bus(priv), ofs);
                IWL_INFO(priv, "32bit value to read 0x%x\n", val32);
 
                skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
@@ -321,7 +324,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
                } else {
                        val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
                        IWL_INFO(priv, "32bit value to write 0x%x\n", val32);
-                       iwl_write32(bus(priv), ofs, val32);
+                       iwl_write_direct32(bus(priv), ofs, val32);
                }
                break;
        case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
@@ -422,7 +425,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
        struct sk_buff *skb;
        unsigned char *rsp_data_ptr = NULL;
        int status = 0, rsp_data_len = 0;
-       u32 devid;
+       u32 devid, inst_size = 0, data_size = 0;
 
        switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
        case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
@@ -548,6 +551,41 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
                                        "Error sending msg : %d\n", status);
                break;
 
+       case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
+               skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8);
+               if (!skb) {
+                       IWL_DEBUG_INFO(priv, "Error allocating memory\n");
+                       return -ENOMEM;
+               }
+               switch (priv->shrd->ucode_type) {
+               case IWL_UCODE_REGULAR:
+                       inst_size = trans(priv)->ucode_rt.code.len;
+                       data_size = trans(priv)->ucode_rt.data.len;
+                       break;
+               case IWL_UCODE_INIT:
+                       inst_size = trans(priv)->ucode_init.code.len;
+                       data_size = trans(priv)->ucode_init.data.len;
+                       break;
+               case IWL_UCODE_WOWLAN:
+                       inst_size = trans(priv)->ucode_wowlan.code.len;
+                       data_size = trans(priv)->ucode_wowlan.data.len;
+                       break;
+               case IWL_UCODE_NONE:
+                       IWL_DEBUG_INFO(priv, "The uCode has not been loaded\n");
+                       break;
+               default:
+                       IWL_DEBUG_INFO(priv, "Unsupported uCode type\n");
+                       break;
+               }
+               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);
+               NLA_PUT_U32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size);
+               status = cfg80211_testmode_reply(skb);
+               if (status < 0)
+                       IWL_DEBUG_INFO(priv,
+                                       "Error sending msg : %d\n", status);
+               break;
+
        default:
                IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n");
                return -ENOSYS;
@@ -733,7 +771,7 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
 static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb)
 {
        struct iwl_priv *priv = hw->priv;
-       u32 base, ofs, size, maxsize;
+       u32 ofs, size, maxsize;
 
        if (priv->testmode_sram.sram_readed)
                return -EBUSY;
@@ -759,25 +797,24 @@ static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb)
                maxsize = trans(priv)->ucode_wowlan.data.len;
                break;
        case IWL_UCODE_NONE:
-               IWL_DEBUG_INFO(priv, "Error, uCode does not been loaded\n");
+               IWL_ERR(priv, "Error, uCode does not been loaded\n");
                return -ENOSYS;
        default:
-               IWL_DEBUG_INFO(priv, "Error, unsupported uCode type\n");
+               IWL_ERR(priv, "Error, unsupported uCode type\n");
                return -ENOSYS;
        }
-       if ((ofs + size) > maxsize) {
-               IWL_DEBUG_INFO(priv, "Invalid offset/size: out of range\n");
+       if ((ofs + size) > (maxsize + SRAM_DATA_SEG_OFFSET)) {
+               IWL_ERR(priv, "Invalid offset/size: out of range\n");
                return -EINVAL;
        }
        priv->testmode_sram.buff_size = (size / 4) * 4;
        priv->testmode_sram.buff_addr =
                kmalloc(priv->testmode_sram.buff_size, GFP_KERNEL);
        if (priv->testmode_sram.buff_addr == NULL) {
-               IWL_DEBUG_INFO(priv, "Error allocating memory\n");
+               IWL_ERR(priv, "Error allocating memory\n");
                return -ENOMEM;
        }
-       base = 0x800000;
-       _iwl_read_targ_mem_words(bus(priv), base + ofs,
+       _iwl_read_targ_mem_words(bus(priv), ofs,
                                        priv->testmode_sram.buff_addr,
                                        priv->testmode_sram.buff_size / 4);
        priv->testmode_sram.num_chunks =
@@ -882,6 +919,7 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
        case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
        case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
        case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
+       case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
                IWL_DEBUG_INFO(priv, "testmode cmd to driver\n");
                result = iwl_testmode_driver(hw, tb);
                break;