All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

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

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.comReported-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
...@@ -1186,6 +1186,14 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, ...@@ -1186,6 +1186,14 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
u16 num_mac; u16 num_mac;
u32 ucode_flags; u32 ucode_flags;
struct iwl_trans_config trans_cfg; 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 * 1. Allocating HW data
...@@ -1211,6 +1219,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, ...@@ -1211,6 +1219,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
* to know about. * to know about.
*/ */
trans_cfg.op_mode = op_mode; 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; ucode_flags = fw->ucode_capa.flags;
......
...@@ -291,6 +291,8 @@ struct iwl_trans_pcie { ...@@ -291,6 +291,8 @@ struct iwl_trans_pcie {
wait_queue_head_t ucode_write_waitq; wait_queue_head_t ucode_write_waitq;
unsigned long status; unsigned long status;
u8 cmd_queue; u8 cmd_queue;
u8 n_no_reclaim_cmds;
u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS];
}; };
#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
......
...@@ -395,13 +395,17 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, ...@@ -395,13 +395,17 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
* there is no command buffer to reclaim. * there is no command buffer to reclaim.
* Ucode should set SEQ_RX_FRAME bit if ucode-originated, * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
* but apparently a few don't get set; catch them here. */ * but apparently a few don't get set; catch them here. */
reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME);
(pkt->hdr.cmd != REPLY_RX_PHY_CMD) && if (reclaim) {
(pkt->hdr.cmd != REPLY_RX) && int i;
(pkt->hdr.cmd != REPLY_RX_MPDU_CMD) &&
(pkt->hdr.cmd != REPLY_COMPRESSED_BA) && for (i = 0; i < trans_pcie->n_no_reclaim_cmds; i++) {
(pkt->hdr.cmd != STATISTICS_NOTIFICATION) && if (trans_pcie->no_reclaim_cmds[i] == pkt->hdr.cmd) {
(pkt->hdr.cmd != REPLY_TX); reclaim = false;
break;
}
}
}
sequence = le16_to_cpu(pkt->hdr.sequence); sequence = le16_to_cpu(pkt->hdr.sequence);
index = SEQ_TO_INDEX(sequence); index = SEQ_TO_INDEX(sequence);
...@@ -412,17 +416,6 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, ...@@ -412,17 +416,6 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
else else
cmd = NULL; 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); err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);
/* /*
......
...@@ -1626,6 +1626,13 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, ...@@ -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); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
trans_pcie->cmd_queue = trans_cfg->cmd_queue; 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) static void iwl_trans_pcie_free(struct iwl_trans *trans)
......
...@@ -274,6 +274,8 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) ...@@ -274,6 +274,8 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r)
return p; return p;
} }
#define MAX_NO_RECLAIM_CMDS 6
/** /**
* struct iwl_trans_config - transport configuration * struct iwl_trans_config - transport configuration
* *
...@@ -281,10 +283,17 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) ...@@ -281,10 +283,17 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r)
* Must be set before any other call. * Must be set before any other call.
* @cmd_queue: the index of the command queue. * @cmd_queue: the index of the command queue.
* Must be set before start_fw. * 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_trans_config {
struct iwl_op_mode *op_mode; struct iwl_op_mode *op_mode;
u8 cmd_queue; u8 cmd_queue;
const u8 *no_reclaim_cmds;
int n_no_reclaim_cmds;
}; };
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment