linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
To: linux-wireless@vger.kernel.org
Cc: Sara Sharon <sara.sharon@intel.com>,
	Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Subject: [PATCH 26/43] iwlwifi: mvm: add RSS queues notification infrastructure
Date: Wed,  2 Mar 2016 09:56:27 +0200	[thread overview]
Message-ID: <1456905404-14435-26-git-send-email-emmanuel.grumbach@intel.com> (raw)
In-Reply-To: <0BA3FCBA62E2DC44AF3030971E174FB32EA50146@hasmsx107.ger.corp.intel.com>

From: Sara Sharon <sara.sharon@intel.com>

In multi rx queue HW, without execessive locking, there is no sync
between the ctrl path (default queue) and the rest of the rx queues.
This might cause issues on certain situations. For example, in case
a delBA was processed on a default queue but out of order packets
still wait for processing on the other queue.

The solution is to introduce internal messaging between the CTRL path
and the other rx queues.
The driver will send a message to the firmware, which will echo it to
all the requested queues. The message will be in order inside the queue.
This way we can avoid CTRL path and RSS queues races.

Add support for this messaging mechanism. As the firmware is agnostic to
the data sent, add internal representation of the data as well.
Although currently only delBA flow will use it, the internal representation
will enable generic use of this infrastructure for future uses.
Next patch will utilize this messaging mechanism for the reorder buffer
delBA flow.

Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h | 52 ++++++++++++++++++++++
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h    |  2 +
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h       |  4 ++
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c       |  8 ++++
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c      | 48 ++++++++++++++++++++
 5 files changed, 114 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
index df939f5..eb9b870 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
@@ -391,4 +391,56 @@ struct iwl_rss_config_cmd {
 	u8 indirection_table[IWL_RSS_INDIRECTION_TABLE_SIZE];
 } __packed; /* RSS_CONFIG_CMD_API_S_VER_1 */
 
+#define IWL_MULTI_QUEUE_SYNC_MSG_MAX_SIZE 128
+#define IWL_MULTI_QUEUE_SYNC_SENDER_POS 0
+#define IWL_MULTI_QUEUE_SYNC_SENDER_MSK 0xf
+
+/**
+ * struct iwl_rxq_sync_cmd - RXQ notification trigger
+ *
+ * @flags: flags of the notification. bit 0:3 are the sender queue
+ * @rxq_mask: rx queues to send the notification on
+ * @count: number of bytes in payload, should be DWORD aligned
+ * @payload: data to send to rx queues
+ */
+struct iwl_rxq_sync_cmd {
+	__le32 flags;
+	__le32 rxq_mask;
+	__le32 count;
+	u8 payload[];
+} __packed; /* MULTI_QUEUE_DRV_SYNC_HDR_CMD_API_S_VER_1 */
+
+/**
+ * struct iwl_rxq_sync_notification - Notification triggered by RXQ
+ * sync command
+ *
+ * @count: number of bytes in payload
+ * @payload: data to send to rx queues
+ */
+struct iwl_rxq_sync_notification {
+	__le32 count;
+	u8 payload[];
+} __packed; /* MULTI_QUEUE_DRV_SYNC_HDR_CMD_API_S_VER_1 */
+
+/**
+* Internal message identifier
+*
+* @IWL_MVM_RXQ_NOTIF_DEL_BA: notify RSS queues of delBA
+*/
+enum iwl_mvm_rxq_notif_type {
+	IWL_MVM_RXQ_NOTIF_DEL_BA,
+};
+
+/**
+* struct iwl_mvm_internal_rxq_notif - Internal representation of the data sent
+* in &iwl_rxq_sync_cmd. Should be DWORD aligned.
+*
+* @type: value from &iwl_mvm_rxq_notif_type
+* @data: payload
+*/
+struct iwl_mvm_internal_rxq_notif {
+	u32 type;
+	u8 data[];
+} __packed;
+
 #endif /* __fw_api_rx_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
index e1e1194..f432ddd 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
@@ -289,6 +289,8 @@ enum iwl_phy_ops_subcmd_ids {
 
 enum iwl_data_path_subcmd_ids {
 	UPDATE_MU_GROUPS_CMD = 0x1,
+	TRIGGER_RX_QUEUES_NOTIF_CMD = 0x2,
+	RX_QUEUES_NOTIFICATION = 0xFF,
 };
 
 enum iwl_prot_offload_subcmd_ids {
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index fa987bd..f05d2a1 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1225,6 +1225,10 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
 			struct iwl_rx_cmd_buffer *rxb, int queue);
 void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm,
 			      struct iwl_rx_cmd_buffer *rxb, int queue);
+int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask,
+			    const u8 *data, u32 count);
+void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
+			    int queue);
 void iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
 void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
 void iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 52c73d0..ac271ff 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -404,6 +404,8 @@ static const struct iwl_hcmd_names iwl_mvm_phy_names[] = {
  */
 static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = {
 	HCMD_NAME(UPDATE_MU_GROUPS_CMD),
+	HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD),
+	HCMD_NAME(RX_QUEUES_NOTIFICATION),
 };
 
 /* Please keep this array *SORTED* by hex value.
@@ -876,6 +878,9 @@ static void iwl_mvm_rx_mq(struct iwl_op_mode *op_mode,
 		iwl_mvm_rx_mpdu_mq(mvm, napi, rxb, 0);
 	else if (pkt->hdr.cmd == REPLY_RX_PHY_CMD)
 		iwl_mvm_rx_phy_cmd_mq(mvm, rxb);
+	else if (unlikely(pkt->hdr.group_id == DATA_PATH_GROUP &&
+			  pkt->hdr.cmd == RX_QUEUES_NOTIFICATION))
+		iwl_mvm_rx_queue_notif(mvm, rxb, 0);
 	else
 		iwl_mvm_rx_common(mvm, rxb, pkt);
 }
@@ -1548,6 +1553,9 @@ static void iwl_mvm_rx_mq_rss(struct iwl_op_mode *op_mode,
 
 	if (unlikely(pkt->hdr.cmd == FRAME_RELEASE))
 		iwl_mvm_rx_frame_release(mvm, rxb, queue);
+	else if (unlikely(pkt->hdr.cmd == RX_QUEUES_NOTIFICATION &&
+			  pkt->hdr.group_id == DATA_PATH_GROUP))
+		iwl_mvm_rx_queue_notif(mvm, rxb, queue);
 	else
 		iwl_mvm_rx_mpdu_mq(mvm, napi, rxb, queue);
 }
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index d891942..590fc6f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -345,6 +345,54 @@ static bool iwl_mvm_is_nonagg_dup(struct ieee80211_sta *sta, int queue,
 	return false;
 }
 
+int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask,
+			    const u8 *data, u32 count)
+{
+	struct iwl_rxq_sync_cmd *cmd;
+	u32 data_size = sizeof(*cmd) + count;
+	int ret;
+
+	/* should be DWORD aligned */
+	if (WARN_ON(count & 3 || count > IWL_MULTI_QUEUE_SYNC_MSG_MAX_SIZE))
+		return -EINVAL;
+
+	cmd = kzalloc(data_size, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->rxq_mask = cpu_to_le32(rxq_mask);
+	cmd->count =  cpu_to_le32(count);
+	cmd->flags = 0;
+	memcpy(cmd->payload, data, count);
+
+	ret = iwl_mvm_send_cmd_pdu(mvm,
+				   WIDE_ID(DATA_PATH_GROUP,
+					   TRIGGER_RX_QUEUES_NOTIF_CMD),
+				   0, data_size, cmd);
+
+	kfree(cmd);
+	return ret;
+}
+
+void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
+			    int queue)
+{
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
+	struct iwl_rxq_sync_notification *notif;
+	struct iwl_mvm_internal_rxq_notif *internal_notif;
+
+	notif = (void *)pkt->data;
+	internal_notif = (void *)notif->payload;
+
+	switch (internal_notif->type) {
+	case IWL_MVM_RXQ_NOTIF_DEL_BA:
+		/* TODO */
+		break;
+	default:
+		WARN_ONCE(1, "Invalid identifier %d", internal_notif->type);
+	}
+}
+
 void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
 			struct iwl_rx_cmd_buffer *rxb, int queue)
 {
-- 
2.5.0


  parent reply	other threads:[~2016-03-02  7:57 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-02  7:51 pull request: iwlwifi-next 2016-03-02 Grumbach, Emmanuel
2016-03-02  7:56 ` [PATCH 01/43] iwlwifi: mvm: add CT-KILL notification Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 02/43] iwlwifi: mvm: add registration to thermal zone Emmanuel Grumbach
2016-03-04 18:39   ` Bjørn Mork
2016-03-04 18:53     ` Bjørn Mork
2016-03-04 19:57       ` Coelho, Luciano
2016-03-04 20:22         ` Bjørn Mork
2016-03-04 20:30           ` Coelho, Luciano
2016-03-04 19:52     ` Coelho, Luciano
2016-03-02  7:56 ` [PATCH 03/43] iwlwifi: mvm: add registration to cooling device Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 04/43] iwlwifi: mvm: set the correct descriptor size for tracing Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 05/43] iwlwifi: mvm: fix RSS key sizing Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 06/43] iwlwifi: mvm: handle pass all scan reporting Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 07/43] iwlwifi: mvm: rs: fix a theoretical access to uninitialized array elements Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 08/43] iwlwifi: mvm: bump firmware API to 21 Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 09/43] iwlwifi: pcie: aggregate Flow Handler configuration writes Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 10/43] iwlwifi: pcie: Add new configuration to enable MSIX Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 11/43] iwlwifi: pcie: fix identation in trans.c Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 12/43] iwlwifi: mvm: enable VHT MU-MIMO for supported hardware Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 13/43] iwlwifi: mvm: update firmware of VHT MU-MIMO groups status on restart Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 14/43] iwlwifi: mvm: send large SKBs to the transport Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 15/43] iwlwifi: mvm: add Tx A-MSDU inside A-MPDU Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 16/43] iwlwifi: mvm: allow to limit the A-MSDU from debugfs Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 17/43] iwlwifi: mvm: don't enable A-MSDU when the rates are too low Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 18/43] iwlwifi: mvm: don't send an A-MSDU that is larger than the TXF Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 19/43] iwlwifi: support tracing wide commands Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 20/43] iwlwifi: mvm: update rx_status with mactime flag Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 21/43] iwlwifi: mvm: support filtered frames notification Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 22/43] iwlwifi: pcie: configure more RFH settings Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 23/43] iwlwifi: pcie: add pm_prepare and pm_complete ops Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 24/43] iwlwifi: pcie: prevent skbs shadowing in iwl_trans_pcie_reclaim Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 25/43] iwlwifi: mvm: add duplicate packet detection per rx queue Emmanuel Grumbach
2016-03-02  7:56 ` Emmanuel Grumbach [this message]
2016-03-02  7:56 ` [PATCH 27/43] iwlwifi: mvm: remove unused field in iwl_mvm_tid_data Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 28/43] iwlwifi: mvm: support VHT MU-MIMO notification Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 29/43] iwlwifi: mvm: various trivial cleanups Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 30/43] iwlwifi: mvm: Set global RRM capability Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 31/43] iwlwifi: mvm: forbid U-APSD for P2P Client if the firmware doesn't support it Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 32/43] iwlwifi: mvm: Send power command on BSS_CHANGED_BEACON_INFO if needed Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 33/43] iwlwifi: mvm: take care of padded packets Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 34/43] iwlwifi: mvm: kill iwl_mvm_enable_agg_txq Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 35/43] iwlwifi: mvm: Disable beacon storing in D3 when WOWLAN configured Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 36/43] iwlwifi: support ucode with d0 unified image - regular and usniffer Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 37/43] iwlwifi: mvm: update ucode status before stopping device Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 38/43] iwlwifi: pcie: detect and workaround invalid write ptr behavior Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 39/43] iwlwifi: mvm: disable DQA support Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 40/43] iwlwifi: mvm: only release the trans ref if d0i3 is supported in fw Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 41/43] iwlwifi: add disable_11ac module param Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 42/43] iwlwifi: mvm: take the transport ref back when leaving Emmanuel Grumbach
2016-03-02  7:56 ` [PATCH 43/43] iwlwifi: mvm: support sw queue start/stop from mvm Emmanuel Grumbach
2016-03-07 13:50 ` pull request: iwlwifi-next 2016-03-02 Kalle Valo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1456905404-14435-26-git-send-email-emmanuel.grumbach@intel.com \
    --to=emmanuel.grumbach@intel.com \
    --cc=linux-wireless@vger.kernel.org \
    --cc=sara.sharon@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).