iwlwifi: fix erroneous use of iwl_rx_packet.len as a length
[pandora-kernel.git] / drivers / net / wireless / iwlwifi / iwl-core.c
index 202bc39..f4c2431 100644 (file)
@@ -394,7 +394,8 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
 
        ht_info->ht_supported = true;
 
-       ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
+       if (priv->cfg->ht_greenfield_support)
+               ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
        ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
        ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
                             (WLAN_HT_CAP_SM_PS_DISABLED << 2));
@@ -1343,17 +1344,10 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
        u32 desc, time, count, base, data1;
        u32 blink1, blink2, ilink1, ilink2;
 
-       switch (priv->ucode_type) {
-       case UCODE_RT:
-               base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
-               break;
-       case UCODE_INIT:
+       if (priv->ucode_type == UCODE_INIT)
                base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
-               break;
-       default:
-               IWL_ERR(priv, "uCode image not available\n");
-               return;
-       }
+       else
+               base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
 
        if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
                IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
@@ -1405,17 +1399,10 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
 
        if (num_events == 0)
                return;
-       switch (priv->ucode_type) {
-       case UCODE_RT:
-               base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
-               break;
-       case UCODE_INIT:
+       if (priv->ucode_type == UCODE_INIT)
                base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
-               break;
-       default:
-               IWL_ERR(priv, "uCode image not available\n");
-               return;
-       }
+       else
+               base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
 
        if (mode == 0)
                event_size = 2 * sizeof(u32);
@@ -1452,17 +1439,10 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
        u32 next_entry; /* index of next entry to be written by uCode */
        u32 size;       /* # entries that we'll print */
 
-       switch (priv->ucode_type) {
-       case UCODE_RT:
-               base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
-               break;
-       case UCODE_INIT:
+       if (priv->ucode_type == UCODE_INIT)
                base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
-               break;
-       default:
-               IWL_ERR(priv, "uCode image not available\n");
-               return;
-       }
+       else
+               base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
 
        if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
                IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
@@ -1589,7 +1569,8 @@ int iwl_setup_mac(struct iwl_priv *priv)
                    IEEE80211_HW_NOISE_DBM |
                    IEEE80211_HW_AMPDU_AGGREGATION |
                    IEEE80211_HW_SPECTRUM_MGMT |
-                   IEEE80211_HW_SUPPORTS_PS;
+                   IEEE80211_HW_SUPPORTS_PS |
+                   IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
        hw->wiphy->interface_modes =
                BIT(NL80211_IFTYPE_STATION) |
                BIT(NL80211_IFTYPE_ADHOC);
@@ -1684,8 +1665,6 @@ int iwl_init_drv(struct iwl_priv *priv)
        priv->qos_data.qos_cap.val = 0;
 
        priv->rates_mask = IWL_RATES_MASK;
-       /* If power management is turned on, default to CAM mode */
-       priv->power_mode = IWL_POWER_MODE_CAM;
        priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MAX;
 
        ret = iwl_init_channel_map(priv);
@@ -2235,7 +2214,7 @@ void iwl_rf_kill_ct_config(struct iwl_priv *priv)
        iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
                    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
        spin_unlock_irqrestore(&priv->lock, flags);
-       priv->power_data.ct_kill_toggle = false;
+       priv->thermal_throttle.ct_kill_toggle = false;
 
        switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
        case CSR_HW_REV_TYPE_1000:
@@ -2248,6 +2227,15 @@ void iwl_rf_kill_ct_config(struct iwl_priv *priv)
 
                ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
                                       sizeof(adv_cmd), &adv_cmd);
+               if (ret)
+                       IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
+               else
+                       IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
+                                       "succeeded, "
+                                       "critical temperature enter is %d,"
+                                       "exit is %d\n",
+                                      priv->hw_params.ct_kill_threshold,
+                                      priv->hw_params.ct_kill_exit_threshold);
                break;
        default:
                cmd.critical_temperature_R =
@@ -2255,16 +2243,15 @@ void iwl_rf_kill_ct_config(struct iwl_priv *priv)
 
                ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
                                       sizeof(cmd), &cmd);
+               if (ret)
+                       IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
+               else
+                       IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
+                                       "succeeded, "
+                                       "critical temperature is %d\n",
+                                       priv->hw_params.ct_kill_threshold);
                break;
        }
-       ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
-                              sizeof(cmd), &cmd);
-       if (ret)
-               IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
-       else
-               IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD succeeded, "
-                       "critical temperature is %d\n",
-                       cmd.critical_temperature_R);
 }
 EXPORT_SYMBOL(iwl_rf_kill_ct_config);
 
@@ -2307,10 +2294,11 @@ void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
                                      struct iwl_rx_mem_buffer *rxb)
 {
        struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+       u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
        IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
-                       "notification for %s:\n",
-                       le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
-       iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+                       "notification for %s:\n", len,
+                       get_cmd_string(pkt->hdr.cmd));
+       iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len);
 }
 EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif);
 
@@ -2405,39 +2393,10 @@ static void iwl_ht_conf(struct iwl_priv *priv,
        }
        ht_conf = &sta->ht_cap;
 
-       if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
-               iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
-       if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
-               iwl_conf->sgf |= HT_SHORT_GI_40MHZ;
-
-       iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
-       iwl_conf->max_amsdu_size =
-               !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
-
-       iwl_conf->supported_chan_width =
-               !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
-
-       /*
-        * XXX: The HT configuration needs to be moved into iwl_mac_config()
-        *      to be done there correctly.
-        */
-
-       iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
-       if (conf_is_ht40_minus(&priv->hw->conf))
-               iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
-       else if (conf_is_ht40_plus(&priv->hw->conf))
-               iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
-
-       /* If no above or below channel supplied disable HT40 channel */
-       if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE &&
-           iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW)
-               iwl_conf->supported_chan_width = 0;
-
        iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
 
        memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16);
 
-       iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0;
        iwl_conf->ht_protection =
                bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
        iwl_conf->non_GF_STA_present =
@@ -2564,7 +2523,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
                if (bss_conf->assoc) {
                        priv->assoc_id = bss_conf->aid;
                        priv->beacon_int = bss_conf->beacon_int;
-                       priv->power_data.dtim_period = bss_conf->dtim_period;
                        priv->timestamp = bss_conf->timestamp;
                        priv->assoc_capability = bss_conf->assoc_capability;
 
@@ -2751,6 +2709,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
        struct iwl_priv *priv = hw->priv;
        const struct iwl_channel_info *ch_info;
        struct ieee80211_conf *conf = &hw->conf;
+       struct iwl_ht_info *ht_conf = &priv->current_ht_config;
        unsigned long flags = 0;
        int ret = 0;
        u16 ch;
@@ -2792,10 +2751,32 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
                        goto set_ch_out;
                }
 
-               priv->current_ht_config.is_ht = conf_is_ht(conf);
-
                spin_lock_irqsave(&priv->lock, flags);
 
+               /* Configure HT40 channels */
+               ht_conf->is_ht = conf_is_ht(conf);
+               if (ht_conf->is_ht) {
+                       if (conf_is_ht40_minus(conf)) {
+                               ht_conf->extension_chan_offset =
+                                       IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+                               ht_conf->supported_chan_width =
+                                       IWL_CHANNEL_WIDTH_40MHZ;
+                       } else if (conf_is_ht40_plus(conf)) {
+                               ht_conf->extension_chan_offset =
+                                       IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+                               ht_conf->supported_chan_width =
+                                       IWL_CHANNEL_WIDTH_40MHZ;
+                       } else {
+                               ht_conf->extension_chan_offset =
+                                       IEEE80211_HT_PARAM_CHA_SEC_NONE;
+                               ht_conf->supported_chan_width =
+                                       IWL_CHANNEL_WIDTH_20MHZ;
+                       }
+               } else
+                       ht_conf->supported_chan_width = IWL_CHANNEL_WIDTH_20MHZ;
+               /* Default to no protection. Protection mode will later be set
+                * from BSS config in iwl_ht_conf */
+               ht_conf->ht_protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
 
                /* if we are switching from ht to 2.4 clear flags
                 * from any ht related info since 2.4 does not
@@ -2814,13 +2795,10 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
                iwl_set_rate(priv);
        }
 
-       if (changed & IEEE80211_CONF_CHANGE_PS &&
-           priv->iw_mode == NL80211_IFTYPE_STATION) {
-               priv->power_data.power_disabled =
-                       !(conf->flags & IEEE80211_CONF_PS);
-               ret = iwl_power_update_mode(priv, 0);
+       if (changed & IEEE80211_CONF_CHANGE_PS) {
+               ret = iwl_power_update_mode(priv, false);
                if (ret)
-                       IWL_DEBUG_MAC80211(priv, "Error setting power level\n");
+                       IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
        }
 
        if (changed & IEEE80211_CONF_CHANGE_POWER) {
@@ -3193,22 +3171,6 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
        }
 }
 EXPORT_SYMBOL(iwl_update_stats);
-
-#else
-void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
-{
-       struct traffic_stats    *stats;
-
-       if (is_tx)
-               stats = &priv->tx_stats;
-       else
-               stats = &priv->rx_stats;
-
-       if (ieee80211_is_data(fc)) {
-               /* data */
-               stats->data_bytes += len;
-       }
-}
 #endif
 
 #ifdef CONFIG_PM