Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ed8c8365 authored by David Spinadel's avatar David Spinadel Committed by John W. Linville
Browse files

iwlwifi: Add TLVs and fields for 16.0 uCode



New TLVs for ucode sections that are not known as
instruction or data.

New TLVs for phy-configuration and default calibrations.

Add default calib and phy config fields to iwl_fw.

Signed-off-by: default avatarDavid Spinadel <david.spinadel@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 0cedacc5
Loading
Loading
Loading
Loading
+84 −0
Original line number Original line Diff line number Diff line
@@ -208,6 +208,25 @@ struct fw_img_parsing {
	int sec_counter;
	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 iwl_firmware_pieces {
	struct fw_img_parsing img[IWL_UCODE_TYPE_MAX];
	struct fw_img_parsing img[IWL_UCODE_TYPE_MAX];


@@ -257,6 +276,47 @@ static void set_sec_offset(struct iwl_firmware_pieces *pieces,
	pieces->img[type].sec[sec].offset = offset;
	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,
static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
				    const struct firmware *ucode_raw,
				    const struct firmware *ucode_raw,
				    struct iwl_firmware_pieces *pieces)
				    struct iwl_firmware_pieces *pieces)
@@ -586,6 +646,29 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
			capa->standard_phy_calibration_size =
			capa->standard_phy_calibration_size =
					le32_to_cpup((__le32 *)tlv_data);
					le32_to_cpup((__le32 *)tlv_data);
			break;
			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:
		default:
			IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
			IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
			break;
			break;
@@ -602,6 +685,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,


 invalid_tlv_len:
 invalid_tlv_len:
	IWL_ERR(drv, "TLV %d has invalid size: %u\n", tlv_type, 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);
	iwl_print_hex_dump(drv, IWL_DL_FW, tlv_data, tlv_len);


	return -EINVAL;
	return -EINVAL;
+5 −0
Original line number Original line Diff line number Diff line
@@ -124,6 +124,11 @@ enum iwl_ucode_tlv_type {
	IWL_UCODE_TLV_WOWLAN_INST	= 16,
	IWL_UCODE_TLV_WOWLAN_INST	= 16,
	IWL_UCODE_TLV_WOWLAN_DATA	= 17,
	IWL_UCODE_TLV_WOWLAN_DATA	= 17,
	IWL_UCODE_TLV_FLAGS		= 18,
	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 {
struct iwl_ucode_tlv {
+19 −0
Original line number Original line Diff line number Diff line
@@ -85,6 +85,22 @@ enum iwl_ucode_tlv_flag {
#define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE		19
#define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE		19
#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE			253
#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 {
struct iwl_ucode_capabilities {
	u32 max_probe_length;
	u32 max_probe_length;
	u32 standard_phy_calibration_size;
	u32 standard_phy_calibration_size;
@@ -142,6 +158,9 @@ struct iwl_fw {


	u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
	u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
	u32 inst_evtlog_ptr, inst_evtlog_size, inst_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__ */
#endif  /* __iwl_fw_h__ */
+0 −16
Original line number Original line Diff line number Diff line
@@ -192,22 +192,6 @@ struct iwl_hw_params {
	const struct iwl_sensitivity_ranges *sens;
	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
 * LED mode
 *    IWL_LED_DEFAULT:  use device default
 *    IWL_LED_DEFAULT:  use device default