Commit 840fd8ff authored by John W. Linville's avatar John W. Linville

Merge branch 'wireless-next-2.6' of...

Merge branch 'wireless-next-2.6' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6
parents b84a7d3d 9e2e7422
...@@ -278,7 +278,6 @@ struct iwl_cfg iwl1000_bgn_cfg = { ...@@ -278,7 +278,6 @@ struct iwl_cfg iwl1000_bgn_cfg = {
.fw_name_pre = IWL1000_FW_PRE, .fw_name_pre = IWL1000_FW_PRE,
.ucode_api_max = IWL1000_UCODE_API_MAX, .ucode_api_max = IWL1000_UCODE_API_MAX,
.ucode_api_min = IWL1000_UCODE_API_MIN, .ucode_api_min = IWL1000_UCODE_API_MIN,
.sku = IWL_SKU_G|IWL_SKU_N,
.valid_tx_ant = ANT_A, .valid_tx_ant = ANT_A,
.valid_rx_ant = ANT_AB, .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
...@@ -287,6 +286,7 @@ struct iwl_cfg iwl1000_bgn_cfg = { ...@@ -287,6 +286,7 @@ struct iwl_cfg iwl1000_bgn_cfg = {
.mod_params = &iwlagn_mod_params, .mod_params = &iwlagn_mod_params,
.base_params = &iwl1000_base_params, .base_params = &iwl1000_base_params,
.ht_params = &iwl1000_ht_params, .ht_params = &iwl1000_ht_params,
.led_mode = IWL_LED_BLINK,
}; };
struct iwl_cfg iwl1000_bg_cfg = { struct iwl_cfg iwl1000_bg_cfg = {
...@@ -294,7 +294,6 @@ struct iwl_cfg iwl1000_bg_cfg = { ...@@ -294,7 +294,6 @@ struct iwl_cfg iwl1000_bg_cfg = {
.fw_name_pre = IWL1000_FW_PRE, .fw_name_pre = IWL1000_FW_PRE,
.ucode_api_max = IWL1000_UCODE_API_MAX, .ucode_api_max = IWL1000_UCODE_API_MAX,
.ucode_api_min = IWL1000_UCODE_API_MIN, .ucode_api_min = IWL1000_UCODE_API_MIN,
.sku = IWL_SKU_G,
.valid_tx_ant = ANT_A, .valid_tx_ant = ANT_A,
.valid_rx_ant = ANT_AB, .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
...@@ -302,6 +301,7 @@ struct iwl_cfg iwl1000_bg_cfg = { ...@@ -302,6 +301,7 @@ struct iwl_cfg iwl1000_bg_cfg = {
.ops = &iwl1000_ops, .ops = &iwl1000_ops,
.mod_params = &iwlagn_mod_params, .mod_params = &iwlagn_mod_params,
.base_params = &iwl1000_base_params, .base_params = &iwl1000_base_params,
.led_mode = IWL_LED_BLINK,
}; };
struct iwl_cfg iwl100_bgn_cfg = { struct iwl_cfg iwl100_bgn_cfg = {
...@@ -309,7 +309,6 @@ struct iwl_cfg iwl100_bgn_cfg = { ...@@ -309,7 +309,6 @@ struct iwl_cfg iwl100_bgn_cfg = {
.fw_name_pre = IWL100_FW_PRE, .fw_name_pre = IWL100_FW_PRE,
.ucode_api_max = IWL100_UCODE_API_MAX, .ucode_api_max = IWL100_UCODE_API_MAX,
.ucode_api_min = IWL100_UCODE_API_MIN, .ucode_api_min = IWL100_UCODE_API_MIN,
.sku = IWL_SKU_G|IWL_SKU_N,
.valid_tx_ant = ANT_A, .valid_tx_ant = ANT_A,
.valid_rx_ant = ANT_A, .valid_rx_ant = ANT_A,
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
...@@ -318,6 +317,7 @@ struct iwl_cfg iwl100_bgn_cfg = { ...@@ -318,6 +317,7 @@ struct iwl_cfg iwl100_bgn_cfg = {
.mod_params = &iwlagn_mod_params, .mod_params = &iwlagn_mod_params,
.base_params = &iwl1000_base_params, .base_params = &iwl1000_base_params,
.ht_params = &iwl1000_ht_params, .ht_params = &iwl1000_ht_params,
.led_mode = IWL_LED_RF_STATE,
}; };
struct iwl_cfg iwl100_bg_cfg = { struct iwl_cfg iwl100_bg_cfg = {
...@@ -325,7 +325,6 @@ struct iwl_cfg iwl100_bg_cfg = { ...@@ -325,7 +325,6 @@ struct iwl_cfg iwl100_bg_cfg = {
.fw_name_pre = IWL100_FW_PRE, .fw_name_pre = IWL100_FW_PRE,
.ucode_api_max = IWL100_UCODE_API_MAX, .ucode_api_max = IWL100_UCODE_API_MAX,
.ucode_api_min = IWL100_UCODE_API_MIN, .ucode_api_min = IWL100_UCODE_API_MIN,
.sku = IWL_SKU_G,
.valid_tx_ant = ANT_A, .valid_tx_ant = ANT_A,
.valid_rx_ant = ANT_A, .valid_rx_ant = ANT_A,
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
...@@ -333,6 +332,7 @@ struct iwl_cfg iwl100_bg_cfg = { ...@@ -333,6 +332,7 @@ struct iwl_cfg iwl100_bg_cfg = {
.ops = &iwl1000_ops, .ops = &iwl1000_ops,
.mod_params = &iwlagn_mod_params, .mod_params = &iwlagn_mod_params,
.base_params = &iwl1000_base_params, .base_params = &iwl1000_base_params,
.led_mode = IWL_LED_RF_STATE,
}; };
MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
......
...@@ -297,7 +297,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, ...@@ -297,7 +297,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) && if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) &&
(txq_id != IWL39_CMD_QUEUE_NUM) && (txq_id != IWL39_CMD_QUEUE_NUM) &&
priv->mac80211_registered) priv->mac80211_registered)
iwl_wake_queue(priv, txq_id); iwl_wake_queue(priv, txq);
} }
/** /**
...@@ -2788,6 +2788,7 @@ static struct iwl_cfg iwl3945_bg_cfg = { ...@@ -2788,6 +2788,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
.ops = &iwl3945_ops, .ops = &iwl3945_ops,
.mod_params = &iwl3945_mod_params, .mod_params = &iwl3945_mod_params,
.base_params = &iwl3945_base_params, .base_params = &iwl3945_base_params,
.led_mode = IWL_LED_BLINK,
}; };
static struct iwl_cfg iwl3945_abg_cfg = { static struct iwl_cfg iwl3945_abg_cfg = {
...@@ -2800,6 +2801,7 @@ static struct iwl_cfg iwl3945_abg_cfg = { ...@@ -2800,6 +2801,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
.ops = &iwl3945_ops, .ops = &iwl3945_ops,
.mod_params = &iwl3945_mod_params, .mod_params = &iwl3945_mod_params,
.base_params = &iwl3945_base_params, .base_params = &iwl3945_base_params,
.led_mode = IWL_LED_BLINK,
}; };
DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
......
...@@ -2238,12 +2238,8 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, ...@@ -2238,12 +2238,8 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
if (priv->mac80211_registered && if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark) && (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
(agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) { (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
if (agg->state == IWL_AGG_OFF) iwl_wake_queue(priv, txq);
iwl_wake_queue(priv, txq_id);
else
iwl_wake_queue(priv, txq->swq_id);
}
} }
} else { } else {
info->status.rates[0].count = tx_resp->failure_frame + 1; info->status.rates[0].count = tx_resp->failure_frame + 1;
...@@ -2267,7 +2263,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, ...@@ -2267,7 +2263,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
if (priv->mac80211_registered && if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark)) (iwl_queue_space(&txq->q) > txq->q.low_mark))
iwl_wake_queue(priv, txq_id); iwl_wake_queue(priv, txq);
} }
if (qc && likely(sta_id != IWL_INVALID_STATION)) if (qc && likely(sta_id != IWL_INVALID_STATION))
iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
...@@ -2620,6 +2616,7 @@ static struct iwl_base_params iwl4965_base_params = { ...@@ -2620,6 +2616,7 @@ static struct iwl_base_params iwl4965_base_params = {
.ucode_tracing = true, .ucode_tracing = true,
.sensitivity_calib_by_driver = true, .sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true, .chain_noise_calib_by_driver = true,
.no_agg_framecnt_info = true,
}; };
struct iwl_cfg iwl4965_agn_cfg = { struct iwl_cfg iwl4965_agn_cfg = {
...@@ -2627,7 +2624,6 @@ struct iwl_cfg iwl4965_agn_cfg = { ...@@ -2627,7 +2624,6 @@ struct iwl_cfg iwl4965_agn_cfg = {
.fw_name_pre = IWL4965_FW_PRE, .fw_name_pre = IWL4965_FW_PRE,
.ucode_api_max = IWL4965_UCODE_API_MAX, .ucode_api_max = IWL4965_UCODE_API_MAX,
.ucode_api_min = IWL4965_UCODE_API_MIN, .ucode_api_min = IWL4965_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
.valid_tx_ant = ANT_AB, .valid_tx_ant = ANT_AB,
.valid_rx_ant = ANT_ABC, .valid_rx_ant = ANT_ABC,
.eeprom_ver = EEPROM_4965_EEPROM_VERSION, .eeprom_ver = EEPROM_4965_EEPROM_VERSION,
...@@ -2635,6 +2631,7 @@ struct iwl_cfg iwl4965_agn_cfg = { ...@@ -2635,6 +2631,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
.ops = &iwl4965_ops, .ops = &iwl4965_ops,
.mod_params = &iwlagn_mod_params, .mod_params = &iwlagn_mod_params,
.base_params = &iwl4965_base_params, .base_params = &iwl4965_base_params,
.led_mode = IWL_LED_BLINK,
/* /*
* Force use of chains B and C for scan RX on 5 GHz band * Force use of chains B and C for scan RX on 5 GHz band
* because the device has off-channel reception on chain A. * because the device has off-channel reception on chain A.
......
...@@ -527,7 +527,6 @@ struct iwl_cfg iwl5300_agn_cfg = { ...@@ -527,7 +527,6 @@ struct iwl_cfg iwl5300_agn_cfg = {
.fw_name_pre = IWL5000_FW_PRE, .fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN, .ucode_api_min = IWL5000_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
.valid_tx_ant = ANT_ABC, .valid_tx_ant = ANT_ABC,
.valid_rx_ant = ANT_ABC, .valid_rx_ant = ANT_ABC,
.eeprom_ver = EEPROM_5000_EEPROM_VERSION, .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
...@@ -536,6 +535,7 @@ struct iwl_cfg iwl5300_agn_cfg = { ...@@ -536,6 +535,7 @@ struct iwl_cfg iwl5300_agn_cfg = {
.mod_params = &iwlagn_mod_params, .mod_params = &iwlagn_mod_params,
.base_params = &iwl5000_base_params, .base_params = &iwl5000_base_params,
.ht_params = &iwl5000_ht_params, .ht_params = &iwl5000_ht_params,
.led_mode = IWL_LED_BLINK,
}; };
struct iwl_cfg iwl5100_bgn_cfg = { struct iwl_cfg iwl5100_bgn_cfg = {
...@@ -543,7 +543,6 @@ struct iwl_cfg iwl5100_bgn_cfg = { ...@@ -543,7 +543,6 @@ struct iwl_cfg iwl5100_bgn_cfg = {
.fw_name_pre = IWL5000_FW_PRE, .fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN, .ucode_api_min = IWL5000_UCODE_API_MIN,
.sku = IWL_SKU_G|IWL_SKU_N,
.valid_tx_ant = ANT_B, .valid_tx_ant = ANT_B,
.valid_rx_ant = ANT_AB, .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_5000_EEPROM_VERSION, .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
...@@ -552,6 +551,7 @@ struct iwl_cfg iwl5100_bgn_cfg = { ...@@ -552,6 +551,7 @@ struct iwl_cfg iwl5100_bgn_cfg = {
.mod_params = &iwlagn_mod_params, .mod_params = &iwlagn_mod_params,
.base_params = &iwl5000_base_params, .base_params = &iwl5000_base_params,
.ht_params = &iwl5000_ht_params, .ht_params = &iwl5000_ht_params,
.led_mode = IWL_LED_BLINK,
}; };
struct iwl_cfg iwl5100_abg_cfg = { struct iwl_cfg iwl5100_abg_cfg = {
...@@ -559,7 +559,6 @@ struct iwl_cfg iwl5100_abg_cfg = { ...@@ -559,7 +559,6 @@ struct iwl_cfg iwl5100_abg_cfg = {
.fw_name_pre = IWL5000_FW_PRE, .fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN, .ucode_api_min = IWL5000_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G,
.valid_tx_ant = ANT_B, .valid_tx_ant = ANT_B,
.valid_rx_ant = ANT_AB, .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_5000_EEPROM_VERSION, .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
...@@ -567,6 +566,7 @@ struct iwl_cfg iwl5100_abg_cfg = { ...@@ -567,6 +566,7 @@ struct iwl_cfg iwl5100_abg_cfg = {
.ops = &iwl5000_ops, .ops = &iwl5000_ops,
.mod_params = &iwlagn_mod_params, .mod_params = &iwlagn_mod_params,
.base_params = &iwl5000_base_params, .base_params = &iwl5000_base_params,
.led_mode = IWL_LED_BLINK,
}; };
struct iwl_cfg iwl5100_agn_cfg = { struct iwl_cfg iwl5100_agn_cfg = {
...@@ -574,7 +574,6 @@ struct iwl_cfg iwl5100_agn_cfg = { ...@@ -574,7 +574,6 @@ struct iwl_cfg iwl5100_agn_cfg = {
.fw_name_pre = IWL5000_FW_PRE, .fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN, .ucode_api_min = IWL5000_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
.valid_tx_ant = ANT_B, .valid_tx_ant = ANT_B,
.valid_rx_ant = ANT_AB, .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_5000_EEPROM_VERSION, .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
...@@ -583,6 +582,7 @@ struct iwl_cfg iwl5100_agn_cfg = { ...@@ -583,6 +582,7 @@ struct iwl_cfg iwl5100_agn_cfg = {
.mod_params = &iwlagn_mod_params, .mod_params = &iwlagn_mod_params,
.base_params = &iwl5000_base_params, .base_params = &iwl5000_base_params,
.ht_params = &iwl5000_ht_params, .ht_params = &iwl5000_ht_params,
.led_mode = IWL_LED_BLINK,
}; };
struct iwl_cfg iwl5350_agn_cfg = { struct iwl_cfg iwl5350_agn_cfg = {
...@@ -590,7 +590,6 @@ struct iwl_cfg iwl5350_agn_cfg = { ...@@ -590,7 +590,6 @@ struct iwl_cfg iwl5350_agn_cfg = {
.fw_name_pre = IWL5000_FW_PRE, .fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN, .ucode_api_min = IWL5000_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
.valid_tx_ant = ANT_ABC, .valid_tx_ant = ANT_ABC,
.valid_rx_ant = ANT_ABC, .valid_rx_ant = ANT_ABC,
.eeprom_ver = EEPROM_5050_EEPROM_VERSION, .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
...@@ -599,6 +598,7 @@ struct iwl_cfg iwl5350_agn_cfg = { ...@@ -599,6 +598,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
.mod_params = &iwlagn_mod_params, .mod_params = &iwlagn_mod_params,
.base_params = &iwl5000_base_params, .base_params = &iwl5000_base_params,
.ht_params = &iwl5000_ht_params, .ht_params = &iwl5000_ht_params,
.led_mode = IWL_LED_BLINK,
}; };
struct iwl_cfg iwl5150_agn_cfg = { struct iwl_cfg iwl5150_agn_cfg = {
...@@ -606,7 +606,6 @@ struct iwl_cfg iwl5150_agn_cfg = { ...@@ -606,7 +606,6 @@ struct iwl_cfg iwl5150_agn_cfg = {
.fw_name_pre = IWL5150_FW_PRE, .fw_name_pre = IWL5150_FW_PRE,
.ucode_api_max = IWL5150_UCODE_API_MAX, .ucode_api_max = IWL5150_UCODE_API_MAX,
.ucode_api_min = IWL5150_UCODE_API_MIN, .ucode_api_min = IWL5150_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
.valid_tx_ant = ANT_A, .valid_tx_ant = ANT_A,
.valid_rx_ant = ANT_AB, .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_5050_EEPROM_VERSION, .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
...@@ -616,6 +615,7 @@ struct iwl_cfg iwl5150_agn_cfg = { ...@@ -616,6 +615,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
.base_params = &iwl5000_base_params, .base_params = &iwl5000_base_params,
.ht_params = &iwl5000_ht_params, .ht_params = &iwl5000_ht_params,
.need_dc_calib = true, .need_dc_calib = true,
.led_mode = IWL_LED_BLINK,
}; };
struct iwl_cfg iwl5150_abg_cfg = { struct iwl_cfg iwl5150_abg_cfg = {
...@@ -623,7 +623,6 @@ struct iwl_cfg iwl5150_abg_cfg = { ...@@ -623,7 +623,6 @@ struct iwl_cfg iwl5150_abg_cfg = {
.fw_name_pre = IWL5150_FW_PRE, .fw_name_pre = IWL5150_FW_PRE,
.ucode_api_max = IWL5150_UCODE_API_MAX, .ucode_api_max = IWL5150_UCODE_API_MAX,
.ucode_api_min = IWL5150_UCODE_API_MIN, .ucode_api_min = IWL5150_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G,
.valid_tx_ant = ANT_A, .valid_tx_ant = ANT_A,
.valid_rx_ant = ANT_AB, .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_5050_EEPROM_VERSION, .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
...@@ -632,6 +631,7 @@ struct iwl_cfg iwl5150_abg_cfg = { ...@@ -632,6 +631,7 @@ struct iwl_cfg iwl5150_abg_cfg = {
.mod_params = &iwlagn_mod_params, .mod_params = &iwlagn_mod_params,
.base_params = &iwl5000_base_params, .base_params = &iwl5000_base_params,
.need_dc_calib = true, .need_dc_calib = true,
.led_mode = IWL_LED_BLINK,
}; };
MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
......
This diff is collapsed.
...@@ -248,6 +248,27 @@ int iwl_eeprom_check_version(struct iwl_priv *priv) ...@@ -248,6 +248,27 @@ int iwl_eeprom_check_version(struct iwl_priv *priv)
} }
int iwl_eeprom_check_sku(struct iwl_priv *priv)
{
u16 eeprom_sku;
eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP);
priv->cfg->sku = ((eeprom_sku & EEPROM_SKU_CAP_BAND_SELECTION) >>
EEPROM_SKU_CAP_BAND_POS);
if (eeprom_sku & EEPROM_SKU_CAP_11N_ENABLE)
priv->cfg->sku |= IWL_SKU_N;
if (!priv->cfg->sku) {
IWL_ERR(priv, "Invalid device sku\n");
return -EINVAL;
}
IWL_INFO(priv, "Device SKU: 0X%x\n", priv->cfg->sku);
return 0;
}
void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac) void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
{ {
const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv, const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv,
......
...@@ -307,6 +307,7 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) ...@@ -307,6 +307,7 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
if (ctx_bss->vif && ctx_pan->vif) { if (ctx_bss->vif && ctx_pan->vif) {
int bcnint = ctx_pan->vif->bss_conf.beacon_int; int bcnint = ctx_pan->vif->bss_conf.beacon_int;
int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1;
/* should be set, but seems unused?? */ /* should be set, but seems unused?? */
cmd.flags |= cpu_to_le16(IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE); cmd.flags |= cpu_to_le16(IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE);
...@@ -329,10 +330,10 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) ...@@ -329,10 +330,10 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
if (test_bit(STATUS_SCAN_HW, &priv->status) || if (test_bit(STATUS_SCAN_HW, &priv->status) ||
(!ctx_bss->vif->bss_conf.idle && (!ctx_bss->vif->bss_conf.idle &&
!ctx_bss->vif->bss_conf.assoc)) { !ctx_bss->vif->bss_conf.assoc)) {
slot0 = bcnint * 3 - 20; slot0 = dtim * bcnint * 3 - 20;
slot1 = 20; slot1 = 20;
} else if (!ctx_pan->vif->bss_conf.idle && } else if (!ctx_pan->vif->bss_conf.idle &&
!ctx_pan->vif->bss_conf.assoc) { !ctx_pan->vif->bss_conf.assoc) {
slot1 = bcnint * 3 - 20; slot1 = bcnint * 3 - 20;
slot0 = 20; slot0 = 20;
} }
......
...@@ -445,22 +445,17 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, ...@@ -445,22 +445,17 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
if (priv->mac80211_registered && if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark) && (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
(agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) { (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
if (agg->state == IWL_AGG_OFF) iwl_wake_queue(priv, txq);
iwl_wake_queue(priv, txq_id);
else
iwl_wake_queue(priv, txq->swq_id);
}
} }
} else { } else {
BUG_ON(txq_id != txq->swq_id);
iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false); iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false);
freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
iwl_free_tfds_in_queue(priv, sta_id, tid, freed); iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
if (priv->mac80211_registered && if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark)) (iwl_queue_space(&txq->q) > txq->q.low_mark))
iwl_wake_queue(priv, txq_id); iwl_wake_queue(priv, txq);
} }
iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
...@@ -2025,7 +2020,6 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, ...@@ -2025,7 +2020,6 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif;
struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 }; struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 };
struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg;
u8 last_traffic_load;
IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n");
IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status);
...@@ -2034,11 +2028,10 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, ...@@ -2034,11 +2028,10 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
coex->bt_ci_compliance); coex->bt_ci_compliance);
iwlagn_print_uartmsg(priv, uart_msg); iwlagn_print_uartmsg(priv, uart_msg);
last_traffic_load = priv->notif_bt_traffic_load; priv->last_bt_traffic_load = priv->bt_traffic_load;
priv->notif_bt_traffic_load = coex->bt_traffic_load;
if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
if (priv->bt_status != coex->bt_status || if (priv->bt_status != coex->bt_status ||
last_traffic_load != coex->bt_traffic_load) { priv->last_bt_traffic_load != coex->bt_traffic_load) {
if (coex->bt_status) { if (coex->bt_status) {
/* BT on */ /* BT on */
if (!priv->bt_ch_announce) if (!priv->bt_ch_announce)
......
...@@ -833,17 +833,23 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, ...@@ -833,17 +833,23 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
struct iwl_lq_sta *lq_sta) struct iwl_lq_sta *lq_sta)
{ {
struct iwl_scale_tbl_info *tbl; struct iwl_scale_tbl_info *tbl;
bool full_concurrent; bool full_concurrent = priv->bt_full_concurrent;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&priv->lock, flags); if (priv->bt_ant_couple_ok) {
if (priv->bt_ci_compliance && priv->bt_ant_couple_ok) /*
full_concurrent = true; * Is there a need to switch between
else * full concurrency and 3-wire?
full_concurrent = false; */
spin_unlock_irqrestore(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
if (priv->bt_ci_compliance && priv->bt_ant_couple_ok)
if (priv->bt_full_concurrent != full_concurrent) { full_concurrent = true;
else
full_concurrent = false;
spin_unlock_irqrestore(&priv->lock, flags);
}
if ((priv->bt_traffic_load != priv->last_bt_traffic_load) ||
(priv->bt_full_concurrent != full_concurrent)) {
priv->bt_full_concurrent = full_concurrent; priv->bt_full_concurrent = full_concurrent;
/* Update uCode's rate table. */ /* Update uCode's rate table. */
...@@ -1040,8 +1046,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, ...@@ -1040,8 +1046,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
if (sta && sta->supp_rates[sband->band]) if (sta && sta->supp_rates[sband->band])
rs_rate_scale_perform(priv, skb, sta, lq_sta); rs_rate_scale_perform(priv, skb, sta, lq_sta);
/* Is there a need to switch between full concurrency and 3-wire? */ if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist)
if (priv->bt_ant_couple_ok)
rs_bt_update_lq(priv, ctx, lq_sta); rs_bt_update_lq(priv, ctx, lq_sta);
} }
...@@ -3010,10 +3015,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, ...@@ -3010,10 +3015,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
*/ */
if (priv && priv->cfg->bt_params && if (priv && priv->cfg->bt_params &&
priv->cfg->bt_params->agg_time_limit && priv->cfg->bt_params->agg_time_limit &&
priv->cfg->bt_params->agg_time_limit >= priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
LINK_QUAL_AGG_TIME_LIMIT_MIN &&
priv->cfg->bt_params->agg_time_limit <=
LINK_QUAL_AGG_TIME_LIMIT_MAX)
lq_cmd->agg_params.agg_time_limit = lq_cmd->agg_params.agg_time_limit =
cpu_to_le16(priv->cfg->bt_params->agg_time_limit); cpu_to_le16(priv->cfg->bt_params->agg_time_limit);
} }
......
...@@ -72,6 +72,34 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, ...@@ -72,6 +72,34 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
return ret; return ret;
} }
static void iwlagn_update_qos(struct iwl_priv *priv,
struct iwl_rxon_context *ctx)
{
int ret;
if (!ctx->is_active)
return;
ctx->qos_data.def_qos_parm.qos_flags = 0;
if (ctx->qos_data.qos_active)
ctx->qos_data.def_qos_parm.qos_flags |=
QOS_PARAM_FLG_UPDATE_EDCA_MSK;
if (ctx->ht.enabled)
ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
ctx->qos_data.qos_active,
ctx->qos_data.def_qos_parm.qos_flags);
ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd,
sizeof(struct iwl_qosparam_cmd),
&ctx->qos_data.def_qos_parm);
if (ret)
IWL_ERR(priv, "Failed to update QoS\n");
}
static int iwlagn_update_beacon(struct iwl_priv *priv, static int iwlagn_update_beacon(struct iwl_priv *priv,
struct ieee80211_vif *vif) struct ieee80211_vif *vif)
{ {
...@@ -97,6 +125,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ...@@ -97,6 +125,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
/* cast away the const for active_rxon in this function */ /* cast away the const for active_rxon in this function */
struct iwl_rxon_cmd *active = (void *)&ctx->active; struct iwl_rxon_cmd *active = (void *)&ctx->active;
bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK);
int ret; int ret;
lockdep_assert_held(&priv->mutex); lockdep_assert_held(&priv->mutex);
...@@ -176,25 +205,27 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ...@@ -176,25 +205,27 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
* AP station must be done after the BSSID is set to correctly * AP station must be done after the BSSID is set to correctly
* set up filters in the device. * set up filters in the device.
*/ */
if (ctx->ctxid == IWL_RXON_CTX_BSS) if ((old_assoc && new_assoc) || !new_assoc) {
ret = iwlagn_disable_bss(priv, ctx, &ctx->staging); if (ctx->ctxid == IWL_RXON_CTX_BSS)
else ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
ret = iwlagn_disable_pan(priv, ctx, &ctx->staging); else
if (ret) ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
return ret; if (ret)
return ret;
memcpy(active, &ctx->staging, sizeof(*active)); memcpy(active, &ctx->staging, sizeof(*active));
/* /*
* Un-assoc RXON clears the station table and WEP * Un-assoc RXON clears the station table and WEP
* keys, so we have to restore those afterwards. * keys, so we have to restore those afterwards.
*/ */
iwl_clear_ucode_stations(priv, ctx); iwl_clear_ucode_stations(priv, ctx);
iwl_restore_stations(priv, ctx); iwl_restore_stations(priv, ctx);
ret = iwl_restore_default_wep_keys(priv, ctx); ret = iwl_restore_default_wep_keys(priv, ctx);
if (ret) { if (ret) {
IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
return ret; return ret;
}
} }
/* RXON timing must be before associated RXON */ /* RXON timing must be before associated RXON */
...@@ -205,6 +236,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ...@@ -205,6 +236,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
} }
if (new_assoc) { if (new_assoc) {
/* QoS info may be cleared by previous un-assoc RXON */
iwlagn_update_qos(priv, ctx);
/* /*
* We'll run into this code path when beaconing is * We'll run into this code path when beaconing is
* enabled, but then we also need to send the beacon * enabled, but then we also need to send the beacon
...@@ -235,6 +269,8 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ...@@ -235,6 +269,8 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
} }
memcpy(active, &ctx->staging, sizeof(*active)); memcpy(active, &ctx->staging, sizeof(*active));
iwl_reprogram_ap_sta(priv, ctx);
/* IBSS beacon needs to be sent after setting assoc */ /* IBSS beacon needs to be sent after setting assoc */
if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC)) if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
if (iwlagn_update_beacon(priv, ctx->vif)) if (iwlagn_update_beacon(priv, ctx->vif))
...@@ -261,34 +297,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ...@@ -261,34 +297,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
return 0; return 0;
} }
static void iwlagn_update_qos(struct iwl_priv *priv,
struct iwl_rxon_context *ctx)
{
int ret;
if (!ctx->is_active)
return;
ctx->qos_data.def_qos_parm.qos_flags = 0;
if (ctx->qos_data.qos_active)
ctx->qos_data.def_qos_parm.qos_flags |=
QOS_PARAM_FLG_UPDATE_EDCA_MSK;
if (ctx->ht.enabled)
ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
ctx->qos_data.qos_active,
ctx->qos_data.def_qos_parm.qos_flags);
ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd,
sizeof(struct iwl_qosparam_cmd),
&ctx->qos_data.def_qos_parm);
if (ret)
IWL_ERR(priv, "Failed to update QoS\n");
}
int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = hw->priv;
...@@ -507,6 +515,11 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, ...@@ -507,6 +515,11 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
if (WARN_ON(!ctx->vif)) {
mutex_unlock(&priv->mutex);
return;
}
if (changes & BSS_CHANGED_BEACON_INT) if (changes & BSS_CHANGED_BEACON_INT)
force = true; force = true;
......
...@@ -518,7 +518,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -518,7 +518,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
struct iwl_cmd_meta *out_meta; struct iwl_cmd_meta *out_meta;
struct iwl_tx_cmd *tx_cmd; struct iwl_tx_cmd *tx_cmd;
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
int swq_id, txq_id; int txq_id;
dma_addr_t phys_addr; dma_addr_t phys_addr;
dma_addr_t txcmd_phys; dma_addr_t txcmd_phys;
dma_addr_t scratch_phys; dma_addr_t scratch_phys;
...@@ -620,7 +620,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -620,7 +620,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
} }
txq = &priv->txq[txq_id]; txq = &priv->txq[txq_id];
swq_id = txq->swq_id;
q = &txq->q; q = &txq->q;
if (unlikely(iwl_queue_space(q) < q->high_mark)) { if (unlikely(iwl_queue_space(q) < q->high_mark)) {
...@@ -775,7 +774,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -775,7 +774,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
iwl_txq_update_write_ptr(priv, txq); iwl_txq_update_write_ptr(priv, txq);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
} else { } else {
iwl_stop_queue(priv, txq->swq_id); iwl_stop_queue(priv, txq);
} }
} }
...@@ -1004,7 +1003,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, ...@@ -1004,7 +1003,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
tid_data = &priv->stations[sta_id].tid[tid]; tid_data = &priv->stations[sta_id].tid[tid];
*ssn = SEQ_TO_SN(tid_data->seq_number); *ssn = SEQ_TO_SN(tid_data->seq_number);
tid_data->agg.txq_id = txq_id; tid_data->agg.txq_id = txq_id;
priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(get_ac_from_tid(tid), txq_id); iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id);
spin_unlock_irqrestore(&priv->sta_lock, flags); spin_unlock_irqrestore(&priv->sta_lock, flags);
ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo, ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo,
...@@ -1232,37 +1231,61 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, ...@@ -1232,37 +1231,61 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
if (sh < 0) /* tbw something is wrong with indices */ if (sh < 0) /* tbw something is wrong with indices */
sh += 0x100; sh += 0x100;
/* don't use 64-bit values for now */
bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
if (agg->frame_count > (64 - sh)) { if (agg->frame_count > (64 - sh)) {
IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size"); IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size");
return -1; return -1;
} }
if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
/* check for success or failure according to the /*
* transmitted bitmap and block-ack bitmap */ * sent and ack information provided by uCode
sent_bitmap = bitmap & agg->bitmap; * use it instead of figure out ourself
*/
/* For each frame attempted in aggregation, if (ba_resp->txed_2_done > ba_resp->txed) {
* update driver's record of tx frame's status. */ IWL_DEBUG_TX_REPLY(priv,
i = 0; "bogus sent(%d) and ack(%d) count\n",
while (sent_bitmap) { ba_resp->txed, ba_resp->txed_2_done);
ack = sent_bitmap & 1ULL; /*
successes += ack; * set txed_2_done = txed,
IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n", * so it won't impact rate scale
ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff, */
agg->start_idx + i); ba_resp->txed = ba_resp->txed_2_done;
sent_bitmap >>= 1; }
++i; IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
ba_resp->txed, ba_resp->txed_2_done);
} else {
/* don't use 64-bit values for now */
bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
/* check for success or failure according to the
* transmitted bitmap and block-ack bitmap */
sent_bitmap = bitmap & agg->bitmap;
/* For each frame attempted in aggregation,
* update driver's record of tx frame's status. */
i = 0;
while (sent_bitmap) {
ack = sent_bitmap & 1ULL;
successes += ack;
IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
ack ? "ACK" : "NACK", i,
(agg->start_idx + i) & 0xff,
agg->start_idx + i);
sent_bitmap >>= 1;
++i;
}
} }
info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb); info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb);
memset(&info->status, 0, sizeof(info->status)); memset(&info->status, 0, sizeof(info->status));
info->flags |= IEEE80211_TX_STAT_ACK; info->flags |= IEEE80211_TX_STAT_ACK;
info->flags |= IEEE80211_TX_STAT_AMPDU; info->flags |= IEEE80211_TX_STAT_AMPDU;
info->status.ampdu_ack_len = successes; if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
info->status.ampdu_len = agg->frame_count; info->status.ampdu_ack_len = ba_resp->txed_2_done;
info->status.ampdu_len = ba_resp->txed;
} else {
info->status.ampdu_ack_len = successes;
info->status.ampdu_len = agg->frame_count;
}
iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap); IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap);
...@@ -1376,7 +1399,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, ...@@ -1376,7 +1399,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
if ((iwl_queue_space(&txq->q) > txq->q.low_mark) && if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
priv->mac80211_registered && priv->mac80211_registered &&
(agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
iwl_wake_queue(priv, txq->swq_id); iwl_wake_queue(priv, txq);
iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow); iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow);
} }
......
...@@ -40,30 +40,36 @@ ...@@ -40,30 +40,36 @@
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-agn-calib.h" #include "iwl-agn-calib.h"
static const s8 iwlagn_default_queue_to_tx_fifo[] = { #define IWL_AC_UNSET -1
IWL_TX_FIFO_VO,
IWL_TX_FIFO_VI, struct queue_to_fifo_ac {
IWL_TX_FIFO_BE, s8 fifo, ac;
IWL_TX_FIFO_BK, };
IWLAGN_CMD_FIFO_NUM,
IWL_TX_FIFO_UNUSED, static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = {
IWL_TX_FIFO_UNUSED, { IWL_TX_FIFO_VO, 0, },
IWL_TX_FIFO_UNUSED, { IWL_TX_FIFO_VI, 1, },
IWL_TX_FIFO_UNUSED, { IWL_TX_FIFO_BE, 2, },
IWL_TX_FIFO_UNUSED, { IWL_TX_FIFO_BK, 3, },
{ IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
{ IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
{ IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
{ IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
{ IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
{ IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
}; };
static const s8 iwlagn_ipan_queue_to_tx_fifo[] = { static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = {
IWL_TX_FIFO_VO, { IWL_TX_FIFO_VO, 0, },
IWL_TX_FIFO_VI, { IWL_TX_FIFO_VI, 1, },
IWL_TX_FIFO_BE, { IWL_TX_FIFO_BE, 2, },
IWL_TX_FIFO_BK, { IWL_TX_FIFO_BK, 3, },
IWL_TX_FIFO_BK_IPAN, { IWL_TX_FIFO_BK_IPAN, 3, },
IWL_TX_FIFO_BE_IPAN, { IWL_TX_FIFO_BE_IPAN, 2, },
IWL_TX_FIFO_VI_IPAN, { IWL_TX_FIFO_VI_IPAN, 1, },
IWL_TX_FIFO_VO_IPAN, { IWL_TX_FIFO_VO_IPAN, 0, },
IWL_TX_FIFO_BE_IPAN, { IWL_TX_FIFO_BE_IPAN, 2, },
IWLAGN_CMD_FIFO_NUM, { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
}; };
static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
...@@ -429,7 +435,7 @@ void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) ...@@ -429,7 +435,7 @@ void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
int iwlagn_alive_notify(struct iwl_priv *priv) int iwlagn_alive_notify(struct iwl_priv *priv)
{ {
const s8 *queues; const struct queue_to_fifo_ac *queue_to_fifo;
u32 a; u32 a;
unsigned long flags; unsigned long flags;
int i, chan; int i, chan;
...@@ -492,9 +498,9 @@ int iwlagn_alive_notify(struct iwl_priv *priv) ...@@ -492,9 +498,9 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
/* map queues to FIFOs */ /* map queues to FIFOs */
if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
queues = iwlagn_ipan_queue_to_tx_fifo; queue_to_fifo = iwlagn_ipan_queue_to_tx_fifo;
else else
queues = iwlagn_default_queue_to_tx_fifo; queue_to_fifo = iwlagn_default_queue_to_tx_fifo;
iwlagn_set_wr_ptrs(priv, priv->cmd_queue, 0); iwlagn_set_wr_ptrs(priv, priv->cmd_queue, 0);
...@@ -510,14 +516,17 @@ int iwlagn_alive_notify(struct iwl_priv *priv) ...@@ -510,14 +516,17 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10); BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
int ac = queues[i]; int fifo = queue_to_fifo[i].fifo;
int ac = queue_to_fifo[i].ac;
iwl_txq_ctx_activate(priv, i); iwl_txq_ctx_activate(priv, i);
if (ac == IWL_TX_FIFO_UNUSED) if (fifo == IWL_TX_FIFO_UNUSED)
continue; continue;
iwlagn_tx_queue_set_status(priv, &priv->txq[i], ac, 0); if (ac != IWL_AC_UNSET)
iwl_set_swq_id(&priv->txq[i], ac, i);
iwlagn_tx_queue_set_status(priv, &priv->txq[i], fifo, 0);
} }
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
......
...@@ -97,7 +97,8 @@ void iwl_update_chain_flags(struct iwl_priv *priv) ...@@ -97,7 +97,8 @@ void iwl_update_chain_flags(struct iwl_priv *priv)
if (priv->cfg->ops->hcmd->set_rxon_chain) { if (priv->cfg->ops->hcmd->set_rxon_chain) {
for_each_context(priv, ctx) { for_each_context(priv, ctx) {
priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
iwlcore_commit_rxon(priv, ctx); if (ctx->active.rx_chain != ctx->staging.rx_chain)
iwlcore_commit_rxon(priv, ctx);
} }
} }
} }
...@@ -2716,6 +2717,8 @@ static void iwl_alive_start(struct iwl_priv *priv) ...@@ -2716,6 +2717,8 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwl_reset_run_time_calib(priv); iwl_reset_run_time_calib(priv);
set_bit(STATUS_READY, &priv->status);
/* Configure the adapter for unassociated operation */ /* Configure the adapter for unassociated operation */
iwlcore_commit_rxon(priv, ctx); iwlcore_commit_rxon(priv, ctx);
...@@ -2725,7 +2728,6 @@ static void iwl_alive_start(struct iwl_priv *priv) ...@@ -2725,7 +2728,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwl_leds_init(priv); iwl_leds_init(priv);
IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
set_bit(STATUS_READY, &priv->status);
wake_up_interruptible(&priv->wait_command_queue); wake_up_interruptible(&priv->wait_command_queue);
iwl_power_update_mode(priv, true); iwl_power_update_mode(priv, true);
...@@ -3837,7 +3839,6 @@ static int iwl_init_drv(struct iwl_priv *priv) ...@@ -3837,7 +3839,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
priv->bt_on_thresh = BT_ON_THRESHOLD_DEF; priv->bt_on_thresh = BT_ON_THRESHOLD_DEF;
priv->bt_duration = BT_DURATION_LIMIT_DEF; priv->bt_duration = BT_DURATION_LIMIT_DEF;
priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF; priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF;
priv->dynamic_agg_thresh = BT_AGG_THRESHOLD_DEF;
} }
/* Set the tx_power_user_lmt to the lowest power level /* Set the tx_power_user_lmt to the lowest power level
...@@ -4135,6 +4136,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -4135,6 +4136,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err) if (err)
goto out_free_eeprom; goto out_free_eeprom;
err = iwl_eeprom_check_sku(priv);
if (err)
goto out_free_eeprom;
/* extract MAC Address */ /* extract MAC Address */
iwl_eeprom_get_mac(priv, priv->addresses[0].addr); iwl_eeprom_get_mac(priv, priv->addresses[0].addr);
IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr); IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr);
......
...@@ -2022,6 +2022,9 @@ struct iwl_compressed_ba_resp { ...@@ -2022,6 +2022,9 @@ struct iwl_compressed_ba_resp {
__le64 bitmap; __le64 bitmap;
__le16 scd_flow; __le16 scd_flow;
__le16 scd_ssn; __le16 scd_ssn;
/* following only for 5000 series and up */
u8 txed; /* number of frames sent */
u8 txed_2_done; /* number of frames acked */
} __packed; } __packed;
/* /*
...@@ -2407,9 +2410,9 @@ struct iwl_link_quality_cmd { ...@@ -2407,9 +2410,9 @@ struct iwl_link_quality_cmd {
#define BT_FRAG_THRESHOLD_MAX 0 #define BT_FRAG_THRESHOLD_MAX 0
#define BT_FRAG_THRESHOLD_MIN 0 #define BT_FRAG_THRESHOLD_MIN 0
#define BT_AGG_THRESHOLD_DEF 0 #define BT_AGG_THRESHOLD_DEF 1200
#define BT_AGG_THRESHOLD_MAX 0 #define BT_AGG_THRESHOLD_MAX 8000
#define BT_AGG_THRESHOLD_MIN 0 #define BT_AGG_THRESHOLD_MIN 400
/* /*
* REPLY_BT_CONFIG = 0x9b (command, has simple generic response) * REPLY_BT_CONFIG = 0x9b (command, has simple generic response)
...@@ -2447,8 +2450,8 @@ struct iwl_bt_cmd { ...@@ -2447,8 +2450,8 @@ struct iwl_bt_cmd {
#define IWLAGN_BT3_T7_DEFAULT 1 #define IWLAGN_BT3_T7_DEFAULT 1
#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffffffff) #define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffff0000)
#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffffffff) #define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffff0000)
#define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2 #define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2
......
...@@ -1469,7 +1469,7 @@ static void iwl_teardown_interface(struct iwl_priv *priv, ...@@ -1469,7 +1469,7 @@ static void iwl_teardown_interface(struct iwl_priv *priv,
* both values are the same and zero. * both values are the same and zero.
*/ */
if (vif->type == NL80211_IFTYPE_ADHOC) if (vif->type == NL80211_IFTYPE_ADHOC)
priv->bt_traffic_load = priv->notif_bt_traffic_load; priv->bt_traffic_load = priv->last_bt_traffic_load;
} }
void iwl_mac_remove_interface(struct ieee80211_hw *hw, void iwl_mac_remove_interface(struct ieee80211_hw *hw,
......
...@@ -291,7 +291,9 @@ struct iwl_mod_params { ...@@ -291,7 +291,9 @@ struct iwl_mod_params {
* @chain_noise_calib_by_driver: driver has the capability to perform * @chain_noise_calib_by_driver: driver has the capability to perform
* chain noise calibration operation * chain noise calibration operation
* @shadow_reg_enable: HW shadhow register bit * @shadow_reg_enable: HW shadhow register bit
*/ * @no_agg_framecnt_info: uCode do not provide aggregation frame count
* information
*/
struct iwl_base_params { struct iwl_base_params {
int eeprom_size; int eeprom_size;
int num_of_queues; /* def: HW dependent */ int num_of_queues; /* def: HW dependent */
...@@ -322,6 +324,7 @@ struct iwl_base_params { ...@@ -322,6 +324,7 @@ struct iwl_base_params {
const bool sensitivity_calib_by_driver; const bool sensitivity_calib_by_driver;
const bool chain_noise_calib_by_driver; const bool chain_noise_calib_by_driver;
const bool shadow_reg_enable; const bool shadow_reg_enable;
const bool no_agg_framecnt_info;
}; };
/* /*
* @advanced_bt_coexist: support advanced bt coexist * @advanced_bt_coexist: support advanced bt coexist
...@@ -360,6 +363,7 @@ struct iwl_ht_params { ...@@ -360,6 +363,7 @@ struct iwl_ht_params {
* @need_dc_calib: need to perform init dc calibration * @need_dc_calib: need to perform init dc calibration
* @need_temp_offset_calib: need to perform temperature offset calibration * @need_temp_offset_calib: need to perform temperature offset calibration
* @scan_antennas: available antenna for scan operation * @scan_antennas: available antenna for scan operation
* @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off)
* *
* We enable the driver to be backward compatible wrt API version. The * We enable the driver to be backward compatible wrt API version. The
* driver specifies which APIs it supports (with @ucode_api_max being the * driver specifies which APIs it supports (with @ucode_api_max being the
...@@ -406,6 +410,7 @@ struct iwl_cfg { ...@@ -406,6 +410,7 @@ struct iwl_cfg {
const bool need_temp_offset_calib; /* if used set to true */ const bool need_temp_offset_calib; /* if used set to true */
u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
enum iwl_led_mode led_mode;
}; };
/*************************** /***************************
......
...@@ -992,11 +992,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, ...@@ -992,11 +992,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
" swq_id=%#.2x (ac %d/hwq %d)\n", " swq_id=%#.2x (ac %d/hwq %d)\n",
cnt, q->read_ptr, q->write_ptr, cnt, q->read_ptr, q->write_ptr,
!!test_bit(cnt, priv->queue_stopped), !!test_bit(cnt, priv->queue_stopped),
txq->swq_id, txq->swq_id, txq->swq_id & 3,
txq->swq_id & 0x80 ? txq->swq_id & 3 : (txq->swq_id >> 2) & 0x1f);
txq->swq_id,
txq->swq_id & 0x80 ? (txq->swq_id >> 2) &
0x1f : txq->swq_id);
if (cnt >= 4) if (cnt >= 4)
continue; continue;
/* for the ACs, display the stop count too */ /* for the ACs, display the stop count too */
...@@ -1580,7 +1577,7 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file, ...@@ -1580,7 +1577,7 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file,
priv->bt_full_concurrent ? "full concurrency" : "3-wire"); priv->bt_full_concurrent ? "full concurrency" : "3-wire");
pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, " pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, "
"last traffic notif: %d\n", "last traffic notif: %d\n",
priv->bt_status ? "On" : "Off", priv->notif_bt_traffic_load); priv->bt_status ? "On" : "Off", priv->last_bt_traffic_load);
pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, " pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, "
"sco_active: %d, kill_ack_mask: %x, " "sco_active: %d, kill_ack_mask: %x, "
"kill_cts_mask: %x\n", "kill_cts_mask: %x\n",
......
...@@ -1471,7 +1471,7 @@ struct iwl_priv { ...@@ -1471,7 +1471,7 @@ struct iwl_priv {
/* bt coex */ /* bt coex */
u8 bt_status; u8 bt_status;
u8 bt_traffic_load, notif_bt_traffic_load; u8 bt_traffic_load, last_bt_traffic_load;
bool bt_ch_announce; bool bt_ch_announce;
bool bt_sco_active; bool bt_sco_active;
bool bt_full_concurrent; bool bt_full_concurrent;
...@@ -1482,7 +1482,6 @@ struct iwl_priv { ...@@ -1482,7 +1482,6 @@ struct iwl_priv {
u16 bt_on_thresh; u16 bt_on_thresh;
u16 bt_duration; u16 bt_duration;
u16 dynamic_frag_thresh; u16 dynamic_frag_thresh;
u16 dynamic_agg_thresh;
u8 bt_ci_compliance; u8 bt_ci_compliance;
struct work_struct bt_traffic_change_work; struct work_struct bt_traffic_change_work;
......
...@@ -110,9 +110,18 @@ enum { ...@@ -110,9 +110,18 @@ enum {
}; };
/* SKU Capabilities */ /* SKU Capabilities */
/* 3945 only */
#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0) #define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0)
#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1) #define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1)
/* 5000 and up */
#define EEPROM_SKU_CAP_BAND_POS (4)
#define EEPROM_SKU_CAP_BAND_SELECTION \
(3 << EEPROM_SKU_CAP_BAND_POS)
#define EEPROM_SKU_CAP_11N_ENABLE (1 << 6)
#define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7)
#define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8)
/* *regulatory* channel data format in eeprom, one for each channel. /* *regulatory* channel data format in eeprom, one for each channel.
* There are separate entries for HT40 (40 MHz) vs. normal (20 MHz) channels. */ * There are separate entries for HT40 (40 MHz) vs. normal (20 MHz) channels. */
struct iwl_eeprom_channel { struct iwl_eeprom_channel {
...@@ -397,7 +406,7 @@ struct iwl_eeprom_calib_info { ...@@ -397,7 +406,7 @@ struct iwl_eeprom_calib_info {
#define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ #define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */
#define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ #define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */
#define EEPROM_VERSION (2*0x44) /* 2 bytes */ #define EEPROM_VERSION (2*0x44) /* 2 bytes */
#define EEPROM_SKU_CAP (2*0x45) /* 1 bytes */ #define EEPROM_SKU_CAP (2*0x45) /* 2 bytes */
#define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ #define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */
#define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */ #define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */
#define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ #define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */
...@@ -504,6 +513,7 @@ struct iwl_eeprom_ops { ...@@ -504,6 +513,7 @@ struct iwl_eeprom_ops {
int iwl_eeprom_init(struct iwl_priv *priv); int iwl_eeprom_init(struct iwl_priv *priv);
void iwl_eeprom_free(struct iwl_priv *priv); void iwl_eeprom_free(struct iwl_priv *priv);
int iwl_eeprom_check_version(struct iwl_priv *priv); int iwl_eeprom_check_version(struct iwl_priv *priv);
int iwl_eeprom_check_sku(struct iwl_priv *priv);
const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset); const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
int iwlcore_eeprom_verify_signature(struct iwl_priv *priv); int iwlcore_eeprom_verify_signature(struct iwl_priv *priv);
u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset); u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset);
......
...@@ -95,42 +95,36 @@ static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev, ...@@ -95,42 +95,36 @@ static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
* | | | | | | | | * | | | | | | | |
* | | | | | | +-+-------- AC queue (0-3) * | | | | | | +-+-------- AC queue (0-3)
* | | | | | | * | | | | | |
* | +-+-+-+-+------------ HW A-MPDU queue * | +-+-+-+-+------------ HW queue ID
* | * |
* +---------------------- indicates agg queue * +---------------------- unused
*/ */
static inline u8 iwl_virtual_agg_queue_num(u8 ac, u8 hwq) static inline void iwl_set_swq_id(struct iwl_tx_queue *txq, u8 ac, u8 hwq)
{ {
BUG_ON(ac > 3); /* only have 2 bits */ BUG_ON(ac > 3); /* only have 2 bits */
BUG_ON(hwq > 31); /* only have 5 bits */ BUG_ON(hwq > 31); /* only use 5 bits */
return 0x80 | (hwq << 2) | ac; txq->swq_id = (hwq << 2) | ac;
} }
static inline void iwl_wake_queue(struct iwl_priv *priv, u8 queue) static inline void iwl_wake_queue(struct iwl_priv *priv,
struct iwl_tx_queue *txq)
{ {
u8 ac = queue; u8 queue = txq->swq_id;
u8 hwq = queue; u8 ac = queue & 3;
u8 hwq = (queue >> 2) & 0x1f;
if (queue & 0x80) {
ac = queue & 3;
hwq = (queue >> 2) & 0x1f;
}
if (test_and_clear_bit(hwq, priv->queue_stopped)) if (test_and_clear_bit(hwq, priv->queue_stopped))
if (atomic_dec_return(&priv->queue_stop_count[ac]) <= 0) if (atomic_dec_return(&priv->queue_stop_count[ac]) <= 0)
ieee80211_wake_queue(priv->hw, ac); ieee80211_wake_queue(priv->hw, ac);
} }
static inline void iwl_stop_queue(struct iwl_priv *priv, u8 queue) static inline void iwl_stop_queue(struct iwl_priv *priv,
struct iwl_tx_queue *txq)
{ {
u8 ac = queue; u8 queue = txq->swq_id;
u8 hwq = queue; u8 ac = queue & 3;
u8 hwq = (queue >> 2) & 0x1f;
if (queue & 0x80) {
ac = queue & 3;
hwq = (queue >> 2) & 0x1f;
}
if (!test_and_set_bit(hwq, priv->queue_stopped)) if (!test_and_set_bit(hwq, priv->queue_stopped))
if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0) if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0)
......
...@@ -45,9 +45,8 @@ ...@@ -45,9 +45,8 @@
/* default: IWL_LED_BLINK(0) using blinking index table */ /* default: IWL_LED_BLINK(0) using blinking index table */
static int led_mode; static int led_mode;
module_param(led_mode, int, S_IRUGO); module_param(led_mode, int, S_IRUGO);
MODULE_PARM_DESC(led_mode, "led mode: 0=blinking, 1=On(RF On)/Off(RF Off), " MODULE_PARM_DESC(led_mode, "led mode: 0=system default, "
"(default 0)"); "1=On(RF On)/Off(RF Off), 2=blinking");
static const struct { static const struct {
u16 tpt; /* Mb/s */ u16 tpt; /* Mb/s */
...@@ -128,7 +127,7 @@ EXPORT_SYMBOL(iwl_led_start); ...@@ -128,7 +127,7 @@ EXPORT_SYMBOL(iwl_led_start);
int iwl_led_associate(struct iwl_priv *priv) int iwl_led_associate(struct iwl_priv *priv)
{ {
IWL_DEBUG_LED(priv, "Associated\n"); IWL_DEBUG_LED(priv, "Associated\n");
if (led_mode == IWL_LED_BLINK) if (priv->cfg->led_mode == IWL_LED_BLINK)
priv->allow_blinking = 1; priv->allow_blinking = 1;
priv->last_blink_time = jiffies; priv->last_blink_time = jiffies;
...@@ -223,5 +222,8 @@ void iwl_leds_init(struct iwl_priv *priv) ...@@ -223,5 +222,8 @@ void iwl_leds_init(struct iwl_priv *priv)
priv->last_blink_rate = 0; priv->last_blink_rate = 0;
priv->last_blink_time = 0; priv->last_blink_time = 0;
priv->allow_blinking = 0; priv->allow_blinking = 0;
if (led_mode != IWL_LED_DEFAULT &&
led_mode != priv->cfg->led_mode)
priv->cfg->led_mode = led_mode;
} }
EXPORT_SYMBOL(iwl_leds_init); EXPORT_SYMBOL(iwl_leds_init);
...@@ -47,14 +47,16 @@ enum led_type { ...@@ -47,14 +47,16 @@ enum led_type {
/* /*
* LED mode * LED mode
* IWL_LED_BLINK: adjust led blink rate based on blink table * IWL_LED_DEFAULT: use system default
* IWL_LED_RF_STATE: turn LED on/off based on RF state * IWL_LED_RF_STATE: turn LED on/off based on RF state
* LED ON = RF ON * LED ON = RF ON
* LED OFF = RF OFF * LED OFF = RF OFF
* IWL_LED_BLINK: adjust led blink rate based on blink table
*/ */
enum iwl_led_mode { enum iwl_led_mode {
IWL_LED_BLINK, IWL_LED_DEFAULT,
IWL_LED_RF_STATE, IWL_LED_RF_STATE,
IWL_LED_BLINK,
}; };
void iwl_leds_init(struct iwl_priv *priv); void iwl_leds_init(struct iwl_priv *priv);
......
...@@ -400,7 +400,8 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id) ...@@ -400,7 +400,8 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
} }
static int iwl_send_remove_station(struct iwl_priv *priv, static int iwl_send_remove_station(struct iwl_priv *priv,
const u8 *addr, int sta_id) const u8 *addr, int sta_id,
bool temporary)
{ {
struct iwl_rx_packet *pkt; struct iwl_rx_packet *pkt;
int ret; int ret;
...@@ -436,9 +437,11 @@ static int iwl_send_remove_station(struct iwl_priv *priv, ...@@ -436,9 +437,11 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
if (!ret) { if (!ret) {
switch (pkt->u.rem_sta.status) { switch (pkt->u.rem_sta.status) {
case REM_STA_SUCCESS_MSK: case REM_STA_SUCCESS_MSK:
spin_lock_irqsave(&priv->sta_lock, flags_spin); if (!temporary) {
iwl_sta_ucode_deactivate(priv, sta_id); spin_lock_irqsave(&priv->sta_lock, flags_spin);
spin_unlock_irqrestore(&priv->sta_lock, flags_spin); iwl_sta_ucode_deactivate(priv, sta_id);
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
}
IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
break; break;
default: default:
...@@ -505,7 +508,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, ...@@ -505,7 +508,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
spin_unlock_irqrestore(&priv->sta_lock, flags); spin_unlock_irqrestore(&priv->sta_lock, flags);
return iwl_send_remove_station(priv, addr, sta_id); return iwl_send_remove_station(priv, addr, sta_id, false);
out_err: out_err:
spin_unlock_irqrestore(&priv->sta_lock, flags); spin_unlock_irqrestore(&priv->sta_lock, flags);
return -EINVAL; return -EINVAL;
...@@ -624,6 +627,44 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ...@@ -624,6 +627,44 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
} }
EXPORT_SYMBOL(iwl_restore_stations); EXPORT_SYMBOL(iwl_restore_stations);
void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
unsigned long flags;
int sta_id = ctx->ap_sta_id;
int ret;
struct iwl_addsta_cmd sta_cmd;
struct iwl_link_quality_cmd lq;
bool active;
spin_lock_irqsave(&priv->sta_lock, flags);
if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
spin_unlock_irqrestore(&priv->sta_lock, flags);
return;
}
memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
sta_cmd.mode = 0;
memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq));
active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE;
spin_unlock_irqrestore(&priv->sta_lock, flags);
if (active) {
ret = iwl_send_remove_station(
priv, priv->stations[sta_id].sta.sta.addr,
sta_id, true);
if (ret)
IWL_ERR(priv, "failed to remove STA %pM (%d)\n",
priv->stations[sta_id].sta.sta.addr, ret);
}
ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
if (ret)
IWL_ERR(priv, "failed to re-add STA %pM (%d)\n",
priv->stations[sta_id].sta.sta.addr, ret);
iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
}
EXPORT_SYMBOL(iwl_reprogram_ap_sta);
int iwl_get_free_ucode_key_index(struct iwl_priv *priv) int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
{ {
int i; int i;
......
...@@ -63,6 +63,7 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, ...@@ -63,6 +63,7 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
struct iwl_link_quality_cmd *lq, u8 flags, bool init); struct iwl_link_quality_cmd *lq, u8 flags, bool init);
void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
/** /**
* iwl_clear_driver_stations - clear knowledge of all stations from driver * iwl_clear_driver_stations - clear knowledge of all stations from driver
......
...@@ -359,13 +359,12 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, ...@@ -359,13 +359,12 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
txq->need_update = 0; txq->need_update = 0;
/* /*
* Aggregation TX queues will get their ID when aggregation begins; * For the default queues 0-3, set up the swq_id
* they overwrite the setting done here. The command FIFO doesn't * already -- all others need to get one later
* need an swq_id so don't set one to catch errors, all others can * (if they need one at all).
* be set up to the identity mapping.
*/ */
if (txq_id != priv->cmd_queue) if (txq_id < 4)
txq->swq_id = txq_id; iwl_set_swq_id(txq, txq_id, txq_id);
/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
* iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
......
...@@ -655,7 +655,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -655,7 +655,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
} }
iwl_stop_queue(priv, skb_get_queue_mapping(skb)); iwl_stop_queue(priv, txq);
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment