Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
This commit is contained in:
commit
324640e359
|
@ -568,7 +568,6 @@ enum iwl_scan_type {
|
||||||
*
|
*
|
||||||
* @tx_chains_num: Number of TX chains
|
* @tx_chains_num: Number of TX chains
|
||||||
* @rx_chains_num: Number of RX chains
|
* @rx_chains_num: Number of RX chains
|
||||||
* @sku: sku read from EEPROM
|
|
||||||
* @ct_kill_threshold: temperature threshold - in hw dependent unit
|
* @ct_kill_threshold: temperature threshold - in hw dependent unit
|
||||||
* @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit
|
* @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit
|
||||||
* relevant for 1000, 6000 and up
|
* relevant for 1000, 6000 and up
|
||||||
|
@ -579,7 +578,6 @@ struct iwl_hw_params {
|
||||||
u8 tx_chains_num;
|
u8 tx_chains_num;
|
||||||
u8 rx_chains_num;
|
u8 rx_chains_num;
|
||||||
bool use_rts_for_aggregation;
|
bool use_rts_for_aggregation;
|
||||||
u16 sku;
|
|
||||||
u32 ct_kill_threshold;
|
u32 ct_kill_threshold;
|
||||||
u32 ct_kill_exit_threshold;
|
u32 ct_kill_exit_threshold;
|
||||||
|
|
||||||
|
|
|
@ -250,17 +250,6 @@ struct iwl_lib_ops iwl2030_lib = {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* NIC configuration for 5000 series */
|
/* NIC configuration for 5000 series */
|
||||||
static void iwl5000_nic_config(struct iwl_priv *priv)
|
|
||||||
{
|
|
||||||
/* W/A : NIC is stuck in a reset state after Early PCIe power off
|
|
||||||
* (PCIe power is lost before PERST# is asserted),
|
|
||||||
* causing ME FW to lose ownership and not being able to obtain it back.
|
|
||||||
*/
|
|
||||||
iwl_set_bits_mask_prph(priv->trans, APMG_PS_CTRL_REG,
|
|
||||||
APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
|
|
||||||
~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct iwl_sensitivity_ranges iwl5000_sensitivity = {
|
static const struct iwl_sensitivity_ranges iwl5000_sensitivity = {
|
||||||
.min_nrg_cck = 100,
|
.min_nrg_cck = 100,
|
||||||
.auto_corr_min_ofdm = 90,
|
.auto_corr_min_ofdm = 90,
|
||||||
|
@ -433,14 +422,12 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
|
||||||
struct iwl_lib_ops iwl5000_lib = {
|
struct iwl_lib_ops iwl5000_lib = {
|
||||||
.set_hw_params = iwl5000_hw_set_hw_params,
|
.set_hw_params = iwl5000_hw_set_hw_params,
|
||||||
.set_channel_switch = iwl5000_hw_channel_switch,
|
.set_channel_switch = iwl5000_hw_channel_switch,
|
||||||
.nic_config = iwl5000_nic_config,
|
|
||||||
.temperature = iwlagn_temperature,
|
.temperature = iwlagn_temperature,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct iwl_lib_ops iwl5150_lib = {
|
struct iwl_lib_ops iwl5150_lib = {
|
||||||
.set_hw_params = iwl5150_hw_set_hw_params,
|
.set_hw_params = iwl5150_hw_set_hw_params,
|
||||||
.set_channel_switch = iwl5000_hw_channel_switch,
|
.set_channel_switch = iwl5000_hw_channel_switch,
|
||||||
.nic_config = iwl5000_nic_config,
|
|
||||||
.temperature = iwl5150_temperature,
|
.temperature = iwl5150_temperature,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
|
||||||
IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK |
|
IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK |
|
||||||
IWL_PAN_SCD_MULTICAST_MSK;
|
IWL_PAN_SCD_MULTICAST_MSK;
|
||||||
|
|
||||||
if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE)
|
if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE)
|
||||||
flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK;
|
flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK;
|
||||||
|
|
||||||
IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n",
|
IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n",
|
||||||
|
|
|
@ -164,7 +164,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
|
||||||
hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
|
hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE)
|
if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE)
|
||||||
hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
|
hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
|
||||||
IEEE80211_HW_SUPPORTS_STATIC_SMPS;
|
IEEE80211_HW_SUPPORTS_STATIC_SMPS;
|
||||||
|
|
||||||
|
@ -649,7 +649,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
|
||||||
IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
|
IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
|
||||||
sta->addr, tid);
|
sta->addr, tid);
|
||||||
|
|
||||||
if (!(priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE))
|
if (!(priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE))
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
|
||||||
IWL_DEBUG_MAC80211(priv, "enter\n");
|
IWL_DEBUG_MAC80211(priv, "enter\n");
|
||||||
|
@ -1036,8 +1036,18 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
|
||||||
mutex_lock(&priv->mutex);
|
mutex_lock(&priv->mutex);
|
||||||
|
|
||||||
if (test_bit(STATUS_SCAN_HW, &priv->status)) {
|
if (test_bit(STATUS_SCAN_HW, &priv->status)) {
|
||||||
err = -EBUSY;
|
/* mac80211 should not scan while ROC or ROC while scanning */
|
||||||
goto out;
|
if (WARN_ON_ONCE(priv->scan_type != IWL_SCAN_RADIO_RESET)) {
|
||||||
|
err = -EBUSY;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
iwl_scan_cancel_timeout(priv, 100);
|
||||||
|
|
||||||
|
if (test_bit(STATUS_SCAN_HW, &priv->status)) {
|
||||||
|
err = -EBUSY;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->hw_roc_channel = channel;
|
priv->hw_roc_channel = channel;
|
||||||
|
|
|
@ -51,11 +51,13 @@
|
||||||
#include "iwl-op-mode.h"
|
#include "iwl-op-mode.h"
|
||||||
#include "iwl-drv.h"
|
#include "iwl-drv.h"
|
||||||
#include "iwl-modparams.h"
|
#include "iwl-modparams.h"
|
||||||
|
#include "iwl-prph.h"
|
||||||
|
|
||||||
#include "dev.h"
|
#include "dev.h"
|
||||||
#include "calib.h"
|
#include "calib.h"
|
||||||
#include "agn.h"
|
#include "agn.h"
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* module boiler plate
|
* module boiler plate
|
||||||
|
@ -1185,9 +1187,6 @@ static void iwl_set_hw_params(struct iwl_priv *priv)
|
||||||
priv->hw_params.use_rts_for_aggregation =
|
priv->hw_params.use_rts_for_aggregation =
|
||||||
priv->cfg->ht_params->use_rts_for_aggregation;
|
priv->cfg->ht_params->use_rts_for_aggregation;
|
||||||
|
|
||||||
if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
|
|
||||||
priv->hw_params.sku &= ~EEPROM_SKU_CAP_11N_ENABLE;
|
|
||||||
|
|
||||||
/* Device-specific setup */
|
/* Device-specific setup */
|
||||||
priv->lib->set_hw_params(priv);
|
priv->lib->set_hw_params(priv);
|
||||||
}
|
}
|
||||||
|
@ -1232,20 +1231,20 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
|
||||||
{
|
{
|
||||||
u16 radio_cfg;
|
u16 radio_cfg;
|
||||||
|
|
||||||
priv->hw_params.sku = priv->eeprom_data->sku;
|
priv->eeprom_data->sku = priv->eeprom_data->sku;
|
||||||
|
|
||||||
if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE &&
|
if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE &&
|
||||||
!priv->cfg->ht_params) {
|
!priv->cfg->ht_params) {
|
||||||
IWL_ERR(priv, "Invalid 11n configuration\n");
|
IWL_ERR(priv, "Invalid 11n configuration\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!priv->hw_params.sku) {
|
if (!priv->eeprom_data->sku) {
|
||||||
IWL_ERR(priv, "Invalid device sku\n");
|
IWL_ERR(priv, "Invalid device sku\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
IWL_INFO(priv, "Device SKU: 0x%X\n", priv->hw_params.sku);
|
IWL_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku);
|
||||||
|
|
||||||
radio_cfg = priv->eeprom_data->radio_cfg;
|
radio_cfg = priv->eeprom_data->radio_cfg;
|
||||||
|
|
||||||
|
@ -1352,6 +1351,9 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||||
trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED;
|
trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED;
|
||||||
trans_cfg.command_names = iwl_dvm_cmd_strings;
|
trans_cfg.command_names = iwl_dvm_cmd_strings;
|
||||||
|
|
||||||
|
WARN_ON(sizeof(priv->transport_queue_stop) * BITS_PER_BYTE <
|
||||||
|
priv->cfg->base_params->num_of_queues);
|
||||||
|
|
||||||
ucode_flags = fw->ucode_capa.flags;
|
ucode_flags = fw->ucode_capa.flags;
|
||||||
|
|
||||||
#ifndef CONFIG_IWLWIFI_P2P
|
#ifndef CONFIG_IWLWIFI_P2P
|
||||||
|
@ -1448,7 +1450,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||||
************************/
|
************************/
|
||||||
iwl_set_hw_params(priv);
|
iwl_set_hw_params(priv);
|
||||||
|
|
||||||
if (!(priv->hw_params.sku & EEPROM_SKU_CAP_IPAN_ENABLE)) {
|
if (!(priv->eeprom_data->sku & EEPROM_SKU_CAP_IPAN_ENABLE)) {
|
||||||
IWL_DEBUG_INFO(priv, "Your EEPROM disabled PAN");
|
IWL_DEBUG_INFO(priv, "Your EEPROM disabled PAN");
|
||||||
ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
|
ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
|
||||||
/*
|
/*
|
||||||
|
@ -2073,7 +2075,16 @@ static void iwl_nic_config(struct iwl_op_mode *op_mode)
|
||||||
CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
|
CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
|
||||||
CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
|
CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
|
||||||
|
|
||||||
priv->lib->nic_config(priv);
|
/* W/A : NIC is stuck in a reset state after Early PCIe power off
|
||||||
|
* (PCIe power is lost before PERST# is asserted),
|
||||||
|
* causing ME FW to lose ownership and not being able to obtain it back.
|
||||||
|
*/
|
||||||
|
iwl_set_bits_mask_prph(priv->trans, APMG_PS_CTRL_REG,
|
||||||
|
APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
|
||||||
|
~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
|
||||||
|
|
||||||
|
if (priv->lib->nic_config)
|
||||||
|
priv->lib->nic_config(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iwl_wimax_active(struct iwl_op_mode *op_mode)
|
static void iwl_wimax_active(struct iwl_op_mode *op_mode)
|
||||||
|
|
|
@ -51,6 +51,9 @@
|
||||||
#define IWL_CHANNEL_TUNE_TIME 5
|
#define IWL_CHANNEL_TUNE_TIME 5
|
||||||
#define MAX_SCAN_CHANNEL 50
|
#define MAX_SCAN_CHANNEL 50
|
||||||
|
|
||||||
|
/* For reset radio, need minimal dwell time only */
|
||||||
|
#define IWL_RADIO_RESET_DWELL_TIME 5
|
||||||
|
|
||||||
static int iwl_send_scan_abort(struct iwl_priv *priv)
|
static int iwl_send_scan_abort(struct iwl_priv *priv)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -469,45 +472,39 @@ static u8 iwl_get_single_channel_number(struct iwl_priv *priv,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
|
static int iwl_get_channel_for_reset_scan(struct iwl_priv *priv,
|
||||||
struct ieee80211_vif *vif,
|
struct ieee80211_vif *vif,
|
||||||
enum ieee80211_band band,
|
enum ieee80211_band band,
|
||||||
struct iwl_scan_channel *scan_ch)
|
struct iwl_scan_channel *scan_ch)
|
||||||
{
|
{
|
||||||
const struct ieee80211_supported_band *sband;
|
const struct ieee80211_supported_band *sband;
|
||||||
u16 passive_dwell = 0;
|
u16 channel;
|
||||||
u16 active_dwell = 0;
|
|
||||||
int added = 0;
|
|
||||||
u16 channel = 0;
|
|
||||||
|
|
||||||
sband = iwl_get_hw_mode(priv, band);
|
sband = iwl_get_hw_mode(priv, band);
|
||||||
if (!sband) {
|
if (!sband) {
|
||||||
IWL_ERR(priv, "invalid band\n");
|
IWL_ERR(priv, "invalid band\n");
|
||||||
return added;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
active_dwell = iwl_get_active_dwell_time(priv, band, 0);
|
|
||||||
passive_dwell = iwl_get_passive_dwell_time(priv, band);
|
|
||||||
|
|
||||||
if (passive_dwell <= active_dwell)
|
|
||||||
passive_dwell = active_dwell + 1;
|
|
||||||
|
|
||||||
channel = iwl_get_single_channel_number(priv, band);
|
channel = iwl_get_single_channel_number(priv, band);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
scan_ch->channel = cpu_to_le16(channel);
|
scan_ch->channel = cpu_to_le16(channel);
|
||||||
scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
|
scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
|
||||||
scan_ch->active_dwell = cpu_to_le16(active_dwell);
|
scan_ch->active_dwell =
|
||||||
scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
|
cpu_to_le16(IWL_RADIO_RESET_DWELL_TIME);
|
||||||
|
scan_ch->passive_dwell =
|
||||||
|
cpu_to_le16(IWL_RADIO_RESET_DWELL_TIME);
|
||||||
/* Set txpower levels to defaults */
|
/* Set txpower levels to defaults */
|
||||||
scan_ch->dsp_atten = 110;
|
scan_ch->dsp_atten = 110;
|
||||||
if (band == IEEE80211_BAND_5GHZ)
|
if (band == IEEE80211_BAND_5GHZ)
|
||||||
scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
|
scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
|
||||||
else
|
else
|
||||||
scan_ch->tx_gain = ((1 << 5) | (5 << 3));
|
scan_ch->tx_gain = ((1 << 5) | (5 << 3));
|
||||||
added++;
|
return 1;
|
||||||
} else
|
}
|
||||||
IWL_ERR(priv, "no valid channel found\n");
|
|
||||||
return added;
|
IWL_ERR(priv, "no valid channel found\n");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iwl_get_channels_for_scan(struct iwl_priv *priv,
|
static int iwl_get_channels_for_scan(struct iwl_priv *priv,
|
||||||
|
@ -896,7 +893,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
|
||||||
switch (priv->scan_type) {
|
switch (priv->scan_type) {
|
||||||
case IWL_SCAN_RADIO_RESET:
|
case IWL_SCAN_RADIO_RESET:
|
||||||
scan->channel_count =
|
scan->channel_count =
|
||||||
iwl_get_single_channel_for_scan(priv, vif, band,
|
iwl_get_channel_for_reset_scan(priv, vif, band,
|
||||||
(void *)&scan->data[cmd_len]);
|
(void *)&scan->data[cmd_len]);
|
||||||
break;
|
break;
|
||||||
case IWL_SCAN_NORMAL:
|
case IWL_SCAN_NORMAL:
|
||||||
|
|
|
@ -853,6 +853,9 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
|
||||||
EEPROM_RADIO_CONFIG);
|
EEPROM_RADIO_CONFIG);
|
||||||
data->sku = iwl_eeprom_query16(eeprom, eeprom_size,
|
data->sku = iwl_eeprom_query16(eeprom, eeprom_size,
|
||||||
EEPROM_SKU_CAP);
|
EEPROM_SKU_CAP);
|
||||||
|
if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
|
||||||
|
data->sku &= ~EEPROM_SKU_CAP_11N_ENABLE;
|
||||||
|
|
||||||
data->eeprom_version = iwl_eeprom_query16(eeprom, eeprom_size,
|
data->eeprom_version = iwl_eeprom_query16(eeprom, eeprom_size,
|
||||||
EEPROM_VERSION);
|
EEPROM_VERSION);
|
||||||
|
|
||||||
|
|
|
@ -121,13 +121,12 @@ EXPORT_SYMBOL_GPL(iwl_notification_wait_notify);
|
||||||
|
|
||||||
void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait)
|
void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct iwl_notification_wait *wait_entry;
|
struct iwl_notification_wait *wait_entry;
|
||||||
|
|
||||||
spin_lock_irqsave(¬if_wait->notif_wait_lock, flags);
|
spin_lock(¬if_wait->notif_wait_lock);
|
||||||
list_for_each_entry(wait_entry, ¬if_wait->notif_waits, list)
|
list_for_each_entry(wait_entry, ¬if_wait->notif_waits, list)
|
||||||
wait_entry->aborted = true;
|
wait_entry->aborted = true;
|
||||||
spin_unlock_irqrestore(¬if_wait->notif_wait_lock, flags);
|
spin_unlock(¬if_wait->notif_wait_lock);
|
||||||
|
|
||||||
wake_up_all(¬if_wait->notif_waitq);
|
wake_up_all(¬if_wait->notif_waitq);
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,22 +111,25 @@ struct iwl_cfg;
|
||||||
* May sleep
|
* May sleep
|
||||||
* @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the
|
* @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the
|
||||||
* HCMD the this Rx responds to.
|
* HCMD the this Rx responds to.
|
||||||
* Must be atomic.
|
* Must be atomic and called with BH disabled.
|
||||||
* @queue_full: notifies that a HW queue is full.
|
* @queue_full: notifies that a HW queue is full.
|
||||||
* Must be atomic
|
* Must be atomic and called with BH disabled.
|
||||||
* @queue_not_full: notifies that a HW queue is not full any more.
|
* @queue_not_full: notifies that a HW queue is not full any more.
|
||||||
* Must be atomic
|
* Must be atomic and called with BH disabled.
|
||||||
* @hw_rf_kill:notifies of a change in the HW rf kill switch. True means that
|
* @hw_rf_kill:notifies of a change in the HW rf kill switch. True means that
|
||||||
* the radio is killed. Must be atomic.
|
* the radio is killed. Must be atomic.
|
||||||
* @free_skb: allows the transport layer to free skbs that haven't been
|
* @free_skb: allows the transport layer to free skbs that haven't been
|
||||||
* reclaimed by the op_mode. This can happen when the driver is freed and
|
* reclaimed by the op_mode. This can happen when the driver is freed and
|
||||||
* there are Tx packets pending in the transport layer.
|
* there are Tx packets pending in the transport layer.
|
||||||
* Must be atomic
|
* Must be atomic
|
||||||
* @nic_error: error notification. Must be atomic
|
* @nic_error: error notification. Must be atomic and must be called with BH
|
||||||
* @cmd_queue_full: Called when the command queue gets full. Must be atomic.
|
* disabled.
|
||||||
|
* @cmd_queue_full: Called when the command queue gets full. Must be atomic and
|
||||||
|
* called with BH disabled.
|
||||||
* @nic_config: configure NIC, called before firmware is started.
|
* @nic_config: configure NIC, called before firmware is started.
|
||||||
* May sleep
|
* May sleep
|
||||||
* @wimax_active: invoked when WiMax becomes active. Must be atomic.
|
* @wimax_active: invoked when WiMax becomes active. Must be atomic and called
|
||||||
|
* with BH disabled.
|
||||||
*/
|
*/
|
||||||
struct iwl_op_mode_ops {
|
struct iwl_op_mode_ops {
|
||||||
struct iwl_op_mode *(*start)(struct iwl_trans *trans,
|
struct iwl_op_mode *(*start)(struct iwl_trans *trans,
|
||||||
|
@ -165,7 +168,6 @@ struct iwl_op_mode {
|
||||||
static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode)
|
static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode)
|
||||||
{
|
{
|
||||||
might_sleep();
|
might_sleep();
|
||||||
|
|
||||||
op_mode->ops->stop(op_mode);
|
op_mode->ops->stop(op_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -867,24 +867,23 @@ void iwl_disable_ict(struct iwl_trans *trans)
|
||||||
spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
|
spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* legacy (non-ICT) ISR. Assumes that trans_pcie->irq_lock is held */
|
||||||
static irqreturn_t iwl_isr(int irq, void *data)
|
static irqreturn_t iwl_isr(int irq, void *data)
|
||||||
{
|
{
|
||||||
struct iwl_trans *trans = data;
|
struct iwl_trans *trans = data;
|
||||||
struct iwl_trans_pcie *trans_pcie;
|
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||||
u32 inta, inta_mask;
|
u32 inta, inta_mask;
|
||||||
unsigned long flags;
|
|
||||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||||
u32 inta_fh;
|
u32 inta_fh;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
lockdep_assert_held(&trans_pcie->irq_lock);
|
||||||
|
|
||||||
if (!trans)
|
if (!trans)
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
|
|
||||||
trace_iwlwifi_dev_irq(trans->dev);
|
trace_iwlwifi_dev_irq(trans->dev);
|
||||||
|
|
||||||
trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&trans_pcie->irq_lock, flags);
|
|
||||||
|
|
||||||
/* Disable (but don't clear!) interrupts here to avoid
|
/* Disable (but don't clear!) interrupts here to avoid
|
||||||
* back-to-back ISRs and sporadic interrupts from our NIC.
|
* back-to-back ISRs and sporadic interrupts from our NIC.
|
||||||
* If we have something to service, the tasklet will re-enable ints.
|
* If we have something to service, the tasklet will re-enable ints.
|
||||||
|
@ -907,7 +906,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
|
||||||
/* Hardware disappeared. It might have already raised
|
/* Hardware disappeared. It might have already raised
|
||||||
* an interrupt */
|
* an interrupt */
|
||||||
IWL_WARN(trans, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
|
IWL_WARN(trans, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
|
||||||
goto unplugged;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||||
|
@ -926,18 +925,13 @@ static irqreturn_t iwl_isr(int irq, void *data)
|
||||||
!trans_pcie->inta)
|
!trans_pcie->inta)
|
||||||
iwl_enable_interrupts(trans);
|
iwl_enable_interrupts(trans);
|
||||||
|
|
||||||
unplugged:
|
none:
|
||||||
spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
|
|
||||||
none:
|
|
||||||
/* re-enable interrupts here since we don't have anything to service. */
|
/* re-enable interrupts here since we don't have anything to service. */
|
||||||
/* only Re-enable if disabled by irq and no schedules tasklet. */
|
/* only Re-enable if disabled by irq and no schedules tasklet. */
|
||||||
if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
|
if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
|
||||||
!trans_pcie->inta)
|
!trans_pcie->inta)
|
||||||
iwl_enable_interrupts(trans);
|
iwl_enable_interrupts(trans);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
|
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -963,15 +957,19 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
|
||||||
|
|
||||||
trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&trans_pcie->irq_lock, flags);
|
||||||
|
|
||||||
/* dram interrupt table not set yet,
|
/* dram interrupt table not set yet,
|
||||||
* use legacy interrupt.
|
* use legacy interrupt.
|
||||||
*/
|
*/
|
||||||
if (!trans_pcie->use_ict)
|
if (unlikely(!trans_pcie->use_ict)) {
|
||||||
return iwl_isr(irq, data);
|
irqreturn_t ret = iwl_isr(irq, data);
|
||||||
|
spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
trace_iwlwifi_dev_irq(trans->dev);
|
trace_iwlwifi_dev_irq(trans->dev);
|
||||||
|
|
||||||
spin_lock_irqsave(&trans_pcie->irq_lock, flags);
|
|
||||||
|
|
||||||
/* Disable (but don't clear!) interrupts here to avoid
|
/* Disable (but don't clear!) interrupts here to avoid
|
||||||
* back-to-back ISRs and sporadic interrupts from our NIC.
|
* back-to-back ISRs and sporadic interrupts from our NIC.
|
||||||
|
|
|
@ -296,6 +296,7 @@ static void iwlagn_free_dma_ptr(struct iwl_trans *trans,
|
||||||
static void iwl_trans_pcie_queue_stuck_timer(unsigned long data)
|
static void iwl_trans_pcie_queue_stuck_timer(unsigned long data)
|
||||||
{
|
{
|
||||||
struct iwl_tx_queue *txq = (void *)data;
|
struct iwl_tx_queue *txq = (void *)data;
|
||||||
|
struct iwl_queue *q = &txq->q;
|
||||||
struct iwl_trans_pcie *trans_pcie = txq->trans_pcie;
|
struct iwl_trans_pcie *trans_pcie = txq->trans_pcie;
|
||||||
struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie);
|
struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie);
|
||||||
u32 scd_sram_addr = trans_pcie->scd_base_addr +
|
u32 scd_sram_addr = trans_pcie->scd_base_addr +
|
||||||
|
@ -346,6 +347,14 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data)
|
||||||
iwl_read_prph(trans, SCD_QUEUE_WRPTR(i)));
|
iwl_read_prph(trans, SCD_QUEUE_WRPTR(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = q->read_ptr; i != q->write_ptr;
|
||||||
|
i = iwl_queue_inc_wrap(i, q->n_bd)) {
|
||||||
|
struct iwl_tx_cmd *tx_cmd =
|
||||||
|
(struct iwl_tx_cmd *)txq->entries[i].cmd->payload;
|
||||||
|
IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
|
||||||
|
get_unaligned_le32(&tx_cmd->scratch));
|
||||||
|
}
|
||||||
|
|
||||||
iwl_op_mode_nic_error(trans->op_mode);
|
iwl_op_mode_nic_error(trans->op_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1037,15 +1046,12 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
|
* Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
|
||||||
* must be called under the irq lock and with MAC access
|
|
||||||
*/
|
*/
|
||||||
static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask)
|
static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask)
|
||||||
{
|
{
|
||||||
struct iwl_trans_pcie __maybe_unused *trans_pcie =
|
struct iwl_trans_pcie __maybe_unused *trans_pcie =
|
||||||
IWL_TRANS_GET_PCIE_TRANS(trans);
|
IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||||
|
|
||||||
lockdep_assert_held(&trans_pcie->irq_lock);
|
|
||||||
|
|
||||||
iwl_write_prph(trans, SCD_TXFACT, mask);
|
iwl_write_prph(trans, SCD_TXFACT, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1053,12 +1059,9 @@ static void iwl_tx_start(struct iwl_trans *trans)
|
||||||
{
|
{
|
||||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||||
u32 a;
|
u32 a;
|
||||||
unsigned long flags;
|
|
||||||
int i, chan;
|
int i, chan;
|
||||||
u32 reg_val;
|
u32 reg_val;
|
||||||
|
|
||||||
spin_lock_irqsave(&trans_pcie->irq_lock, flags);
|
|
||||||
|
|
||||||
/* make sure all queue are not stopped/used */
|
/* make sure all queue are not stopped/used */
|
||||||
memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped));
|
memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped));
|
||||||
memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used));
|
memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used));
|
||||||
|
@ -1109,8 +1112,6 @@ static void iwl_tx_start(struct iwl_trans *trans)
|
||||||
iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG,
|
iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG,
|
||||||
reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
|
reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
|
|
||||||
|
|
||||||
/* Enable L1-Active */
|
/* Enable L1-Active */
|
||||||
iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG,
|
iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG,
|
||||||
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
|
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
|
||||||
|
@ -2017,7 +2018,9 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
|
||||||
if (!trans->op_mode)
|
if (!trans->op_mode)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
|
local_bh_disable();
|
||||||
iwl_op_mode_nic_error(trans->op_mode);
|
iwl_op_mode_nic_error(trans->op_mode);
|
||||||
|
local_bh_enable();
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue