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

Commit d663ee73 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

iwlwifi: abstract out missing SEQ_RX_FRAME workaround

Mohammed Shafi ran into [1] the SEQ_RX_FRAME workaround
warning with a statistics notification, this means we
can't just remove it as we'd hoped.

Abstract it out so that the higher layer can configure
this as a kind of "filter" in the transport.

[1] http://mid.gmane.org/CAD2nsn1_DzbRHuSbS_1rFNzuux_9pW1-pABEasQ01_y7-ndO5w@mail.gmail.com



Reported-by: default avatarMohammed Shafi <shafi.wireless@gmail.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 10d8f31e
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1186,6 +1186,14 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
	u16 num_mac;
	u32 ucode_flags;
	struct iwl_trans_config trans_cfg;
	static const u8 no_reclaim_cmds[] = {
		REPLY_RX_PHY_CMD,
		REPLY_RX,
		REPLY_RX_MPDU_CMD,
		REPLY_COMPRESSED_BA,
		STATISTICS_NOTIFICATION,
		REPLY_TX,
	};

	/************************
	 * 1. Allocating HW data
@@ -1211,6 +1219,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
	 * to know about.
	 */
	trans_cfg.op_mode = op_mode;
	trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
	trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);

	ucode_flags = fw->ucode_capa.flags;

+2 −0
Original line number Diff line number Diff line
@@ -291,6 +291,8 @@ struct iwl_trans_pcie {
	wait_queue_head_t ucode_write_waitq;
	unsigned long status;
	u8 cmd_queue;
	u8 n_no_reclaim_cmds;
	u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS];
};

#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
+11 −18
Original line number Diff line number Diff line
@@ -395,13 +395,17 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
	 *   there is no command buffer to reclaim.
	 * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
	 *   but apparently a few don't get set; catch them here. */
	reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
		  (pkt->hdr.cmd != REPLY_RX_PHY_CMD) &&
		  (pkt->hdr.cmd != REPLY_RX) &&
		  (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) &&
		  (pkt->hdr.cmd != REPLY_COMPRESSED_BA) &&
		  (pkt->hdr.cmd != STATISTICS_NOTIFICATION) &&
		  (pkt->hdr.cmd != REPLY_TX);
	reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME);
	if (reclaim) {
		int i;

		for (i = 0; i < trans_pcie->n_no_reclaim_cmds; i++) {
			if (trans_pcie->no_reclaim_cmds[i] == pkt->hdr.cmd) {
				reclaim = false;
				break;
			}
		}
	}

	sequence = le16_to_cpu(pkt->hdr.sequence);
	index = SEQ_TO_INDEX(sequence);
@@ -412,17 +416,6 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
	else
		cmd = NULL;

	/* warn if this is cmd response / notification and the uCode
	 * didn't set the SEQ_RX_FRAME for a frame that is
	 * uCode-originated
	 * If you saw this code after the second half of 2012, then
	 * please remove it
	 */
	WARN(pkt->hdr.cmd != REPLY_TX && reclaim == false &&
	     (!(pkt->hdr.sequence & SEQ_RX_FRAME)),
	     "reclaim is false, SEQ_RX_FRAME unset: %s\n",
	     get_cmd_string(pkt->hdr.cmd));

	err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);

	/*
+7 −0
Original line number Diff line number Diff line
@@ -1626,6 +1626,13 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans,
	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);

	trans_pcie->cmd_queue = trans_cfg->cmd_queue;
	if (WARN_ON(trans_cfg->n_no_reclaim_cmds > MAX_NO_RECLAIM_CMDS))
		trans_pcie->n_no_reclaim_cmds = 0;
	else
		trans_pcie->n_no_reclaim_cmds = trans_cfg->n_no_reclaim_cmds;
	if (trans_pcie->n_no_reclaim_cmds)
		memcpy(trans_pcie->no_reclaim_cmds, trans_cfg->no_reclaim_cmds,
		       trans_pcie->n_no_reclaim_cmds * sizeof(u8));
}

static void iwl_trans_pcie_free(struct iwl_trans *trans)
+9 −0
Original line number Diff line number Diff line
@@ -274,6 +274,8 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r)
	return p;
}

#define MAX_NO_RECLAIM_CMDS	6

/**
 * struct iwl_trans_config - transport configuration
 *
@@ -281,10 +283,17 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r)
 *	Must be set before any other call.
 * @cmd_queue: the index of the command queue.
 *	Must be set before start_fw.
 * @no_reclaim_cmds: Some devices erroneously don't set the
 *	SEQ_RX_FRAME bit on some notifications, this is the
 *	list of such notifications to filter. Max length is
 *	%MAX_NO_RECLAIM_CMDS.
 * @n_no_reclaim_cmds: # of commands in list
 */
struct iwl_trans_config {
	struct iwl_op_mode *op_mode;
	u8 cmd_queue;
	const u8 *no_reclaim_cmds;
	int n_no_reclaim_cmds;
};

/**