]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi...
authorJohn W. Linville <linville@tuxdriver.com>
Tue, 18 Jun 2013 18:43:50 +0000 (14:43 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 18 Jun 2013 18:43:50 +0000 (14:43 -0400)
1  2 
drivers/net/wireless/iwlwifi/pcie/tx.c

index b8f3cb78382bd55eac2bf57dc8bc970d170a0b5b,48acfc6201914ae49823077cea5e78706004ce44..c47c92165aba91d2e97631f1953bd4e480cabad7
@@@ -224,13 -224,13 +224,13 @@@ static void iwl_pcie_txq_update_byte_cn
  
        switch (sec_ctl & TX_CMD_SEC_MSK) {
        case TX_CMD_SEC_CCM:
 -              len += CCMP_MIC_LEN;
 +              len += IEEE80211_CCMP_MIC_LEN;
                break;
        case TX_CMD_SEC_TKIP:
 -              len += TKIP_ICV_LEN;
 +              len += IEEE80211_TKIP_ICV_LEN;
                break;
        case TX_CMD_SEC_WEP:
 -              len += WEP_IV_LEN + WEP_ICV_LEN;
 +              len += IEEE80211_WEP_IV_LEN + IEEE80211_WEP_ICV_LEN;
                break;
        }
  
@@@ -576,10 -576,16 +576,16 @@@ static void iwl_pcie_txq_unmap(struct i
  
        spin_lock_bh(&txq->lock);
        while (q->write_ptr != q->read_ptr) {
+               IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n",
+                                  txq_id, q->read_ptr);
                iwl_pcie_txq_free_tfd(trans, txq);
                q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
        }
+       txq->active = false;
        spin_unlock_bh(&txq->lock);
+       /* just in case - this queue may have been stopped */
+       iwl_wake_queue(trans, txq);
  }
  
  /*
@@@ -927,6 -933,12 +933,12 @@@ void iwl_trans_pcie_reclaim(struct iwl_
  
        spin_lock_bh(&txq->lock);
  
+       if (!txq->active) {
+               IWL_DEBUG_TX_QUEUES(trans, "Q %d inactive - ignoring idx %d\n",
+                                   txq_id, ssn);
+               goto out;
+       }
        if (txq->q.read_ptr == tfd_num)
                goto out;
  
@@@ -1045,10 -1057,6 +1057,10 @@@ static inline void iwl_pcie_txq_set_ina
                (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
  }
  
 +/* Receiver address (actually, Rx station's index into station table),
 + * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
 +#define BUILD_RAxTID(sta_id, tid)     (((sta_id) << 4) + (tid))
 +
  void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
                               int sta_id, int tid, int frame_limit, u16 ssn)
  {
  
                /* enable aggregations for the queue */
                iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id));
 +              trans_pcie->txq[txq_id].ampdu = true;
        } else {
                /*
                 * disable aggregations for the queue, this will also make the
                       (fifo << SCD_QUEUE_STTS_REG_POS_TXF) |
                       (1 << SCD_QUEUE_STTS_REG_POS_WSL) |
                       SCD_QUEUE_STTS_REG_MSK);
+       trans_pcie->txq[txq_id].active = true;
        IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n",
                            txq_id, fifo, ssn & 0xff);
  }
@@@ -1130,7 -1138,6 +1143,7 @@@ void iwl_trans_pcie_txq_disable(struct 
                            ARRAY_SIZE(zero_val));
  
        iwl_pcie_txq_unmap(trans, txq_id);
 +      trans_pcie->txq[txq_id].ampdu = false;
  
        IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id);
  }
@@@ -1524,13 -1531,11 +1537,13 @@@ static int iwl_pcie_send_hcmd_sync(stru
        if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) {
                IWL_ERR(trans, "FW error in SYNC CMD %s\n",
                        get_cmd_string(trans_pcie, cmd->id));
 +              dump_stack();
                ret = -EIO;
                goto cancel;
        }
  
 -      if (test_bit(STATUS_RFKILL, &trans_pcie->status)) {
 +      if (!(cmd->flags & CMD_SEND_IN_RFKILL) &&
 +          test_bit(STATUS_RFKILL, &trans_pcie->status)) {
                IWL_DEBUG_RF_KILL(trans, "RFKILL in SYNC CMD... no rsp\n");
                ret = -ERFKILL;
                goto cancel;
@@@ -1572,8 -1577,7 +1585,8 @@@ int iwl_trans_pcie_send_hcmd(struct iwl
        if (test_bit(STATUS_FW_ERROR, &trans_pcie->status))
                return -EIO;
  
 -      if (test_bit(STATUS_RFKILL, &trans_pcie->status)) {
 +      if (!(cmd->flags & CMD_SEND_IN_RFKILL) &&
 +          test_bit(STATUS_RFKILL, &trans_pcie->status)) {
                IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n",
                                  cmd->id);
                return -ERFKILL;
@@@ -1601,7 -1605,7 +1614,7 @@@ int iwl_trans_pcie_tx(struct iwl_trans 
        u8 wait_write_ptr = 0;
        __le16 fc = hdr->frame_control;
        u8 hdr_len = ieee80211_hdrlen(fc);
 -      u16 __maybe_unused wifi_seq;
 +      u16 wifi_seq;
  
        txq = &trans_pcie->txq[txq_id];
        q = &txq->q;
         * the BA.
         * Check here that the packets are in the right place on the ring.
         */
 -#ifdef CONFIG_IWLWIFI_DEBUG
        wifi_seq = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
 -      WARN_ONCE((iwl_read_prph(trans, SCD_AGGR_SEL) & BIT(txq_id)) &&
 -                ((wifi_seq & 0xff) != q->write_ptr),
 +      WARN_ONCE(trans_pcie->txq[txq_id].ampdu &&
 +                (wifi_seq & 0xff) != q->write_ptr,
                  "Q: %d WiFi Seq %d tfdNum %d",
                  txq_id, wifi_seq, q->write_ptr);
 -#endif
  
        /* Set up driver data for this TFD */
        txq->entries[q->write_ptr].skb = skb;