Skip to contentSkip to conversation

pull request: iwlwifi-next 2013_11_24

PATCH New Emmanuel Grumbach 2 participants 32 messages Nov 24, 2013 – Dec 2, 2013 Networking drivers (wireless)

lore
Share & tools
lore
#0 lore raw

Hi John,

This is the first batch for 3.14.

I have a bunch of small improvements and fixes. Avri made a thorough work checking what bit to set to firmware w.r.t protection. Eliad worked on WoWLAN, so did Luca. Johannes contributes a whole bunch of clean ups, and Alex tries to handle better cases where the firmware dies. Eyal survived his deep dive into the rate control algorigthm and provides a new set of fixes for VHT. I am still playing a bit with BT Coex.

Note that I had to merge iwlwifi-fixes to avoid conflicts before they hit linux-next.
Let me know about any issues!

The following changes since commit 6ce4eac1f600b34f2f7f58f9cd8f0503d79e42ae:

Linux 3.13-rc1 (2013-11-22 11:30:55 -0800)

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git
for-john

for you to fetch changes up to b407dd53844e0d66e726583bae3a084cecdd59a4:

Merge remote-tracking branch 'iwlwifi-fixes/master' into iwlwifi-next
(2013-11-24 21:49:45 +0200)

----------------------------------------------------------------

Alexander Bondar (2):
iwlwifi: mvm: Add debugfs entry to generate NMI to NIC
iwlwifi: pcie: stop sending commands to dead firmware

Avri Altman (1):
iwlwifi: mvm: fix ht protection flags

Eliad Peller (4):
iwlwifi: mvm: enable d3_test even if d3_test_pme_ptr is not available
iwlwifi: mvm: disconnect on disconnection wakeup event
iwlwifi: mvm: allow keeping connections in d3_test
iwlwifi: mvm: fix scan offloading flag definition

Emmanuel Grumbach (10):
iwlwifi: pcie: fix interrupt coalescing for 7260 / 3160
iwlwifi: mvm: BT Coex - don't enable MULTI_PRIO_LUT
iwlwifi: mvm: BT Coex fix another NULL pointer dereference
iwlwifi: mvm: don't WARN about unsuccessful time event
iwlwifi: bump required firmware API version for 3160/7260
iwlwifi: remove TX_CMD id from transport layer
iwlwifi: mvm: BT Coex - fine tune the aggregation size
iwlwifi: mvm: a few more SKUs for 7260 and 3160
iwlwifi: mvm: dump NVM from debugfs
Merge remote-tracking branch 'iwlwifi-fixes/master' into iwlwifi-next

Eyal Shapira (9):
iwlwifi: mvm: fix and improve printing of rate scale table
iwlwifi: mvm: simplify iwl_mvm_send_lq_cmd
iwlwifi: mvm: refactor iwl_mvm_rs_rate_init
iwlwifi: mvm: implement rate_update hook in rs
iwlwifi: mvm: add LQ flags definitions
iwlwifi: fix check for a single rx antenna
iwlwifi: mvm: stop using MIMO in case BT doesn't allow it
iwlwifi: mvm: don't enable VHT MCS9 in 20Mhz
iwlwifi: mvm: don't configure mimo rates if nss is limited to 1

Haim Dreyfuss (1):
iwlwifi: mvm: Implement low-priority scan

Johannes Berg (8):
iwlwifi: mvm: check sta_id/drain values in debugfs
iwlwifi: pcie: remove useless condition test
iwlwifi: mvm: small debugfs cleanups
iwlwifi: mvm: move interface-specific debugfs to a new file
iwlwifi: mvm: don't use void pointers in debugfs
iwlwifi: mvm: refactor debugfs copy_from_user()
iwlwifi: mvm: add iwl_mvm_sta_from_mac80211
iwlwifi: mvm: quota command max_duration should be zero

Luciano Coelho (3):
iwlwifi: mvm: set seqno also when no keys are set
iwlwifi: mvm: use a cast to calculate the last seqno from the next one
iwlwifi: mvm: don't restart HW if suspending fails before D3 image
is loaded

Michal Nazarewicz (1):
iwlwifi: pcie: remove minor dead code

Oren Givon (1):
iwlwifi: add new HW - 7265 series

 drivers/net/wireless/iwlwifi/dvm/rs.h          |    7 -
 drivers/net/wireless/iwlwifi/dvm/tx.c          |    1 +
 drivers/net/wireless/iwlwifi/iwl-7000.c        |   29 +-
 drivers/net/wireless/iwlwifi/iwl-config.h      |   11 +
 drivers/net/wireless/iwlwifi/iwl-csr.h         |    5 +-
 drivers/net/wireless/iwlwifi/iwl-nvm-parse.c   |    3 +-
 drivers/net/wireless/iwlwifi/iwl-prph.h        |    3 +
 drivers/net/wireless/iwlwifi/mvm/Makefile      |    1 +
 drivers/net/wireless/iwlwifi/mvm/bt-coex.c     |   16 +-
 drivers/net/wireless/iwlwifi/mvm/d3.c          |   43 +-
 drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c |  190 +++++++
 drivers/net/wireless/iwlwifi/mvm/debugfs.c     |  640
++----------------------
 drivers/net/wireless/iwlwifi/mvm/debugfs.h     |  101 ++++
 drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h   |   27 +-
 drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h |    5 +-
 drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c    |   51 +-
 drivers/net/wireless/iwlwifi/mvm/mac80211.c    |   19 +-
 drivers/net/wireless/iwlwifi/mvm/mvm.h         |   11 +-
 drivers/net/wireless/iwlwifi/mvm/nvm.c         |   23 +
 drivers/net/wireless/iwlwifi/mvm/quota.c       |    3 +-
 drivers/net/wireless/iwlwifi/mvm/rs.c          |  223 ++++++---
 drivers/net/wireless/iwlwifi/mvm/rs.h          |   23 +-
 drivers/net/wireless/iwlwifi/mvm/scan.c        |   55 +-
 drivers/net/wireless/iwlwifi/mvm/sta.c         |   14 +-
 drivers/net/wireless/iwlwifi/mvm/sta.h         |    6 +
 drivers/net/wireless/iwlwifi/mvm/time-event.c  |    7 +-
 drivers/net/wireless/iwlwifi/mvm/tt.c          |    2 +-
 drivers/net/wireless/iwlwifi/mvm/tx.c          |   11 +-
 drivers/net/wireless/iwlwifi/mvm/utils.c       |    8 +-
 drivers/net/wireless/iwlwifi/pcie/drv.c        |   26 +
 drivers/net/wireless/iwlwifi/pcie/internal.h   |    8 +
 drivers/net/wireless/iwlwifi/pcie/rx.c         |   33 +-
 drivers/net/wireless/iwlwifi/pcie/trans.c      |    3 -
 drivers/net/wireless/iwlwifi/pcie/tx.c         |   37 +-
 34 files changed, 832 insertions(+), 813 deletions(-)
 create mode 100644 drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
 create mode 100644 drivers/net/wireless/iwlwifi/mvm/debugfs.h
#1 lore raw

PATCH 1/29 iwlwifi: remove TX_CMD id from transport layer

From: Emmanuel Grumbach <[email protected]>

The transport layer doesn't need to know the TX_CMD id. It can be set by the op_mode.
The transport layer still needs to know the layout of the Tx command because of alignment issues and because of the scratch pointer.

---
 drivers/net/wireless/iwlwifi/dvm/tx.c  |    1 +
 drivers/net/wireless/iwlwifi/mvm/tx.c  |    1 +
 drivers/net/wireless/iwlwifi/pcie/tx.c |    1 -
 3 files changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/iwlwifi/dvm/tx.c +1 -0
index 1fef524..e12b1a6 100644
@@ -368,6 +368,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
 		goto drop_unlock_priv;
 
 	memset(dev_cmd, 0, sizeof(*dev_cmd));
+	dev_cmd->hdr.cmd = REPLY_TX;
 	tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload;
 
 	/* Total # bytes to be transmitted */
drivers/net/wireless/iwlwifi/mvm/tx.c +1 -0
index 43d97c3..1f19458 100644
@@ -276,6 +276,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
 		return NULL;
 
 	memset(dev_cmd, 0, sizeof(*dev_cmd));
+	dev_cmd->hdr.cmd = TX_CMD;
 	tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload;
 
 	if (info->control.hw_key)
drivers/net/wireless/iwlwifi/pcie/tx.c +0 -1
index 059c5ac..487a517 100644
@@ -1674,7 +1674,6 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
 	txq->entries[q->write_ptr].skb = skb;
 	txq->entries[q->write_ptr].cmd = dev_cmd;
 
-	dev_cmd->hdr.cmd = REPLY_TX;
 	dev_cmd->hdr.sequence =
 		cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
 			    INDEX_TO_SEQ(q->write_ptr)));
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH 2/29 iwlwifi: mvm: Add debugfs entry to generate NMI to NIC

In reply to Emmanuel Grumbach

From: Alexander Bondar <[email protected]>

Writting to fw_nmi entry will set DEVICE_SET_NMI_REG (0x00a01c30) generating NMI that halts NIC CPU.

---
 drivers/net/wireless/iwlwifi/iwl-prph.h    |    3 +++
 drivers/net/wireless/iwlwifi/mvm/debugfs.c |   14 ++++++++++++++
 2 files changed, 17 insertions(+)
drivers/net/wireless/iwlwifi/iwl-prph.h +3 -0
index a70c7b9..f6412da 100644
@@ -102,6 +102,9 @@
 /* Device system time */
 #define DEVICE_SYSTEM_TIME_REG 0xA0206C
 
+/* Device NMI register */
+#define DEVICE_SET_NMI_REG 0x00a01c30
+
 /*****************************************************************************
  *                        7000/3000 series SHR DTS addresses                 *
  *****************************************************************************/
drivers/net/wireless/iwlwifi/mvm/debugfs.c +14 -0
index 9864d71..4b31d06 100644
@@ -63,6 +63,7 @@
 #include "mvm.h"
 #include "sta.h"
 #include "iwl-io.h"
+#include "iwl-prph.h"
 
 struct iwl_dbgfs_mvm_ctx {
 	struct iwl_mvm *mvm;
@@ -800,6 +801,17 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
 	return count;
 }
 
+static ssize_t iwl_dbgfs_fw_nmi_write(struct file *file,
+				      const char __user *user_buf,
+				      size_t count, loff_t *ppos)
+{
+	struct iwl_mvm *mvm = file->private_data;
+
+	iwl_write_prph(mvm->trans, DEVICE_SET_NMI_REG, 1);
+
+	return count;
+}
+
 static ssize_t
 iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
 				char __user *user_buf,
@@ -1164,6 +1176,7 @@ MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off);
 MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
 MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart);
+MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi);
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain);
 
 #ifdef CONFIG_PM_SLEEP
@@ -1192,6 +1205,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
 				     S_IRUSR | S_IWUSR);
 	MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR);
 	MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
+	MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, S_IWUSR);
 	MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir,
 			     S_IWUSR | S_IRUSR);
 #ifdef CONFIG_PM_SLEEP
Signature · 1 line
1.7.9.5
#3 lore raw

PATCH 3/29 iwlwifi: pcie: remove useless condition test

In reply to Emmanuel Grumbach

From: Johannes Berg <[email protected]>

After wait_event_timeout(), the condition must still be true if it returns >0, in fact almost the last thing in it is checking the condition again. It's therefore not useful to check yet again in our code, clean it up.

---
 drivers/net/wireless/iwlwifi/pcie/tx.c |   32 +++++++++++++-------------------
 1 file changed, 13 insertions(+), 19 deletions(-)
drivers/net/wireless/iwlwifi/pcie/tx.c +13 -19
index 487a517..d81d58c 100644
@@ -1542,30 +1542,24 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
 	}
 
 	if (!ret) {
-		if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) {
-			struct iwl_txq *txq =
-				&trans_pcie->txq[trans_pcie->cmd_queue];
-			struct iwl_queue *q = &txq->q;
+		struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue];
+		struct iwl_queue *q = &txq->q;
 
-			IWL_ERR(trans,
-				"Error sending %s: time out after %dms.\n",
-				get_cmd_string(trans_pcie, cmd->id),
-				jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
+		IWL_ERR(trans, "Error sending %s: time out after %dms.\n",
+			get_cmd_string(trans_pcie, cmd->id),
+			jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
 
-			IWL_ERR(trans,
-				"Current CMD queue read_ptr %d write_ptr %d\n",
-				q->read_ptr, q->write_ptr);
+		IWL_ERR(trans, "Current CMD queue read_ptr %d write_ptr %d\n",
+			q->read_ptr, q->write_ptr);
 
-			clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
-			IWL_DEBUG_INFO(trans,
-				       "Clearing HCMD_ACTIVE for command %s\n",
-				       get_cmd_string(trans_pcie, cmd->id));
-			ret = -ETIMEDOUT;
+		clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
+		IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n",
+			       get_cmd_string(trans_pcie, cmd->id));
+		ret = -ETIMEDOUT;
 
-			iwl_op_mode_nic_error(trans->op_mode);
+		iwl_op_mode_nic_error(trans->op_mode);
 
-			goto cancel;
-		}
+		goto cancel;
 	}
 
 	if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) {
Signature · 1 line
1.7.9.5
#4 lore raw

PATCH 4/29 iwlwifi: mvm: fix and improve printing of rate scale table

In reply to Emmanuel Grumbach

From: Eyal Shapira <[email protected]>

Info about VHT/HT rates wasn't printed properly when dumping the rate scale table. Fix that and print more info. While at it fix some other minor issues in the printing and prevent overflowing the print buffer.

---
 drivers/net/wireless/iwlwifi/mvm/rs.c |   91 ++++++++++++++++++++++++++-------
 1 file changed, 73 insertions(+), 18 deletions(-)
drivers/net/wireless/iwlwifi/mvm/rs.c +73 -18
index a0b4cc8..f7ac485 100644
@@ -2566,13 +2566,75 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
 	return count;
 }
 
+static int rs_pretty_print_rate(char *buf, const u32 rate)
+{
+	static const char * const ant_name[] = {
+		[ANT_NONE] = "None",
+		[ANT_A]    = "A",
+		[ANT_B]    = "B",
+		[ANT_AB]   = "AB",
+		[ANT_C]    = "C",
+		[ANT_AC]   = "AC",
+		[ANT_BC]   = "BC",
+		[ANT_ABC]  = "ABC",
+	};
+
+	char *type, *bw;
+	u8 mcs = 0, nss = 0;
+	u8 ant = (rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS;
+
+	if (!(rate & RATE_MCS_HT_MSK) &&
+	    !(rate & RATE_MCS_VHT_MSK)) {
+		int index = iwl_hwrate_to_plcp_idx(rate);
+
+		return sprintf(buf, "Legacy | ANT: %s Rate: %s Mbps\n",
+			       ant_name[ant], iwl_rate_mcs[index].mbps);
+	}
+
+	if (rate & RATE_MCS_VHT_MSK) {
+		type = "VHT";
+		mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK;
+		nss = ((rate & RATE_VHT_MCS_NSS_MSK)
+		       >> RATE_VHT_MCS_NSS_POS) + 1;
+	} else if (rate & RATE_MCS_HT_MSK) {
+		type = "HT";
+		mcs = rate & RATE_HT_MCS_INDEX_MSK;
+	} else {
+		type = "Unknown"; /* shouldn't happen */
+	}
+
+	switch (rate & RATE_MCS_CHAN_WIDTH_MSK) {
+	case RATE_MCS_CHAN_WIDTH_20:
+		bw = "20Mhz";
+		break;
+	case RATE_MCS_CHAN_WIDTH_40:
+		bw = "40Mhz";
+		break;
+	case RATE_MCS_CHAN_WIDTH_80:
+		bw = "80Mhz";
+		break;
+	case RATE_MCS_CHAN_WIDTH_160:
+		bw = "160Mhz";
+		break;
+	default:
+		bw = "BAD BW";
+	}
+
+	return sprintf(buf, "%s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s\n",
+		       type, ant_name[ant], bw, mcs, nss,
+		       (rate & RATE_MCS_SGI_MSK) ? "SGI " : "NGI ",
+		       (rate & RATE_MCS_STBC_MSK) ? "STBC " : "",
+		       (rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "",
+		       (rate & RATE_MCS_BF_MSK) ? "BF " : "",
+		       (rate & RATE_MCS_ZLF_MSK) ? "ZLF " : "");
+}
+
 static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
 			char __user *user_buf, size_t count, loff_t *ppos)
 {
 	char *buff;
 	int desc = 0;
 	int i = 0;
-	int index = 0;
 	ssize_t ret;
 
 	struct iwl_lq_sta *lq_sta = file->private_data;
@@ -2580,7 +2642,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
 	struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
 
 	mvm = lq_sta->drv;
-	buff = kmalloc(1024, GFP_KERNEL);
+	buff = kmalloc(2048, GFP_KERNEL);
 	if (!buff)
 		return -ENOMEM;
 
@@ -2597,7 +2659,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
 	desc += sprintf(buff+desc, "lq type %s\n",
 			(is_legacy(tbl->lq_type)) ? "legacy" :
 			is_vht(tbl->lq_type) ? "VHT" : "HT");
-	if (is_ht(tbl->lq_type)) {
+	if (!is_legacy(tbl->lq_type)) {
 		desc += sprintf(buff+desc, " %s",
 		   (is_siso(tbl->lq_type)) ? "SISO" : "MIMO2");
 		   desc += sprintf(buff+desc, " %s",
@@ -2605,13 +2667,13 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
 				   (is_ht40(tbl)) ? "40MHz" :
 				   (is_ht80(tbl)) ? "80Mhz" : "BAD BW");
 		   desc += sprintf(buff+desc, " %s %s\n",
-				   (tbl->is_SGI) ? "SGI" : "",
+				   (tbl->is_SGI) ? "SGI" : "NGI",
 				   (lq_sta->is_agg) ? "AGG on" : "");
 	}
 	desc += sprintf(buff+desc, "last tx rate=0x%X\n",
 			lq_sta->last_rate_n_flags);
 	desc += sprintf(buff+desc,
-			"general: flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
+			"general: flags=0x%X mimo-d=%d s-ant=0x%x d-ant=0x%x\n",
 			lq_sta->lq.flags,
 			lq_sta->lq.mimo_delim,
 			lq_sta->lq.single_stream_ant_msk,
@@ -2631,19 +2693,12 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
 			lq_sta->lq.initial_rate_index[3]);
 
 	for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
-		index = iwl_hwrate_to_plcp_idx(
-			le32_to_cpu(lq_sta->lq.rs_table[i]));
-		if (is_legacy(tbl->lq_type)) {
-			desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps\n",
-					i, le32_to_cpu(lq_sta->lq.rs_table[i]),
-					iwl_rate_mcs[index].mbps);
-		} else {
-			desc += sprintf(buff+desc,
-					" rate[%d] 0x%X %smbps (%s)\n",
-					i, le32_to_cpu(lq_sta->lq.rs_table[i]),
-					iwl_rate_mcs[index].mbps,
-					iwl_rate_mcs[index].mcs);
-		}
+		u32 rate = le32_to_cpu(lq_sta->lq.rs_table[i]);
+		desc += sprintf(buff+desc,
+				" rate[%d] 0x%X ",
+				i, rate);
+
+		desc += rs_pretty_print_rate(buff+desc, rate);
 	}
 
 	ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
Signature · 1 line
1.7.9.5
#5 lore raw

PATCH 5/29 iwlwifi: mvm: simplify iwl_mvm_send_lq_cmd

In reply to Emmanuel Grumbach

From: Eyal Shapira <[email protected]>

Remove the flags parameter which should be set to sync or async according to whether this is called during sta init or not.

---
 drivers/net/wireless/iwlwifi/mvm/mvm.h   |    3 +--
 drivers/net/wireless/iwlwifi/mvm/rs.c    |   12 ++++++------
 drivers/net/wireless/iwlwifi/mvm/sta.c   |    2 +-
 drivers/net/wireless/iwlwifi/mvm/utils.c |    8 ++------
 4 files changed, 10 insertions(+), 15 deletions(-)
drivers/net/wireless/iwlwifi/mvm/mvm.h +1 -2
index fed21ef..7992baa 100644
@@ -750,8 +750,7 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 #endif /* CONFIG_IWLWIFI_DEBUGFS */
 
 /* rate scaling */
-int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
-			u8 flags, bool init);
+int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init);
 
 /* power managment */
 static inline int iwl_mvm_power_update_mode(struct iwl_mvm *mvm,
drivers/net/wireless/iwlwifi/mvm/rs.c +6 -6
index f7ac485..0a64089 100644
@@ -298,7 +298,7 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm,
 
 	if (lq_sta->dbg_fixed_rate) {
 		rs_fill_link_cmd(NULL, NULL, lq_sta, lq_sta->dbg_fixed_rate);
-		iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false);
+		iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, false);
 	}
 }
 #endif
@@ -855,7 +855,7 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
 		lq_sta->missed_rate_counter++;
 		if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
 			lq_sta->missed_rate_counter = 0;
-			iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false);
+			iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
 		}
 		/* Regardless, ignore this status info for outdated rate */
 		return;
@@ -1667,7 +1667,7 @@ static void rs_update_rate_tbl(struct iwl_mvm *mvm,
 	/* Update uCode's rate table. */
 	rate = rate_n_flags_from_tbl(mvm, tbl, index);
 	rs_fill_link_cmd(mvm, sta, lq_sta, rate);
-	iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false);
+	iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
 }
 
 static u8 rs_get_tid(struct iwl_lq_sta *lq_data,
@@ -2064,7 +2064,7 @@ lq_update:
 				       "Switch current  mcs: %X index: %d\n",
 				       tbl->current_rate, index);
 			rs_fill_link_cmd(mvm, sta, lq_sta, tbl->current_rate);
-			iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false);
+			iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
 		} else {
 			done_search = 1;
 		}
@@ -2168,7 +2168,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
 	rs_set_expected_tpt_table(lq_sta, tbl);
 	rs_fill_link_cmd(NULL, NULL, lq_sta, rate);
 	/* TODO restore station should remember the lq cmd */
-	iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_SYNC, true);
+	iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, true);
 }
 
 static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
@@ -2841,5 +2841,5 @@ int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
 			lq->flags &= ~LQ_FLAG_SET_STA_TLC_RTS_MSK;
 	}
 
-	return iwl_mvm_send_lq_cmd(mvm, lq, CMD_ASYNC, false);
+	return iwl_mvm_send_lq_cmd(mvm, lq, false);
 }
drivers/net/wireless/iwlwifi/mvm/sta.c +1 -1
index 3299523..c89232c 100644
@@ -945,7 +945,7 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 		 */
 	}
 
-	return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, CMD_ASYNC, false);
+	return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, false);
 }
 
 int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
drivers/net/wireless/iwlwifi/mvm/utils.c +2 -6
index ed69e9b..56cf819 100644
@@ -486,22 +486,18 @@ void iwl_mvm_dump_sram(struct iwl_mvm *mvm)
  * this case to clear the state indicating that station creation is in
  * progress.
  */
-int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
-			u8 flags, bool init)
+int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init)
 {
 	struct iwl_host_cmd cmd = {
 		.id = LQ_CMD,
 		.len = { sizeof(struct iwl_lq_cmd), },
-		.flags = flags,
+		.flags = init ? CMD_SYNC : CMD_ASYNC,
 		.data = { lq, },
 	};
 
 	if (WARN_ON(lq->sta_id == IWL_MVM_STATION_COUNT))
 		return -EINVAL;
 
-	if (WARN_ON(init && (cmd.flags & CMD_ASYNC)))
-		return -EINVAL;
-
 	return iwl_mvm_send_cmd(mvm, &cmd);
 }
 
Signature · 1 line
1.7.9.5
#6 lore raw

PATCH 6/29 iwlwifi: mvm: refactor iwl_mvm_rs_rate_init

In reply to Emmanuel Grumbach

From: Eyal Shapira <[email protected]>

Refactor setting of VHT enabled rates in preparation of adding some more logic there.

---
 drivers/net/wireless/iwlwifi/mvm/rs.c |   49 +++++++++++++++++++--------------
 1 file changed, 28 insertions(+), 21 deletions(-)
drivers/net/wireless/iwlwifi/mvm/rs.c +28 -21
index 0a64089..e49bf44 100644
@@ -2242,6 +2242,33 @@ static int rs_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap,
 	return -1;
 }
 
+static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,
+				     struct ieee80211_sta_vht_cap *vht_cap,
+				     struct iwl_lq_sta *lq_sta)
+{
+	int i;
+	int highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 1);
+
+	if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
+		for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
+			if (i == IWL_RATE_9M_INDEX)
+				continue;
+
+			lq_sta->active_siso_rate |= BIT(i);
+		}
+	}
+
+	highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 2);
+	if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
+		for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
+			if (i == IWL_RATE_9M_INDEX)
+				continue;
+
+			lq_sta->active_mimo2_rate |= BIT(i);
+		}
+	}
+}
+
 /*
  * Called after adding a new station to initialize rate scaling
  */
@@ -2308,27 +2335,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
 
 		lq_sta->is_vht = false;
 	} else {
-		int highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 1);
-		if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
-			for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
-				if (i == IWL_RATE_9M_INDEX)
-					continue;
-
-				lq_sta->active_siso_rate |= BIT(i);
-			}
-		}
-
-		highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 2);
-		if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
-			for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
-				if (i == IWL_RATE_9M_INDEX)
-					continue;
-
-				lq_sta->active_mimo2_rate |= BIT(i);
-			}
-		}
-
-		/* TODO: avoid MCS9 in 20Mhz which isn't valid for 11ac */
+		rs_vht_set_enabled_rates(sta, vht_cap, lq_sta);
 		lq_sta->is_vht = true;
 	}
 
Signature · 1 line
1.7.9.5
#7 lore raw

PATCH 7/29 iwlwifi: mvm: enable d3_test even if d3_test_pme_ptr is not available

In reply to Emmanuel Grumbach

From: Eliad Peller <[email protected]>

Even if d3_test_pme_ptr is not available, d3_test can still be useful, e.g. by manually triggering resume (with ctrl-c), and reading the wakeup reasons.

---
 drivers/net/wireless/iwlwifi/mvm/d3.c |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/net/wireless/iwlwifi/mvm/d3.c +8 -8
index 6f45966..096cf80 100644
@@ -1216,10 +1216,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
 	if (len >= sizeof(u32) * 2) {
 		mvm->d3_test_pme_ptr =
 			le32_to_cpup((__le32 *)d3_cfg_cmd.resp_pkt->data);
-	} else if (test) {
-		/* in test mode we require the pointer */
-		ret = -EIO;
-		goto out;
 	}
 #endif
 	iwl_free_resp(&d3_cfg_cmd);
@@ -1870,10 +1866,14 @@ static ssize_t iwl_mvm_d3_test_read(struct file *file, char __user *user_buf,
 	u32 pme_asserted;
 
 	while (true) {
-		pme_asserted = iwl_trans_read_mem32(mvm->trans,
-						    mvm->d3_test_pme_ptr);
-		if (pme_asserted)
-			break;
+		/* read pme_ptr if available */
+		if (mvm->d3_test_pme_ptr) {
+			pme_asserted = iwl_trans_read_mem32(mvm->trans,
+						mvm->d3_test_pme_ptr);
+			if (pme_asserted)
+				break;
+		}
+
 		if (msleep_interruptible(100))
 			break;
 	}
Signature · 1 line
1.7.9.5
#8 lore raw

PATCH 8/29 iwlwifi: mvm: disconnect on disconnection wakeup event

In reply to Emmanuel Grumbach

From: Eliad Peller <[email protected]>

When waking up from d3 due to disconnection event (e.g. because of beacon loss), we should disconnect immediately.

---
 drivers/net/wireless/iwlwifi/mvm/d3.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/net/wireless/iwlwifi/mvm/d3.c +6 -0
index 096cf80..d9eb68e 100644
@@ -1533,10 +1533,16 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
 	struct iwl_mvm_d3_gtk_iter_data gtkdata = {
 		.status = status,
 	};
+	u32 disconnection_reasons =
+		IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
+		IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH;
 
 	if (!status || !vif->bss_conf.bssid)
 		return false;
 
+	if (le32_to_cpu(status->wakeup_reasons) & disconnection_reasons)
+		return false;
+
 	/* find last GTK that we used initially, if any */
 	gtkdata.find_phase = true;
 	ieee80211_iter_keys(mvm->hw, vif,
Signature · 1 line
1.7.9.5
#9 lore raw

PATCH 9/29 iwlwifi: mvm: implement rate_update hook in rs

In reply to Emmanuel Grumbach

From: Eyal Shapira <[email protected]>

Re-initialize rs when we get a rate_update hook called which happens when remote STA changes bandwidth or sends a VHT opmode notification.

---
 drivers/net/wireless/iwlwifi/mvm/mac80211.c |    3 ++-
 drivers/net/wireless/iwlwifi/mvm/rs.c       |   30 +++++++++++++++++++++++----
 drivers/net/wireless/iwlwifi/mvm/rs.h       |    2 +-
 3 files changed, 29 insertions(+), 6 deletions(-)
drivers/net/wireless/iwlwifi/mvm/mac80211.c +2 -1
index 74bc2c8..0cc9c1e 100644
@@ -1149,7 +1149,8 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
 		ret = iwl_mvm_update_sta(mvm, vif, sta);
 		if (ret == 0)
 			iwl_mvm_rs_rate_init(mvm, sta,
-					     mvmvif->phy_ctxt->channel->band);
+					     mvmvif->phy_ctxt->channel->band,
+					     true);
 	} else if (old_state == IEEE80211_STA_ASSOC &&
 		   new_state == IEEE80211_STA_AUTHORIZED) {
 		/* enable beacon filtering */
drivers/net/wireless/iwlwifi/mvm/rs.c +26 -4
index e49bf44..a85938c 100644
@@ -2126,7 +2126,8 @@ out:
 static void rs_initialize_lq(struct iwl_mvm *mvm,
 			     struct ieee80211_sta *sta,
 			     struct iwl_lq_sta *lq_sta,
-			     enum ieee80211_band band)
+			     enum ieee80211_band band,
+			     bool init)
 {
 	struct iwl_scale_tbl_info *tbl;
 	int rate_idx;
@@ -2168,7 +2169,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
 	rs_set_expected_tpt_table(lq_sta, tbl);
 	rs_fill_link_cmd(NULL, NULL, lq_sta, rate);
 	/* TODO restore station should remember the lq cmd */
-	iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, true);
+	iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, init);
 }
 
 static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
@@ -2273,7 +2274,7 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,
  * Called after adding a new station to initialize rate scaling
  */
 void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
-			  enum ieee80211_band band)
+			  enum ieee80211_band band, bool init)
 {
 	int i, j;
 	struct ieee80211_hw *hw = mvm->hw;
@@ -2286,6 +2287,8 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
 
 	sta_priv = (struct iwl_mvm_sta *)sta->drv_priv;
 	lq_sta = &sta_priv->lq_sta;
+	memset(lq_sta, 0, sizeof(*lq_sta));
+
 	sband = hw->wiphy->bands[band];
 
 	lq_sta->lq.sta_id = sta_priv->sta_id;
@@ -2371,7 +2374,25 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
 	lq_sta->dbg_fixed_rate = 0;
 #endif
 
-	rs_initialize_lq(mvm, sta, lq_sta, band);
+	rs_initialize_lq(mvm, sta, lq_sta, band, init);
+}
+
+static void rs_rate_update(void *mvm_r,
+			   struct ieee80211_supported_band *sband,
+			   struct cfg80211_chan_def *chandef,
+			   struct ieee80211_sta *sta, void *priv_sta,
+			   u32 changed)
+{
+	u8 tid;
+	struct iwl_op_mode *op_mode  =
+			(struct iwl_op_mode *)mvm_r;
+	struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
+
+	/* Stop any ongoing aggregations as rs starts off assuming no agg */
+	for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
+		ieee80211_stop_tx_ba_session(sta, tid);
+
+	iwl_mvm_rs_rate_init(mvm, sta, sband->band, false);
 }
 
 static void rs_fill_link_cmd(struct iwl_mvm *mvm,
@@ -2808,6 +2829,7 @@ static struct rate_control_ops rs_mvm_ops = {
 	.free = rs_free,
 	.alloc_sta = rs_alloc_sta,
 	.free_sta = rs_free_sta,
+	.rate_update = rs_rate_update,
 #ifdef CONFIG_MAC80211_DEBUGFS
 	.add_sta_debugfs = rs_add_debugfs,
 	.remove_sta_debugfs = rs_remove_debugfs,
drivers/net/wireless/iwlwifi/mvm/rs.h +1 -1
index 5d5344f..8d5dc78 100644
@@ -353,7 +353,7 @@ static inline u8 num_of_ant(u8 mask)
 
 /* Initialize station's rate scaling information after adding station */
 void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
-			  enum ieee80211_band band);
+			  enum ieee80211_band band, bool init);
 
 /**
  * iwl_rate_control_register - Register the rate control algorithm callbacks
Signature · 1 line
1.7.9.5
#10 lore raw

PATCH 10/29 iwlwifi: mvm: allow keeping connections in d3_test

In reply to Emmanuel Grumbach

From: Eliad Peller <[email protected]>

Keeping connection can be useful also when testing d3 using the debugfs file (d3_test).

Save the vif to keep connection on, and consider it when iterating over the interfaces.

---
 drivers/net/wireless/iwlwifi/mvm/d3.c  |   11 ++++++++++-
 drivers/net/wireless/iwlwifi/mvm/mvm.h |    1 +
 2 files changed, 11 insertions(+), 1 deletion(-)
drivers/net/wireless/iwlwifi/mvm/d3.c +10 -1
index d9eb68e..6964b84 100644
@@ -1806,6 +1806,10 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
 	iwl_mvm_read_d3_sram(mvm);
 
 	keep = iwl_mvm_query_wakeup_reasons(mvm, vif);
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+	if (keep)
+		mvm->keep_vif = vif;
+#endif
 	/* has unlocked the mutex, so skip that */
 	goto out;
 
@@ -1862,6 +1866,7 @@ static int iwl_mvm_d3_test_open(struct inode *inode, struct file *file)
 		return err;
 	}
 	mvm->d3_test_active = true;
+	mvm->keep_vif = NULL;
 	return 0;
 }
 
@@ -1890,6 +1895,10 @@ static ssize_t iwl_mvm_d3_test_read(struct file *file, char __user *user_buf,
 static void iwl_mvm_d3_test_disconn_work_iter(void *_data, u8 *mac,
 					      struct ieee80211_vif *vif)
 {
+	/* skip the one we keep connection on */
+	if (_data == vif)
+		return;
+
 	if (vif->type == NL80211_IFTYPE_STATION)
 		ieee80211_connection_loss(vif);
 }
@@ -1916,7 +1925,7 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file)
 
 	ieee80211_iterate_active_interfaces_atomic(
 		mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
-		iwl_mvm_d3_test_disconn_work_iter, NULL);
+		iwl_mvm_d3_test_disconn_work_iter, mvm->keep_vif);
 
 	ieee80211_wake_queues(mvm->hw);
 
drivers/net/wireless/iwlwifi/mvm/mvm.h +1 -0
index 7992baa..c002b45 100644
@@ -531,6 +531,7 @@ struct iwl_mvm {
 	bool store_d3_resume_sram;
 	void *d3_resume_sram;
 	u32 d3_test_pme_ptr;
+	struct ieee80211_vif *keep_vif;
 #endif
 #endif
 
Signature · 1 line
1.7.9.5
#11 lore raw

PATCH 11/29 iwlwifi: mvm: fix ht protection flags

In reply to Emmanuel Grumbach

From: Avri Altman <[email protected]>

The HT protection flags have been a mess for a long time, this patch fixes all this.

The proper source of information for this is the protection in the HT operation mode IE which is propagated to bss_conf by mac80211.

1) No need to set the HT protection flags when the link doesn't support HT.
2) We need to set the TGG protection when ERP is active.

---
 drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c |   51 ++++++++++++++++++++++-----
 drivers/net/wireless/iwlwifi/mvm/mac80211.c |   11 ++++++
 2 files changed, 53 insertions(+), 9 deletions(-)
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +42 -9
index f41f9b0..fb93961 100644
@@ -488,6 +488,40 @@ static void iwl_mvm_ack_rates(struct iwl_mvm *mvm,
 	*ofdm_rates = ofdm;
 }
 
+static void iwl_mvm_mac_ctxt_set_ht_flags(struct iwl_mvm *mvm,
+					 struct ieee80211_vif *vif,
+					 struct iwl_mac_ctx_cmd *cmd)
+{
+	/* for both sta and ap, ht_operation_mode hold the protection_mode */
+	u8 protection_mode = vif->bss_conf.ht_operation_mode &
+				 IEEE80211_HT_OP_MODE_PROTECTION;
+	/* The fw does not distinguish between ht and fat */
+	u32 ht_flag = MAC_PROT_FLG_HT_PROT | MAC_PROT_FLG_FAT_PROT;
+
+	IWL_DEBUG_RATE(mvm, "protection mode set to %d\n", protection_mode);
+	/*
+	 * See section 9.23.3.1 of IEEE 80211-2012.
+	 * Nongreenfield HT STAs Present is not supported.
+	 */
+	switch (protection_mode) {
+	case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
+		break;
+	case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
+	case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
+		cmd->protection_flags |= cpu_to_le32(ht_flag);
+		break;
+	case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
+		/* Protect when channel wider than 20MHz */
+		if (vif->bss_conf.chandef.width > NL80211_CHAN_WIDTH_20)
+			cmd->protection_flags |= cpu_to_le32(ht_flag);
+		break;
+	default:
+		IWL_ERR(mvm, "Illegal protection mode %d\n",
+			protection_mode);
+		break;
+	}
+}
+
 static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
 					struct ieee80211_vif *vif,
 					struct iwl_mac_ctx_cmd *cmd,
@@ -495,6 +529,8 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
 {
 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 	struct ieee80211_chanctx_conf *chanctx;
+	bool ht_enabled = !!(vif->bss_conf.ht_operation_mode &
+			     IEEE80211_HT_OP_MODE_PROTECTION);
 	u8 cck_ack_rates, ofdm_ack_rates;
 	int i;
 
@@ -573,16 +609,13 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
 			cmd->protection_flags |=
 				cpu_to_le32(MAC_PROT_FLG_SELF_CTS_EN);
 	}
-
-	/*
-	 * I think that we should enable these 2 flags regardless the HT PROT
-	 * fields in the HT IE, but I am not sure. Someone knows whom to ask?...
-	 */
-	if (vif->bss_conf.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) {
+	IWL_DEBUG_RATE(mvm, "use_cts_prot %d, ht_operation_mode %d\n",
+		       vif->bss_conf.use_cts_prot,
+		       vif->bss_conf.ht_operation_mode);
+	if (vif->bss_conf.chandef.width != NL80211_CHAN_WIDTH_20_NOHT)
 		cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_TGN);
-		cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_HT_PROT |
-						     MAC_PROT_FLG_FAT_PROT);
-	}
+	if (ht_enabled)
+		iwl_mvm_mac_ctxt_set_ht_flags(mvm, vif, cmd);
 
 	cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP);
 }
drivers/net/wireless/iwlwifi/mvm/mac80211.c +11 -0
index 0cc9c1e..f892f58 100644
@@ -990,6 +990,17 @@ iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm,
 				 struct ieee80211_bss_conf *bss_conf,
 				 u32 changes)
 {
+	enum ieee80211_bss_change ht_change = BSS_CHANGED_ERP_CTS_PROT |
+					      BSS_CHANGED_HT |
+					      BSS_CHANGED_BANDWIDTH;
+	int ret;
+
+	if (changes & ht_change) {
+		ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
+		if (ret)
+			IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
+	}
+
 	/* Need to send a new beacon template to the FW */
 	if (changes & BSS_CHANGED_BEACON) {
 		if (iwl_mvm_mac_ctxt_beacon_changed(mvm, vif))
Signature · 1 line
1.7.9.5
#12 lore raw

PATCH 12/29 iwlwifi: mvm: small debugfs cleanups

In reply to Emmanuel Grumbach

From: Johannes Berg <[email protected]>

Just clean up the code a bit, in particular
* make all the debugfs writes follow the same pattern with respect to buf/buf_size variables
* get rid of useless comments
* check return values of all file creations
* drop unnecessary parentheses
* remove an unused struct definition
* fix some whitespace

---
 drivers/net/wireless/iwlwifi/mvm/debugfs.c |   77 ++++++++++------------------
 1 file changed, 27 insertions(+), 50 deletions(-)
drivers/net/wireless/iwlwifi/mvm/debugfs.c +27 -50
index 4b31d06..9cb340a 100644
@@ -65,26 +65,19 @@
 #include "iwl-io.h"
 #include "iwl-prph.h"
 
-struct iwl_dbgfs_mvm_ctx {
-	struct iwl_mvm *mvm;
-	struct ieee80211_vif *vif;
-};
-
 static ssize_t iwl_dbgfs_tx_flush_write(struct file *file,
 					const char __user *user_buf,
 					size_t count, loff_t *ppos)
 {
 	struct iwl_mvm *mvm = file->private_data;
-
-	char buf[16];
-	int buf_size, ret;
+	char buf[16] = {};
+	size_t buf_size = min(count, sizeof(buf) - 1);
+	int ret;
 	u32 scd_q_msk;
 
 	if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
 		return -EIO;
 
-	memset(buf, 0, sizeof(buf));
-	buf_size = min(count, sizeof(buf) - 1);
 	if (copy_from_user(buf, user_buf, buf_size))
 		return -EFAULT;
 
@@ -106,15 +99,13 @@ static ssize_t iwl_dbgfs_sta_drain_write(struct file *file,
 {
 	struct iwl_mvm *mvm = file->private_data;
 	struct ieee80211_sta *sta;
-
-	char buf[8];
-	int buf_size, sta_id, drain, ret;
+	char buf[8] = {};
+	size_t buf_size = min(count, sizeof(buf) - 1);
+	int sta_id, drain, ret;
 
 	if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
 		return -EIO;
 
-	memset(buf, 0, sizeof(buf));
-	buf_size = min(count, sizeof(buf) - 1);
 	if (copy_from_user(buf, user_buf, buf_size))
 		return -EFAULT;
 
@@ -196,12 +187,10 @@ static ssize_t iwl_dbgfs_sram_write(struct file *file,
 				    loff_t *ppos)
 {
 	struct iwl_mvm *mvm = file->private_data;
-	char buf[64];
-	int buf_size;
+	char buf[64] = {};
+	size_t buf_size = min(count, sizeof(buf) -  1);
 	u32 offset, len;
 
-	memset(buf, 0, sizeof(buf));
-	buf_size = min(count, sizeof(buf) -  1);
 	if (copy_from_user(buf, user_buf, buf_size))
 		return -EFAULT;
 
@@ -270,14 +259,14 @@ static ssize_t iwl_dbgfs_disable_power_off_write(struct file *file,
 {
 	struct iwl_mvm *mvm = file->private_data;
 	char buf[64] = {};
+	size_t buf_size = min(count, sizeof(buf) - 1);
 	int ret;
 	int val;
 
 	if (!mvm->ucode_loaded)
 		return -EIO;
 
-	count = min_t(size_t, count, sizeof(buf) - 1);
-	if (copy_from_user(buf, user_buf, count))
+	if (copy_from_user(buf, user_buf, buf_size))
 		return -EFAULT;
 
 	if (!strncmp("disable_power_off_d0=", buf, 21)) {
@@ -315,11 +304,10 @@ static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
 		int dtimper_msec = dtimper * vif->bss_conf.beacon_int;
 
 		IWL_DEBUG_POWER(mvm, "debugfs: set keep_alive= %d sec\n", val);
-		if (val * MSEC_PER_SEC < 3 * dtimper_msec) {
+		if (val * MSEC_PER_SEC < 3 * dtimper_msec)
 			IWL_WARN(mvm,
 				 "debugfs: keep alive period (%ld msec) is less than minimum required (%d msec)\n",
 				 val * MSEC_PER_SEC, 3 * dtimper_msec);
-		}
 		dbgfs_pm->keep_alive_seconds = val;
 		break;
 	}
@@ -368,11 +356,11 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
 	struct iwl_mvm *mvm = mvmvif->dbgfs_data;
 	enum iwl_dbgfs_pm_mask param;
 	char buf[32] = {};
+	size_t buf_size = min(count, sizeof(buf) - 1);
 	int val;
 	int ret;
 
-	count = min_t(size_t, count, sizeof(buf) - 1);
-	if (copy_from_user(buf, user_buf, count))
+	if (copy_from_user(buf, user_buf, buf_size))
 		return -EFAULT;
 
 	if (!strncmp("keep_alive=", buf, 11)) {
@@ -467,7 +455,7 @@ static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
 	pos += scnprintf(buf+pos, bufsz-pos, "bssid: %pM\n",
 			 vif->bss_conf.bssid);
 	pos += scnprintf(buf+pos, bufsz-pos, "QoS:\n");
-	for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++) {
+	for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++)
 		pos += scnprintf(buf+pos, bufsz-pos,
 				 "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n",
 				 i, mvmvif->queue_params[i].txop,
@@ -475,7 +463,6 @@ static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
 				 mvmvif->queue_params[i].cw_max,
 				 mvmvif->queue_params[i].aifs,
 				 mvmvif->queue_params[i].uapsd);
-	}
 
 	if (vif->type == NL80211_IFTYPE_STATION &&
 	    ap_sta_id != IWL_MVM_STATION_COUNT) {
@@ -492,12 +479,11 @@ static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
 
 	rcu_read_lock();
 	chanctx_conf = rcu_dereference(vif->chanctx_conf);
-	if (chanctx_conf) {
+	if (chanctx_conf)
 		pos += scnprintf(buf+pos, bufsz-pos,
 				 "idle rx chains %d, active rx chains: %d\n",
 				 chanctx_conf->rx_chains_static,
 				 chanctx_conf->rx_chains_dynamic);
-	}
 	rcu_read_unlock();
 
 	mutex_unlock(&mvm->mutex);
@@ -841,14 +827,10 @@ iwl_dbgfs_scan_ant_rxchain_write(struct file *file,
 				 size_t count, loff_t *ppos)
 {
 	struct iwl_mvm *mvm = file->private_data;
-	char buf[8];
-	int buf_size;
+	char buf[8] = {};
+	size_t buf_size = min(count, sizeof(buf) - 1);
 	u8 scan_rx_ant;
 
-	memset(buf, 0, sizeof(buf));
-	buf_size = min(count, sizeof(buf) - 1);
-
-	/* get the argument from the user and check if it is valid */
 	if (copy_from_user(buf, user_buf, buf_size))
 		return -EFAULT;
 	if (sscanf(buf, "%hhx", &scan_rx_ant) != 1)
@@ -858,7 +840,6 @@ iwl_dbgfs_scan_ant_rxchain_write(struct file *file,
 	if (scan_rx_ant & ~iwl_fw_valid_rx_ant(mvm->fw))
 		return -EINVAL;
 
-	/* change the rx antennas for scan command */
 	mvm->scan_rx_ant = scan_rx_ant;
 
 	return count;
@@ -918,13 +899,10 @@ static ssize_t iwl_dbgfs_bf_params_write(struct file *file,
 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 	struct iwl_mvm *mvm = mvmvif->dbgfs_data;
 	enum iwl_dbgfs_bf_mask param;
-	char buf[256];
-	int buf_size;
-	int value;
-	int ret = 0;
+	char buf[256] = {};
+	size_t buf_size = min(count, sizeof(buf) - 1);
+	int value, ret = 0;
 
-	memset(buf, 0, sizeof(buf));
-	buf_size = min(count, sizeof(buf) - 1);
 	if (copy_from_user(buf, user_buf, buf_size))
 		return -EFAULT;
 
@@ -1008,11 +986,10 @@ static ssize_t iwl_dbgfs_bf_params_write(struct file *file,
 
 	mutex_lock(&mvm->mutex);
 	iwl_dbgfs_update_bf(vif, param, value);
-	if (param == MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value) {
+	if (param == MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value)
 		ret = iwl_mvm_disable_beacon_filter(mvm, vif);
-	} else {
+	else
 		ret = iwl_mvm_enable_beacon_filter(mvm, vif);
-	}
 	mutex_unlock(&mvm->mutex);
 
 	return ret ?: count;
@@ -1074,10 +1051,10 @@ static ssize_t iwl_dbgfs_d3_sram_write(struct file *file,
 {
 	struct iwl_mvm *mvm = file->private_data;
 	char buf[8] = {};
+	size_t buf_size = min(count, sizeof(buf) - 1);
 	int store;
 
-	count = min_t(size_t, count, sizeof(buf) - 1);
-	if (copy_from_user(buf, user_buf, count))
+	if (copy_from_user(buf, user_buf, buf_size))
 		return -EFAULT;
 
 	if (sscanf(buf, "%d", &store) != 1)
@@ -1133,14 +1110,14 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
 #endif
 
 #define MVM_DEBUGFS_READ_FILE_OPS(name)					\
-static const struct file_operations iwl_dbgfs_##name##_ops = {	\
+static const struct file_operations iwl_dbgfs_##name##_ops = {		\
 	.read = iwl_dbgfs_##name##_read,				\
 	.open = simple_open,						\
 	.llseek = generic_file_llseek,					\
 }
 
 #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name)				\
-static const struct file_operations iwl_dbgfs_##name##_ops = {	\
+static const struct file_operations iwl_dbgfs_##name##_ops = {		\
 	.write = iwl_dbgfs_##name##_write,				\
 	.read = iwl_dbgfs_##name##_read,				\
 	.open = simple_open,						\
@@ -1148,7 +1125,7 @@ static const struct file_operations iwl_dbgfs_##name##_ops = {	\
 };
 
 #define MVM_DEBUGFS_WRITE_FILE_OPS(name)				\
-static const struct file_operations iwl_dbgfs_##name##_ops = {	\
+static const struct file_operations iwl_dbgfs_##name##_ops = {		\
 	.write = iwl_dbgfs_##name##_write,				\
 	.open = simple_open,						\
 	.llseek = generic_file_llseek,					\
Signature · 1 line
1.7.9.5
#13 lore raw

PATCH 13/29 iwlwifi: mvm: move interface-specific debugfs to a new file

In reply to Emmanuel Grumbach

From: Johannes Berg <[email protected]>

The debugfs file is getting pretty large and mixed up between code for the hardware and code for each interface (the two aren't even clearly separated in the code). Make it easier to handle by splitting the per-interface code into a separate file called debugfs-vif.c.

---
 drivers/net/wireless/iwlwifi/mvm/Makefile      |    1 +
 drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c |  190 +++++++++
 drivers/net/wireless/iwlwifi/mvm/debugfs.c     |  505 +-----------------------
 drivers/net/wireless/iwlwifi/mvm/debugfs.h     |   84 ++++
 4 files changed, 276 insertions(+), 504 deletions(-)
 create mode 100644 drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
 create mode 100644 drivers/net/wireless/iwlwifi/mvm/debugfs.h
drivers/net/wireless/iwlwifi/mvm/Makefile +1 -0
index 6d73817..285d8c7 100644
@@ -5,6 +5,7 @@ iwlmvm-y += scan.o time-event.o rs.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_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o
 iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
 
 ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../
drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c new file +190 -0

190 lines not on this page · raw message

drivers/net/wireless/iwlwifi/mvm/debugfs.c +1 -504

544 lines not on this page · raw message

drivers/net/wireless/iwlwifi/mvm/debugfs.h new file +84 -0

84 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#14 lore raw

PATCH 14/29 iwlwifi: mvm: don't use void pointers in debugfs

In reply to Emmanuel Grumbach

From: Johannes Berg <[email protected]>

There's really no reason to use void *dbgfs_data
rather than a struct iwl_mvm *mvm, so do that.

---
 drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c |    4 ++--
 drivers/net/wireless/iwlwifi/mvm/mvm.h         |    2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c +2 -2
index a90dde0..67f6a20 100644
@@ -69,7 +69,7 @@ static ssize_t iwl_dbgfs_mac_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_mvm *mvm = mvmvif->mvm;
 	u8 ap_sta_id;
 	struct ieee80211_chanctx_conf *chanctx_conf;
 	char buf[512];
@@ -144,7 +144,7 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 		return;
 
 	mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir);
-	mvmvif->dbgfs_data = mvm;
+	mvmvif->mvm = mvm;
 
 	if (!mvmvif->dbgfs_dir) {
 		IWL_ERR(mvm, "Failed to create debugfs directory under %s\n",
drivers/net/wireless/iwlwifi/mvm/mvm.h +1 -1
index c002b45..e7c97cc 100644
@@ -323,9 +323,9 @@ struct iwl_mvm_vif {
 #endif
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
+	struct iwl_mvm *mvm;
 	struct dentry *dbgfs_dir;
 	struct dentry *dbgfs_slink;
-	void *dbgfs_data;
 	struct iwl_dbgfs_pm dbgfs_pm;
 	struct iwl_dbgfs_bf dbgfs_bf;
 #endif
Signature · 1 line
1.7.9.5
#15 lore raw

PATCH 15/29 iwlwifi: mvm: refactor debugfs copy_from_user()

In reply to Emmanuel Grumbach

From: Johannes Berg <[email protected]>

Abstract the copy_from_user() pattern into the macros defining debugfs files, reducing the code and making adding new files safer by avoiding having deal with copy_from_user() directly.

---
 drivers/net/wireless/iwlwifi/mvm/debugfs.c |   87 +++++++---------------------
 drivers/net/wireless/iwlwifi/mvm/debugfs.h |   25 ++++++--
 2 files changed, 43 insertions(+), 69 deletions(-)
drivers/net/wireless/iwlwifi/mvm/debugfs.c +22 -65
index f0811b1..a9b2d0a 100644
@@ -66,22 +66,15 @@
 #include "iwl-prph.h"
 #include "debugfs.h"
 
-static ssize_t iwl_dbgfs_tx_flush_write(struct file *file,
-					const char __user *user_buf,
+static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf,
 					size_t count, loff_t *ppos)
 {
-	struct iwl_mvm *mvm = file->private_data;
-	char buf[16] = {};
-	size_t buf_size = min(count, sizeof(buf) - 1);
 	int ret;
 	u32 scd_q_msk;
 
 	if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
 		return -EIO;
 
-	if (copy_from_user(buf, user_buf, buf_size))
-		return -EFAULT;
-
 	if (sscanf(buf, "%x", &scd_q_msk) != 1)
 		return -EINVAL;
 
@@ -94,22 +87,15 @@ static ssize_t iwl_dbgfs_tx_flush_write(struct file *file,
 	return ret;
 }
 
-static ssize_t iwl_dbgfs_sta_drain_write(struct file *file,
-					 const char __user *user_buf,
+static ssize_t iwl_dbgfs_sta_drain_write(struct iwl_mvm *mvm, char *buf,
 					 size_t count, loff_t *ppos)
 {
-	struct iwl_mvm *mvm = file->private_data;
 	struct ieee80211_sta *sta;
-	char buf[8] = {};
-	size_t buf_size = min(count, sizeof(buf) - 1);
 	int sta_id, drain, ret;
 
 	if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
 		return -EIO;
 
-	if (copy_from_user(buf, user_buf, buf_size))
-		return -EFAULT;
-
 	if (sscanf(buf, "%d %d", &sta_id, &drain) != 2)
 		return -EINVAL;
 
@@ -183,18 +169,11 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
 	return ret;
 }
 
-static ssize_t iwl_dbgfs_sram_write(struct file *file,
-				    const char __user *user_buf, size_t count,
-				    loff_t *ppos)
+static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf,
+				    size_t count, loff_t *ppos)
 {
-	struct iwl_mvm *mvm = file->private_data;
-	char buf[64] = {};
-	size_t buf_size = min(count, sizeof(buf) -  1);
 	u32 offset, len;
 
-	if (copy_from_user(buf, user_buf, buf_size))
-		return -EFAULT;
-
 	if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
 		if ((offset & 0x3) || (len & 0x3))
 			return -EINVAL;
@@ -254,22 +233,14 @@ static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file,
 	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 }
 
-static ssize_t iwl_dbgfs_disable_power_off_write(struct file *file,
-						 const char __user *user_buf,
+static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf,
 						 size_t count, loff_t *ppos)
 {
-	struct iwl_mvm *mvm = file->private_data;
-	char buf[64] = {};
-	size_t buf_size = min(count, sizeof(buf) - 1);
-	int ret;
-	int val;
+	int ret, val;
 
 	if (!mvm->ucode_loaded)
 		return -EIO;
 
-	if (copy_from_user(buf, user_buf, buf_size))
-		return -EFAULT;
-
 	if (!strncmp("disable_power_off_d0=", buf, 21)) {
 		if (sscanf(buf + 21, "%d", &val) != 1)
 			return -EINVAL;
@@ -564,11 +535,9 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
 }
 #undef PRINT_STAT_LE32
 
-static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
-					  const char __user *user_buf,
+static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
 					  size_t count, loff_t *ppos)
 {
-	struct iwl_mvm *mvm = file->private_data;
 	int ret;
 
 	mutex_lock(&mvm->mutex);
@@ -585,12 +554,9 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
 	return count;
 }
 
-static ssize_t iwl_dbgfs_fw_nmi_write(struct file *file,
-				      const char __user *user_buf,
+static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf,
 				      size_t count, loff_t *ppos)
 {
-	struct iwl_mvm *mvm = file->private_data;
-
 	iwl_write_prph(mvm->trans, DEVICE_SET_NMI_REG, 1);
 
 	return count;
@@ -620,17 +586,11 @@ iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
 }
 
 static ssize_t
-iwl_dbgfs_scan_ant_rxchain_write(struct file *file,
-				 const char __user *user_buf,
+iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
 				 size_t count, loff_t *ppos)
 {
-	struct iwl_mvm *mvm = file->private_data;
-	char buf[8] = {};
-	size_t buf_size = min(count, sizeof(buf) - 1);
 	u8 scan_rx_ant;
 
-	if (copy_from_user(buf, user_buf, buf_size))
-		return -EFAULT;
 	if (sscanf(buf, "%hhx", &scan_rx_ant) != 1)
 		return -EINVAL;
 	if (scan_rx_ant > ANT_ABC)
@@ -644,18 +604,11 @@ iwl_dbgfs_scan_ant_rxchain_write(struct file *file,
 }
 
 #ifdef CONFIG_PM_SLEEP
-static ssize_t iwl_dbgfs_d3_sram_write(struct file *file,
-				       const char __user *user_buf,
+static ssize_t iwl_dbgfs_d3_sram_write(struct iwl_mvm *mvm, char *buf,
 				       size_t count, loff_t *ppos)
 {
-	struct iwl_mvm *mvm = file->private_data;
-	char buf[8] = {};
-	size_t buf_size = min(count, sizeof(buf) - 1);
 	int store;
 
-	if (copy_from_user(buf, user_buf, buf_size))
-		return -EFAULT;
-
 	if (sscanf(buf, "%d", &store) != 1)
 		return -EINVAL;
 
@@ -708,6 +661,10 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
 }
 #endif
 
+#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
+	_MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
+#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
+	_MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
 #define MVM_DEBUGFS_ADD_FILE(name, parent, mode) do {			\
 		if (!debugfs_create_file(#name, mode, parent, mvm,	\
 					 &iwl_dbgfs_##name##_ops))	\
@@ -715,20 +672,20 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
 	} while (0)
 
 /* Device wide debugfs entries */
-MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush);
-MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain);
-MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram);
+MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
+MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
+MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64);
 MVM_DEBUGFS_READ_FILE_OPS(stations);
 MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
 MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
-MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off);
+MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64);
 MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
-MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart);
-MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi);
-MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain);
+MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
+MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
+MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
 
 #ifdef CONFIG_PM_SLEEP
-MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram);
+MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram, 8);
 #endif
 
 int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
drivers/net/wireless/iwlwifi/mvm/debugfs.h +21 -4
index faa73b8..85f9f95 100644
@@ -68,17 +68,34 @@ static const struct file_operations iwl_dbgfs_##name##_ops = {		\
 	.llseek = generic_file_llseek,					\
 }
 
-#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name)				\
+#define MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype)		\
+static ssize_t _iwl_dbgfs_##name##_write(struct file *file,		\
+					 const char __user *user_buf,	\
+					 size_t count, loff_t *ppos)	\
+{									\
+	argtype *arg = 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(arg, buf, buf_size, ppos);	\
+}									\
+
+#define _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, buflen, argtype)		\
+MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype)			\
 static const struct file_operations iwl_dbgfs_##name##_ops = {		\
-	.write = iwl_dbgfs_##name##_write,				\
+	.write = _iwl_dbgfs_##name##_write,				\
 	.read = iwl_dbgfs_##name##_read,				\
 	.open = simple_open,						\
 	.llseek = generic_file_llseek,					\
 };
 
-#define MVM_DEBUGFS_WRITE_FILE_OPS(name)				\
+#define _MVM_DEBUGFS_WRITE_FILE_OPS(name, buflen, argtype)		\
+MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype)			\
 static const struct file_operations iwl_dbgfs_##name##_ops = {		\
-	.write = iwl_dbgfs_##name##_write,				\
+	.write = _iwl_dbgfs_##name##_write,				\
 	.open = simple_open,						\
 	.llseek = generic_file_llseek,					\
 };
Signature · 1 line
1.7.9.5
#16 lore raw

PATCH 16/29 iwlwifi: mvm: add LQ flags definitions

In reply to Emmanuel Grumbach

From: Eyal Shapira <[email protected]>

Add more bit field definitions used in LQ flags. Also rename the first bit to a shorter name.

---
 drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h |   27 ++++++++++++++++++++++++--
 drivers/net/wireless/iwlwifi/mvm/rs.c        |    4 ++--
 2 files changed, 27 insertions(+), 4 deletions(-)
drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h +25 -2
index 538f1c7..532312c 100644
@@ -281,8 +281,31 @@ enum {
 /* # entries in rate scale table to support Tx retries */
 #define  LQ_MAX_RETRY_NUM 16
 
-/* Link quality command flags, only this one is available */
-#define  LQ_FLAG_SET_STA_TLC_RTS_MSK	BIT(0)
+/* Link quality command flags bit fields */
+
+/* Bit 0: (0) Don't use RTS (1) Use RTS */
+#define LQ_FLAG_USE_RTS_POS             0
+#define LQ_FLAG_USE_RTS_MSK	        (1 << LQ_FLAG_USE_RTS_POS)
+
+/* Bit 1-3: LQ command color. Used to match responses to LQ commands */
+#define LQ_FLAG_COLOR_POS               1
+#define LQ_FLAG_COLOR_MSK               (7 << LQ_FLAG_COLOR_POS)
+
+/* Bit 4-5: Tx RTS BW Signalling
+ * (0) No RTS BW signalling
+ * (1) Static BW signalling
+ * (2) Dynamic BW signalling
+ */
+#define LQ_FLAG_RTS_BW_SIG_POS          4
+#define LQ_FLAG_RTS_BW_SIG_NONE         (0 << LQ_FLAG_RTS_BW_SIG_POS)
+#define LQ_FLAG_RTS_BW_SIG_STATIC       (1 << LQ_FLAG_RTS_BW_SIG_POS)
+#define LQ_FLAG_RTS_BW_SIG_DYNAMIC      (2 << LQ_FLAG_RTS_BW_SIG_POS)
+
+/* Bit 6: (0) No dynamic BW selection (1) Allow dynamic BW selection
+ * Dyanmic BW selection allows Tx with narrower BW then requested in rates
+ */
+#define LQ_FLAG_DYNAMIC_BW_POS          6
+#define LQ_FLAG_DYNAMIC_BW_MSK          (1 << LQ_FLAG_DYNAMIC_BW_POS)
 
 /**
  * struct iwl_lq_cmd - link quality command
drivers/net/wireless/iwlwifi/mvm/rs.c +2 -2
index a85938c..482b91b8 100644
@@ -2862,12 +2862,12 @@ int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
 
 	if (enable) {
 		if (mvmsta->tx_protection == 0)
-			lq->flags |= LQ_FLAG_SET_STA_TLC_RTS_MSK;
+			lq->flags |= LQ_FLAG_USE_RTS_MSK;
 		mvmsta->tx_protection++;
 	} else {
 		mvmsta->tx_protection--;
 		if (mvmsta->tx_protection == 0)
-			lq->flags &= ~LQ_FLAG_SET_STA_TLC_RTS_MSK;
+			lq->flags &= ~LQ_FLAG_USE_RTS_MSK;
 	}
 
 	return iwl_mvm_send_lq_cmd(mvm, lq, false);
Signature · 1 line
1.7.9.5
#17 lore raw

PATCH 17/29 iwlwifi: mvm: BT Coex - fine tune the aggregation size

In reply to Emmanuel Grumbach

From: Emmanuel Grumbach <[email protected]>

Latest tests have shown that when BT is active and has connections but the traffic is low, the WiFi aggregation can be large up to 4000us without noticeable impact on BT.

---
 drivers/net/wireless/iwlwifi/mvm/bt-coex.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/iwlwifi/mvm/bt-coex.c +1 -1
index 5d066cb..7dbb058 100644
@@ -917,7 +917,7 @@ u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm,
 	enum iwl_bt_coex_lut_type lut_type;
 
 	if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
-	    BT_LOW_TRAFFIC)
+	    BT_HIGH_TRAFFIC)
 		return LINK_QUAL_AGG_TIME_LIMIT_DEF;
 
 	lut_type = iwl_get_coex_type(mvm, mvmsta->vif);
Signature · 1 line
1.7.9.5
#18 lore raw

PATCH 18/29 iwlwifi: mvm: a few more SKUs for 7260 and 3160

In reply to Emmanuel Grumbach

From: Emmanuel Grumbach <[email protected]>

These devices are not sold as discrete modules but are rather soldered down to the board.

---
 drivers/net/wireless/iwlwifi/pcie/drv.c |    5 +++++
 1 file changed, 5 insertions(+)
drivers/net/wireless/iwlwifi/pcie/drv.c +5 -0
index 941c0c8..c1efc03 100644
@@ -297,6 +297,9 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
 	{IWL_PCI_DEVICE(0x08B2, 0x4370, iwl7260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x08B2, 0x4360, iwl7260_2n_cfg)},
 	{IWL_PCI_DEVICE(0x08B1, 0x5070, iwl7260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x5072, iwl7260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x5170, iwl7260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x5770, iwl7260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)},
 	{IWL_PCI_DEVICE(0x08B1, 0x402A, iwl7260_2n_cfg)},
 	{IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)},
@@ -350,6 +353,8 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
 	{IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x08B3, 0x8570, iwl3160_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B3, 0x1070, iwl3160_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B3, 0x1170, iwl3160_2ac_cfg)},
 
 /* 7265 Series */
 	{IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)},
Signature · 1 line
1.7.9.5
#19 lore raw

PATCH 19/29 iwlwifi: pcie: remove minor dead code

In reply to Emmanuel Grumbach

From: Michal Nazarewicz <[email protected]>

inta is checked to be zero in a IRQ_NONE branch so afterwards it cannot be zero as it is never modified.

[reword the patch title and fix comment]
---
 drivers/net/wireless/iwlwifi/pcie/rx.c |   26 +++++++++++---------------
 1 file changed, 11 insertions(+), 15 deletions(-)
drivers/net/wireless/iwlwifi/pcie/rx.c +11 -15
index 3f237b4..79d46a9 100644
@@ -1121,7 +1121,6 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data)
 	struct iwl_trans *trans = data;
 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 	u32 inta, inta_mask;
-	irqreturn_t ret = IRQ_NONE;
 
 	lockdep_assert_held(&trans_pcie->irq_lock);
 
@@ -1150,7 +1149,16 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data)
 	 * or due to sporadic interrupts thrown from our NIC. */
 	if (!inta) {
 		IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n");
-		goto none;
+		/*
+		 * Re-enable interrupts here since we don't have anything to
+		 * service, but only in case the handler won't run. Note that
+		 * the handler can be scheduled because of a previous
+		 * interrupt.
+		 */
+		if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
+		    !trans_pcie->inta)
+			iwl_enable_interrupts(trans);
+		return IRQ_NONE;
 	}
 
 	if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
@@ -1168,19 +1176,7 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data)
 
 	trans_pcie->inta |= inta;
 	/* the thread will service interrupts and re-enable them */
-	if (likely(inta))
-		return IRQ_WAKE_THREAD;
-
-	ret = IRQ_HANDLED;
-
-none:
-	/* re-enable interrupts here since we don't have anything to service. */
-	/* only Re-enable if disabled by irq  and no schedules tasklet. */
-	if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
-	    !trans_pcie->inta)
-		iwl_enable_interrupts(trans);
-
-	return ret;
+	return IRQ_WAKE_THREAD;
 }
 
 /* interrupt handler using ict table, with this interrupt driver will
Signature · 1 line
1.7.9.5
#20 lore raw

PATCH 20/29 iwlwifi: fix check for a single rx antenna

In reply to Emmanuel Grumbach

From: Eyal Shapira <[email protected]>

valid_rx_ant is a bitmask of available antennas and not the number of Rx antennas. Use num_of_ant and remove duplicate definitions in both dvm and mvm.

---
 drivers/net/wireless/iwlwifi/dvm/rs.h        |    7 -------
 drivers/net/wireless/iwlwifi/iwl-config.h    |    6 ++++++
 drivers/net/wireless/iwlwifi/iwl-nvm-parse.c |    3 ++-
 drivers/net/wireless/iwlwifi/mvm/rs.h        |    8 --------
 4 files changed, 8 insertions(+), 16 deletions(-)
drivers/net/wireless/iwlwifi/dvm/rs.h +0 -7
index 26fc550..41988f4 100644
@@ -389,13 +389,6 @@ struct iwl_lq_sta {
 	u8 last_bt_traffic;
 };
 
-static inline u8 num_of_ant(u8 mask)
-{
-	return  !!((mask) & ANT_A) +
-		!!((mask) & ANT_B) +
-		!!((mask) & ANT_C);
-}
-
 static inline u8 first_antenna(u8 mask)
 {
 	if (mask & ANT_A)
drivers/net/wireless/iwlwifi/iwl-config.h +6 -0
index 18f232e..ab19cea 100644
@@ -129,6 +129,12 @@ enum iwl_led_mode {
 #define ANT_BC		(ANT_B | ANT_C)
 #define ANT_ABC		(ANT_A | ANT_B | ANT_C)
 
+static inline u8 num_of_ant(u8 mask)
+{
+	return  !!((mask) & ANT_A) +
+		!!((mask) & ANT_B) +
+		!!((mask) & ANT_C);
+}
 
 /*
  * @max_ll_items: max number of OTP blocks
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +2 -1
index b76a9a8..5348bd4 100644
@@ -283,7 +283,8 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
 			    IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
 			    IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);
 
-	if (data->valid_rx_ant == 1 || cfg->rx_with_siso_diversity) {
+	if (num_of_ant(data->valid_rx_ant) == 1 ||
+	    cfg->rx_with_siso_diversity) {
 		vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
 				IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
 		/* this works because NOT_SUPPORTED == 3 */
drivers/net/wireless/iwlwifi/mvm/rs.h +0 -8
index 8d5dc78..b41686b 100644
@@ -343,14 +343,6 @@ enum iwl_bt_coex_profile_traffic_load {
  */
 };
 
-
-static inline u8 num_of_ant(u8 mask)
-{
-	return  !!((mask) & ANT_A) +
-		!!((mask) & ANT_B) +
-		!!((mask) & ANT_C);
-}
-
 /* Initialize station's rate scaling information after adding station */
 void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
 			  enum ieee80211_band band, bool init);
Signature · 1 line
1.7.9.5
#21 lore raw

PATCH 21/29 iwlwifi: mvm: add iwl_mvm_sta_from_mac80211

In reply to Emmanuel Grumbach

From: Johannes Berg <[email protected]>

This is just a helper function to go from the mac80211 station struct to our internal one, to later allow us to avoid temporary 'mvmsta' variables.

---
 drivers/net/wireless/iwlwifi/mvm/bt-coex.c  |    8 ++++----
 drivers/net/wireless/iwlwifi/mvm/mac80211.c |    2 +-
 drivers/net/wireless/iwlwifi/mvm/sta.c      |   12 ++++++------
 drivers/net/wireless/iwlwifi/mvm/sta.h      |    6 ++++++
 drivers/net/wireless/iwlwifi/mvm/tt.c       |    2 +-
 drivers/net/wireless/iwlwifi/mvm/tx.c       |   10 +++++-----
 6 files changed, 23 insertions(+), 17 deletions(-)
drivers/net/wireless/iwlwifi/mvm/bt-coex.c +4 -4
index 7dbb058..f0eed69 100644
@@ -515,7 +515,7 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
 	if (IS_ERR_OR_NULL(sta))
 		return 0;
 
-	mvmsta = (void *)sta->drv_priv;
+	mvmsta = iwl_mvm_sta_from_mac80211(sta);
 
 	/* nothing to do */
 	if (mvmsta->bt_reduced_txpower == enable)
@@ -842,7 +842,7 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
 
 	sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
 					lockdep_is_held(&mvm->mutex));
-	mvmsta = (void *)sta->drv_priv;
+	mvmsta = iwl_mvm_sta_from_mac80211(sta);
 
 	data->num_bss_ifaces++;
 
@@ -913,7 +913,7 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm,
 				   struct ieee80211_sta *sta)
 {
-	struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
+	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	enum iwl_bt_coex_lut_type lut_type;
 
 	if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
@@ -932,7 +932,7 @@ u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm,
 bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
 				     struct ieee80211_sta *sta)
 {
-	struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
+	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 
 	if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
 	    BT_HIGH_TRAFFIC)
drivers/net/wireless/iwlwifi/mvm/mac80211.c +1 -1
index f892f58..e25aa23 100644
@@ -1091,7 +1091,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
 				   struct ieee80211_sta *sta)
 {
 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
-	struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
+	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 
 	switch (cmd) {
 	case STA_NOTIFY_SLEEP:
drivers/net/wireless/iwlwifi/mvm/sta.c +6 -6
index c89232c..7a5b747 100644
@@ -840,7 +840,7 @@ static const u8 tid_to_ac[] = {
 int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 			     struct ieee80211_sta *sta, u16 tid, u16 *ssn)
 {
-	struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
+	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	struct iwl_mvm_tid_data *tid_data;
 	int txq_id;
 
@@ -895,7 +895,7 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 			    struct ieee80211_sta *sta, u16 tid, u8 buf_size)
 {
-	struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
+	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
 	int queue, fifo, ret;
 	u16 ssn;
@@ -951,7 +951,7 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 			    struct ieee80211_sta *sta, u16 tid)
 {
-	struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
+	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
 	u16 txq_id;
 	int err;
@@ -1023,7 +1023,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 			    struct ieee80211_sta *sta, u16 tid)
 {
-	struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
+	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
 	u16 txq_id;
 	enum iwl_mvm_agg_state old_state;
@@ -1416,7 +1416,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
 void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
 				struct ieee80211_sta *sta)
 {
-	struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
+	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	struct iwl_mvm_add_sta_cmd_v6 cmd = {
 		.add_modify = STA_MODE_MODIFY,
 		.sta_id = mvmsta->sta_id,
@@ -1438,7 +1438,7 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
 	u16 sleep_state_flags =
 		(reason == IEEE80211_FRAME_RELEASE_UAPSD) ?
 			STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL;
-	struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
+	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	struct iwl_mvm_add_sta_cmd_v6 cmd = {
 		.add_modify = STA_MODE_MODIFY,
 		.sta_id = mvmsta->sta_id,
drivers/net/wireless/iwlwifi/mvm/sta.h +6 -0
index 4dfc359..b349411 100644
@@ -298,6 +298,12 @@ struct iwl_mvm_sta {
 	bool tt_tx_protection;
 };
 
+static inline struct iwl_mvm_sta *
+iwl_mvm_sta_from_mac80211(struct ieee80211_sta *sta)
+{
+	return (void *)sta->drv_priv;
+}
+
 /**
  * struct iwl_mvm_int_sta - representation of an internal station (auxiliary or
  * broadcast)
drivers/net/wireless/iwlwifi/mvm/tt.c +1 -1
index 1f3282d..18be04d 100644
@@ -388,7 +388,7 @@ static void iwl_mvm_tt_tx_protection(struct iwl_mvm *mvm, bool enable)
 						lockdep_is_held(&mvm->mutex));
 		if (IS_ERR_OR_NULL(sta))
 			continue;
-		mvmsta = (void *)sta->drv_priv;
+		mvmsta = iwl_mvm_sta_from_mac80211(sta);
 		if (enable == mvmsta->tt_tx_protection)
 			continue;
 		err = iwl_mvm_tx_protection(mvm, mvmsta, enable);
drivers/net/wireless/iwlwifi/mvm/tx.c +5 -5
index 1f19458..d87649a 100644
@@ -362,7 +362,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
 	u8 txq_id = info->hw_queue;
 	bool is_data_qos = false, is_ampdu = false;
 
-	mvmsta = (void *)sta->drv_priv;
+	mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	fc = hdr->frame_control;
 
 	if (WARN_ON_ONCE(!mvmsta))
@@ -433,7 +433,7 @@ drop:
 static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
 				      struct ieee80211_sta *sta, u8 tid)
 {
-	struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
+	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
 	struct ieee80211_vif *vif = mvmsta->vif;
 
@@ -663,7 +663,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
 	sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
 
 	if (!IS_ERR_OR_NULL(sta)) {
-		mvmsta = (void *)sta->drv_priv;
+		mvmsta = iwl_mvm_sta_from_mac80211(sta);
 
 		if (tid != IWL_TID_NON_QOS) {
 			struct iwl_mvm_tid_data *tid_data =
@@ -794,7 +794,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
 	sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
 
 	if (!WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) {
-		struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
+		struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 		mvmsta->tid_data[tid].rate_n_flags =
 			le32_to_cpu(tx_resp->initial_rate);
 	}
@@ -850,7 +850,7 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
 		return 0;
 	}
 
-	mvmsta = (void *)sta->drv_priv;
+	mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	tid_data = &mvmsta->tid_data[tid];
 
 	if (WARN_ONCE(tid_data->txq_id != scd_flow, "Q %d, tid %d, flow %d",
Signature · 1 line
1.7.9.5
#22 lore raw

PATCH 22/29 iwlwifi: mvm: don't restart HW if suspending fails before D3 image is loaded

In reply to Emmanuel Grumbach

From: Luciano Coelho <[email protected]>

If we haven't loaded the D3 image yet and a failure in the suspend process occurs, we shouldn't restart the HW, because we're still running the D0 image.

---
 drivers/net/wireless/iwlwifi/mvm/d3.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/wireless/iwlwifi/mvm/d3.c +3 -2
index 6964b84..16d9103 100644
@@ -1227,10 +1227,11 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
 	mvm->aux_sta.sta_id = old_aux_sta_id;
 	mvm_ap_sta->sta_id = old_ap_sta_id;
 	mvmvif->ap_sta_id = old_ap_sta_id;
- out_noreset:
-	kfree(key_data.rsc_tsc);
+
 	if (ret < 0)
 		ieee80211_restart_hw(mvm->hw);
+ out_noreset:
+	kfree(key_data.rsc_tsc);
 
 	mutex_unlock(&mvm->mutex);
 
Signature · 1 line
1.7.9.5
#23 lore raw

PATCH 23/29 iwlwifi: mvm: dump NVM from debugfs

In reply to Emmanuel Grumbach

From: Emmanuel Grumbach <[email protected]>

This allows to see the content of the NVM the driver reads. Note that the output is in binary, and requires some external user space tool to display the data properly.

---
 drivers/net/wireless/iwlwifi/mvm/debugfs.c |   13 +++++++++++++
 drivers/net/wireless/iwlwifi/mvm/mvm.h     |    5 +++++
 drivers/net/wireless/iwlwifi/mvm/nvm.c     |   23 +++++++++++++++++++++++
 3 files changed, 41 insertions(+)
drivers/net/wireless/iwlwifi/mvm/debugfs.c +13 -0
index a9b2d0a..145cd72 100644
@@ -716,6 +716,19 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
 		goto err;
 #endif
 
+	if (!debugfs_create_blob("nvm_hw", S_IRUSR,
+				  mvm->debugfs_dir, &mvm->nvm_hw_blob))
+		goto err;
+	if (!debugfs_create_blob("nvm_sw", S_IRUSR,
+				  mvm->debugfs_dir, &mvm->nvm_sw_blob))
+		goto err;
+	if (!debugfs_create_blob("nvm_calib", S_IRUSR,
+				  mvm->debugfs_dir, &mvm->nvm_calib_blob))
+		goto err;
+	if (!debugfs_create_blob("nvm_prod", S_IRUSR,
+				  mvm->debugfs_dir, &mvm->nvm_prod_blob))
+		goto err;
+
 	/*
 	 * Create a symlink with mac80211. It will be removed when mac80211
 	 * exists (before the opmode exists which removes the target.)
drivers/net/wireless/iwlwifi/mvm/mvm.h +5 -0
index e7c97cc..7dc57cf 100644
@@ -494,6 +494,11 @@ struct iwl_mvm {
 	u32 dbgfs_sram_offset, dbgfs_sram_len;
 	bool disable_power_off;
 	bool disable_power_off_d3;
+
+	struct debugfs_blob_wrapper nvm_hw_blob;
+	struct debugfs_blob_wrapper nvm_sw_blob;
+	struct debugfs_blob_wrapper nvm_calib_blob;
+	struct debugfs_blob_wrapper nvm_prod_blob;
 #endif
 
 	struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX];
drivers/net/wireless/iwlwifi/mvm/nvm.c +23 -0
index 2beffd0..e4596c5 100644
@@ -443,6 +443,29 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
 			}
 			mvm->nvm_sections[section].data = temp;
 			mvm->nvm_sections[section].length = ret;
+
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+			switch (section) {
+			case NVM_SECTION_TYPE_HW:
+				mvm->nvm_hw_blob.data = temp;
+				mvm->nvm_hw_blob.size = ret;
+				break;
+			case NVM_SECTION_TYPE_SW:
+				mvm->nvm_sw_blob.data = temp;
+				mvm->nvm_sw_blob.size  = ret;
+				break;
+			case NVM_SECTION_TYPE_CALIBRATION:
+				mvm->nvm_calib_blob.data = temp;
+				mvm->nvm_calib_blob.size  = ret;
+				break;
+			case NVM_SECTION_TYPE_PRODUCTION:
+				mvm->nvm_prod_blob.data = temp;
+				mvm->nvm_prod_blob.size  = ret;
+				break;
+			default:
+				WARN(1, "section: %d", section);
+			};
+#endif
 		}
 		kfree(nvm_buffer);
 		if (ret < 0)
Signature · 1 line
1.7.9.5
#24 lore raw

PATCH 24/29 iwlwifi: mvm: fix scan offloading flag definition

In reply to Emmanuel Grumbach

From: Eliad Peller <[email protected]>

Bit 0 in the scan offloading flags asks the filter to pass all the results (instead of filtering them, by default), rather than the other way around (like it is defined and used today).

Fix the flag name appropriately, and fix its user.

---
 drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h |    5 ++---
 drivers/net/wireless/iwlwifi/mvm/scan.c        |    3 +--
 2 files changed, 3 insertions(+), 5 deletions(-)
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +2 -3
index c3782b4..b3ed592 100644
@@ -530,14 +530,13 @@ struct iwl_scan_offload_schedule {
 /*
  * iwl_scan_offload_flags
  *
- * IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID: filter mode - upload every beacon or match
- *	ssid list.
+ * IWL_SCAN_OFFLOAD_FLAG_PASS_ALL: pass all results - no filtering.
  * IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL: add cached channels to partial scan.
  * IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN: use energy based scan before partial scan
  *	on A band.
  */
 enum iwl_scan_offload_flags {
-	IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID	= BIT(0),
+	IWL_SCAN_OFFLOAD_FLAG_PASS_ALL		= BIT(0),
 	IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL	= BIT(2),
 	IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN	= BIT(3),
 };
drivers/net/wireless/iwlwifi/mvm/scan.c +1 -2
index dff7592..5972266 100644
@@ -817,11 +817,10 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
 		IWL_DEBUG_SCAN(mvm,
 			       "Sending scheduled scan with filtering, filter len %d\n",
 			       req->n_match_sets);
-		scan_req.flags |=
-				cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID);
 	} else {
 		IWL_DEBUG_SCAN(mvm,
 			       "Sending Scheduled scan without filtering\n");
+		scan_req.flags |= cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_PASS_ALL);
 	}
 
 	return iwl_mvm_send_cmd_pdu(mvm, SCAN_OFFLOAD_REQUEST_CMD, CMD_SYNC,
Signature · 1 line
1.7.9.5
#25 lore raw

PATCH 25/29 iwlwifi: mvm: Implement low-priority scan

In reply to Emmanuel Grumbach

From: Haim Dreyfuss <[email protected]>

Advertise driver's support for low priority scan.
Notice that this overwrites current setting by mac80211 which depends only on hw scan support.
This scan priority can be configured by user space application and it affects scan continuity, low priority scan
will be more fragmented scan.

---
 drivers/net/wireless/iwlwifi/mvm/mac80211.c |    3 +-
 drivers/net/wireless/iwlwifi/mvm/scan.c     |   52 ++++++++++++++++++++-------
 2 files changed, 41 insertions(+), 14 deletions(-)
drivers/net/wireless/iwlwifi/mvm/mac80211.c +2 -1
index e25aa23..37fa559 100644
@@ -256,7 +256,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 	}
 
 	hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
-			       NL80211_FEATURE_P2P_GO_OPPPS;
+			       NL80211_FEATURE_P2P_GO_OPPPS |
+			       NL80211_FEATURE_LOW_PRIORITY_SCAN;
 
 	mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
 
drivers/net/wireless/iwlwifi/mvm/scan.c +39 -13

104 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#26 lore raw

PATCH 26/29 iwlwifi: mvm: quota command max_duration should be zero

In reply to Emmanuel Grumbach

From: Johannes Berg <[email protected]>

For now, the firmware doesn't really use the field, but it should be set to zero if there's no specific request. Setting it to the max quota doesn't make sense.

---
 drivers/net/wireless/iwlwifi/mvm/quota.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/wireless/iwlwifi/mvm/quota.c +1 -2
index 17e2bc8..38165eb 100644
@@ -217,8 +217,7 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
 		} else {
 			cmd.quotas[idx].quota =
 				cpu_to_le32(quota * data.n_interfaces[i]);
-			cmd.quotas[idx].max_duration =
-				cpu_to_le32(IWL_MVM_MAX_QUOTA);
+			cmd.quotas[idx].max_duration = cpu_to_le32(0);
 		}
 		idx++;
 	}
Signature · 1 line
1.7.9.5
#27 lore raw

PATCH 27/29 iwlwifi: mvm: stop using MIMO in case BT doesn't allow it

In reply to Emmanuel Grumbach

From: Eyal Shapira <[email protected]>

Switch to using the new btcoex decision api regarding MIMO and stop accessing the internal btcoex structs.
In case MIMO should be disabled it would detect this upon the next Tx and force a search. The search will switch to SISO on a antenna A which isn't used by BT.

---
 drivers/net/wireless/iwlwifi/mvm/rs.c |   26 ++++++--------------------
 drivers/net/wireless/iwlwifi/mvm/rs.h |   13 -------------
 2 files changed, 6 insertions(+), 33 deletions(-)
drivers/net/wireless/iwlwifi/mvm/rs.c +6 -20
index 482b91b8..9565260 100644
@@ -1499,6 +1499,9 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
 	u8 update_search_tbl_counter = 0;
 	int ret;
 
+	if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
+		tbl->action = IWL_MIMO2_SWITCH_SISO_A;
+
 	start_action = tbl->action;
 	while (1) {
 		lq_sta->action_counter++;
@@ -1970,26 +1973,9 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
 	     (current_tpt > (100 * tbl->expected_tpt[low]))))
 		scale_action = 0;
 
-	if ((le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) >=
-	     IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && (is_mimo(tbl->lq_type))) {
-		if (lq_sta->last_bt_traffic >
-		    le32_to_cpu(mvm->last_bt_notif.bt_activity_grading)) {
-			/*
-			 * don't set scale_action, don't want to scale up if
-			 * the rate scale doesn't otherwise think that is a
-			 * good idea.
-			 */
-		} else if (lq_sta->last_bt_traffic <=
-			   le32_to_cpu(mvm->last_bt_notif.bt_activity_grading)) {
-			scale_action = -1;
-		}
-	}
-	lq_sta->last_bt_traffic =
-		le32_to_cpu(mvm->last_bt_notif.bt_activity_grading);
-
-	if ((le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) >=
-	     IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && is_mimo(tbl->lq_type)) {
-		/* search for a new modulation */
+	/* Force a search in case BT doesn't like us being in MIMO */
+	if (is_mimo(tbl->lq_type) &&
+	    !iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) {
 		rs_stay_in_table(lq_sta, true);
 		goto lq_update;
 	}
drivers/net/wireless/iwlwifi/mvm/rs.h +0 -13
index b41686b..5dd30ea 100644
@@ -328,19 +328,6 @@ struct iwl_lq_sta {
 	u32 last_rate_n_flags;
 	/* packets destined for this STA are aggregated */
 	u8 is_agg;
-	/* BT traffic this sta was last updated in */
-	u8 last_bt_traffic;
-};
-
-enum iwl_bt_coex_profile_traffic_load {
-	IWL_BT_COEX_TRAFFIC_LOAD_NONE		= 0,
-	IWL_BT_COEX_TRAFFIC_LOAD_LOW		= 1,
-	IWL_BT_COEX_TRAFFIC_LOAD_HIGH		= 2,
-	IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS	= 3,
-/*
- * There are no more even though below is a u8, the
- * indication from the BT device only has two bits.
- */
 };
 
 /* Initialize station's rate scaling information after adding station */
Signature · 1 line
1.7.9.5
#28 lore raw

PATCH 28/29 iwlwifi: mvm: don't enable VHT MCS9 in 20Mhz

In reply to Emmanuel Grumbach

From: Eyal Shapira <[email protected]>

MCS9 in NSS=1 or NSS=2 isn't valid for 20Mhz so don't enable it in case we're dealing with a 20Mhz sta. Trying to configure an MCS9 rate with 20Mhz in the LQ rate table would lead to a FW assert.

---
 drivers/net/wireless/iwlwifi/mvm/rs.c |   10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/net/wireless/iwlwifi/mvm/rs.c +10 -0
index 9565260..f1364b7 100644
@@ -2241,6 +2241,11 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,
 			if (i == IWL_RATE_9M_INDEX)
 				continue;
 
+			/* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */
+			if (i == IWL_RATE_MCS_9_INDEX &&
+			    sta->bandwidth == IEEE80211_STA_RX_BW_20)
+				continue;
+
 			lq_sta->active_siso_rate |= BIT(i);
 		}
 	}
@@ -2251,6 +2256,11 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,
 			if (i == IWL_RATE_9M_INDEX)
 				continue;
 
+			/* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */
+			if (i == IWL_RATE_MCS_9_INDEX &&
+			    sta->bandwidth == IEEE80211_STA_RX_BW_20)
+				continue;
+
 			lq_sta->active_mimo2_rate |= BIT(i);
 		}
 	}
Signature · 1 line
1.7.9.5
#29 lore raw

PATCH 29/29 iwlwifi: mvm: don't configure mimo rates if nss is limited to 1

In reply to Emmanuel Grumbach

From: Eyal Shapira <[email protected]>

Remote peer can publish a different number of supported nss via the operating mode notification IE or action frame. If it limits to 1 then we don't want mimo rates configured in the rate table.

---
 drivers/net/wireless/iwlwifi/mvm/rs.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/net/wireless/iwlwifi/mvm/rs.c +3 -0
index f1364b7..a7efeb3 100644
@@ -2250,6 +2250,9 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,
 		}
 	}
 
+	if (sta->rx_nss < 2)
+		return;
+
 	highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 2);
 	if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
 		for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
Signature · 1 line
1.7.9.5
#30 lore raw
In reply to Emmanuel Grumbach
Quoted 122 lines · Emmanuel Grumbach

Hi John,

This is the first batch for 3.14.

I have a bunch of small improvements and fixes. Avri made a thorough work checking what bit to set to firmware w.r.t protection. Eliad worked on WoWLAN, so did Luca. Johannes contributes a whole bunch of clean ups, and Alex tries to handle better cases where the firmware dies. Eyal survived his deep dive into the rate control algorigthm and provides a new set of fixes for VHT. I am still playing a bit with BT Coex.

Note that I had to merge iwlwifi-fixes to avoid conflicts before they hit linux-next.
Let me know about any issues!

The following changes since commit 6ce4eac1f600b34f2f7f58f9cd8f0503d79e42ae:

Linux 3.13-rc1 (2013-11-22 11:30:55 -0800)

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git
for-john

for you to fetch changes up to b407dd53844e0d66e726583bae3a084cecdd59a4:

Merge remote-tracking branch 'iwlwifi-fixes/master' into iwlwifi-next
(2013-11-24 21:49:45 +0200)

----------------------------------------------------------------

Alexander Bondar (2):
iwlwifi: mvm: Add debugfs entry to generate NMI to NIC
iwlwifi: pcie: stop sending commands to dead firmware

Avri Altman (1):
iwlwifi: mvm: fix ht protection flags

Eliad Peller (4):
iwlwifi: mvm: enable d3_test even if d3_test_pme_ptr is not available
iwlwifi: mvm: disconnect on disconnection wakeup event
iwlwifi: mvm: allow keeping connections in d3_test
iwlwifi: mvm: fix scan offloading flag definition

Emmanuel Grumbach (10):
iwlwifi: pcie: fix interrupt coalescing for 7260 / 3160
iwlwifi: mvm: BT Coex - don't enable MULTI_PRIO_LUT
iwlwifi: mvm: BT Coex fix another NULL pointer dereference
iwlwifi: mvm: don't WARN about unsuccessful time event
iwlwifi: bump required firmware API version for 3160/7260
iwlwifi: remove TX_CMD id from transport layer
iwlwifi: mvm: BT Coex - fine tune the aggregation size
iwlwifi: mvm: a few more SKUs for 7260 and 3160
iwlwifi: mvm: dump NVM from debugfs
Merge remote-tracking branch 'iwlwifi-fixes/master' into iwlwifi-next

Eyal Shapira (9):
iwlwifi: mvm: fix and improve printing of rate scale table
iwlwifi: mvm: simplify iwl_mvm_send_lq_cmd
iwlwifi: mvm: refactor iwl_mvm_rs_rate_init
iwlwifi: mvm: implement rate_update hook in rs
iwlwifi: mvm: add LQ flags definitions
iwlwifi: fix check for a single rx antenna
iwlwifi: mvm: stop using MIMO in case BT doesn't allow it
iwlwifi: mvm: don't enable VHT MCS9 in 20Mhz
iwlwifi: mvm: don't configure mimo rates if nss is limited to 1

Haim Dreyfuss (1):
iwlwifi: mvm: Implement low-priority scan

Johannes Berg (8):
iwlwifi: mvm: check sta_id/drain values in debugfs
iwlwifi: pcie: remove useless condition test
iwlwifi: mvm: small debugfs cleanups
iwlwifi: mvm: move interface-specific debugfs to a new file
iwlwifi: mvm: don't use void pointers in debugfs
iwlwifi: mvm: refactor debugfs copy_from_user()
iwlwifi: mvm: add iwl_mvm_sta_from_mac80211
iwlwifi: mvm: quota command max_duration should be zero

Luciano Coelho (3):
iwlwifi: mvm: set seqno also when no keys are set
iwlwifi: mvm: use a cast to calculate the last seqno from the next one
iwlwifi: mvm: don't restart HW if suspending fails before D3 image
is loaded

Michal Nazarewicz (1):
iwlwifi: pcie: remove minor dead code

Oren Givon (1):
iwlwifi: add new HW - 7265 series

 drivers/net/wireless/iwlwifi/dvm/rs.h          |    7 -
 drivers/net/wireless/iwlwifi/dvm/tx.c          |    1 +
 drivers/net/wireless/iwlwifi/iwl-7000.c        |   29 +-
 drivers/net/wireless/iwlwifi/iwl-config.h      |   11 +
 drivers/net/wireless/iwlwifi/iwl-csr.h         |    5 +-
 drivers/net/wireless/iwlwifi/iwl-nvm-parse.c   |    3 +-
 drivers/net/wireless/iwlwifi/iwl-prph.h        |    3 +
 drivers/net/wireless/iwlwifi/mvm/Makefile      |    1 +
 drivers/net/wireless/iwlwifi/mvm/bt-coex.c     |   16 +-
 drivers/net/wireless/iwlwifi/mvm/d3.c          |   43 +-
 drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c |  190 +++++++
 drivers/net/wireless/iwlwifi/mvm/debugfs.c     |  640
++----------------------
 drivers/net/wireless/iwlwifi/mvm/debugfs.h     |  101 ++++
 drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h   |   27 +-
 drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h |    5 +-
 drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c    |   51 +-
 drivers/net/wireless/iwlwifi/mvm/mac80211.c    |   19 +-
 drivers/net/wireless/iwlwifi/mvm/mvm.h         |   11 +-
 drivers/net/wireless/iwlwifi/mvm/nvm.c         |   23 +
 drivers/net/wireless/iwlwifi/mvm/quota.c       |    3 +-
 drivers/net/wireless/iwlwifi/mvm/rs.c          |  223 ++++++---
 drivers/net/wireless/iwlwifi/mvm/rs.h          |   23 +-
 drivers/net/wireless/iwlwifi/mvm/scan.c        |   55 +-
 drivers/net/wireless/iwlwifi/mvm/sta.c         |   14 +-
 drivers/net/wireless/iwlwifi/mvm/sta.h         |    6 +
 drivers/net/wireless/iwlwifi/mvm/time-event.c  |    7 +-
 drivers/net/wireless/iwlwifi/mvm/tt.c          |    2 +-
 drivers/net/wireless/iwlwifi/mvm/tx.c          |   11 +-
 drivers/net/wireless/iwlwifi/mvm/utils.c       |    8 +-
Quoted 8 lines
 drivers/net/wireless/iwlwifi/pcie/drv.c        |   26 +
 drivers/net/wireless/iwlwifi/pcie/internal.h   |    8 +
 drivers/net/wireless/iwlwifi/pcie/rx.c         |   33 +-
 drivers/net/wireless/iwlwifi/pcie/trans.c      |    3 -
 drivers/net/wireless/iwlwifi/pcie/tx.c         |   37 +-
 34 files changed, 832 insertions(+), 813 deletions(-)
 create mode 100644 drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
 create mode 100644 drivers/net/wireless/iwlwifi/mvm/debugfs.h

Pulling now...

Signature · 2 lines
John W. Linville		Someday the world will need a hero, and you
[email protected]			might be all we have.  Be ready.
#31 lore raw

Emmanuel pointed-out that this was based on the wrong HEAD. I'll drop this merge and wait for his new request...

Quoted 142 lines · John W. Linville
Quoted 122 lines · Emmanuel Grumbach

Hi John,

This is the first batch for 3.14.

I have a bunch of small improvements and fixes. Avri made a thorough work checking what bit to set to firmware w.r.t protection. Eliad worked on WoWLAN, so did Luca. Johannes contributes a whole bunch of clean ups, and Alex tries to handle better cases where the firmware dies. Eyal survived his deep dive into the rate control algorigthm and provides a new set of fixes for VHT. I am still playing a bit with BT Coex.

Note that I had to merge iwlwifi-fixes to avoid conflicts before they hit linux-next.
Let me know about any issues!

The following changes since commit 6ce4eac1f600b34f2f7f58f9cd8f0503d79e42ae:

Linux 3.13-rc1 (2013-11-22 11:30:55 -0800)

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git
for-john

for you to fetch changes up to b407dd53844e0d66e726583bae3a084cecdd59a4:

Merge remote-tracking branch 'iwlwifi-fixes/master' into iwlwifi-next
(2013-11-24 21:49:45 +0200)

----------------------------------------------------------------

Alexander Bondar (2):
iwlwifi: mvm: Add debugfs entry to generate NMI to NIC
iwlwifi: pcie: stop sending commands to dead firmware

Avri Altman (1):
iwlwifi: mvm: fix ht protection flags

Eliad Peller (4):
iwlwifi: mvm: enable d3_test even if d3_test_pme_ptr is not available
iwlwifi: mvm: disconnect on disconnection wakeup event
iwlwifi: mvm: allow keeping connections in d3_test
iwlwifi: mvm: fix scan offloading flag definition

Emmanuel Grumbach (10):
iwlwifi: pcie: fix interrupt coalescing for 7260 / 3160
iwlwifi: mvm: BT Coex - don't enable MULTI_PRIO_LUT
iwlwifi: mvm: BT Coex fix another NULL pointer dereference
iwlwifi: mvm: don't WARN about unsuccessful time event
iwlwifi: bump required firmware API version for 3160/7260
iwlwifi: remove TX_CMD id from transport layer
iwlwifi: mvm: BT Coex - fine tune the aggregation size
iwlwifi: mvm: a few more SKUs for 7260 and 3160
iwlwifi: mvm: dump NVM from debugfs
Merge remote-tracking branch 'iwlwifi-fixes/master' into iwlwifi-next

Eyal Shapira (9):
iwlwifi: mvm: fix and improve printing of rate scale table
iwlwifi: mvm: simplify iwl_mvm_send_lq_cmd
iwlwifi: mvm: refactor iwl_mvm_rs_rate_init
iwlwifi: mvm: implement rate_update hook in rs
iwlwifi: mvm: add LQ flags definitions
iwlwifi: fix check for a single rx antenna
iwlwifi: mvm: stop using MIMO in case BT doesn't allow it
iwlwifi: mvm: don't enable VHT MCS9 in 20Mhz
iwlwifi: mvm: don't configure mimo rates if nss is limited to 1

Haim Dreyfuss (1):
iwlwifi: mvm: Implement low-priority scan

Johannes Berg (8):
iwlwifi: mvm: check sta_id/drain values in debugfs
iwlwifi: pcie: remove useless condition test
iwlwifi: mvm: small debugfs cleanups
iwlwifi: mvm: move interface-specific debugfs to a new file
iwlwifi: mvm: don't use void pointers in debugfs
iwlwifi: mvm: refactor debugfs copy_from_user()
iwlwifi: mvm: add iwl_mvm_sta_from_mac80211
iwlwifi: mvm: quota command max_duration should be zero

Luciano Coelho (3):
iwlwifi: mvm: set seqno also when no keys are set
iwlwifi: mvm: use a cast to calculate the last seqno from the next one
iwlwifi: mvm: don't restart HW if suspending fails before D3 image
is loaded

Michal Nazarewicz (1):
iwlwifi: pcie: remove minor dead code

Oren Givon (1):
iwlwifi: add new HW - 7265 series

 drivers/net/wireless/iwlwifi/dvm/rs.h          |    7 -
 drivers/net/wireless/iwlwifi/dvm/tx.c          |    1 +
 drivers/net/wireless/iwlwifi/iwl-7000.c        |   29 +-
 drivers/net/wireless/iwlwifi/iwl-config.h      |   11 +
 drivers/net/wireless/iwlwifi/iwl-csr.h         |    5 +-
 drivers/net/wireless/iwlwifi/iwl-nvm-parse.c   |    3 +-
 drivers/net/wireless/iwlwifi/iwl-prph.h        |    3 +
 drivers/net/wireless/iwlwifi/mvm/Makefile      |    1 +
 drivers/net/wireless/iwlwifi/mvm/bt-coex.c     |   16 +-
 drivers/net/wireless/iwlwifi/mvm/d3.c          |   43 +-
 drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c |  190 +++++++
 drivers/net/wireless/iwlwifi/mvm/debugfs.c     |  640
++----------------------
 drivers/net/wireless/iwlwifi/mvm/debugfs.h     |  101 ++++
 drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h   |   27 +-
 drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h |    5 +-
 drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c    |   51 +-
 drivers/net/wireless/iwlwifi/mvm/mac80211.c    |   19 +-
 drivers/net/wireless/iwlwifi/mvm/mvm.h         |   11 +-
 drivers/net/wireless/iwlwifi/mvm/nvm.c         |   23 +
 drivers/net/wireless/iwlwifi/mvm/quota.c       |    3 +-
 drivers/net/wireless/iwlwifi/mvm/rs.c          |  223 ++++++---
 drivers/net/wireless/iwlwifi/mvm/rs.h          |   23 +-
 drivers/net/wireless/iwlwifi/mvm/scan.c        |   55 +-
 drivers/net/wireless/iwlwifi/mvm/sta.c         |   14 +-
 drivers/net/wireless/iwlwifi/mvm/sta.h         |    6 +
 drivers/net/wireless/iwlwifi/mvm/time-event.c  |    7 +-
 drivers/net/wireless/iwlwifi/mvm/tt.c          |    2 +-
 drivers/net/wireless/iwlwifi/mvm/tx.c          |   11 +-
 drivers/net/wireless/iwlwifi/mvm/utils.c       |    8 +-
Quoted 8 lines
 drivers/net/wireless/iwlwifi/pcie/drv.c        |   26 +
 drivers/net/wireless/iwlwifi/pcie/internal.h   |    8 +
 drivers/net/wireless/iwlwifi/pcie/rx.c         |   33 +-
 drivers/net/wireless/iwlwifi/pcie/trans.c      |    3 -
 drivers/net/wireless/iwlwifi/pcie/tx.c         |   37 +-
 34 files changed, 832 insertions(+), 813 deletions(-)
 create mode 100644 drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
 create mode 100644 drivers/net/wireless/iwlwifi/mvm/debugfs.h

Pulling now...

Signature · 6 lines
John W. Linville		Someday the world will need a hero, and you
[email protected]			might be all we have.  Be ready.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Signature · 2 lines
John W. Linville		Someday the world will need a hero, and you
[email protected]			might be all we have.  Be ready.