Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 291438
b: refs/heads/master
c: 6dfa8d0
h: refs/heads/master
v: v3
  • Loading branch information
David Spinadel authored and John W. Linville committed Mar 12, 2012
1 parent e5e4418 commit 17933cc
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 142 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ed8c8365c4431eeb733def3dd314cf303e1b12ea
refs/heads/master: 6dfa8d019cd21d08634ceb65a3fb90d0648bd93b
17 changes: 5 additions & 12 deletions trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
int pos = 0;
int sram;
struct iwl_priv *priv = file->private_data;
const struct fw_img *img;
size_t bufsz;

/* default is to dump the entire data segment */
Expand All @@ -239,17 +240,8 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
IWL_ERR(priv, "No uCode has been loadded.\n");
return -EINVAL;
}
if (priv->shrd->ucode_type == IWL_UCODE_INIT) {
priv->dbgfs_sram_len = priv->fw->ucode_init.data.len;
} else if (priv->shrd->ucode_type == IWL_UCODE_REGULAR) {
priv->dbgfs_sram_len = priv->fw->ucode_rt.data.len;
} else if (priv->shrd->ucode_type == IWL_UCODE_WOWLAN) {
priv->dbgfs_sram_len = priv->fw->ucode_wowlan.data.len;
} else {
IWL_ERR(priv, "Unsupported type of uCode loaded?"
" that shouldn't happen.\n");
return -EINVAL;
}
img = &priv->fw->img[priv->shrd->ucode_type];
priv->dbgfs_sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
}
len = priv->dbgfs_sram_len;

Expand Down Expand Up @@ -346,13 +338,14 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
const struct fw_img *img = &priv->fw->img[IWL_UCODE_WOWLAN];

if (!priv->wowlan_sram)
return -ENODATA;

return simple_read_from_buffer(user_buf, count, ppos,
priv->wowlan_sram,
priv->fw->ucode_wowlan.data.len);
img->sec[IWL_UCODE_SECTION_DATA].len);
}
static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
Expand Down
141 changes: 76 additions & 65 deletions trunk/drivers/net/wireless/iwlwifi/iwl-drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,16 @@ static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc)

static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img)
{
iwl_free_fw_desc(drv, &img->code);
iwl_free_fw_desc(drv, &img->data);
int i;
for (i = 0; i < IWL_UCODE_SECTION_MAX; i++)
iwl_free_fw_desc(drv, &img->sec[i]);
}

static void iwl_dealloc_ucode(struct iwl_drv *drv)
{
iwl_free_fw_img(drv, &drv->fw.ucode_rt);
iwl_free_fw_img(drv, &drv->fw.ucode_init);
iwl_free_fw_img(drv, &drv->fw.ucode_wowlan);
int i;
for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
iwl_free_fw_img(drv, drv->fw.img + i);
}

static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc,
Expand Down Expand Up @@ -189,22 +190,8 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
GFP_KERNEL, drv, iwl_ucode_callback);
}

/*
* enumeration of ucode section.
* This enumeration is used for legacy tlv style (before 16.0 uCode).
*/
enum iwl_ucode_sec {
IWL_UCODE_SECTION_INST,
IWL_UCODE_SECTION_DATA,
};
/*
* For 16.0 uCode and above, there is no differentiation between section,
* just an offset to the HW address.
*/
#define UCODE_SECTION_MAX 4

struct fw_img_parsing {
struct fw_sec sec[UCODE_SECTION_MAX];
struct fw_sec sec[IWL_UCODE_SECTION_MAX];
int sec_counter;
};

Expand Down Expand Up @@ -691,6 +678,71 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
return -EINVAL;
}

static int alloc_pci_desc(struct iwl_drv *drv,
struct iwl_firmware_pieces *pieces,
enum iwl_ucode_type type)
{
int i;
for (i = 0;
i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i);
i++)
if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]),
get_sec(pieces, type, i)))
return -1;
return 0;
}

static int validate_sec_sizes(struct iwl_drv *drv,
struct iwl_firmware_pieces *pieces,
const struct iwl_cfg *cfg)
{
IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n",
get_sec_size(pieces, IWL_UCODE_REGULAR,
IWL_UCODE_SECTION_INST));
IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n",
get_sec_size(pieces, IWL_UCODE_REGULAR,
IWL_UCODE_SECTION_DATA));
IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n",
get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST));
IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n",
get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA));

/* Verify that uCode images will fit in card's SRAM. */
if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) >
cfg->max_inst_size) {
IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n",
get_sec_size(pieces, IWL_UCODE_REGULAR,
IWL_UCODE_SECTION_INST));
return -1;
}

if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) >
cfg->max_data_size) {
IWL_ERR(drv, "uCode data len %Zd too large to fit in\n",
get_sec_size(pieces, IWL_UCODE_REGULAR,
IWL_UCODE_SECTION_DATA));
return -1;
}

if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) >
cfg->max_inst_size) {
IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n",
get_sec_size(pieces, IWL_UCODE_INIT,
IWL_UCODE_SECTION_INST));
return -1;
}

if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA) >
cfg->max_data_size) {
IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n",
get_sec_size(pieces, IWL_UCODE_REGULAR,
IWL_UCODE_SECTION_DATA));
return -1;
}
return 0;
}


/**
* iwl_ucode_callback - callback when firmware was loaded
*
Expand All @@ -709,6 +761,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
unsigned int api_ok = cfg->ucode_api_ok;
const unsigned int api_min = cfg->ucode_api_min;
u32 api_ver;
int i;

fw->ucode_capa.max_probe_length = 200;
fw->ucode_capa.standard_phy_calibration_size =
Expand Down Expand Up @@ -817,59 +870,17 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
goto try_again;
}

if (get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) >
cfg->max_inst_size) {
IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n",
get_sec_size(&pieces, IWL_UCODE_INIT,
IWL_UCODE_SECTION_INST));
if (validate_sec_sizes(drv, &pieces, cfg))
goto try_again;
}

if (get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA) >
cfg->max_data_size) {
IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n",
get_sec_size(&pieces, IWL_UCODE_REGULAR,
IWL_UCODE_SECTION_DATA));
goto try_again;
}

/* Allocate ucode buffers for card's bus-master loading ... */

/* Runtime instructions and 2 copies of data:
* 1) unmodified from disk
* 2) backup cache for save/restore during power-downs */
if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.code,
get_sec(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST)))
goto err_pci_alloc;
if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.data,
get_sec(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA)))
goto err_pci_alloc;

/* Initialization instructions and data */
if (get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) &&
get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)) {
if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_init.code,
get_sec(&pieces, IWL_UCODE_INIT,
IWL_UCODE_SECTION_INST)))
goto err_pci_alloc;
if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_init.data,
get_sec(&pieces, IWL_UCODE_INIT,
IWL_UCODE_SECTION_DATA)))
for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
if (alloc_pci_desc(drv, &pieces, i))
goto err_pci_alloc;
}

/* WoWLAN instructions and data */
if (get_sec_size(&pieces, IWL_UCODE_WOWLAN, IWL_UCODE_SECTION_INST) &&
get_sec_size(&pieces, IWL_UCODE_WOWLAN, IWL_UCODE_SECTION_DATA)) {
if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_wowlan.code,
get_sec(&pieces, IWL_UCODE_WOWLAN,
IWL_UCODE_SECTION_INST)))
goto err_pci_alloc;
if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_wowlan.data,
get_sec(&pieces, IWL_UCODE_WOWLAN,
IWL_UCODE_SECTION_DATA)))
goto err_pci_alloc;
}

/* Now that we can no longer fail, copy information */

Expand Down
25 changes: 17 additions & 8 deletions trunk/drivers/net/wireless/iwlwifi/iwl-fw.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@ enum iwl_ucode_type {
IWL_UCODE_TYPE_MAX,
};

/*
* enumeration of ucode section.
* This enumeration is used for legacy tlv style (before 16.0 uCode).
*/
enum iwl_ucode_sec {
IWL_UCODE_SECTION_INST,
IWL_UCODE_SECTION_DATA,
};
/*
* For 16.0 uCode and above, there is no differentiation between sections,
* just an offset to the HW address.
*/
#define IWL_UCODE_SECTION_MAX 4

struct iwl_ucode_capabilities {
u32 max_probe_length;
u32 standard_phy_calibration_size;
Expand All @@ -116,8 +130,7 @@ struct fw_desc {
};

struct fw_img {
struct fw_desc code; /* firmware code image */
struct fw_desc data; /* firmware data image */
struct fw_desc sec[IWL_UCODE_SECTION_MAX];
};

/* uCode version contains 4 values: Major/Minor/API/Serial */
Expand All @@ -131,9 +144,7 @@ struct fw_img {
*
* @ucode_ver: ucode version from the ucode file
* @fw_version: firmware version string
* @ucode_rt: run time ucode image
* @ucode_init: init ucode image
* @ucode_wowlan: wake on wireless ucode image (optional)
* @img: ucode image like ucode_rt, ucode_init, ucode_wowlan.
* @ucode_capa: capabilities parsed from the ucode file.
* @enhance_sensitivity_table: device can do enhanced sensitivity.
* @init_evtlog_ptr: event log offset for init ucode.
Expand All @@ -149,9 +160,7 @@ struct iwl_fw {
char fw_version[ETHTOOL_BUSINFO_LEN];

/* ucode images */
struct fw_img ucode_rt;
struct fw_img ucode_init;
struct fw_img ucode_wowlan;
struct fw_img img[IWL_UCODE_TYPE_MAX];

struct iwl_ucode_capabilities ucode_capa;
bool enhance_sensitivity_table;
Expand Down
15 changes: 9 additions & 6 deletions trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
WIPHY_FLAG_DISABLE_BEACON_HINTS |
WIPHY_FLAG_IBSS_RSN;

if (priv->fw->ucode_wowlan.code.len &&
if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
trans(priv)->ops->wowlan_suspend &&
device_can_wakeup(trans(priv)->dev)) {
hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
Expand Down Expand Up @@ -437,6 +437,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
unsigned long flags;
u32 base, status = 0xffffffff;
int ret = -EIO;
const struct fw_img *img;

IWL_DEBUG_MAC80211(priv, "enter\n");
mutex_lock(&priv->mutex);
Expand All @@ -457,16 +458,18 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)

#ifdef CONFIG_IWLWIFI_DEBUGFS
if (ret == 0) {
if (!priv->wowlan_sram)
img = &(priv->fw->img[IWL_UCODE_WOWLAN]);
if (!priv->wowlan_sram) {
priv->wowlan_sram =
kzalloc(priv->fw->ucode_wowlan.data.len,
kzalloc(img->sec[IWL_UCODE_SECTION_DATA].len,
GFP_KERNEL);
}

if (priv->wowlan_sram)
_iwl_read_targ_mem_words(
trans(priv), 0x800000,
priv->wowlan_sram,
priv->fw->ucode_wowlan.data.len / 4);
trans(priv), 0x800000,
priv->wowlan_sram,
img->sec[IWL_UCODE_SECTION_DATA].len / 4);
}
#endif
}
Expand Down
21 changes: 4 additions & 17 deletions trunk/drivers/net/wireless/iwlwifi/iwl-testmode.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,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:
Expand Down Expand Up @@ -597,23 +598,9 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
IWL_ERR(priv, "No uCode has not been loaded\n");
return -EINVAL;
} else {
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;
default:
IWL_ERR(priv, "Unsupported uCode type\n");
break;
}
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);
Expand Down
Loading

0 comments on commit 17933cc

Please sign in to comment.