|
@@ -542,6 +542,11 @@ struct iwl_trans_txq_scd_cfg {
|
|
* @wait_tx_queue_empty: wait until tx queues are empty. May sleep.
|
|
* @wait_tx_queue_empty: wait until tx queues are empty. May sleep.
|
|
* @freeze_txq_timer: prevents the timer of the queue from firing until the
|
|
* @freeze_txq_timer: prevents the timer of the queue from firing until the
|
|
* queue is set to awake. Must be atomic.
|
|
* queue is set to awake. Must be atomic.
|
|
|
|
+ * @block_txq_ptrs: stop updating the write pointers of the Tx queues. Note
|
|
|
|
+ * that the transport needs to refcount the calls since this function
|
|
|
|
+ * will be called several times with block = true, and then the queues
|
|
|
|
+ * need to be unblocked only after the same number of calls with
|
|
|
|
+ * block = false.
|
|
* @write8: write a u8 to a register at offset ofs from the BAR
|
|
* @write8: write a u8 to a register at offset ofs from the BAR
|
|
* @write32: write a u32 to a register at offset ofs from the BAR
|
|
* @write32: write a u32 to a register at offset ofs from the BAR
|
|
* @read32: read a u32 register at offset ofs from the BAR
|
|
* @read32: read a u32 register at offset ofs from the BAR
|
|
@@ -600,6 +605,7 @@ struct iwl_trans_ops {
|
|
int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm);
|
|
int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm);
|
|
void (*freeze_txq_timer)(struct iwl_trans *trans, unsigned long txqs,
|
|
void (*freeze_txq_timer)(struct iwl_trans *trans, unsigned long txqs,
|
|
bool freeze);
|
|
bool freeze);
|
|
|
|
+ void (*block_txq_ptrs)(struct iwl_trans *trans, bool block);
|
|
|
|
|
|
void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val);
|
|
void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val);
|
|
void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val);
|
|
void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val);
|
|
@@ -1010,6 +1016,16 @@ static inline void iwl_trans_freeze_txq_timer(struct iwl_trans *trans,
|
|
trans->ops->freeze_txq_timer(trans, txqs, freeze);
|
|
trans->ops->freeze_txq_timer(trans, txqs, freeze);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static inline void iwl_trans_block_txq_ptrs(struct iwl_trans *trans,
|
|
|
|
+ bool block)
|
|
|
|
+{
|
|
|
|
+ if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
|
|
|
|
+ IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
|
|
|
|
+
|
|
|
|
+ if (trans->ops->block_txq_ptrs)
|
|
|
|
+ trans->ops->block_txq_ptrs(trans, block);
|
|
|
|
+}
|
|
|
|
+
|
|
static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans,
|
|
static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans,
|
|
u32 txqs)
|
|
u32 txqs)
|
|
{
|
|
{
|