Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
authorJohn W. Linville <linville@tuxdriver.com>
Fri, 9 Mar 2012 19:57:30 +0000 (14:57 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 9 Mar 2012 19:57:30 +0000 (14:57 -0500)
1  2 
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ipw2x00/ipw2100.c
drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c

@@@ -1386,10 -1386,16 +1386,16 @@@ static bool ath9k_hw_set_reset_reg(stru
  static bool ath9k_hw_chip_reset(struct ath_hw *ah,
                                struct ath9k_channel *chan)
  {
-       if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) {
-               if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON))
-                       return false;
-       } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
+       int reset_type = ATH9K_RESET_WARM;
+       if (AR_SREV_9280(ah)) {
+               if (ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
+                       reset_type = ATH9K_RESET_POWER_ON;
+               else
+                       reset_type = ATH9K_RESET_COLD;
+       }
+       if (!ath9k_hw_set_reset_reg(ah, reset_type))
                return false;
  
        if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
@@@ -1562,7 -1568,7 +1568,7 @@@ int ath9k_hw_reset(struct ath_hw *ah, s
                allow_fbs = true;
  
        if (bChannelChange &&
 -          (ah->chip_fullsleep != true) &&
 +          (!ah->chip_fullsleep) &&
            (ah->curchan != NULL) &&
            (chan->channel != ah->curchan->channel) &&
            (allow_fbs ||
@@@ -1930,7 -1936,8 +1936,7 @@@ static bool ath9k_hw_set_power_awake(st
        if (setChip) {
                if ((REG_READ(ah, AR_RTC_STATUS) &
                     AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) {
 -                      if (ath9k_hw_set_reset_reg(ah,
 -                                         ATH9K_RESET_POWER_ON) != true) {
 +                      if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
                                return false;
                        }
                        if (!AR_SREV_9300_20_OR_LATER(ah))
@@@ -298,8 -298,6 +298,6 @@@ static const char *command_types[] = 
  };
  #endif
  
- #define WEXT_USECHANNELS 1
  static const long ipw2100_frequencies[] = {
        2412, 2417, 2422, 2427,
        2432, 2437, 2442, 2447,
@@@ -3457,8 -3455,11 +3455,8 @@@ static int ipw2100_msg_allocate(struct 
        priv->msg_buffers =
            kmalloc(IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet),
                    GFP_KERNEL);
 -      if (!priv->msg_buffers) {
 -              printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg "
 -                     "buffers.\n", priv->net_dev->name);
 +      if (!priv->msg_buffers)
                return -ENOMEM;
 -      }
  
        for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) {
                v = pci_alloc_consistent(priv->pci_dev,
  #define IWL_TX_CRC_SIZE 4
  #define IWL_TX_DELIMITER_SIZE 4
  
+ /*
+  * mac80211 queues, ACs, hardware queues, FIFOs.
+  *
+  * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues
+  *
+  * Mac80211 uses the following numbers, which we get as from it
+  * by way of skb_get_queue_mapping(skb):
+  *
+  *    VO      0
+  *    VI      1
+  *    BE      2
+  *    BK      3
+  *
+  *
+  * Regular (not A-MPDU) frames are put into hardware queues corresponding
+  * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their
+  * own queue per aggregation session (RA/TID combination), such queues are
+  * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In
+  * order to map frames to the right queue, we also need an AC->hw queue
+  * mapping. This is implemented here.
+  *
+  * Due to the way hw queues are set up (by the hw specific code), the AC->hw
+  * queue mapping is the identity mapping.
+  */
+ static const u8 tid_to_ac[] = {
+       IEEE80211_AC_BE,
+       IEEE80211_AC_BK,
+       IEEE80211_AC_BK,
+       IEEE80211_AC_BE,
+       IEEE80211_AC_VI,
+       IEEE80211_AC_VI,
+       IEEE80211_AC_VO,
+       IEEE80211_AC_VO
+ };
  /**
   * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
   */
@@@ -99,7 -136,7 +136,7 @@@ void iwl_txq_update_write_ptr(struct iw
        if (txq->need_update == 0)
                return;
  
-       if (hw_params(trans).shadow_reg_enable) {
+       if (cfg(trans)->base_params->shadow_reg_enable) {
                /* shadow register enabled */
                iwl_write32(trans, HBUS_TARG_WRPTR,
                            txq->q.write_ptr | (txq_id << 8));
@@@ -217,6 -254,8 +254,8 @@@ void iwlagn_txq_free_tfd(struct iwl_tra
  {
        struct iwl_tfd *tfd_tmp = txq->tfds;
  
+       lockdep_assert_held(&txq->lock);
        iwlagn_unmap_tfd(trans, &txq->meta[index], &tfd_tmp[index], dma_dir);
  
        /* free SKB */
@@@ -358,7 -397,7 +397,7 @@@ static void iwlagn_txq_inval_byte_cnt_t
  
        WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);
  
-       if (txq_id != trans->shrd->cmd_queue)
+       if (txq_id != trans_pcie->cmd_queue)
                sta_id = tx_cmd->sta_id;
  
        bc_ent = cpu_to_le16(1 | (sta_id << 12));
@@@ -440,6 -479,15 +479,15 @@@ void iwl_trans_tx_queue_set_status(stru
                        scd_retry ? "BA" : "AC/CMD", txq_id);
  }
  
+ static inline int get_ac_from_tid(u16 tid)
+ {
+       if (likely(tid < ARRAY_SIZE(tid_to_ac)))
+               return tid_to_ac[tid];
+       /* no support for TIDs 8-15 yet */
+       return -EINVAL;
+ }
  static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie,
                                    u8 ctx, u16 tid)
  {
@@@ -482,7 -530,7 +530,7 @@@ void iwl_trans_pcie_tx_agg_setup(struc
        }
  
        txq_id = trans_pcie->agg_txq[sta_id][tid];
 -      if (WARN_ON_ONCE(is_agg_txqid_valid(trans, txq_id) == false)) {
 +      if (WARN_ON_ONCE(!is_agg_txqid_valid(trans, txq_id))) {
                IWL_ERR(trans,
                        "queue number out of range: %d, must be %d to %d\n",
                        txq_id, IWLAGN_FIRST_AMPDU_QUEUE,
@@@ -547,7 -595,8 +595,8 @@@ static int iwlagn_txq_ctx_activate_free
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        int txq_id;
  
-       for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++)
+       for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues;
+            txq_id++)
                if (!test_and_set_bit(txq_id,
                                        &trans_pcie->txq_ctx_active_msk))
                        return txq_id;
@@@ -577,7 -626,7 +626,7 @@@ int iwl_trans_pcie_tx_agg_disable(struc
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        u8 txq_id = trans_pcie->agg_txq[sta_id][tid];
  
 -      if (WARN_ON_ONCE(is_agg_txqid_valid(trans, txq_id) == false)) {
 +      if (WARN_ON_ONCE(!is_agg_txqid_valid(trans, txq_id))) {
                IWL_ERR(trans,
                        "queue number out of range: %d, must be %d to %d\n",
                        txq_id, IWLAGN_FIRST_AMPDU_QUEUE,
  static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
  {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-       struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue];
+       struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue];
        struct iwl_queue *q = &txq->q;
        struct iwl_device_cmd *out_cmd;
        struct iwl_cmd_meta *out_meta;
        dma_addr_t phys_addr;
-       unsigned long flags;
        u32 idx;
        u16 copy_size, cmd_size;
-       bool is_ct_kill = false;
        bool had_nocopy = false;
        int i;
        u8 *cmd_dest;
                return -EIO;
        }
  
-       if ((trans->shrd->ucode_owner == IWL_OWNERSHIP_TM) &&
-           !(cmd->flags & CMD_ON_DEMAND)) {
-               IWL_DEBUG_HC(trans, "tm own the uCode, no regular hcmd send\n");
-               return -EIO;
-       }
        copy_size = sizeof(out_cmd->hdr);
        cmd_size = sizeof(out_cmd->hdr);
  
        if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE))
                return -EINVAL;
  
-       if (iwl_is_rfkill(trans->shrd) || iwl_is_ctkill(trans->shrd)) {
-               IWL_WARN(trans, "Not sending command - %s KILL\n",
-                        iwl_is_rfkill(trans->shrd) ? "RF" : "CT");
-               return -EIO;
-       }
-       spin_lock_irqsave(&trans->hcmd_lock, flags);
+       spin_lock_bh(&txq->lock);
  
        if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
-               spin_unlock_irqrestore(&trans->hcmd_lock, flags);
+               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;
        }
  
        out_cmd->hdr.cmd = cmd->id;
        out_cmd->hdr.flags = 0;
        out_cmd->hdr.sequence =
-               cpu_to_le16(QUEUE_TO_SEQ(trans->shrd->cmd_queue) |
+               cpu_to_le16(QUEUE_TO_SEQ(trans_pcie->cmd_queue) |
                                         INDEX_TO_SEQ(q->write_ptr));
  
        /* and copy the data that needs to be copied */
                        get_cmd_string(out_cmd->hdr.cmd),
                        out_cmd->hdr.cmd,
                        le16_to_cpu(out_cmd->hdr.sequence), cmd_size,
-                       q->write_ptr, idx, trans->shrd->cmd_queue);
+                       q->write_ptr, idx, trans_pcie->cmd_queue);
  
        phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size,
                                DMA_BIDIRECTIONAL);
        /* check that tracing gets all possible blocks */
        BUILD_BUG_ON(IWL_MAX_CMD_TFDS + 1 != 3);
  #ifdef CONFIG_IWLWIFI_DEVICE_TRACING
-       trace_iwlwifi_dev_hcmd(priv(trans), cmd->flags,
+       trace_iwlwifi_dev_hcmd(trans->dev, cmd->flags,
                               trace_bufs[0], trace_lens[0],
                               trace_bufs[1], trace_lens[1],
                               trace_bufs[2], trace_lens[2]);
        iwl_txq_update_write_ptr(trans, txq);
  
   out:
-       spin_unlock_irqrestore(&trans->hcmd_lock, flags);
+       spin_unlock_bh(&txq->lock);
        return idx;
  }
  
@@@ -809,6 -840,8 +840,8 @@@ static void iwl_hcmd_queue_reclaim(stru
        struct iwl_queue *q = &txq->q;
        int nfreed = 0;
  
+       lockdep_assert_held(&txq->lock);
        if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) {
                IWL_ERR(trans, "%s: Read index for DMA queue txq id (%d), "
                          "index %d is out of range [0-%d] %d %d.\n", __func__,
   * will be executed.  The attached skb (if present) will only be freed
   * if the callback returns 1
   */
- void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
+ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb,
                         int handler_status)
  {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_device_cmd *cmd;
        struct iwl_cmd_meta *meta;
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-       struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue];
-       unsigned long flags;
+       struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue];
  
        /* If a Tx command is being handled and it isn't in the actual
         * command queue then there a command routing bug has been introduced
         * in the queue management code. */
-       if (WARN(txq_id != trans->shrd->cmd_queue,
+       if (WARN(txq_id != trans_pcie->cmd_queue,
                 "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n",
-                 txq_id, trans->shrd->cmd_queue, sequence,
-                 trans_pcie->txq[trans->shrd->cmd_queue].q.read_ptr,
-                 trans_pcie->txq[trans->shrd->cmd_queue].q.write_ptr)) {
+                 txq_id, trans_pcie->cmd_queue, sequence,
+                 trans_pcie->txq[trans_pcie->cmd_queue].q.read_ptr,
+                 trans_pcie->txq[trans_pcie->cmd_queue].q.write_ptr)) {
                iwl_print_hex_error(trans, pkt, 32);
                return;
        }
  
+       spin_lock(&txq->lock);
        cmd_index = get_cmd_index(&txq->q, index);
        cmd = txq->cmd[cmd_index];
        meta = &txq->meta[cmd_index];
  
        /* Input error checking is done when commands are added to queue. */
        if (meta->flags & CMD_WANT_SKB) {
-               meta->source->reply_page = (unsigned long)rxb_addr(rxb);
+               struct page *p = rxb_steal_page(rxb);
+               meta->source->resp_pkt = pkt;
+               meta->source->_rx_page_addr = (unsigned long)page_address(p);
+               meta->source->_rx_page_order = hw_params(trans).rx_page_order;
                meta->source->handler_status = handler_status;
-               rxb->page = NULL;
        }
  
-       spin_lock_irqsave(&trans->hcmd_lock, flags);
        iwl_hcmd_queue_reclaim(trans, txq_id, index);
  
        if (!(meta->flags & CMD_ASYNC)) {
  
        meta->flags = 0;
  
-       spin_unlock_irqrestore(&trans->hcmd_lock, flags);
+       spin_unlock(&txq->lock);
  }
  
  #define HOST_COMPLETE_TIMEOUT (2 * HZ)
@@@ -912,12 -947,9 +947,9 @@@ static int iwl_send_cmd_async(struct iw
                return -EINVAL;
  
  
-       if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status))
-               return -EBUSY;
        ret = iwl_enqueue_hcmd(trans, cmd);
        if (ret < 0) {
-               IWL_DEBUG_QUIET_RFKILL(trans,
+               IWL_ERR(trans,
                        "Error sending %s: enqueue_hcmd failed: %d\n",
                          get_cmd_string(cmd->id), ret);
                return ret;
@@@ -931,26 -963,22 +963,22 @@@ static int iwl_send_cmd_sync(struct iwl
        int cmd_idx;
        int ret;
  
-       lockdep_assert_held(&trans->shrd->mutex);
        IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n",
                        get_cmd_string(cmd->id));
  
-       if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status))
-               return -EBUSY;
-       if (test_bit(STATUS_RF_KILL_HW, &trans->shrd->status)) {
-               IWL_ERR(trans, "Command %s aborted: RF KILL Switch\n",
-                              get_cmd_string(cmd->id));
-               return -ECANCELED;
-       }
        if (test_bit(STATUS_FW_ERROR, &trans->shrd->status)) {
                IWL_ERR(trans, "Command %s failed: FW Error\n",
                               get_cmd_string(cmd->id));
                return -EIO;
        }
-       set_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
+       if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE,
+                                    &trans->shrd->status))) {
+               IWL_ERR(trans, "Command %s: a command is already active!\n",
+                       get_cmd_string(cmd->id));
+               return -EIO;
+       }
        IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n",
                        get_cmd_string(cmd->id));
  
        if (cmd_idx < 0) {
                ret = cmd_idx;
                clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
-               IWL_DEBUG_QUIET_RFKILL(trans,
+               IWL_ERR(trans,
                        "Error sending %s: enqueue_hcmd failed: %d\n",
                          get_cmd_string(cmd->id), ret);
                return ret;
        if (!ret) {
                if (test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) {
                        struct iwl_tx_queue *txq =
-                               &trans_pcie->txq[trans->shrd->cmd_queue];
+                               &trans_pcie->txq[trans_pcie->cmd_queue];
                        struct iwl_queue *q = &txq->q;
  
-                       IWL_DEBUG_QUIET_RFKILL(trans,
+                       IWL_ERR(trans,
                                "Error sending %s: time out after %dms.\n",
                                get_cmd_string(cmd->id),
                                jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
  
-                       IWL_DEBUG_QUIET_RFKILL(trans,
+                       IWL_ERR(trans,
                                "Current CMD queue read_ptr %d write_ptr %d\n",
                                q->read_ptr, q->write_ptr);
  
                }
        }
  
-       if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) {
+       if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) {
                IWL_ERR(trans, "Error: Response NULL in '%s'\n",
                          get_cmd_string(cmd->id));
                ret = -EIO;
@@@ -1007,13 -1035,13 +1035,13 @@@ cancel
                 * in later, it will possibly set an invalid
                 * address (cmd->meta.source).
                 */
-               trans_pcie->txq[trans->shrd->cmd_queue].meta[cmd_idx].flags &=
+               trans_pcie->txq[trans_pcie->cmd_queue].meta[cmd_idx].flags &=
                                                        ~CMD_WANT_SKB;
        }
  
-       if (cmd->reply_page) {
-               iwl_free_pages(trans->shrd, cmd->reply_page);
-               cmd->reply_page = 0;
+       if (cmd->resp_pkt) {
+               iwl_free_resp(cmd);
+               cmd->resp_pkt = NULL;
        }
  
        return ret;
@@@ -1038,9 -1066,11 +1066,11 @@@ int iwl_tx_queue_reclaim(struct iwl_tra
        int freed = 0;
  
        /* This function is not meant to release cmd queue*/
-       if (WARN_ON(txq_id == trans->shrd->cmd_queue))
+       if (WARN_ON(txq_id == trans_pcie->cmd_queue))
                return 0;
  
+       lockdep_assert_held(&txq->lock);
        /*Since we free until index _not_ inclusive, the one before index is
         * the last we will free. This one must be used */
        last_to_free = iwl_queue_dec_wrap(index, q->n_bd);
@@@ -329,8 -329,8 +329,8 @@@ static void rtl92c_dm_initial_gain_mult
        if (mac->opmode == NL80211_IFTYPE_ADHOC)
                multi_sta = true;
  
 -      if ((multi_sta == false) || (dm_digtable.cursta_connectctate !=
 -                                   DIG_STA_DISCONNECT)) {
 +      if (!multi_sta ||
 +          dm_digtable.cursta_connectctate != DIG_STA_DISCONNECT) {
                initialized = false;
                dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
                return;
@@@ -520,6 -520,10 +520,10 @@@ void rtl92c_dm_write_dig(struct ieee802
                 dm_digtable.cur_igvalue, dm_digtable.pre_igvalue,
                 dm_digtable.backoff_val);
  
+       dm_digtable.cur_igvalue += 2;
+       if (dm_digtable.cur_igvalue > 0x3f)
+               dm_digtable.cur_igvalue = 0x3f;
        if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) {
                rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
                              dm_digtable.cur_igvalue);
@@@ -1201,13 -1205,18 +1205,18 @@@ static void rtl92c_dm_refresh_rate_adap
                                 "PreState = %d, CurState = %d\n",
                                 p_ra->pre_ratr_state, p_ra->ratr_state);
  
-                       rcu_read_lock();
-                       sta = ieee80211_find_sta(mac->vif, mac->bssid);
+                       /* Only the PCI card uses sta in the update rate table
+                        * callback routine */
+                       if (rtlhal->interface == INTF_PCI) {
+                               rcu_read_lock();
+                               sta = ieee80211_find_sta(mac->vif, mac->bssid);
+                       }
                        rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
                                        p_ra->ratr_state);
  
                        p_ra->pre_ratr_state = p_ra->ratr_state;
-                       rcu_read_unlock();
+                       if (rtlhal->interface == INTF_PCI)
+                               rcu_read_unlock();
                }
        }
  }