summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi/iwl-trans.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-trans.h')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h40
1 files changed, 26 insertions, 14 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 7d1990c7f658..0c81cbaa8088 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -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;
};
/**
@@ -404,6 +413,7 @@ enum iwl_trans_state {
* @hw_id_str: a string with info about HW ID. Set during transport allocation.
* @nvm_device_type: indicates OTP or eeprom
* @pm_support: set to true in start_hw if link pm is supported
+ * @wait_command_queue: the wait_queue for SYNC host commands
*/
struct iwl_trans {
const struct iwl_trans_ops *ops;
@@ -420,6 +430,8 @@ struct iwl_trans {
int nvm_device_type;
bool pm_support;
+ wait_queue_head_t wait_command_queue;
+
/* pointer to trans specific struct */
/*Ensure that this pointer will always be aligned to sizeof pointer */
char trans_specific[0] __aligned(sizeof(void *));
@@ -488,8 +500,8 @@ static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans)
static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
struct iwl_host_cmd *cmd)
{
- if (trans->state != IWL_TRANS_FW_ALIVE)
- IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+ WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
+ "%s bad state = %d", __func__, trans->state);
return trans->ops->send_cmd(trans, cmd);
}
@@ -508,8 +520,8 @@ static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id,
int tid, int txq_id, int ssn,
struct sk_buff_head *skbs)
{
- if (trans->state != IWL_TRANS_FW_ALIVE)
- IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+ WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
+ "%s bad state = %d", __func__, trans->state);
return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, skbs);
}
@@ -517,8 +529,8 @@ static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id,
static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans,
int sta_id, int tid)
{
- if (trans->state != IWL_TRANS_FW_ALIVE)
- IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+ WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
+ "%s bad state = %d", __func__, trans->state);
return trans->ops->tx_agg_disable(trans, sta_id, tid);
}
@@ -526,8 +538,8 @@ static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans,
static inline int iwl_trans_tx_agg_alloc(struct iwl_trans *trans,
int sta_id, int tid)
{
- if (trans->state != IWL_TRANS_FW_ALIVE)
- IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+ WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
+ "%s bad state = %d", __func__, trans->state);
return trans->ops->tx_agg_alloc(trans, sta_id, tid);
}
@@ -540,8 +552,8 @@ static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans,
{
might_sleep();
- if (trans->state != IWL_TRANS_FW_ALIVE)
- IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+ WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
+ "%s bad state = %d", __func__, trans->state);
trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn);
}
@@ -553,16 +565,16 @@ static inline void iwl_trans_free(struct iwl_trans *trans)
static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans)
{
- if (trans->state != IWL_TRANS_FW_ALIVE)
- IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+ WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
+ "%s bad state = %d", __func__, trans->state);
return trans->ops->wait_tx_queue_empty(trans);
}
static inline int iwl_trans_check_stuck_queue(struct iwl_trans *trans, int q)
{
- if (trans->state != IWL_TRANS_FW_ALIVE)
- IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+ WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
+ "%s bad state = %d", __func__, trans->state);
return trans->ops->check_stuck_queue(trans, q);
}