Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 291437
b: refs/heads/master
c: ed8c836
h: refs/heads/master
i:
  291435: 8315ef3
v: v3
  • Loading branch information
David Spinadel authored and John W. Linville committed Mar 12, 2012
1 parent fcb0a2f commit e5e4418
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 17 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: 0cedacc5797bbae5b07e5e861fbe7b8e33f2ef78
refs/heads/master: ed8c8365c4431eeb733def3dd314cf303e1b12ea
84 changes: 84 additions & 0 deletions trunk/drivers/net/wireless/iwlwifi/iwl-drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,25 @@ struct fw_img_parsing {
int sec_counter;
};

/*
* struct fw_sec_parsing: to extract fw section and it's offset from tlv
*/
struct fw_sec_parsing {
__le32 offset;
const u8 data[];
} __packed;

/**
* struct iwl_tlv_calib_data - parse the default calib data from TLV
*
* @ucode_type: the uCode to which the following default calib relates.
* @calib: default calibrations.
*/
struct iwl_tlv_calib_data {
__le32 ucode_type;
__le64 calib;
} __packed;

struct iwl_firmware_pieces {
struct fw_img_parsing img[IWL_UCODE_TYPE_MAX];

Expand Down Expand Up @@ -257,6 +276,47 @@ static void set_sec_offset(struct iwl_firmware_pieces *pieces,
pieces->img[type].sec[sec].offset = offset;
}

/*
* Gets uCode section from tlv.
*/
static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces,
const void *data, enum iwl_ucode_type type,
int size)
{
struct fw_img_parsing *img;
struct fw_sec *sec;
struct fw_sec_parsing *sec_parse;

if (WARN_ON(!pieces || !data || type >= IWL_UCODE_TYPE_MAX))
return -1;

sec_parse = (struct fw_sec_parsing *)data;

img = &pieces->img[type];
sec = &img->sec[img->sec_counter];

sec->offset = le32_to_cpu(sec_parse->offset);
sec->data = sec_parse->data;

++img->sec_counter;

return 0;
}

static int iwl_set_default_calib(struct iwl_drv *drv, const u8 *data)
{
struct iwl_tlv_calib_data *def_calib =
(struct iwl_tlv_calib_data *)data;
u32 ucode_type = le32_to_cpu(def_calib->ucode_type);
if (ucode_type >= IWL_UCODE_TYPE_MAX) {
IWL_ERR(drv, "Wrong ucode_type %u for default calibration.\n",
ucode_type);
return -EINVAL;
}
drv->fw.default_calib[ucode_type] = le64_to_cpu(def_calib->calib);
return 0;
}

static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
const struct firmware *ucode_raw,
struct iwl_firmware_pieces *pieces)
Expand Down Expand Up @@ -586,6 +646,29 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
capa->standard_phy_calibration_size =
le32_to_cpup((__le32 *)tlv_data);
break;
case IWL_UCODE_TLV_SEC_RT:
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR,
tlv_len);
break;
case IWL_UCODE_TLV_SEC_INIT:
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_INIT,
tlv_len);
break;
case IWL_UCODE_TLV_SEC_WOWLAN:
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_WOWLAN,
tlv_len);
break;
case IWL_UCODE_TLV_DEF_CALIB:
if (tlv_len != sizeof(struct iwl_tlv_calib_data))
goto invalid_tlv_len;
if (iwl_set_default_calib(drv, tlv_data))
goto tlv_error;
break;
case IWL_UCODE_TLV_PHY_SKU:
if (tlv_len != sizeof(u32))
goto invalid_tlv_len;
drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data);
break;
default:
IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
break;
Expand All @@ -602,6 +685,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,

invalid_tlv_len:
IWL_ERR(drv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len);
tlv_error:
iwl_print_hex_dump(drv, IWL_DL_FW, tlv_data, tlv_len);

return -EINVAL;
Expand Down
5 changes: 5 additions & 0 deletions trunk/drivers/net/wireless/iwlwifi/iwl-fw-file.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_WOWLAN_INST = 16,
IWL_UCODE_TLV_WOWLAN_DATA = 17,
IWL_UCODE_TLV_FLAGS = 18,
IWL_UCODE_TLV_SEC_RT = 19,
IWL_UCODE_TLV_SEC_INIT = 20,
IWL_UCODE_TLV_SEC_WOWLAN = 21,
IWL_UCODE_TLV_DEF_CALIB = 22,
IWL_UCODE_TLV_PHY_SKU = 23,
};

struct iwl_ucode_tlv {
Expand Down
19 changes: 19 additions & 0 deletions trunk/drivers/net/wireless/iwlwifi/iwl-fw.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,22 @@ enum iwl_ucode_tlv_flag {
#define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19
#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE 253

/**
* enum iwl_ucode_type
*
* The type of ucode.
*
* @IWL_UCODE_REGULAR: Normal runtime ucode
* @IWL_UCODE_INIT: Initial ucode
* @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode
*/
enum iwl_ucode_type {
IWL_UCODE_REGULAR,
IWL_UCODE_INIT,
IWL_UCODE_WOWLAN,
IWL_UCODE_TYPE_MAX,
};

struct iwl_ucode_capabilities {
u32 max_probe_length;
u32 standard_phy_calibration_size;
Expand Down Expand Up @@ -142,6 +158,9 @@ struct iwl_fw {

u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;

u64 default_calib[IWL_UCODE_TYPE_MAX];
u32 phy_config;
};

#endif /* __iwl_fw_h__ */
16 changes: 0 additions & 16 deletions trunk/drivers/net/wireless/iwlwifi/iwl-shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,22 +192,6 @@ struct iwl_hw_params {
const struct iwl_sensitivity_ranges *sens;
};

/**
* enum iwl_ucode_type
*
* The type of ucode.
*
* @IWL_UCODE_REGULAR: Normal runtime ucode
* @IWL_UCODE_INIT: Initial ucode
* @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode
*/
enum iwl_ucode_type {
IWL_UCODE_REGULAR,
IWL_UCODE_INIT,
IWL_UCODE_WOWLAN,
IWL_UCODE_TYPE_MAX,
};

/*
* LED mode
* IWL_LED_DEFAULT: use device default
Expand Down

0 comments on commit e5e4418

Please sign in to comment.