Commit e811ada7 authored by Alexander Bondar's avatar Alexander Bondar Committed by Johannes Berg
Browse files

iwlwifi: mvm: Upgrade to a new power management uAPSD API



Change power management implementation to support new host-device API
containing uAPSD parameters. Verify FW support for this new API.
Use the new power table command (0xA9) to configure power management.
Use the legacy command (0x77) if FW does not support the new API.
New file power_legacy.c is introduced for legacy implementation.

Signed-off-by: default avatarAlexander Bondar <alexander.bondar@intel.com>
Reviewed-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 0c393d4e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@
 * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
 * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
 * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS
 * @IWL_UCODE_TLV_FLAGS_UAPSD: This uCode image supports uAPSD
 */
enum iwl_ucode_tlv_flag {
	IWL_UCODE_TLV_FLAGS_PAN		= BIT(0),
@@ -81,6 +82,7 @@ enum iwl_ucode_tlv_flag {
	IWL_UCODE_TLV_FLAGS_MFP		= BIT(2),
	IWL_UCODE_TLV_FLAGS_P2P		= BIT(3),
	IWL_UCODE_TLV_FLAGS_DW_BC_TABLE	= BIT(4),
	IWL_UCODE_TLV_FLAGS_UAPSD	= BIT(6),
};

/* The default calibrate table size if not specified by firmware file */
+1 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@ obj-$(CONFIG_IWLMVM) += iwlmvm.o
iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o
iwlmvm-y += scan.o time-event.o rs.o
iwlmvm-y += power.o bt-coex.o
iwlmvm-y += power.o power_legacy.o bt-coex.o
iwlmvm-y += led.o tt.o
iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o
iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
+2 −31
Original line number Diff line number Diff line
@@ -424,40 +424,11 @@ static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
	struct ieee80211_vif *vif = file->private_data;
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	struct iwl_mvm *mvm = mvmvif->dbgfs_data;
	struct iwl_powertable_cmd cmd = {};
	char buf[256];
	int bufsz = sizeof(buf);
	int pos = 0;
	int pos;

	iwl_mvm_power_build_cmd(mvm, vif, &cmd);

	pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n",
			 (cmd.flags &
			 cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ?
			 0 : 1);
	pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n",
			 le32_to_cpu(cmd.skip_dtim_periods));
	pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n",
			 iwlmvm_mod_params.power_scheme);
	pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n",
			 le16_to_cpu(cmd.flags));
	pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n",
			 cmd.keep_alive_seconds);

	if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
		pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n",
				 (cmd.flags &
				 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ?
				 1 : 0);
		pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n",
				 le32_to_cpu(cmd.rx_data_timeout));
		pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n",
				 le32_to_cpu(cmd.tx_data_timeout));
		if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
			pos += scnprintf(buf+pos, bufsz-pos,
					 "lprx_rssi_threshold = %d\n",
					 le32_to_cpu(cmd.lprx_rssi_threshold));
	}
	pos = iwl_mvm_power_dbgfs_read(mvm, vif, buf, bufsz);

	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
+74 −1
Original line number Diff line number Diff line
@@ -79,6 +79,10 @@
 *		'1' Driver enables PM (use rest of parameters)
 * @POWER_FLAGS_SKIP_OVER_DTIM_MSK: '0' PM have to walk up every DTIM,
 *		'1' PM could sleep over DTIM till listen Interval.
 * @POWER_FLAGS_SNOOZE_ENA_MSK: Enable snoozing only if uAPSD is enabled and all
 *		access categories are both delivery and trigger enabled.
 * @POWER_FLAGS_BT_SCO_ENA: Enable BT SCO coex only if uAPSD and
 *		PBW Snoozing enabled
 * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask
 * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable.
*/
@@ -86,6 +90,8 @@ enum iwl_power_flags {
	POWER_FLAGS_POWER_SAVE_ENA_MSK		= BIT(0),
	POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK	= BIT(1),
	POWER_FLAGS_SKIP_OVER_DTIM_MSK		= BIT(2),
	POWER_FLAGS_SNOOZE_ENA_MSK		= BIT(5),
	POWER_FLAGS_BT_SCO_ENA			= BIT(8),
	POWER_FLAGS_ADVANCE_PM_ENA_MSK		= BIT(9),
	POWER_FLAGS_LPRX_ENA_MSK		= BIT(11),
};
@@ -93,7 +99,8 @@ enum iwl_power_flags {
#define IWL_POWER_VEC_SIZE 5

/**
 * struct iwl_powertable_cmd - Power Table Command
 * struct iwl_powertable_cmd - legacy power command. Beside old API support this
 *	is used also with a new	power API for device wide power settings.
 * POWER_TABLE_CMD = 0x77 (command, has simple generic response)
 *
 * @flags:		Power table command flags from POWER_FLAGS_*
@@ -124,6 +131,72 @@ struct iwl_powertable_cmd {
	__le32 lprx_rssi_threshold;
} __packed;

/**
 * struct iwl_mac_power_cmd - New power command containing uAPSD support
 * MAC_PM_POWER_TABLE = 0xA9 (command, has simple generic response)
 * @id_and_color:	MAC contex identifier
 * @flags:		Power table command flags from POWER_FLAGS_*
 * @keep_alive_seconds:	Keep alive period in seconds. Default - 25 sec.
 *			Minimum allowed:- 3 * DTIM. Keep alive period must be
 *			set regardless of power scheme or current power state.
 *			FW use this value also when PM is disabled.
 * @rx_data_timeout:    Minimum time (usec) from last Rx packet for AM to
 *			PSM transition - legacy PM
 * @tx_data_timeout:    Minimum time (usec) from last Tx packet for AM to
 *			PSM transition - legacy PM
 * @sleep_interval:	not in use
 * @skip_dtim_periods:	Number of DTIM periods to skip if Skip over DTIM flag
 *			is set. For example, if it is required to skip over
 *			one DTIM, this value need to be set to 2 (DTIM periods).
 * @rx_data_timeout_uapsd: Minimum time (usec) from last Rx packet for AM to
 *			PSM transition - uAPSD
 * @tx_data_timeout_uapsd: Minimum time (usec) from last Tx packet for AM to
 *			PSM transition - uAPSD
 * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled.
 *			Default: 80dbm
 * @num_skip_dtim:	Number of DTIMs to skip if Skip over DTIM flag is set
 * @snooze_interval:	TBD
 * @snooze_window:	TBD
 * @snooze_step:	TBD
 * @qndp_tid:		TID client shall use for uAPSD QNDP triggers
 * @uapsd_ac_flags:	Set trigger-enabled and delivery-enabled indication for
 *			each corresponding AC.
 *			Use IEEE80211_WMM_IE_STA_QOSINFO_AC* for correct values.
 * @uapsd_max_sp:	Use IEEE80211_WMM_IE_STA_QOSINFO_SP_* for correct
 *			values.
 * @heavy_traffic_thr_tx_pkts:	TX threshold measured in number of packets
 * @heavy_traffic_thr_rx_pkts:	RX threshold measured in number of packets
 * @heavy_traffic_thr_tx_load:	TX threshold measured in load's percentage
 * @heavy_traffic_thr_rx_load:	RX threshold measured in load's percentage
 * @limited_ps_threshold:
*/
struct iwl_mac_power_cmd {
	/* CONTEXT_DESC_API_T_VER_1 */
	__le32 id_and_color;

	/* CLIENT_PM_POWER_TABLE_S_VER_1 */
	__le16 flags;
	__le16 keep_alive_seconds;
	__le32 rx_data_timeout;
	__le32 tx_data_timeout;
	__le32 rx_data_timeout_uapsd;
	__le32 tx_data_timeout_uapsd;
	u8 lprx_rssi_threshold;
	u8 skip_dtim_periods;
	__le16 snooze_interval;
	__le16 snooze_window;
	u8 snooze_step;
	u8 qndp_tid;
	u8 uapsd_ac_flags;
	u8 uapsd_max_sp;
	u8 heavy_traffic_threshold_tx_packets;
	u8 heavy_traffic_threshold_rx_packets;
	u8 heavy_traffic_threshold_tx_percentage;
	u8 heavy_traffic_threshold_rx_percentage;
	u8 limited_ps_threshold;
	u8 reserved;
} __packed;

/**
 * struct iwl_beacon_filter_cmd
 * REPLY_BEACON_FILTERING_CMD = 0xd2 (command)
+4 −1
Original line number Diff line number Diff line
@@ -136,7 +136,7 @@ enum {
	CALIB_RES_NOTIF_PHY_DB = 0x6b,
	/* PHY_DB_CMD = 0x6c, */

	/* Power */
	/* Power - legacy power table command */
	POWER_TABLE_CMD = 0x77,

	/* Thermal Throttling*/
@@ -166,6 +166,9 @@ enum {

	MISSED_BEACONS_NOTIFICATION = 0xa2,

	/* Power - new power table command */
	MAC_PM_POWER_TABLE = 0xa9,

	REPLY_RX_PHY_CMD = 0xc0,
	REPLY_RX_MPDU_CMD = 0xc1,
	BA_NOTIF = 0xc5,
Loading