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

Commit a08e61d2 authored by Kalle Valo's avatar Kalle Valo
Browse files

Merge tag 'iwlwifi-next-for-kalle-2017-12-20' of...

Merge tag 'iwlwifi-next-for-kalle-2017-12-20' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next

Third batch of updates for v4.16

* Small cleanups in the new rate-scaling code;
* Some improvements in debugging;
* New FW API changes;
* Fix a bug where we got a false-positive warning;
* Fix forced quota debugfs functionality;
parents a9f89463 4243edb4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ iwlwifi-objs += fw/notif-wait.o
iwlwifi-$(CONFIG_IWLMVM) += fw/paging.o fw/smem.o fw/init.o fw/dbg.o
iwlwifi-$(CONFIG_IWLMVM) += fw/common_rx.o fw/nvm.o
iwlwifi-$(CONFIG_ACPI) += fw/acpi.o
iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += fw/debugfs.o

iwlwifi-objs += $(iwlwifi-m)

+3 −1
Original line number Diff line number Diff line
@@ -250,10 +250,12 @@ struct iwl_mfu_assert_dump_notif {
 * The ids for different type of markers to insert into the usniffer logs
 *
 * @MARKER_ID_TX_FRAME_LATENCY: TX latency marker
 * @MARKER_ID_SYNC_CLOCK: sync FW time and systime
 */
enum iwl_mvm_marker_id {
	MARKER_ID_TX_FRAME_LATENCY = 1,
}; /* MARKER_ID_API_E_VER_1 */
	MARKER_ID_SYNC_CLOCK = 2,
}; /* MARKER_ID_API_E_VER_2 */

/**
 * struct iwl_mvm_marker - mark info into the usniffer logs
+19 −0
Original line number Diff line number Diff line
@@ -67,6 +67,10 @@
 * enum iwl_mac_conf_subcmd_ids - mac configuration command IDs
 */
enum iwl_mac_conf_subcmd_ids {
	/**
	 * @LOW_LATENCY_CMD: &struct iwl_mac_low_latency_cmd
	 */
	LOW_LATENCY_CMD = 0x3,
	/**
	 * @CHANNEL_SWITCH_NOA_NOTIF: &struct iwl_channel_switch_noa_notif
	 */
@@ -82,4 +86,19 @@ struct iwl_channel_switch_noa_notif {
	__le32 id_and_color;
} __packed; /* CHANNEL_SWITCH_START_NTFY_API_S_VER_1 */

/**
 * struct iwl_mac_low_latency_cmd - set/clear mac to 'low-latency mode'
 *
 * @mac_id: MAC ID to whom to apply the low-latency configurations
 * @low_latency_rx: 1/0 to set/clear Rx low latency direction
 * @low_latency_tx: 1/0 to set/clear Tx low latency direction
 * @reserved: reserved for alignment purposes
 */
struct iwl_mac_low_latency_cmd {
	__le32 mac_id;
	u8 low_latency_rx;
	u8 low_latency_tx;
	__le16 reserved;
} __packed; /* MAC_LOW_LATENCY_API_S_VER_1 */

#endif /* __iwl_fw_api_mac_cfg_h__ */
+17 −17
Original line number Diff line number Diff line
@@ -71,7 +71,7 @@
 * @IWL_TLC_MNG_CFG_FLAGS_BF_MSK: enable BFER
 * @IWL_TLC_MNG_CFG_FLAGS_DCM_MSK: enable DCM
 */
enum iwl_tlc_mng_cfg_flags_enum {
enum iwl_tlc_mng_cfg_flags {
	IWL_TLC_MNG_CFG_FLAGS_CCK_MSK	= BIT(0),
	IWL_TLC_MNG_CFG_FLAGS_DD_MSK	= BIT(1),
	IWL_TLC_MNG_CFG_FLAGS_STBC_MSK	= BIT(2),
@@ -81,14 +81,14 @@ enum iwl_tlc_mng_cfg_flags_enum {
};

/**
 * enum iwl_tlc_mng_cfg_cw_enum - channel width options
 * enum iwl_tlc_mng_cfg_cw - channel width options
 * @IWL_TLC_MNG_MAX_CH_WIDTH_20MHZ: 20MHZ channel
 * @IWL_TLC_MNG_MAX_CH_WIDTH_40MHZ: 40MHZ channel
 * @IWL_TLC_MNG_MAX_CH_WIDTH_80MHZ: 80MHZ channel
 * @IWL_TLC_MNG_MAX_CH_WIDTH_160MHZ: 160MHZ channel
 * @IWL_TLC_MNG_MAX_CH_WIDTH_LAST: maximum value
 */
enum iwl_tlc_mng_cfg_cw_enum {
enum iwl_tlc_mng_cfg_cw {
	IWL_TLC_MNG_MAX_CH_WIDTH_20MHZ,
	IWL_TLC_MNG_MAX_CH_WIDTH_40MHZ,
	IWL_TLC_MNG_MAX_CH_WIDTH_80MHZ,
@@ -97,25 +97,25 @@ enum iwl_tlc_mng_cfg_cw_enum {
};

/**
 * enum iwl_tlc_mng_cfg_chains_enum - possible chains
 * enum iwl_tlc_mng_cfg_chains - possible chains
 * @IWL_TLC_MNG_CHAIN_A_MSK: chain A
 * @IWL_TLC_MNG_CHAIN_B_MSK: chain B
 * @IWL_TLC_MNG_CHAIN_C_MSK: chain C
 */
enum iwl_tlc_mng_cfg_chains_enum {
enum iwl_tlc_mng_cfg_chains {
	IWL_TLC_MNG_CHAIN_A_MSK = BIT(0),
	IWL_TLC_MNG_CHAIN_B_MSK = BIT(1),
	IWL_TLC_MNG_CHAIN_C_MSK = BIT(2),
};

/**
 * enum iwl_tlc_mng_cfg_gi_enum - guard interval options
 * enum iwl_tlc_mng_cfg_gi - guard interval options
 * @IWL_TLC_MNG_SGI_20MHZ_MSK: enable short GI for 20MHZ
 * @IWL_TLC_MNG_SGI_40MHZ_MSK: enable short GI for 40MHZ
 * @IWL_TLC_MNG_SGI_80MHZ_MSK: enable short GI for 80MHZ
 * @IWL_TLC_MNG_SGI_160MHZ_MSK: enable short GI for 160MHZ
 */
enum iwl_tlc_mng_cfg_gi_enum {
enum iwl_tlc_mng_cfg_gi {
	IWL_TLC_MNG_SGI_20MHZ_MSK  = BIT(0),
	IWL_TLC_MNG_SGI_40MHZ_MSK  = BIT(1),
	IWL_TLC_MNG_SGI_80MHZ_MSK  = BIT(2),
@@ -123,7 +123,7 @@ enum iwl_tlc_mng_cfg_gi_enum {
};

/**
 * enum iwl_tlc_mng_cfg_mode_enum - supported modes
 * enum iwl_tlc_mng_cfg_mode - supported modes
 * @IWL_TLC_MNG_MODE_CCK: enable CCK
 * @IWL_TLC_MNG_MODE_OFDM_NON_HT: enable OFDM (non HT)
 * @IWL_TLC_MNG_MODE_NON_HT: enable non HT
@@ -133,7 +133,7 @@ enum iwl_tlc_mng_cfg_gi_enum {
 * @IWL_TLC_MNG_MODE_INVALID: invalid value
 * @IWL_TLC_MNG_MODE_NUM: a count of possible modes
 */
enum iwl_tlc_mng_cfg_mode_enum {
enum iwl_tlc_mng_cfg_mode {
	IWL_TLC_MNG_MODE_CCK = 0,
	IWL_TLC_MNG_MODE_OFDM_NON_HT = IWL_TLC_MNG_MODE_CCK,
	IWL_TLC_MNG_MODE_NON_HT = IWL_TLC_MNG_MODE_CCK,
@@ -145,14 +145,14 @@ enum iwl_tlc_mng_cfg_mode_enum {
};

/**
 * enum iwl_tlc_mng_vht_he_types_enum - VHT HE types
 * enum iwl_tlc_mng_vht_he_types - VHT HE types
 * @IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU: VHT HT single user
 * @IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU_EXT: VHT HT single user extended
 * @IWL_TLC_MNG_VALID_VHT_HE_TYPES_MU: VHT HT multiple users
 * @IWL_TLC_MNG_VALID_VHT_HE_TYPES_TRIG_BASED: trigger based
 * @IWL_TLC_MNG_VALID_VHT_HE_TYPES_NUM: a count of possible types
 */
enum iwl_tlc_mng_vht_he_types_enum {
enum iwl_tlc_mng_vht_he_types {
	IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU = 0,
	IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU_EXT,
	IWL_TLC_MNG_VALID_VHT_HE_TYPES_MU,
@@ -163,7 +163,7 @@ enum iwl_tlc_mng_vht_he_types_enum {
};

/**
 * enum iwl_tlc_mng_ht_rates_enum - HT/VHT rates
 * enum iwl_tlc_mng_ht_rates - HT/VHT rates
 * @IWL_TLC_MNG_HT_RATE_MCS0: index of MCS0
 * @IWL_TLC_MNG_HT_RATE_MCS1: index of MCS1
 * @IWL_TLC_MNG_HT_RATE_MCS2: index of MCS2
@@ -176,7 +176,7 @@ enum iwl_tlc_mng_vht_he_types_enum {
 * @IWL_TLC_MNG_HT_RATE_MCS9: index of MCS9
 * @IWL_TLC_MNG_HT_RATE_MAX: maximal rate for HT/VHT
 */
enum iwl_tlc_mng_ht_rates_enum {
enum iwl_tlc_mng_ht_rates {
	IWL_TLC_MNG_HT_RATE_MCS0 = 0,
	IWL_TLC_MNG_HT_RATE_MCS1,
	IWL_TLC_MNG_HT_RATE_MCS2,
@@ -198,13 +198,13 @@ enum iwl_tlc_mng_ht_rates_enum {
 * @sta_id: station id
 * @reserved1: reserved
 * @max_supp_ch_width: channel width
 * @flags: bitmask of %IWL_TLC_MNG_CONFIG_FLAGS_ENABLE_\*
 * @chains: bitmask of %IWL_TLC_MNG_CHAIN_\*
 * @flags: bitmask of &enum iwl_tlc_mng_cfg_flags
 * @chains: bitmask of &enum iwl_tlc_mng_cfg_chains
 * @max_supp_ss: valid values are 0-3, 0 - spatial streams are not supported
 * @valid_vht_he_types: bitmap of %IWL_TLC_MNG_VALID_VHT_HE_TYPES_\*
 * @valid_vht_he_types: bitmap of &enum iwl_tlc_mng_vht_he_types
 * @non_ht_supp_rates: bitmap of supported legacy rates
 * @ht_supp_rates: bitmap of supported HT/VHT rates, valid bits are 0-9
 * @mode: modulation type %IWL_TLC_MNG_MODE_\*
 * @mode: &enum iwl_tlc_mng_cfg_mode
 * @reserved2: reserved
 * @he_supp_rates: bitmap of supported HE rates
 * @sgi_ch_width_supp: bitmap of SGI support per channel width
+195 −0
Original line number Diff line number Diff line
/******************************************************************************
 *
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
 *
 * GPL LICENSE SUMMARY
 *
 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
 *
 * 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
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.
 *
 * The full GNU General Public License is included in this distribution
 * in the file called COPYING.
 *
 * Contact Information:
 *  Intel Linux Wireless <linuxwifi@intel.com>
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 * BSD LICENSE
 *
 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name Intel Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/
#include "api/commands.h"
#include "debugfs.h"

#define FWRT_DEBUGFS_READ_FILE_OPS(name)				\
static ssize_t iwl_dbgfs_##name##_read(struct iwl_fw_runtime *fwrt,	\
				       char *buf, size_t count,		\
				       loff_t *ppos);			\
static const struct file_operations iwl_dbgfs_##name##_ops = {		\
	.read = iwl_dbgfs_##name##_read,				\
	.open = simple_open,						\
	.llseek = generic_file_llseek,					\
}

#define FWRT_DEBUGFS_WRITE_WRAPPER(name, buflen)			\
static ssize_t iwl_dbgfs_##name##_write(struct iwl_fw_runtime *fwrt,	\
					char *buf, size_t count,	\
					loff_t *ppos);			\
static ssize_t _iwl_dbgfs_##name##_write(struct file *file,		\
					 const char __user *user_buf,	\
					 size_t count, loff_t *ppos)	\
{									\
	struct iwl_fw_runtime *fwrt = file->private_data;		\
	char buf[buflen] = {};						\
	size_t buf_size = min(count, sizeof(buf) -  1);			\
									\
	if (copy_from_user(buf, user_buf, buf_size))			\
		return -EFAULT;						\
									\
	return iwl_dbgfs_##name##_write(fwrt, buf, buf_size, ppos);	\
}

#define FWRT_DEBUGFS_READ_WRITE_FILE_OPS(name, buflen)			\
FWRT_DEBUGFS_WRITE_WRAPPER(name, buflen)				\
static const struct file_operations iwl_dbgfs_##name##_ops = {		\
	.write = _iwl_dbgfs_##name##_write,				\
	.read = iwl_dbgfs_##name##_read,				\
	.open = simple_open,						\
	.llseek = generic_file_llseek,					\
}

#define FWRT_DEBUGFS_WRITE_FILE_OPS(name, buflen)			\
FWRT_DEBUGFS_WRITE_WRAPPER(name, buflen)				\
static const struct file_operations iwl_dbgfs_##name##_ops = {		\
	.write = _iwl_dbgfs_##name##_write,				\
	.open = simple_open,						\
	.llseek = generic_file_llseek,					\
}

#define FWRT_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do {	\
		if (!debugfs_create_file(alias, mode, parent, fwrt,	\
					 &iwl_dbgfs_##name##_ops))	\
			goto err;					\
	} while (0)
#define FWRT_DEBUGFS_ADD_FILE(name, parent, mode) \
	FWRT_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode)

static int iwl_fw_send_timestamp_marker_cmd(struct iwl_fw_runtime *fwrt)
{
	struct iwl_mvm_marker marker = {
		.dw_len = sizeof(struct iwl_mvm_marker) / 4,
		.marker_id = MARKER_ID_SYNC_CLOCK,

		/* the real timestamp is taken from the ftrace clock
		 * this is for finding the match between fw and kernel logs
		 */
		.timestamp = cpu_to_le64(fwrt->timestamp.seq++),
	};

	struct iwl_host_cmd hcmd = {
		.id = MARKER_CMD,
		.flags = CMD_ASYNC,
		.data[0] = &marker,
		.len[0] = sizeof(marker),
	};

	return iwl_trans_send_cmd(fwrt->trans, &hcmd);
}

static void iwl_fw_timestamp_marker_wk(struct work_struct *work)
{
	int ret;
	struct iwl_fw_runtime *fwrt =
		container_of(work, struct iwl_fw_runtime, timestamp.wk.work);
	unsigned long delay = fwrt->timestamp.delay;

	ret = iwl_fw_send_timestamp_marker_cmd(fwrt);
	if (!ret && delay)
		schedule_delayed_work(&fwrt->timestamp.wk,
				      round_jiffies_relative(delay));
	else
		IWL_INFO(fwrt,
			 "stopping timestamp_marker, ret: %d, delay: %u\n",
			 ret, jiffies_to_msecs(delay) / 1000);
}

static ssize_t iwl_dbgfs_timestamp_marker_write(struct iwl_fw_runtime *fwrt,
						char *buf, size_t count,
						loff_t *ppos)
{
	int ret;
	u32 delay;

	ret = kstrtou32(buf, 10, &delay);
	if (ret < 0)
		return ret;

	IWL_INFO(fwrt,
		 "starting timestamp_marker trigger with delay: %us\n",
		 delay);

	iwl_fw_cancel_timestamp(fwrt);

	fwrt->timestamp.delay = msecs_to_jiffies(delay * 1000);

	schedule_delayed_work(&fwrt->timestamp.wk,
			      round_jiffies_relative(fwrt->timestamp.delay));
	return count;
}

FWRT_DEBUGFS_WRITE_FILE_OPS(timestamp_marker, 10);

int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
			    struct dentry *dbgfs_dir)
{
	INIT_DELAYED_WORK(&fwrt->timestamp.wk, iwl_fw_timestamp_marker_wk);
	FWRT_DEBUGFS_ADD_FILE(timestamp_marker, dbgfs_dir, S_IWUSR);
	return 0;
err:
	IWL_ERR(fwrt, "Can't create the fwrt debugfs directory\n");
	return -ENOMEM;
}
Loading