forked from Minki/linux
iwlwifi: virtualize command queue full behaviour
When the command queue is full, the transport will return -ENOSPC, but the reaction to that depends on the op_mode. Virtualize that, the DVM op_mode checks for CT-kill and restarts the hardware otherwise. We may be able to get rid of this callback by putting the behaviour check into the wrapper but that needs more careful evaluation. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
6c1011e191
commit
0e781842cb
@ -1403,6 +1403,16 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
|
||||
ieee80211_free_hw(priv->hw);
|
||||
}
|
||||
|
||||
static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode)
|
||||
{
|
||||
struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
|
||||
|
||||
if (!iwl_check_for_ct_kill(priv)) {
|
||||
IWL_ERR(priv, "Restarting adapter queue is full\n");
|
||||
iwl_nic_error(op_mode);
|
||||
}
|
||||
}
|
||||
|
||||
const struct iwl_op_mode_ops iwl_dvm_ops = {
|
||||
.start = iwl_op_mode_dvm_start,
|
||||
.stop = iwl_op_mode_dvm_stop,
|
||||
@ -1412,6 +1422,7 @@ const struct iwl_op_mode_ops iwl_dvm_ops = {
|
||||
.hw_rf_kill = iwl_set_hw_rfkill_state,
|
||||
.free_skb = iwl_free_skb,
|
||||
.nic_error = iwl_nic_error,
|
||||
.cmd_queue_full = iwl_cmd_queue_full,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -90,6 +90,8 @@ void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state);
|
||||
void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac);
|
||||
void iwl_nic_error(struct iwl_op_mode *op_mode);
|
||||
|
||||
bool iwl_check_for_ct_kill(struct iwl_priv *priv);
|
||||
|
||||
/* MAC80211 */
|
||||
struct ieee80211_hw *iwl_alloc_all(void);
|
||||
int iwlagn_mac_setup_register(struct iwl_priv *priv,
|
||||
|
@ -122,6 +122,7 @@ struct iwl_fw;
|
||||
* there are Tx packets pending in the transport layer.
|
||||
* Must be atomic
|
||||
* @nic_error: error notification. Must be atomic
|
||||
* @cmd_queue_full: Called when the command queue gets full. Must be atomic.
|
||||
*/
|
||||
struct iwl_op_mode_ops {
|
||||
struct iwl_op_mode *(*start)(struct iwl_trans *trans,
|
||||
@ -134,6 +135,7 @@ struct iwl_op_mode_ops {
|
||||
void (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state);
|
||||
void (*free_skb)(struct iwl_op_mode *op_mode, struct sk_buff *skb);
|
||||
void (*nic_error)(struct iwl_op_mode *op_mode);
|
||||
void (*cmd_queue_full)(struct iwl_op_mode *op_mode);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -192,6 +194,11 @@ static inline void iwl_op_mode_nic_error(struct iwl_op_mode *op_mode)
|
||||
op_mode->ops->nic_error(op_mode);
|
||||
}
|
||||
|
||||
static inline void iwl_op_mode_cmd_queue_full(struct iwl_op_mode *op_mode)
|
||||
{
|
||||
op_mode->ops->cmd_queue_full(op_mode);
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* Op mode layers implementations
|
||||
******************************************************/
|
||||
|
@ -461,8 +461,6 @@ enum iwl_rxon_context_id {
|
||||
int iwlagn_hw_valid_rtc_data_addr(u32 addr);
|
||||
void iwl_nic_config(struct iwl_priv *priv);
|
||||
const char *get_cmd_string(u8 cmd);
|
||||
bool iwl_check_for_ct_kill(struct iwl_priv *priv);
|
||||
|
||||
|
||||
/* notification wait support */
|
||||
void iwl_abort_notification_waits(struct iwl_shared *shrd);
|
||||
|
@ -671,7 +671,6 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
|
||||
dma_addr_t phys_addr;
|
||||
u32 idx;
|
||||
u16 copy_size, cmd_size;
|
||||
bool is_ct_kill = false;
|
||||
bool had_nocopy = false;
|
||||
int i;
|
||||
u8 *cmd_dest;
|
||||
@ -727,11 +726,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
|
||||
spin_unlock_bh(&txq->lock);
|
||||
|
||||
IWL_ERR(trans, "No space in command queue\n");
|
||||
is_ct_kill = iwl_check_for_ct_kill(priv(trans));
|
||||
if (!is_ct_kill) {
|
||||
IWL_ERR(trans, "Restarting adapter queue is full\n");
|
||||
iwl_op_mode_nic_error(trans->op_mode);
|
||||
}
|
||||
iwl_op_mode_cmd_queue_full(trans->op_mode);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user