Merge branch 'wireless-2.6' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi...
authorJohn W. Linville <linville@tuxdriver.com>
Fri, 26 Feb 2010 21:58:18 +0000 (16:58 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 26 Feb 2010 21:58:18 +0000 (16:58 -0500)
1  2 
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-tx.c

index ab3c77b92cc813fee2eb24b53112e977ff7797f0,cfd6c842311344a2a013215035f50479f6c92a90..6383d9f8c9b3e561cadfaf5dd322e532b364a192
@@@ -5,7 -5,7 +5,7 @@@
   *
   * GPL LICENSE SUMMARY
   *
 - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
 + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -30,7 -30,7 +30,7 @@@
   *
   * BSD LICENSE
   *
 - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
 + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -120,6 -120,7 +120,6 @@@ enum 
        CALIBRATION_COMPLETE_NOTIFICATION = 0x67,
  
        /* 802.11h related */
 -      RADAR_NOTIFICATION = 0x70,      /* not used */
        REPLY_QUIET_CMD = 0x71,         /* not used */
        REPLY_CHANNEL_SWITCH = 0x72,
        CHANNEL_SWITCH_NOTIFICATION = 0x73,
@@@ -2247,22 -2248,10 +2247,22 @@@ struct iwl_link_quality_cmd 
        __le32 reserved2;
  } __attribute__ ((packed));
  
 +/*
 + * BT configuration enable flags:
 + *   bit 0 - 1: BT channel announcement enabled
 + *           0: disable
 + *   bit 1 - 1: priority of BT device enabled
 + *           0: disable
 + *   bit 2 - 1: BT 2 wire support enabled
 + *           0: disable
 + */
 +#define BT_COEX_DISABLE (0x0)
 +#define BT_ENABLE_CHANNEL_ANNOUNCE BIT(0)
 +#define BT_ENABLE_PRIORITY       BIT(1)
 +#define BT_ENABLE_2_WIRE         BIT(2)
 +
  #define BT_COEX_DISABLE (0x0)
 -#define BT_COEX_MODE_2W (0x1)
 -#define BT_COEX_MODE_3W (0x2)
 -#define BT_COEX_MODE_4W (0x3)
 +#define BT_COEX_ENABLE  (BT_ENABLE_CHANNEL_ANNOUNCE | BT_ENABLE_PRIORITY)
  
  #define BT_LEAD_TIME_MIN (0x0)
  #define BT_LEAD_TIME_DEF (0x1E)
@@@ -2521,7 -2510,7 +2521,7 @@@ struct iwl_card_state_notif 
  
  #define HW_CARD_DISABLED   0x01
  #define SW_CARD_DISABLED   0x02
 -#define RF_CARD_DISABLED   0x04
 +#define CT_CARD_DISABLED   0x04
  #define RXON_CARD_DISABLED 0x10
  
  struct iwl_ct_kill_config {
@@@ -2623,6 -2612,7 +2623,7 @@@ struct iwl_ssid_ie 
  #define TX_CMD_LIFE_TIME_INFINITE     cpu_to_le32(0xFFFFFFFF)
  #define IWL_GOOD_CRC_TH                       cpu_to_le16(1)
  #define IWL_MAX_SCAN_SIZE 1024
+ #define IWL_MAX_CMD_SIZE 4096
  #define IWL_MAX_PROBE_REQUEST         200
  
  /*
@@@ -2995,7 -2985,7 +2996,7 @@@ struct statistics_rx_ht_phy 
        __le32 agg_crc32_good;
        __le32 agg_mpdu_cnt;
        __le32 agg_cnt;
 -      __le32 reserved2;
 +      __le32 unsupport_mcs;
  } __attribute__ ((packed));
  
  #define INTERFERENCE_DATA_AVAILABLE      cpu_to_le32(1)
@@@ -3098,8 -3088,8 +3099,8 @@@ struct statistics_div 
  } __attribute__ ((packed));
  
  struct statistics_general {
 -      __le32 temperature;
 -      __le32 temperature_m;
 +      __le32 temperature;   /* radio temperature */
 +      __le32 temperature_m; /* for 5000 and up, this is radio voltage */
        struct statistics_dbg dbg;
        __le32 sleep_time;
        __le32 slots_out;
        __le32 ttl_timestamp;
        struct statistics_div div;
        __le32 rx_enable_counter;
 -      __le32 reserved1;
 +      /*
 +       * num_of_sos_states:
 +       *  count the number of times we have to re-tune
 +       *  in order to get out of bad PHY status
 +       */
 +      __le32 num_of_sos_states;
        __le32 reserved2;
        __le32 reserved3;
  } __attribute__ ((packed));
@@@ -3177,30 -3162,13 +3178,30 @@@ struct iwl_notif_statistics 
  
  /*
   * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
 + *
 + * uCode send MISSED_BEACONS_NOTIFICATION to driver when detect beacon missed
 + * in regardless of how many missed beacons, which mean when driver receive the
 + * notification, inside the command, it can find all the beacons information
 + * which include number of total missed beacons, number of consecutive missed
 + * beacons, number of beacons received and number of beacons expected to
 + * receive.
 + *
 + * If uCode detected consecutive_missed_beacons > 5, it will reset the radio
 + * in order to bring the radio/PHY back to working state; which has no relation
 + * to when driver will perform sensitivity calibration.
 + *
 + * Driver should set it own missed_beacon_threshold to decide when to perform
 + * sensitivity calibration based on number of consecutive missed beacons in
 + * order to improve overall performance, especially in noisy environment.
 + *
   */
 -/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row,
 - * then this notification will be sent. */
 -#define CONSECUTIVE_MISSED_BCONS_TH 20
 +
 +#define IWL_MISSED_BEACON_THRESHOLD_MIN       (1)
 +#define IWL_MISSED_BEACON_THRESHOLD_DEF       (5)
 +#define IWL_MISSED_BEACON_THRESHOLD_MAX       IWL_MISSED_BEACON_THRESHOLD_DEF
  
  struct iwl_missed_beacon_notif {
 -      __le32 consequtive_missed_beacons;
 +      __le32 consecutive_missed_beacons;
        __le32 total_missed_becons;
        __le32 num_expected_beacons;
        __le32 num_recvd_beacons;
@@@ -3470,7 -3438,11 +3471,7 @@@ enum 
        IWL_PHY_CALIBRATE_DIFF_GAIN_CMD         = 7,
        IWL_PHY_CALIBRATE_DC_CMD                = 8,
        IWL_PHY_CALIBRATE_LO_CMD                = 9,
 -      IWL_PHY_CALIBRATE_RX_BB_CMD             = 10,
        IWL_PHY_CALIBRATE_TX_IQ_CMD             = 11,
 -      IWL_PHY_CALIBRATE_RX_IQ_CMD             = 12,
 -      IWL_PHY_CALIBRATION_NOISE_CMD           = 13,
 -      IWL_PHY_CALIBRATE_AGC_TABLE_CMD         = 14,
        IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD       = 15,
        IWL_PHY_CALIBRATE_BASE_BAND_CMD         = 16,
        IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD        = 17,
index 10701b8eef23fab98df67a736bef25a4d244e53f,066491fc75f25b642d5760f5be3589ebdd858ae3..1ed5206721ecb587688bbd8b463f172e0f5d2de1
@@@ -1,6 -1,6 +1,6 @@@
  /******************************************************************************
   *
 - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
 + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
   *
   * Portions of this file are derived from the ipw3945 project, as well
   * as portions of the ieee80211 subsystem header files.
@@@ -60,8 -60,7 +60,8 @@@ static const u16 default_tid_to_tx_fifo
  static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv,
                                    struct iwl_dma_ptr *ptr, size_t size)
  {
 -      ptr->addr = pci_alloc_consistent(priv->pci_dev, size, &ptr->dma);
 +      ptr->addr = dma_alloc_coherent(&priv->pci_dev->dev, size, &ptr->dma,
 +                                     GFP_KERNEL);
        if (!ptr->addr)
                return -ENOMEM;
        ptr->size = size;
@@@ -74,20 -73,21 +74,20 @@@ static inline void iwl_free_dma_ptr(str
        if (unlikely(!ptr->addr))
                return;
  
 -      pci_free_consistent(priv->pci_dev, ptr->size, ptr->addr, ptr->dma);
 +      dma_free_coherent(&priv->pci_dev->dev, ptr->size, ptr->addr, ptr->dma);
        memset(ptr, 0, sizeof(*ptr));
  }
  
  /**
   * iwl_txq_update_write_ptr - Send new write index to hardware
   */
 -int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
 +void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
  {
        u32 reg = 0;
 -      int ret = 0;
        int txq_id = txq->q.id;
  
        if (txq->need_update == 0)
 -              return ret;
 +              return;
  
        /* if we're trying to save power */
        if (test_bit(STATUS_POWER_PMI, &priv->status)) {
                                      txq_id, reg);
                        iwl_set_bit(priv, CSR_GP_CNTRL,
                                    CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 -                      return ret;
 +                      return;
                }
  
                iwl_write_direct32(priv, HBUS_TARG_WRPTR,
                            txq->q.write_ptr | (txq_id << 8));
  
        txq->need_update = 0;
 -
 -      return ret;
  }
  EXPORT_SYMBOL(iwl_txq_update_write_ptr);
  
@@@ -144,7 -146,7 +144,7 @@@ void iwl_tx_queue_free(struct iwl_priv 
  {
        struct iwl_tx_queue *txq = &priv->txq[txq_id];
        struct iwl_queue *q = &txq->q;
 -      struct pci_dev *dev = priv->pci_dev;
 +      struct device *dev = &priv->pci_dev->dev;
        int i;
  
        if (q->n_bd == 0)
  
        /* De-alloc circular buffer of TFDs */
        if (txq->q.n_bd)
 -              pci_free_consistent(dev, priv->hw_params.tfd_size *
 -                                  txq->q.n_bd, txq->tfds, txq->q.dma_addr);
 +              dma_free_coherent(dev, priv->hw_params.tfd_size *
 +                                txq->q.n_bd, txq->tfds, txq->q.dma_addr);
  
        /* De-alloc array of per-TFD driver data */
        kfree(txq->txb);
@@@ -191,7 -193,7 +191,7 @@@ void iwl_cmd_queue_free(struct iwl_pri
  {
        struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
        struct iwl_queue *q = &txq->q;
 -      struct pci_dev *dev = priv->pci_dev;
 +      struct device *dev = &priv->pci_dev->dev;
        int i;
  
        if (q->n_bd == 0)
  
        /* De-alloc circular buffer of TFDs */
        if (txq->q.n_bd)
 -              pci_free_consistent(dev, priv->hw_params.tfd_size *
 -                                  txq->q.n_bd, txq->tfds, txq->q.dma_addr);
 +              dma_free_coherent(dev, priv->hw_params.tfd_size * txq->q.n_bd,
 +                                txq->tfds, txq->q.dma_addr);
  
        /* deallocate arrays */
        kfree(txq->cmd);
@@@ -295,7 -297,7 +295,7 @@@ static int iwl_queue_init(struct iwl_pr
  static int iwl_tx_queue_alloc(struct iwl_priv *priv,
                              struct iwl_tx_queue *txq, u32 id)
  {
 -      struct pci_dev *dev = priv->pci_dev;
 +      struct device *dev = &priv->pci_dev->dev;
        size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX;
  
        /* Driver private data, only for Tx (not command) queues,
  
        /* Circular buffer of transmit frame descriptors (TFDs),
         * shared with device */
 -      txq->tfds = pci_alloc_consistent(dev, tfd_sz, &txq->q.dma_addr);
 -
 +      txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr,
 +                                     GFP_KERNEL);
        if (!txq->tfds) {
                IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz);
                goto error;
@@@ -364,7 -366,7 +364,7 @@@ int iwl_tx_queue_init(struct iwl_priv *
        for (i = 0; i < actual_slots; i++) {
                /* only happens for cmd queue */
                if (i == slots_num)
-                       len += IWL_MAX_SCAN_SIZE;
+                       len = IWL_MAX_CMD_SIZE;
  
                txq->cmd[i] = kmalloc(len, GFP_KERNEL);
                if (!txq->cmd[i])
@@@ -743,6 -745,7 +743,6 @@@ int iwl_tx_skb(struct iwl_priv *priv, s
        u8 tid = 0;
        u8 *qc = NULL;
        unsigned long flags;
 -      int ret;
  
        spin_lock_irqsave(&priv->lock, flags);
        if (iwl_is_rfkill(priv)) {
                hdr->seq_ctrl |= cpu_to_le16(seq_number);
                seq_number += 0x10;
                /* aggregation is on for this <sta,tid> */
 -              if (info->flags & IEEE80211_TX_CTL_AMPDU)
 +              if (info->flags & IEEE80211_TX_CTL_AMPDU &&
 +                  priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) {
                        txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
 +              }
        }
  
        txq = &priv->txq[txq_id];
  
        /* Tell device the write index *just past* this latest filled TFD */
        q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
 -      ret = iwl_txq_update_write_ptr(priv, txq);
 +      iwl_txq_update_write_ptr(priv, txq);
        spin_unlock_irqrestore(&priv->lock, flags);
  
        /*
        if (sta_priv && sta_priv->client)
                atomic_inc(&sta_priv->pending_frames);
  
 -      if (ret)
 -              return ret;
 -
        if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) {
                if (wait_write_ptr) {
                        spin_lock_irqsave(&priv->lock, flags);
@@@ -1014,7 -1018,7 +1014,7 @@@ int iwl_enqueue_hcmd(struct iwl_priv *p
        struct iwl_cmd_meta *out_meta;
        dma_addr_t phys_addr;
        unsigned long flags;
 -      int len, ret;
 +      int len;
        u32 idx;
        u16 fix_size;
  
  
        /* If any of the command structures end up being larger than
         * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then
-        * we will need to increase the size of the TFD entries */
+        * we will need to increase the size of the TFD entries
+        * Also, check to see if command buffer should not exceed the size
+        * of device_cmd and max_cmd_size. */
        BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
               !(cmd->flags & CMD_SIZE_HUGE));
+       BUG_ON(fix_size > IWL_MAX_CMD_SIZE);
  
        if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) {
                IWL_WARN(priv, "Not sending command - %s KILL\n",
        if (cmd->flags & CMD_SIZE_HUGE)
                out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
        len = sizeof(struct iwl_device_cmd);
-       len += (idx == TFD_CMD_SLOTS) ?  IWL_MAX_SCAN_SIZE : 0;
+       if (idx == TFD_CMD_SLOTS)
+               len = IWL_MAX_CMD_SIZE;
  
  #ifdef CONFIG_IWLWIFI_DEBUG
        switch (out_cmd->hdr.cmd) {
  
        /* Increment and update queue's write index */
        q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
 -      ret = iwl_txq_update_write_ptr(priv, txq);
 +      iwl_txq_update_write_ptr(priv, txq);
  
        spin_unlock_irqrestore(&priv->hcmd_lock, flags);
 -      return ret ? ret : idx;
 +      return idx;
  }
  
  static void iwl_tx_status(struct iwl_priv *priv, struct sk_buff *skb)
@@@ -1256,8 -1263,6 +1259,8 @@@ void iwl_tx_cmd_complete(struct iwl_pri
  
        if (!(meta->flags & CMD_ASYNC)) {
                clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
 +              IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s \n",
 +                             get_cmd_string(cmd->hdr.cmd));
                wake_up_interruptible(&priv->wait_command_queue);
        }
  }
@@@ -1344,7 -1349,7 +1347,7 @@@ int iwl_tx_agg_stop(struct iwl_priv *pr
  {
        int tx_fifo_id, txq_id, sta_id, ssn = -1;
        struct iwl_tid_data *tid_data;
 -      int ret, write_ptr, read_ptr;
 +      int write_ptr, read_ptr;
        unsigned long flags;
  
        if (!ra) {
        priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
  
        spin_lock_irqsave(&priv->lock, flags);
 -      ret = priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn,
 +      /*
 +       * the only reason this call can fail is queue number out of range,
 +       * which can happen if uCode is reloaded and all the station
 +       * information are lost. if it is outside the range, there is no need
 +       * to deactivate the uCode queue, just return "success" to allow
 +       *  mac80211 to clean up it own data.
 +       */
 +      priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn,
                                                   tx_fifo_id);
        spin_unlock_irqrestore(&priv->lock, flags);
  
 -      if (ret)
 -              return ret;
 -
        ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid);
  
        return 0;