Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi...
authorJohn W. Linville <linville@tuxdriver.com>
Tue, 5 Nov 2013 20:53:10 +0000 (15:53 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 5 Nov 2013 20:53:10 +0000 (15:53 -0500)
1  2 
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/pcie/tx.c

index c6bac7c90b00bf458b17a829ec2895c2acaa065d,2dc64b5c94c1dcd0f9d7f6fea3431435966b7b95..143292b4dbbffeac763f86d5c9d9b1badae1aecc
@@@ -344,7 -344,7 +344,7 @@@ struct iwl_trans_config 
        u8 cmd_queue;
        u8 cmd_fifo;
        const u8 *no_reclaim_cmds;
-       int n_no_reclaim_cmds;
+       unsigned int n_no_reclaim_cmds;
  
        bool rx_buf_size_8k;
        bool bc_table_dword;
@@@ -601,10 -601,8 +601,10 @@@ static inline int iwl_trans_send_cmd(st
  {
        int ret;
  
 -      WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
 -                "%s bad state = %d", __func__, trans->state);
 +      if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) {
 +              IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
 +              return -EIO;
 +      }
  
        if (!(cmd->flags & CMD_ASYNC))
                lock_map_acquire_read(&trans->sync_cmd_lockdep_map);
@@@ -640,8 -638,8 +640,8 @@@ static inline void iwl_trans_free_tx_cm
  static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
                               struct iwl_device_cmd *dev_cmd, int queue)
  {
 -      WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
 -                "%s bad state = %d", __func__, trans->state);
 +      if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
 +              IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
  
        return trans->ops->tx(trans, skb, dev_cmd, queue);
  }
  static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue,
                                     int ssn, struct sk_buff_head *skbs)
  {
 -      WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
 -                "%s bad state = %d", __func__, trans->state);
 +      if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
 +              IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
  
        trans->ops->reclaim(trans, queue, ssn, skbs);
  }
  
  static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue)
  {
 -      WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
 -                "%s bad state = %d", __func__, trans->state);
 +      if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
 +              IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
  
        trans->ops->txq_disable(trans, queue);
  }
@@@ -669,8 -667,8 +669,8 @@@ static inline void iwl_trans_txq_enable
  {
        might_sleep();
  
 -      WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
 -                "%s bad state = %d", __func__, trans->state);
 +      if (unlikely((trans->state != IWL_TRANS_FW_ALIVE)))
 +              IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
  
        trans->ops->txq_enable(trans, queue, fifo, sta_id, tid,
                                 frame_limit, ssn);
@@@ -685,8 -683,8 +685,8 @@@ static inline void iwl_trans_ac_txq_ena
  
  static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans)
  {
 -      WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
 -                "%s bad state = %d", __func__, trans->state);
 +      if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
 +              IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
  
        return trans->ops->wait_tx_queue_empty(trans);
  }
index f644fcf861a8c9ead756169ce4b6d960a8f51e1b,cc184402b88a658f27ab54899ae7fb35e1122ee2..059c5acad3a0d2e7b9eb73bf6466ef088e54e5c2
@@@ -1102,8 -1102,6 +1102,8 @@@ void iwl_trans_pcie_txq_enable(struct i
                 * non-AGG queue.
                 */
                iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id));
 +
 +              ssn = trans_pcie->txq[txq_id].q.read_ptr;
        }
  
        /* Place first TFD at index corresponding to start sequence number.
@@@ -1465,8 -1463,7 +1465,8 @@@ void iwl_pcie_hcmd_complete(struct iwl_
        spin_unlock_bh(&txq->lock);
  }
  
 -#define HOST_COMPLETE_TIMEOUT (2 * HZ)
 +#define HOST_COMPLETE_TIMEOUT (2 * HZ)
 +#define COMMAND_POKE_TIMEOUT  (HZ / 10)
  
  static int iwl_pcie_send_hcmd_async(struct iwl_trans *trans,
                                    struct iwl_host_cmd *cmd)
@@@ -1494,17 -1491,15 +1494,16 @@@ static int iwl_pcie_send_hcmd_sync(stru
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        int cmd_idx;
        int ret;
 +      int timeout = HOST_COMPLETE_TIMEOUT;
  
        IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n",
                       get_cmd_string(trans_pcie, cmd->id));
  
-       if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE,
-                                    &trans_pcie->status))) {
-               IWL_ERR(trans, "Command %s: a command is already active!\n",
-                       get_cmd_string(trans_pcie, cmd->id));
+       if (WARN(test_and_set_bit(STATUS_HCMD_ACTIVE,
+                                 &trans_pcie->status),
+                "Command %s: a command is already active!\n",
+                get_cmd_string(trans_pcie, cmd->id)))
                return -EIO;
-       }
  
        IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n",
                       get_cmd_string(trans_pcie, cmd->id));
                return ret;
        }
  
 -      ret = wait_event_timeout(trans_pcie->wait_command_queue,
 -                               !test_bit(STATUS_HCMD_ACTIVE,
 -                                         &trans_pcie->status),
 -                               HOST_COMPLETE_TIMEOUT);
 +      while (timeout > 0) {
 +              unsigned long flags;
 +
 +              timeout -= COMMAND_POKE_TIMEOUT;
 +              ret = wait_event_timeout(trans_pcie->wait_command_queue,
 +                                       !test_bit(STATUS_HCMD_ACTIVE,
 +                                                 &trans_pcie->status),
 +                                       COMMAND_POKE_TIMEOUT);
 +              if (ret)
 +                      break;
 +              /* poke the device - it may have lost the command */
 +              if (iwl_trans_grab_nic_access(trans, true, &flags)) {
 +                      iwl_trans_release_nic_access(trans, &flags);
 +                      IWL_DEBUG_INFO(trans,
 +                                     "Tried to wake NIC for command %s\n",
 +                                     get_cmd_string(trans_pcie, cmd->id));
 +              } else {
 +                      IWL_ERR(trans, "Failed to poke NIC for command %s\n",
 +                              get_cmd_string(trans_pcie, cmd->id));
 +                      break;
 +              }
 +      }
 +
        if (!ret) {
                if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) {
                        struct iwl_txq *txq =