Commit 1c62c72b 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 da1fdb02 9f6e1baf
...@@ -30,9 +30,11 @@ config IWLWIFI_DEBUG ...@@ -30,9 +30,11 @@ config IWLWIFI_DEBUG
config IWLWIFI_DEBUGFS config IWLWIFI_DEBUGFS
bool "iwlagn debugfs support" bool "iwlagn debugfs support"
depends on IWLWIFI && IWLWIFI_DEBUG && MAC80211_DEBUGFS depends on IWLWIFI && MAC80211_DEBUGFS
---help--- ---help---
Enable creation of debugfs files for the iwlwifi drivers. Enable creation of debugfs files for the iwlwifi drivers. This
is a low-impact option that allows getting insight into the
driver's state at runtime.
config IWLWIFI_DEVICE_TRACING config IWLWIFI_DEVICE_TRACING
bool "iwlwifi device access tracing" bool "iwlwifi device access tracing"
......
...@@ -28,6 +28,28 @@ ...@@ -28,6 +28,28 @@
#include "iwl-3945-debugfs.h" #include "iwl-3945-debugfs.h"
static int iwl3945_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
{
int p = 0;
p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
le32_to_cpu(priv->_3945.statistics.flag));
if (le32_to_cpu(priv->_3945.statistics.flag) &
UCODE_STATISTICS_CLEAR_MSK)
p += scnprintf(buf + p, bufsz - p,
"\tStatistics have been cleared\n");
p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
(le32_to_cpu(priv->_3945.statistics.flag) &
UCODE_STATISTICS_FREQUENCY_MSK)
? "2.4 GHz" : "5.2 GHz");
p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
(le32_to_cpu(priv->_3945.statistics.flag) &
UCODE_STATISTICS_NARROW_BAND_MSK)
? "enabled" : "disabled");
return p;
}
ssize_t iwl3945_ucode_rx_stats_read(struct file *file, ssize_t iwl3945_ucode_rx_stats_read(struct file *file,
char __user *user_buf, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
...@@ -70,7 +92,7 @@ ssize_t iwl3945_ucode_rx_stats_read(struct file *file, ...@@ -70,7 +92,7 @@ ssize_t iwl3945_ucode_rx_stats_read(struct file *file,
max_cck = &priv->_3945.max_delta.rx.cck; max_cck = &priv->_3945.max_delta.rx.cck;
max_general = &priv->_3945.max_delta.rx.general; max_general = &priv->_3945.max_delta.rx.general;
pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); pos += iwl3945_statistics_flag(priv, buf, bufsz);
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
"acumulative delta max\n", "acumulative delta max\n",
"Statistics_Rx - OFDM:"); "Statistics_Rx - OFDM:");
...@@ -331,7 +353,7 @@ ssize_t iwl3945_ucode_tx_stats_read(struct file *file, ...@@ -331,7 +353,7 @@ ssize_t iwl3945_ucode_tx_stats_read(struct file *file,
accum_tx = &priv->_3945.accum_statistics.tx; accum_tx = &priv->_3945.accum_statistics.tx;
delta_tx = &priv->_3945.delta_statistics.tx; delta_tx = &priv->_3945.delta_statistics.tx;
max_tx = &priv->_3945.max_delta.tx; max_tx = &priv->_3945.max_delta.tx;
pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); pos += iwl3945_statistics_flag(priv, buf, bufsz);
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
"acumulative delta max\n", "acumulative delta max\n",
"Statistics_Tx:"); "Statistics_Tx:");
...@@ -438,7 +460,7 @@ ssize_t iwl3945_ucode_general_stats_read(struct file *file, ...@@ -438,7 +460,7 @@ ssize_t iwl3945_ucode_general_stats_read(struct file *file,
accum_div = &priv->_3945.accum_statistics.general.div; accum_div = &priv->_3945.accum_statistics.general.div;
delta_div = &priv->_3945.delta_statistics.general.div; delta_div = &priv->_3945.delta_statistics.general.div;
max_div = &priv->_3945.max_delta.general.div; max_div = &priv->_3945.max_delta.general.div;
pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); pos += iwl3945_statistics_flag(priv, buf, bufsz);
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
"acumulative delta max\n", "acumulative delta max\n",
"Statistics_General:"); "Statistics_General:");
......
...@@ -352,7 +352,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv, ...@@ -352,7 +352,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
* RX handler implementations * RX handler implementations
* *
*****************************************************************************/ *****************************************************************************/
#ifdef CONFIG_IWLWIFI_DEBUG #ifdef CONFIG_IWLWIFI_DEBUGFS
/* /*
* based on the assumption of all statistics counter are in DWORD * based on the assumption of all statistics counter are in DWORD
* FIXME: This function is for debugging, do not deal with * FIXME: This function is for debugging, do not deal with
...@@ -460,7 +460,7 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv, ...@@ -460,7 +460,7 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
(int)sizeof(struct iwl3945_notif_statistics), (int)sizeof(struct iwl3945_notif_statistics),
le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
#ifdef CONFIG_IWLWIFI_DEBUG #ifdef CONFIG_IWLWIFI_DEBUGFS
iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw);
#endif #endif
iwl_recover_from_statistics(priv, pkt); iwl_recover_from_statistics(priv, pkt);
...@@ -475,7 +475,7 @@ void iwl3945_reply_statistics(struct iwl_priv *priv, ...@@ -475,7 +475,7 @@ void iwl3945_reply_statistics(struct iwl_priv *priv,
__le32 *flag = (__le32 *)&pkt->u.raw; __le32 *flag = (__le32 *)&pkt->u.raw;
if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) { if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) {
#ifdef CONFIG_IWLWIFI_DEBUG #ifdef CONFIG_IWLWIFI_DEBUGFS
memset(&priv->_3945.accum_statistics, 0, memset(&priv->_3945.accum_statistics, 0,
sizeof(struct iwl3945_notif_statistics)); sizeof(struct iwl3945_notif_statistics));
memset(&priv->_3945.delta_statistics, 0, memset(&priv->_3945.delta_statistics, 0,
...@@ -947,8 +947,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, ...@@ -947,8 +947,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]); tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]);
} }
static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate)
u16 tx_rate, u8 flags)
{ {
unsigned long flags_spin; unsigned long flags_spin;
struct iwl_station_entry *station; struct iwl_station_entry *station;
...@@ -962,10 +961,9 @@ static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, ...@@ -962,10 +961,9 @@ static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK; station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;
station->sta.rate_n_flags = cpu_to_le16(tx_rate); station->sta.rate_n_flags = cpu_to_le16(tx_rate);
station->sta.mode = STA_CONTROL_MODIFY_MSK; station->sta.mode = STA_CONTROL_MODIFY_MSK;
iwl_send_add_sta(priv, &station->sta, CMD_ASYNC);
spin_unlock_irqrestore(&priv->sta_lock, flags_spin); spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
iwl_send_add_sta(priv, &station->sta, flags);
IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n", IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n",
sta_id, tx_rate); sta_id, tx_rate);
return sta_id; return sta_id;
...@@ -2473,8 +2471,7 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv, ...@@ -2473,8 +2471,7 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id, iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id,
(priv->band == IEEE80211_BAND_5GHZ) ? (priv->band == IEEE80211_BAND_5GHZ) ?
IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP);
CMD_ASYNC);
iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id); iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id);
return 0; return 0;
......
...@@ -1542,7 +1542,7 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv) ...@@ -1542,7 +1542,7 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv)
u32 R4; u32 R4;
if (test_bit(STATUS_TEMPERATURE, &priv->status) && if (test_bit(STATUS_TEMPERATURE, &priv->status) &&
(priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)) { (priv->_agn.statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)) {
IWL_DEBUG_TEMP(priv, "Running HT40 temperature calibration\n"); IWL_DEBUG_TEMP(priv, "Running HT40 temperature calibration\n");
R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]); R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]);
R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]); R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]);
...@@ -1567,7 +1567,7 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv) ...@@ -1567,7 +1567,7 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv)
vt = sign_extend(R4, 23); vt = sign_extend(R4, 23);
else else
vt = sign_extend( vt = sign_extend(
le32_to_cpu(priv->statistics.general.temperature), 23); le32_to_cpu(priv->_agn.statistics.general.temperature), 23);
IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
...@@ -2026,6 +2026,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, ...@@ -2026,6 +2026,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
int sta_id; int sta_id;
int freed; int freed;
u8 *qc = NULL; u8 *qc = NULL;
unsigned long flags;
if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
...@@ -2050,10 +2051,10 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, ...@@ -2050,10 +2051,10 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
return; return;
} }
spin_lock_irqsave(&priv->sta_lock, flags);
if (txq->sched_retry) { if (txq->sched_retry) {
const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp);
struct iwl_ht_agg *agg = NULL; struct iwl_ht_agg *agg = NULL;
WARN_ON(!qc); WARN_ON(!qc);
agg = &priv->stations[sta_id].tid[tid].agg; agg = &priv->stations[sta_id].tid[tid].agg;
...@@ -2110,6 +2111,8 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, ...@@ -2110,6 +2111,8 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
iwl_check_abort_status(priv, tx_resp->frame_count, status); iwl_check_abort_status(priv, tx_resp->frame_count, status);
spin_unlock_irqrestore(&priv->sta_lock, flags);
} }
static int iwl4965_calc_rssi(struct iwl_priv *priv, static int iwl4965_calc_rssi(struct iwl_priv *priv,
......
...@@ -260,7 +260,7 @@ static void iwl5150_temperature(struct iwl_priv *priv) ...@@ -260,7 +260,7 @@ static void iwl5150_temperature(struct iwl_priv *priv)
u32 vt = 0; u32 vt = 0;
s32 offset = iwl_temp_calib_to_offset(priv); s32 offset = iwl_temp_calib_to_offset(priv);
vt = le32_to_cpu(priv->statistics.general.temperature); vt = le32_to_cpu(priv->_agn.statistics.general.temperature);
vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
/* now vt hold the temperature in Kelvin */ /* now vt hold the temperature in Kelvin */
priv->temperature = KELVIN_TO_CELSIUS(vt); priv->temperature = KELVIN_TO_CELSIUS(vt);
......
This diff is collapsed.
...@@ -28,6 +28,27 @@ ...@@ -28,6 +28,27 @@
#include "iwl-agn-debugfs.h" #include "iwl-agn-debugfs.h"
static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
{
int p = 0;
p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
le32_to_cpu(priv->_agn.statistics.flag));
if (le32_to_cpu(priv->_agn.statistics.flag) &
UCODE_STATISTICS_CLEAR_MSK)
p += scnprintf(buf + p, bufsz - p,
"\tStatistics have been cleared\n");
p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
(le32_to_cpu(priv->_agn.statistics.flag) &
UCODE_STATISTICS_FREQUENCY_MSK)
? "2.4 GHz" : "5.2 GHz");
p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
(le32_to_cpu(priv->_agn.statistics.flag) &
UCODE_STATISTICS_NARROW_BAND_MSK)
? "enabled" : "disabled");
return p;
}
ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
...@@ -58,24 +79,24 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, ...@@ -58,24 +79,24 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
* the last statistics notification from uCode * the last statistics notification from uCode
* might not reflect the current uCode activity * might not reflect the current uCode activity
*/ */
ofdm = &priv->statistics.rx.ofdm; ofdm = &priv->_agn.statistics.rx.ofdm;
cck = &priv->statistics.rx.cck; cck = &priv->_agn.statistics.rx.cck;
general = &priv->statistics.rx.general; general = &priv->_agn.statistics.rx.general;
ht = &priv->statistics.rx.ofdm_ht; ht = &priv->_agn.statistics.rx.ofdm_ht;
accum_ofdm = &priv->accum_statistics.rx.ofdm; accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm;
accum_cck = &priv->accum_statistics.rx.cck; accum_cck = &priv->_agn.accum_statistics.rx.cck;
accum_general = &priv->accum_statistics.rx.general; accum_general = &priv->_agn.accum_statistics.rx.general;
accum_ht = &priv->accum_statistics.rx.ofdm_ht; accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht;
delta_ofdm = &priv->delta_statistics.rx.ofdm; delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm;
delta_cck = &priv->delta_statistics.rx.cck; delta_cck = &priv->_agn.delta_statistics.rx.cck;
delta_general = &priv->delta_statistics.rx.general; delta_general = &priv->_agn.delta_statistics.rx.general;
delta_ht = &priv->delta_statistics.rx.ofdm_ht; delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht;
max_ofdm = &priv->max_delta.rx.ofdm; max_ofdm = &priv->_agn.max_delta.rx.ofdm;
max_cck = &priv->max_delta.rx.cck; max_cck = &priv->_agn.max_delta.rx.cck;
max_general = &priv->max_delta.rx.general; max_general = &priv->_agn.max_delta.rx.general;
max_ht = &priv->max_delta.rx.ofdm_ht; max_ht = &priv->_agn.max_delta.rx.ofdm_ht;
pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); pos += iwl_statistics_flag(priv, buf, bufsz);
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
"acumulative delta max\n", "acumulative delta max\n",
"Statistics_Rx - OFDM:"); "Statistics_Rx - OFDM:");
...@@ -539,11 +560,11 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, ...@@ -539,11 +560,11 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
* the last statistics notification from uCode * the last statistics notification from uCode
* might not reflect the current uCode activity * might not reflect the current uCode activity
*/ */
tx = &priv->statistics.tx; tx = &priv->_agn.statistics.tx;
accum_tx = &priv->accum_statistics.tx; accum_tx = &priv->_agn.accum_statistics.tx;
delta_tx = &priv->delta_statistics.tx; delta_tx = &priv->_agn.delta_statistics.tx;
max_tx = &priv->max_delta.tx; max_tx = &priv->_agn.max_delta.tx;
pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); pos += iwl_statistics_flag(priv, buf, bufsz);
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
"acumulative delta max\n", "acumulative delta max\n",
"Statistics_Tx:"); "Statistics_Tx:");
...@@ -756,19 +777,19 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, ...@@ -756,19 +777,19 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
* the last statistics notification from uCode * the last statistics notification from uCode
* might not reflect the current uCode activity * might not reflect the current uCode activity
*/ */
general = &priv->statistics.general; general = &priv->_agn.statistics.general;
dbg = &priv->statistics.general.dbg; dbg = &priv->_agn.statistics.general.dbg;
div = &priv->statistics.general.div; div = &priv->_agn.statistics.general.div;
accum_general = &priv->accum_statistics.general; accum_general = &priv->_agn.accum_statistics.general;
delta_general = &priv->delta_statistics.general; delta_general = &priv->_agn.delta_statistics.general;
max_general = &priv->max_delta.general; max_general = &priv->_agn.max_delta.general;
accum_dbg = &priv->accum_statistics.general.dbg; accum_dbg = &priv->_agn.accum_statistics.general.dbg;
delta_dbg = &priv->delta_statistics.general.dbg; delta_dbg = &priv->_agn.delta_statistics.general.dbg;
max_dbg = &priv->max_delta.general.dbg; max_dbg = &priv->_agn.max_delta.general.dbg;
accum_div = &priv->accum_statistics.general.div; accum_div = &priv->_agn.accum_statistics.general.div;
delta_div = &priv->delta_statistics.general.div; delta_div = &priv->_agn.delta_statistics.general.div;
max_div = &priv->max_delta.general.div; max_div = &priv->_agn.max_delta.general.div;
pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); pos += iwl_statistics_flag(priv, buf, bufsz);
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
"acumulative delta max\n", "acumulative delta max\n",
"Statistics_General:"); "Statistics_General:");
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#include "iwl-io.h" #include "iwl-io.h"
#include "iwl-agn.h" #include "iwl-agn.h"
static int iwlagn_send_rxon_assoc(struct iwl_priv *priv) int iwlagn_send_rxon_assoc(struct iwl_priv *priv)
{ {
int ret = 0; int ret = 0;
struct iwl5000_rxon_assoc_cmd rxon_assoc; struct iwl5000_rxon_assoc_cmd rxon_assoc;
...@@ -84,7 +84,7 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv) ...@@ -84,7 +84,7 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv)
return ret; return ret;
} }
static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
{ {
struct iwl_tx_ant_config_cmd tx_ant_cmd = { struct iwl_tx_ant_config_cmd tx_ant_cmd = {
.valid = cpu_to_le32(valid_tx_ant), .valid = cpu_to_le32(valid_tx_ant),
......
...@@ -184,6 +184,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, ...@@ -184,6 +184,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
int tid; int tid;
int sta_id; int sta_id;
int freed; int freed;
unsigned long flags;
if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
...@@ -199,9 +200,10 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, ...@@ -199,9 +200,10 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS; tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS;
sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS; sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS;
spin_lock_irqsave(&priv->sta_lock, flags);
if (txq->sched_retry) { if (txq->sched_retry) {
const u32 scd_ssn = iwlagn_get_scd_ssn(tx_resp); const u32 scd_ssn = iwlagn_get_scd_ssn(tx_resp);
struct iwl_ht_agg *agg = NULL; struct iwl_ht_agg *agg;
agg = &priv->stations[sta_id].tid[tid].agg; agg = &priv->stations[sta_id].tid[tid].agg;
...@@ -256,6 +258,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, ...@@ -256,6 +258,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
iwl_check_abort_status(priv, tx_resp->frame_count, status); iwl_check_abort_status(priv, tx_resp->frame_count, status);
spin_unlock_irqrestore(&priv->sta_lock, flags);
} }
void iwlagn_rx_handler_setup(struct iwl_priv *priv) void iwlagn_rx_handler_setup(struct iwl_priv *priv)
...@@ -319,7 +322,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) ...@@ -319,7 +322,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
void iwlagn_temperature(struct iwl_priv *priv) void iwlagn_temperature(struct iwl_priv *priv)
{ {
/* store temperature from statistics (in Celsius) */ /* store temperature from statistics (in Celsius) */
priv->temperature = le32_to_cpu(priv->statistics.general.temperature); priv->temperature =
le32_to_cpu(priv->_agn.statistics.general.temperature);
iwl_tt_handler(priv); iwl_tt_handler(priv);
} }
...@@ -1528,3 +1532,18 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, ...@@ -1528,3 +1532,18 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id, return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
vif->bss_conf.bssid); vif->bss_conf.bssid);
} }
void iwl_free_tfds_in_queue(struct iwl_priv *priv,
int sta_id, int tid, int freed)
{
WARN_ON(!spin_is_locked(&priv->sta_lock));
if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
else {
IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n",
priv->stations[sta_id].tid[tid].tfds_in_queue,
freed);
priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
}
}
...@@ -567,10 +567,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -567,10 +567,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
hdr_len = ieee80211_hdrlen(fc); hdr_len = ieee80211_hdrlen(fc);
/* Find index into station table for destination station */ /* Find index into station table for destination station */
if (!info->control.sta) sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta);
sta_id = priv->hw_params.bcast_sta_id;
else
sta_id = iwl_sta_id(info->control.sta);
if (sta_id == IWL_INVALID_STATION) { if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1); hdr->addr1);
...@@ -598,11 +595,17 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -598,11 +595,17 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
} }
txq_id = get_queue_from_ac(skb_get_queue_mapping(skb)); txq_id = get_queue_from_ac(skb_get_queue_mapping(skb));
/* irqs already disabled/saved above when locking priv->lock */
spin_lock(&priv->sta_lock);
if (ieee80211_is_data_qos(fc)) { if (ieee80211_is_data_qos(fc)) {
qc = ieee80211_get_qos_ctl(hdr); qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
if (unlikely(tid >= MAX_TID_COUNT)) if (WARN_ON_ONCE(tid >= MAX_TID_COUNT)) {
spin_unlock(&priv->sta_lock);
goto drop_unlock; goto drop_unlock;
}
seq_number = priv->stations[sta_id].tid[tid].seq_number; seq_number = priv->stations[sta_id].tid[tid].seq_number;
seq_number &= IEEE80211_SCTL_SEQ; seq_number &= IEEE80211_SCTL_SEQ;
hdr->seq_ctrl = hdr->seq_ctrl & hdr->seq_ctrl = hdr->seq_ctrl &
...@@ -620,11 +623,18 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -620,11 +623,18 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
swq_id = txq->swq_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)) {
spin_unlock(&priv->sta_lock);
goto drop_unlock; goto drop_unlock;
}
if (ieee80211_is_data_qos(fc)) if (ieee80211_is_data_qos(fc)) {
priv->stations[sta_id].tid[tid].tfds_in_queue++; priv->stations[sta_id].tid[tid].tfds_in_queue++;
if (!ieee80211_has_morefrags(fc))
priv->stations[sta_id].tid[tid].seq_number = seq_number;
}
spin_unlock(&priv->sta_lock);
/* Set up driver data for this TFD */ /* Set up driver data for this TFD */
memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
...@@ -703,8 +713,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -703,8 +713,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (!ieee80211_has_morefrags(hdr->frame_control)) { if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1; txq->need_update = 1;
if (qc)
priv->stations[sta_id].tid[tid].seq_number = seq_number;
} else { } else {
wait_write_ptr = 1; wait_write_ptr = 1;
txq->need_update = 0; txq->need_update = 0;
...@@ -1009,6 +1017,8 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, ...@@ -1009,6 +1017,8 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
if (ret) if (ret)
return ret; return ret;
spin_lock_irqsave(&priv->sta_lock, flags);
tid_data = &priv->stations[sta_id].tid[tid];
if (tid_data->tfds_in_queue == 0) { if (tid_data->tfds_in_queue == 0) {
IWL_DEBUG_HT(priv, "HW queue is empty\n"); IWL_DEBUG_HT(priv, "HW queue is empty\n");
tid_data->agg.state = IWL_AGG_ON; tid_data->agg.state = IWL_AGG_ON;
...@@ -1018,6 +1028,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, ...@@ -1018,6 +1028,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
tid_data->tfds_in_queue); tid_data->tfds_in_queue);
tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
} }
spin_unlock_irqrestore(&priv->sta_lock, flags);
return ret; return ret;
} }
...@@ -1040,11 +1051,14 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, ...@@ -1040,11 +1051,14 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
return -ENXIO; return -ENXIO;
} }
spin_lock_irqsave(&priv->sta_lock, flags);
if (priv->stations[sta_id].tid[tid].agg.state == if (priv->stations[sta_id].tid[tid].agg.state ==
IWL_EMPTYING_HW_QUEUE_ADDBA) { IWL_EMPTYING_HW_QUEUE_ADDBA) {
IWL_DEBUG_HT(priv, "AGG stop before setup done\n"); IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
spin_unlock_irqrestore(&priv->sta_lock, flags);
return 0; return 0;
} }
...@@ -1062,13 +1076,17 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, ...@@ -1062,13 +1076,17 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n"); IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n");
priv->stations[sta_id].tid[tid].agg.state = priv->stations[sta_id].tid[tid].agg.state =
IWL_EMPTYING_HW_QUEUE_DELBA; IWL_EMPTYING_HW_QUEUE_DELBA;
spin_unlock_irqrestore(&priv->sta_lock, flags);
return 0; return 0;
} }
IWL_DEBUG_HT(priv, "HW queue is empty\n"); IWL_DEBUG_HT(priv, "HW queue is empty\n");
priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
spin_lock_irqsave(&priv->lock, flags); /* do not restore/save irqs */
spin_unlock(&priv->sta_lock);
spin_lock(&priv->lock);
/* /*
* the only reason this call can fail is queue number out of range, * the only reason this call can fail is queue number out of range,
* which can happen if uCode is reloaded and all the station * which can happen if uCode is reloaded and all the station
...@@ -1092,6 +1110,8 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, ...@@ -1092,6 +1110,8 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
u8 *addr = priv->stations[sta_id].sta.sta.addr; u8 *addr = priv->stations[sta_id].sta.sta.addr;
struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid];
WARN_ON(!spin_is_locked(&priv->sta_lock));
switch (priv->stations[sta_id].tid[tid].agg.state) { switch (priv->stations[sta_id].tid[tid].agg.state) {
case IWL_EMPTYING_HW_QUEUE_DELBA: case IWL_EMPTYING_HW_QUEUE_DELBA:
/* We are reclaiming the last packet of the */ /* We are reclaiming the last packet of the */
...@@ -1116,6 +1136,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, ...@@ -1116,6 +1136,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
} }
break; break;
} }
return 0; return 0;
} }
...@@ -1279,6 +1300,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, ...@@ -1279,6 +1300,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
int index; int index;
int sta_id; int sta_id;
int tid; int tid;
unsigned long flags;
/* "flow" corresponds to Tx queue */ /* "flow" corresponds to Tx queue */
u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
...@@ -1301,7 +1323,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, ...@@ -1301,7 +1323,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
/* Find index just before block-ack window */ /* Find index just before block-ack window */
index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
/* TODO: Need to get this copy more safely - now good for debug */ spin_lock_irqsave(&priv->sta_lock, flags);
IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, " IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
"sta_id = %d\n", "sta_id = %d\n",
...@@ -1337,4 +1359,6 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, ...@@ -1337,4 +1359,6 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow); iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow);
} }
spin_unlock_irqrestore(&priv->sta_lock, flags);
} }
...@@ -423,3 +423,126 @@ int iwlagn_alive_notify(struct iwl_priv *priv) ...@@ -423,3 +423,126 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
return 0; return 0;
} }
/**
* iwl_verify_inst_sparse - verify runtime uCode image in card vs. host,
* using sample data 100 bytes apart. If these sample points are good,
* it's a pretty good bet that everything between them is good, too.
*/
static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
{
u32 val;
int ret = 0;
u32 errcnt = 0;
u32 i;
IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
/* read data comes through single port, auto-incr addr */
/* NOTE: Use the debugless read so we don't flood kernel log
* if IWL_DL_IO is set */
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
i + IWLAGN_RTC_INST_LOWER_BOUND);
val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
ret = -EIO;
errcnt++;
if (errcnt >= 3)
break;
}
}
return ret;
}
/**
* iwlcore_verify_inst_full - verify runtime uCode image in card vs. host,
* looking at all data.
*/
static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
u32 len)
{
u32 val;
u32 save_len = len;
int ret = 0;
u32 errcnt;
IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
IWLAGN_RTC_INST_LOWER_BOUND);
errcnt = 0;
for (; len > 0; len -= sizeof(u32), image++) {
/* read data comes through single port, auto-incr addr */
/* NOTE: Use the debugless read so we don't flood kernel log
* if IWL_DL_IO is set */
val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
IWL_ERR(priv, "uCode INST section is invalid at "
"offset 0x%x, is 0x%x, s/b 0x%x\n",
save_len - len, val, le32_to_cpu(*image));
ret = -EIO;
errcnt++;
if (errcnt >= 20)
break;
}
}
if (!errcnt)
IWL_DEBUG_INFO(priv,
"ucode image in INSTRUCTION memory is good\n");
return ret;
}
/**
* iwl_verify_ucode - determine which instruction image is in SRAM,
* and verify its contents
*/
int iwl_verify_ucode(struct iwl_priv *priv)
{
__le32 *image;
u32 len;
int ret;
/* Try bootstrap */
image = (__le32 *)priv->ucode_boot.v_addr;
len = priv->ucode_boot.len;
ret = iwlcore_verify_inst_sparse(priv, image, len);
if (!ret) {
IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
return 0;
}
/* Try initialize */
image = (__le32 *)priv->ucode_init.v_addr;
len = priv->ucode_init.len;
ret = iwlcore_verify_inst_sparse(priv, image, len);
if (!ret) {
IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
return 0;
}
/* Try runtime/protocol */
image = (__le32 *)priv->ucode_code.v_addr;
len = priv->ucode_code.len;
ret = iwlcore_verify_inst_sparse(priv, image, len);
if (!ret) {
IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
return 0;
}
IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
/* Since nothing seems to match, show first several data entries in
* instruction SRAM, so maybe visual inspection will give a clue.
* Selection of bootstrap image (vs. other images) is arbitrary. */
image = (__le32 *)priv->ucode_boot.v_addr;
len = priv->ucode_boot.len;
ret = iwl_verify_inst_full(priv, image, len);
return ret;
}
This diff is collapsed.
...@@ -65,6 +65,33 @@ ...@@ -65,6 +65,33 @@
#include "iwl-dev.h" #include "iwl-dev.h"
/* configuration for the _agn devices */
extern struct iwl_cfg iwl4965_agn_cfg;
extern struct iwl_cfg iwl5300_agn_cfg;
extern struct iwl_cfg iwl5100_agn_cfg;
extern struct iwl_cfg iwl5350_agn_cfg;
extern struct iwl_cfg iwl5100_bgn_cfg;
extern struct iwl_cfg iwl5100_abg_cfg;
extern struct iwl_cfg iwl5150_agn_cfg;
extern struct iwl_cfg iwl5150_abg_cfg;
extern struct iwl_cfg iwl6000g2a_2agn_cfg;
extern struct iwl_cfg iwl6000g2a_2abg_cfg;
extern struct iwl_cfg iwl6000g2a_2bg_cfg;
extern struct iwl_cfg iwl6000g2b_bgn_cfg;
extern struct iwl_cfg iwl6000g2b_bg_cfg;
extern struct iwl_cfg iwl6000g2b_2agn_cfg;
extern struct iwl_cfg iwl6000g2b_2abg_cfg;
extern struct iwl_cfg iwl6000g2b_2bgn_cfg;
extern struct iwl_cfg iwl6000g2b_2bg_cfg;
extern struct iwl_cfg iwl6000i_2agn_cfg;
extern struct iwl_cfg iwl6000i_2abg_cfg;
extern struct iwl_cfg iwl6000i_2bg_cfg;
extern struct iwl_cfg iwl6000_3agn_cfg;
extern struct iwl_cfg iwl6050_2agn_cfg;
extern struct iwl_cfg iwl6050_2abg_cfg;
extern struct iwl_cfg iwl1000_bgn_cfg;
extern struct iwl_cfg iwl1000_bg_cfg;
extern struct iwl_mod_params iwlagn_mod_params; extern struct iwl_mod_params iwlagn_mod_params;
extern struct iwl_hcmd_ops iwlagn_hcmd; extern struct iwl_hcmd_ops iwlagn_hcmd;
extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils; extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
...@@ -93,6 +120,8 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, ...@@ -93,6 +120,8 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
u16 ssn_idx, u8 tx_fifo); u16 ssn_idx, u8 tx_fifo);
void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask); void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask);
void iwl_free_tfds_in_queue(struct iwl_priv *priv,
int sta_id, int tid, int freed);
/* uCode */ /* uCode */
int iwlagn_load_ucode(struct iwl_priv *priv); int iwlagn_load_ucode(struct iwl_priv *priv);
...@@ -102,6 +131,7 @@ void iwlagn_rx_calib_complete(struct iwl_priv *priv, ...@@ -102,6 +131,7 @@ void iwlagn_rx_calib_complete(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb); struct iwl_rx_mem_buffer *rxb);
void iwlagn_init_alive_start(struct iwl_priv *priv); void iwlagn_init_alive_start(struct iwl_priv *priv);
int iwlagn_alive_notify(struct iwl_priv *priv); int iwlagn_alive_notify(struct iwl_priv *priv);
int iwl_verify_ucode(struct iwl_priv *priv);
/* lib */ /* lib */
void iwl_check_abort_status(struct iwl_priv *priv, void iwl_check_abort_status(struct iwl_priv *priv,
...@@ -178,4 +208,8 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); ...@@ -178,4 +208,8 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
int iwlagn_manage_ibss_station(struct iwl_priv *priv, int iwlagn_manage_ibss_station(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add); struct ieee80211_vif *vif, bool add);
/* hcmd */
int iwlagn_send_rxon_assoc(struct iwl_priv *priv);
int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
#endif /* __iwl_agn_h__ */ #endif /* __iwl_agn_h__ */
...@@ -952,7 +952,6 @@ struct iwl_qosparam_cmd { ...@@ -952,7 +952,6 @@ struct iwl_qosparam_cmd {
/* Special, dedicated locations within device's station table */ /* Special, dedicated locations within device's station table */
#define IWL_AP_ID 0 #define IWL_AP_ID 0
#define IWL_MULTICAST_ID 1
#define IWL_STA_ID 2 #define IWL_STA_ID 2
#define IWL3945_BROADCAST_ID 24 #define IWL3945_BROADCAST_ID 24
#define IWL3945_STATION_COUNT 25 #define IWL3945_STATION_COUNT 25
......
...@@ -457,7 +457,7 @@ u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv, ...@@ -457,7 +457,7 @@ u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
if (!sta_ht_inf->ht_supported) if (!sta_ht_inf->ht_supported)
return 0; return 0;
} }
#ifdef CONFIG_IWLWIFI_DEBUG #ifdef CONFIG_IWLWIFI_DEBUGFS
if (priv->disable_ht40) if (priv->disable_ht40)
return 0; return 0;
#endif #endif
...@@ -904,14 +904,11 @@ static void iwl_set_flags_for_band(struct iwl_priv *priv, ...@@ -904,14 +904,11 @@ static void iwl_set_flags_for_band(struct iwl_priv *priv,
priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
} else { } else {
/* Copied from iwl_post_associate() */ /* Copied from iwl_post_associate() */
if (vif && vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) if (vif && vif->bss_conf.use_short_slot)
priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
else else
priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
if (vif && vif->type == NL80211_IFTYPE_ADHOC)
priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK; priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK; priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
...@@ -1463,130 +1460,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) ...@@ -1463,130 +1460,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
} }
EXPORT_SYMBOL(iwl_send_statistics_request); EXPORT_SYMBOL(iwl_send_statistics_request);
/**
* iwl_verify_inst_sparse - verify runtime uCode image in card vs. host,
* using sample data 100 bytes apart. If these sample points are good,
* it's a pretty good bet that everything between them is good, too.
*/
static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
{
u32 val;
int ret = 0;
u32 errcnt = 0;
u32 i;
IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
/* read data comes through single port, auto-incr addr */
/* NOTE: Use the debugless read so we don't flood kernel log
* if IWL_DL_IO is set */
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
i + IWL49_RTC_INST_LOWER_BOUND);
val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
ret = -EIO;
errcnt++;
if (errcnt >= 3)
break;
}
}
return ret;
}
/**
* iwlcore_verify_inst_full - verify runtime uCode image in card vs. host,
* looking at all data.
*/
static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
u32 len)
{
u32 val;
u32 save_len = len;
int ret = 0;
u32 errcnt;
IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
IWL49_RTC_INST_LOWER_BOUND);
errcnt = 0;
for (; len > 0; len -= sizeof(u32), image++) {
/* read data comes through single port, auto-incr addr */
/* NOTE: Use the debugless read so we don't flood kernel log
* if IWL_DL_IO is set */
val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
IWL_ERR(priv, "uCode INST section is invalid at "
"offset 0x%x, is 0x%x, s/b 0x%x\n",
save_len - len, val, le32_to_cpu(*image));
ret = -EIO;
errcnt++;
if (errcnt >= 20)
break;
}
}
if (!errcnt)
IWL_DEBUG_INFO(priv,
"ucode image in INSTRUCTION memory is good\n");
return ret;
}
/**
* iwl_verify_ucode - determine which instruction image is in SRAM,
* and verify its contents
*/
int iwl_verify_ucode(struct iwl_priv *priv)
{
__le32 *image;
u32 len;
int ret;
/* Try bootstrap */
image = (__le32 *)priv->ucode_boot.v_addr;
len = priv->ucode_boot.len;
ret = iwlcore_verify_inst_sparse(priv, image, len);
if (!ret) {
IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
return 0;
}
/* Try initialize */
image = (__le32 *)priv->ucode_init.v_addr;
len = priv->ucode_init.len;
ret = iwlcore_verify_inst_sparse(priv, image, len);
if (!ret) {
IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
return 0;
}
/* Try runtime/protocol */
image = (__le32 *)priv->ucode_code.v_addr;
len = priv->ucode_code.len;
ret = iwlcore_verify_inst_sparse(priv, image, len);
if (!ret) {
IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
return 0;
}
IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
/* Since nothing seems to match, show first several data entries in
* instruction SRAM, so maybe visual inspection will give a clue.
* Selection of bootstrap image (vs. other images) is arbitrary. */
image = (__le32 *)priv->ucode_boot.v_addr;
len = priv->ucode_boot.len;
ret = iwl_verify_inst_full(priv, image, len);
return ret;
}
EXPORT_SYMBOL(iwl_verify_ucode);
void iwl_rf_kill_ct_config(struct iwl_priv *priv) void iwl_rf_kill_ct_config(struct iwl_priv *priv)
{ {
struct iwl_ct_kill_config cmd; struct iwl_ct_kill_config cmd;
......
...@@ -472,8 +472,6 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, ...@@ -472,8 +472,6 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
dma_addr_t addr, u16 len, u8 reset, u8 pad); dma_addr_t addr, u16 len, u8 reset, u8 pad);
int iwl_hw_tx_queue_init(struct iwl_priv *priv, int iwl_hw_tx_queue_init(struct iwl_priv *priv,
struct iwl_tx_queue *txq); struct iwl_tx_queue *txq);
void iwl_free_tfds_in_queue(struct iwl_priv *priv,
int sta_id, int tid, int freed);
void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
int slots_num, u32 txq_id); int slots_num, u32 txq_id);
...@@ -691,7 +689,6 @@ extern void iwl_rf_kill_ct_config(struct iwl_priv *priv); ...@@ -691,7 +689,6 @@ extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
extern void iwl_send_bt_config(struct iwl_priv *priv); extern void iwl_send_bt_config(struct iwl_priv *priv);
extern int iwl_send_statistics_request(struct iwl_priv *priv, extern int iwl_send_statistics_request(struct iwl_priv *priv,
u8 flags, bool clear); u8 flags, bool clear);
extern int iwl_verify_ucode(struct iwl_priv *priv);
extern int iwl_send_lq_cmd(struct iwl_priv *priv, extern int iwl_send_lq_cmd(struct iwl_priv *priv,
struct iwl_link_quality_cmd *lq, u8 flags, bool init); struct iwl_link_quality_cmd *lq, u8 flags, bool init);
void iwl_apm_stop(struct iwl_priv *priv); void iwl_apm_stop(struct iwl_priv *priv);
......
...@@ -106,27 +106,6 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ ...@@ -106,27 +106,6 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
.open = iwl_dbgfs_open_file_generic, \ .open = iwl_dbgfs_open_file_generic, \
}; };
int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
{
int p = 0;
p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
le32_to_cpu(priv->statistics.flag));
if (le32_to_cpu(priv->statistics.flag) & UCODE_STATISTICS_CLEAR_MSK)
p += scnprintf(buf + p, bufsz - p,
"\tStatistics have been cleared\n");
p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
(le32_to_cpu(priv->statistics.flag) &
UCODE_STATISTICS_FREQUENCY_MSK)
? "2.4 GHz" : "5.2 GHz");
p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
(le32_to_cpu(priv->statistics.flag) &
UCODE_STATISTICS_NARROW_BAND_MSK)
? "enabled" : "disabled");
return p;
}
EXPORT_SYMBOL(iwl_dbgfs_statistics_flag);
static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file, static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
char __user *user_buf, char __user *user_buf,
size_t count, loff_t *ppos) { size_t count, loff_t *ppos) {
...@@ -330,46 +309,36 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, ...@@ -330,46 +309,36 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
for (i = 0; i < max_sta; i++) { for (i = 0; i < max_sta; i++) {
station = &priv->stations[i]; station = &priv->stations[i];
if (station->used) { if (!station->used)
pos += scnprintf(buf + pos, bufsz - pos, continue;
"station %d:\ngeneral data:\n", i+1);
pos += scnprintf(buf + pos, bufsz - pos, "id: %u\n",
station->sta.sta.sta_id);
pos += scnprintf(buf + pos, bufsz - pos, "mode: %u\n",
station->sta.mode);
pos += scnprintf(buf + pos, bufsz - pos, pos += scnprintf(buf + pos, bufsz - pos,
"flags: 0x%x\n", "station %d - addr: %pM, flags: %#x\n",
i, station->sta.sta.addr,
station->sta.station_flags_msk); station->sta.station_flags_msk);
pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n");
pos += scnprintf(buf + pos, bufsz - pos,
"seq_num\t\ttxq_id");
pos += scnprintf(buf + pos, bufsz - pos,
"\tframe_count\twait_for_ba\t");
pos += scnprintf(buf + pos, bufsz - pos, pos += scnprintf(buf + pos, bufsz - pos,
"start_idx\tbitmap0\t"); "TID\tseq_num\ttxq_id\tframes\ttfds\t");
pos += scnprintf(buf + pos, bufsz - pos, pos += scnprintf(buf + pos, bufsz - pos,
"bitmap1\trate_n_flags"); "start_idx\tbitmap\t\t\trate_n_flags\n");
pos += scnprintf(buf + pos, bufsz - pos, "\n");
for (j = 0; j < MAX_TID_COUNT; j++) { for (j = 0; j < MAX_TID_COUNT; j++) {
pos += scnprintf(buf + pos, bufsz - pos, pos += scnprintf(buf + pos, bufsz - pos,
"[%d]:\t\t%u", j, "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
station->tid[j].seq_number); j, station->tid[j].seq_number,
pos += scnprintf(buf + pos, bufsz - pos,
"\t%u\t\t%u\t\t%u\t\t",
station->tid[j].agg.txq_id, station->tid[j].agg.txq_id,
station->tid[j].agg.frame_count, station->tid[j].agg.frame_count,
station->tid[j].agg.wait_for_ba); station->tid[j].tfds_in_queue,
pos += scnprintf(buf + pos, bufsz - pos,
"%u\t%llu\t%u",
station->tid[j].agg.start_idx, station->tid[j].agg.start_idx,
(unsigned long long)station->tid[j].agg.bitmap, station->tid[j].agg.bitmap,
station->tid[j].agg.rate_n_flags); station->tid[j].agg.rate_n_flags);
if (station->tid[j].agg.wait_for_ba)
pos += scnprintf(buf + pos, bufsz - pos,
" - waitforba");
pos += scnprintf(buf + pos, bufsz - pos, "\n"); pos += scnprintf(buf + pos, bufsz - pos, "\n");
} }
pos += scnprintf(buf + pos, bufsz - pos, "\n"); pos += scnprintf(buf + pos, bufsz - pos, "\n");
} }
}
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
kfree(buf); kfree(buf);
......
...@@ -48,25 +48,6 @@ ...@@ -48,25 +48,6 @@
#include "iwl-power.h" #include "iwl-power.h"
#include "iwl-agn-rs.h" #include "iwl-agn-rs.h"
/* configuration for the iwl4965 */
extern struct iwl_cfg iwl4965_agn_cfg;
extern struct iwl_cfg iwl5300_agn_cfg;
extern struct iwl_cfg iwl5100_agn_cfg;
extern struct iwl_cfg iwl5350_agn_cfg;
extern struct iwl_cfg iwl5100_bgn_cfg;
extern struct iwl_cfg iwl5100_abg_cfg;
extern struct iwl_cfg iwl5150_agn_cfg;
extern struct iwl_cfg iwl5150_abg_cfg;
extern struct iwl_cfg iwl6000g2a_2agn_cfg;
extern struct iwl_cfg iwl6000i_2agn_cfg;
extern struct iwl_cfg iwl6000i_2abg_cfg;
extern struct iwl_cfg iwl6000i_2bg_cfg;
extern struct iwl_cfg iwl6000_3agn_cfg;
extern struct iwl_cfg iwl6050_2agn_cfg;
extern struct iwl_cfg iwl6050_2abg_cfg;
extern struct iwl_cfg iwl1000_bgn_cfg;
extern struct iwl_cfg iwl1000_bg_cfg;
struct iwl_tx_queue; struct iwl_tx_queue;
/* CT-KILL constants */ /* CT-KILL constants */
...@@ -433,7 +414,7 @@ struct iwl_ht_agg { ...@@ -433,7 +414,7 @@ struct iwl_ht_agg {
struct iwl_tid_data { struct iwl_tid_data {
u16 seq_number; u16 seq_number; /* agn only */
u16 tfds_in_queue; u16 tfds_in_queue;
struct iwl_ht_agg agg; struct iwl_ht_agg agg;
}; };
...@@ -583,6 +564,12 @@ enum iwl_ucode_tlv_type { ...@@ -583,6 +564,12 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_INIT_DATA = 4, IWL_UCODE_TLV_INIT_DATA = 4,
IWL_UCODE_TLV_BOOT = 5, IWL_UCODE_TLV_BOOT = 5,
IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */
IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8,
IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9,
IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10,
IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11,
IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12,
IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13,
}; };
struct iwl_ucode_tlv { struct iwl_ucode_tlv {
...@@ -1109,7 +1096,7 @@ struct iwl_priv { ...@@ -1109,7 +1096,7 @@ struct iwl_priv {
/* force reset */ /* force reset */
struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET];
/* we allocate array of iwl4965_channel_info for NIC's valid channels. /* we allocate array of iwl_channel_info for NIC's valid channels.
* Access via channel # using indirect index array */ * Access via channel # using indirect index array */
struct iwl_channel_info *channel_info; /* channel info array */ struct iwl_channel_info *channel_info; /* channel info array */
u8 channel_count; /* # of channels */ u8 channel_count; /* # of channels */
...@@ -1174,7 +1161,7 @@ struct iwl_priv { ...@@ -1174,7 +1161,7 @@ struct iwl_priv {
struct iwl_switch_rxon switch_rxon; struct iwl_switch_rxon switch_rxon;
/* 1st responses from initialize and runtime uCode images. /* 1st responses from initialize and runtime uCode images.
* 4965's initialize alive response contains some calibration data. */ * _agn's initialize alive response contains some calibration data. */
struct iwl_init_alive_resp card_alive_init; struct iwl_init_alive_resp card_alive_init;
struct iwl_alive_resp card_alive; struct iwl_alive_resp card_alive;
...@@ -1220,18 +1207,13 @@ struct iwl_priv { ...@@ -1220,18 +1207,13 @@ struct iwl_priv {
struct iwl_power_mgr power_data; struct iwl_power_mgr power_data;
struct iwl_tt_mgmt thermal_throttle; struct iwl_tt_mgmt thermal_throttle;
struct iwl_notif_statistics statistics;
#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_notif_statistics accum_statistics;
struct iwl_notif_statistics delta_statistics;
struct iwl_notif_statistics max_delta;
#endif
/* context information */ /* context information */
u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */ u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */
u8 mac_addr[ETH_ALEN]; u8 mac_addr[ETH_ALEN];
/*station table variables */ /* station table variables */
/* Note: if lock and sta_lock are needed, lock must be acquired first */
spinlock_t sta_lock; spinlock_t sta_lock;
int num_stations; int num_stations;
struct iwl_station_entry stations[IWL_STATION_COUNT]; struct iwl_station_entry stations[IWL_STATION_COUNT];
...@@ -1273,7 +1255,7 @@ struct iwl_priv { ...@@ -1273,7 +1255,7 @@ struct iwl_priv {
struct delayed_work rfkill_poll; struct delayed_work rfkill_poll;
struct iwl3945_notif_statistics statistics; struct iwl3945_notif_statistics statistics;
#ifdef CONFIG_IWLWIFI_DEBUG #ifdef CONFIG_IWLWIFI_DEBUGFS
struct iwl3945_notif_statistics accum_statistics; struct iwl3945_notif_statistics accum_statistics;
struct iwl3945_notif_statistics delta_statistics; struct iwl3945_notif_statistics delta_statistics;
struct iwl3945_notif_statistics max_delta; struct iwl3945_notif_statistics max_delta;
...@@ -1315,6 +1297,16 @@ struct iwl_priv { ...@@ -1315,6 +1297,16 @@ struct iwl_priv {
bool last_phy_res_valid; bool last_phy_res_valid;
struct completion firmware_loading_complete; struct completion firmware_loading_complete;
struct iwl_notif_statistics statistics;
#ifdef CONFIG_IWLWIFI_DEBUGFS
struct iwl_notif_statistics accum_statistics;
struct iwl_notif_statistics delta_statistics;
struct iwl_notif_statistics max_delta;
#endif
u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
} _agn; } _agn;
#endif #endif
}; };
...@@ -1355,7 +1347,7 @@ struct iwl_priv { ...@@ -1355,7 +1347,7 @@ struct iwl_priv {
iwl_debug_level if set */ iwl_debug_level if set */
u32 framecnt_to_us; u32 framecnt_to_us;
atomic_t restrict_refcnt; atomic_t restrict_refcnt;
bool disable_ht40; #endif /* CONFIG_IWLWIFI_DEBUG */
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
/* debugfs */ /* debugfs */
u16 tx_traffic_idx; u16 tx_traffic_idx;
...@@ -1364,8 +1356,8 @@ struct iwl_priv { ...@@ -1364,8 +1356,8 @@ struct iwl_priv {
u8 *rx_traffic; u8 *rx_traffic;
struct dentry *debugfs_dir; struct dentry *debugfs_dir;
u32 dbgfs_sram_offset, dbgfs_sram_len; u32 dbgfs_sram_offset, dbgfs_sram_len;
bool disable_ht40;
#endif /* CONFIG_IWLWIFI_DEBUGFS */ #endif /* CONFIG_IWLWIFI_DEBUGFS */
#endif /* CONFIG_IWLWIFI_DEBUG */
struct work_struct txpower_work; struct work_struct txpower_work;
u32 disable_sens_cal; u32 disable_sens_cal;
......
...@@ -92,6 +92,11 @@ static inline void iwl_free_fw_desc(struct pci_dev *pci_dev, ...@@ -92,6 +92,11 @@ static inline void iwl_free_fw_desc(struct pci_dev *pci_dev,
static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev, static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
struct fw_desc *desc) struct fw_desc *desc)
{ {
if (!desc->len) {
desc->v_addr = NULL;
return -EINVAL;
}
desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len, desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len,
&desc->p_addr, GFP_KERNEL); &desc->p_addr, GFP_KERNEL);
return (desc->v_addr != NULL) ? 0 : -ENOMEM; return (desc->v_addr != NULL) ? 0 : -ENOMEM;
......
...@@ -251,7 +251,7 @@ EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif); ...@@ -251,7 +251,7 @@ EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif);
static void iwl_rx_calc_noise(struct iwl_priv *priv) static void iwl_rx_calc_noise(struct iwl_priv *priv)
{ {
struct statistics_rx_non_phy *rx_info struct statistics_rx_non_phy *rx_info
= &(priv->statistics.rx.general); = &(priv->_agn.statistics.rx.general);
int num_active_rx = 0; int num_active_rx = 0;
int total_silence = 0; int total_silence = 0;
int bcn_silence_a = int bcn_silence_a =
...@@ -286,7 +286,7 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) ...@@ -286,7 +286,7 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
last_rx_noise); last_rx_noise);
} }
#ifdef CONFIG_IWLWIFI_DEBUG #ifdef CONFIG_IWLWIFI_DEBUGFS
/* /*
* based on the assumption of all statistics counter are in DWORD * based on the assumption of all statistics counter are in DWORD
* FIXME: This function is for debugging, do not deal with * FIXME: This function is for debugging, do not deal with
...@@ -300,10 +300,10 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv, ...@@ -300,10 +300,10 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
u32 *accum_stats; u32 *accum_stats;
u32 *delta, *max_delta; u32 *delta, *max_delta;
prev_stats = (__le32 *)&priv->statistics; prev_stats = (__le32 *)&priv->_agn.statistics;
accum_stats = (u32 *)&priv->accum_statistics; accum_stats = (u32 *)&priv->_agn.accum_statistics;
delta = (u32 *)&priv->delta_statistics; delta = (u32 *)&priv->_agn.delta_statistics;
max_delta = (u32 *)&priv->max_delta; max_delta = (u32 *)&priv->_agn.max_delta;
for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics); for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics);
i += sizeof(__le32), stats++, prev_stats++, delta++, i += sizeof(__le32), stats++, prev_stats++, delta++,
...@@ -318,18 +318,18 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv, ...@@ -318,18 +318,18 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
} }
/* reset accumulative statistics for "no-counter" type statistics */ /* reset accumulative statistics for "no-counter" type statistics */
priv->accum_statistics.general.temperature = priv->_agn.accum_statistics.general.temperature =
priv->statistics.general.temperature; priv->_agn.statistics.general.temperature;
priv->accum_statistics.general.temperature_m = priv->_agn.accum_statistics.general.temperature_m =
priv->statistics.general.temperature_m; priv->_agn.statistics.general.temperature_m;
priv->accum_statistics.general.ttl_timestamp = priv->_agn.accum_statistics.general.ttl_timestamp =
priv->statistics.general.ttl_timestamp; priv->_agn.statistics.general.ttl_timestamp;
priv->accum_statistics.tx.tx_power.ant_a = priv->_agn.accum_statistics.tx.tx_power.ant_a =
priv->statistics.tx.tx_power.ant_a; priv->_agn.statistics.tx.tx_power.ant_a;
priv->accum_statistics.tx.tx_power.ant_b = priv->_agn.accum_statistics.tx.tx_power.ant_b =
priv->statistics.tx.tx_power.ant_b; priv->_agn.statistics.tx.tx_power.ant_b;
priv->accum_statistics.tx.tx_power.ant_c = priv->_agn.accum_statistics.tx.tx_power.ant_c =
priv->statistics.tx.tx_power.ant_c; priv->_agn.statistics.tx.tx_power.ant_c;
} }
#endif #endif
...@@ -364,9 +364,9 @@ bool iwl_good_plcp_health(struct iwl_priv *priv, ...@@ -364,9 +364,9 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
if (plcp_msec) { if (plcp_msec) {
combined_plcp_delta = combined_plcp_delta =
(le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) - (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) -
le32_to_cpu(priv->statistics.rx.ofdm.plcp_err)) + le32_to_cpu(priv->_agn.statistics.rx.ofdm.plcp_err)) +
(le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) - (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) -
le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err)); le32_to_cpu(priv->_agn.statistics.rx.ofdm_ht.plcp_err));
if ((combined_plcp_delta > 0) && if ((combined_plcp_delta > 0) &&
((combined_plcp_delta * 100) / plcp_msec) > ((combined_plcp_delta * 100) / plcp_msec) >
...@@ -386,10 +386,10 @@ bool iwl_good_plcp_health(struct iwl_priv *priv, ...@@ -386,10 +386,10 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
"%u, %u, %u, %u, %d, %u mSecs\n", "%u, %u, %u, %u, %d, %u mSecs\n",
priv->cfg->plcp_delta_threshold, priv->cfg->plcp_delta_threshold,
le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err), le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
le32_to_cpu(priv->statistics.rx.ofdm.plcp_err), le32_to_cpu(priv->_agn.statistics.rx.ofdm.plcp_err),
le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err), le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
le32_to_cpu( le32_to_cpu(
priv->statistics.rx.ofdm_ht.plcp_err), priv->_agn.statistics.rx.ofdm_ht.plcp_err),
combined_plcp_delta, plcp_msec); combined_plcp_delta, plcp_msec);
rc = false; rc = false;
} }
...@@ -439,21 +439,22 @@ void iwl_rx_statistics(struct iwl_priv *priv, ...@@ -439,21 +439,22 @@ void iwl_rx_statistics(struct iwl_priv *priv,
IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
(int)sizeof(priv->statistics), (int)sizeof(priv->_agn.statistics),
le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
change = ((priv->statistics.general.temperature != change = ((priv->_agn.statistics.general.temperature !=
pkt->u.stats.general.temperature) || pkt->u.stats.general.temperature) ||
((priv->statistics.flag & ((priv->_agn.statistics.flag &
STATISTICS_REPLY_FLG_HT40_MODE_MSK) != STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
(pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK))); (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
#ifdef CONFIG_IWLWIFI_DEBUG #ifdef CONFIG_IWLWIFI_DEBUGFS
iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
#endif #endif
iwl_recover_from_statistics(priv, pkt); iwl_recover_from_statistics(priv, pkt);
memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); memcpy(&priv->_agn.statistics, &pkt->u.stats,
sizeof(priv->_agn.statistics));
set_bit(STATUS_STATISTICS, &priv->status); set_bit(STATUS_STATISTICS, &priv->status);
...@@ -480,12 +481,12 @@ void iwl_reply_statistics(struct iwl_priv *priv, ...@@ -480,12 +481,12 @@ void iwl_reply_statistics(struct iwl_priv *priv,
struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_rx_packet *pkt = rxb_addr(rxb);
if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
#ifdef CONFIG_IWLWIFI_DEBUG #ifdef CONFIG_IWLWIFI_DEBUGFS
memset(&priv->accum_statistics, 0, memset(&priv->_agn.accum_statistics, 0,
sizeof(struct iwl_notif_statistics)); sizeof(struct iwl_notif_statistics));
memset(&priv->delta_statistics, 0, memset(&priv->_agn.delta_statistics, 0,
sizeof(struct iwl_notif_statistics)); sizeof(struct iwl_notif_statistics));
memset(&priv->max_delta, 0, memset(&priv->_agn.max_delta, 0,
sizeof(struct iwl_notif_statistics)); sizeof(struct iwl_notif_statistics));
#endif #endif
IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
......
...@@ -311,10 +311,10 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr, ...@@ -311,10 +311,10 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
struct ieee80211_sta_ht_cap *ht_info, struct ieee80211_sta_ht_cap *ht_info,
u8 *sta_id_r) u8 *sta_id_r)
{ {
struct iwl_station_entry *station;
unsigned long flags_spin; unsigned long flags_spin;
int ret = 0; int ret = 0;
u8 sta_id; u8 sta_id;
struct iwl_addsta_cmd sta_cmd;
*sta_id_r = 0; *sta_id_r = 0;
spin_lock_irqsave(&priv->sta_lock, flags_spin); spin_lock_irqsave(&priv->sta_lock, flags_spin);
...@@ -347,14 +347,15 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr, ...@@ -347,14 +347,15 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
} }
priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS; priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS;
station = &priv->stations[sta_id]; memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
spin_unlock_irqrestore(&priv->sta_lock, flags_spin); spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
/* Add station to device's station table */ /* Add station to device's station table */
ret = iwl_send_add_sta(priv, &station->sta, CMD_SYNC); ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
if (ret) { if (ret) {
IWL_ERR(priv, "Adding station %pM failed.\n", station->sta.sta.addr);
spin_lock_irqsave(&priv->sta_lock, flags_spin); spin_lock_irqsave(&priv->sta_lock, flags_spin);
IWL_ERR(priv, "Adding station %pM failed.\n",
priv->stations[sta_id].sta.sta.addr);
priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
spin_unlock_irqrestore(&priv->sta_lock, flags_spin); spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
...@@ -488,7 +489,7 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id) ...@@ -488,7 +489,7 @@ 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,
struct iwl_station_entry *station) const u8 *addr, int sta_id)
{ {
struct iwl_rx_packet *pkt; struct iwl_rx_packet *pkt;
int ret; int ret;
...@@ -505,7 +506,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, ...@@ -505,7 +506,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
rm_sta_cmd.num_sta = 1; rm_sta_cmd.num_sta = 1;
memcpy(&rm_sta_cmd.addr, &station->sta.sta.addr , ETH_ALEN); memcpy(&rm_sta_cmd.addr, addr, ETH_ALEN);
cmd.flags |= CMD_WANT_SKB; cmd.flags |= CMD_WANT_SKB;
...@@ -525,7 +526,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, ...@@ -525,7 +526,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
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); spin_lock_irqsave(&priv->sta_lock, flags_spin);
iwl_sta_ucode_deactivate(priv, station->sta.sta.sta_id); iwl_sta_ucode_deactivate(priv, sta_id);
spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 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;
...@@ -546,7 +547,6 @@ static int iwl_send_remove_station(struct iwl_priv *priv, ...@@ -546,7 +547,6 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
const u8 *addr) const u8 *addr)
{ {
struct iwl_station_entry *station;
unsigned long flags; unsigned long flags;
if (!iwl_is_ready(priv)) { if (!iwl_is_ready(priv)) {
...@@ -592,10 +592,9 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, ...@@ -592,10 +592,9 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
BUG_ON(priv->num_stations < 0); BUG_ON(priv->num_stations < 0);
station = &priv->stations[sta_id];
spin_unlock_irqrestore(&priv->sta_lock, flags); spin_unlock_irqrestore(&priv->sta_lock, flags);
return iwl_send_remove_station(priv, station); return iwl_send_remove_station(priv, addr, sta_id);
out_err: out_err:
spin_unlock_irqrestore(&priv->sta_lock, flags); spin_unlock_irqrestore(&priv->sta_lock, flags);
return -EINVAL; return -EINVAL;
...@@ -643,11 +642,13 @@ EXPORT_SYMBOL(iwl_clear_ucode_stations); ...@@ -643,11 +642,13 @@ EXPORT_SYMBOL(iwl_clear_ucode_stations);
*/ */
void iwl_restore_stations(struct iwl_priv *priv) void iwl_restore_stations(struct iwl_priv *priv)
{ {
struct iwl_station_entry *station; struct iwl_addsta_cmd sta_cmd;
struct iwl_link_quality_cmd lq;
unsigned long flags_spin; unsigned long flags_spin;
int i; int i;
bool found = false; bool found = false;
int ret; int ret;
bool send_lq;
if (!iwl_is_ready(priv)) { if (!iwl_is_ready(priv)) {
IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n"); IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n");
...@@ -669,13 +670,20 @@ void iwl_restore_stations(struct iwl_priv *priv) ...@@ -669,13 +670,20 @@ void iwl_restore_stations(struct iwl_priv *priv)
for (i = 0; i < priv->hw_params.max_stations; i++) { for (i = 0; i < priv->hw_params.max_stations; i++) {
if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) { if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) {
memcpy(&sta_cmd, &priv->stations[i].sta,
sizeof(struct iwl_addsta_cmd));
send_lq = false;
if (priv->stations[i].lq) {
memcpy(&lq, priv->stations[i].lq,
sizeof(struct iwl_link_quality_cmd));
send_lq = true;
}
spin_unlock_irqrestore(&priv->sta_lock, flags_spin); spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
station = &priv->stations[i]; ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
ret = iwl_send_add_sta(priv, &priv->stations[i].sta, CMD_SYNC);
if (ret) { if (ret) {
IWL_ERR(priv, "Adding station %pM failed.\n",
station->sta.sta.addr);
spin_lock_irqsave(&priv->sta_lock, flags_spin); spin_lock_irqsave(&priv->sta_lock, flags_spin);
IWL_ERR(priv, "Adding station %pM failed.\n",
priv->stations[i].sta.sta.addr);
priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE; priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE;
priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
spin_unlock_irqrestore(&priv->sta_lock, flags_spin); spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
...@@ -684,8 +692,8 @@ void iwl_restore_stations(struct iwl_priv *priv) ...@@ -684,8 +692,8 @@ void iwl_restore_stations(struct iwl_priv *priv)
* Rate scaling has already been initialized, send * Rate scaling has already been initialized, send
* current LQ command * current LQ command
*/ */
if (station->lq) if (send_lq)
iwl_send_lq_cmd(priv, station->lq, CMD_SYNC, true); iwl_send_lq_cmd(priv, &lq, CMD_SYNC, true);
spin_lock_irqsave(&priv->sta_lock, flags_spin); spin_lock_irqsave(&priv->sta_lock, flags_spin);
priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
} }
...@@ -972,24 +980,16 @@ void iwl_update_tkip_key(struct iwl_priv *priv, ...@@ -972,24 +980,16 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
unsigned long flags; unsigned long flags;
int i; int i;
if (sta) {
sta_id = iwl_sta_id(sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_MAC80211(priv, "leave - %pM not initialised.\n",
sta->addr);
return;
}
} else
sta_id = priv->hw_params.bcast_sta_id;
if (iwl_scan_cancel(priv)) { if (iwl_scan_cancel(priv)) {
/* cancel scan failed, just live w/ bad key and rely /* cancel scan failed, just live w/ bad key and rely
briefly on SW decryption */ briefly on SW decryption */
return; return;
} }
sta_id = iwl_sta_id_or_broadcast(priv, sta);
if (sta_id == IWL_INVALID_STATION)
return;
spin_lock_irqsave(&priv->sta_lock, flags); spin_lock_irqsave(&priv->sta_lock, flags);
priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
...@@ -1277,9 +1277,8 @@ void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) ...@@ -1277,9 +1277,8 @@ void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
spin_unlock_irqrestore(&priv->sta_lock, flags);
iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
spin_unlock_irqrestore(&priv->sta_lock, flags);
} }
EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid); EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid);
...@@ -1310,7 +1309,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, ...@@ -1310,7 +1309,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
int tid) int tid)
{ {
unsigned long flags; unsigned long flags;
int sta_id; int sta_id, ret;
sta_id = iwl_sta_id(sta); sta_id = iwl_sta_id(sta);
if (sta_id == IWL_INVALID_STATION) { if (sta_id == IWL_INVALID_STATION) {
...@@ -1323,10 +1322,11 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, ...@@ -1323,10 +1322,11 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
spin_unlock_irqrestore(&priv->sta_lock, flags); spin_unlock_irqrestore(&priv->sta_lock, flags);
return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, return ret;
CMD_ASYNC);
} }
EXPORT_SYMBOL(iwl_sta_rx_agg_stop); EXPORT_SYMBOL(iwl_sta_rx_agg_stop);
...@@ -1340,9 +1340,9 @@ void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) ...@@ -1340,9 +1340,9 @@ void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
priv->stations[sta_id].sta.sta.modify_mask = 0; priv->stations[sta_id].sta.sta.modify_mask = 0;
priv->stations[sta_id].sta.sleep_tx_count = 0; priv->stations[sta_id].sta.sleep_tx_count = 0;
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
spin_unlock_irqrestore(&priv->sta_lock, flags); spin_unlock_irqrestore(&priv->sta_lock, flags);
iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
} }
EXPORT_SYMBOL(iwl_sta_modify_ps_wake); EXPORT_SYMBOL(iwl_sta_modify_ps_wake);
...@@ -1357,9 +1357,9 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) ...@@ -1357,9 +1357,9 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
STA_MODIFY_SLEEP_TX_COUNT_MSK; STA_MODIFY_SLEEP_TX_COUNT_MSK;
priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt); priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
spin_unlock_irqrestore(&priv->sta_lock, flags); spin_unlock_irqrestore(&priv->sta_lock, flags);
iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
} }
EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count); EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count);
......
...@@ -107,4 +107,33 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta) ...@@ -107,4 +107,33 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta)
return ((struct iwl_station_priv_common *)sta->drv_priv)->sta_id; return ((struct iwl_station_priv_common *)sta->drv_priv)->sta_id;
} }
/**
* iwl_sta_id_or_broadcast - return sta_id or broadcast sta
* @priv: iwl priv
* @sta: mac80211 station
*
* In certain circumstances mac80211 passes a station pointer
* that may be %NULL, for example during TX or key setup. In
* that case, we need to use the broadcast station, so this
* inline wraps that pattern.
*/
static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv,
struct ieee80211_sta *sta)
{
int sta_id;
if (!sta)
return priv->hw_params.bcast_sta_id;
sta_id = iwl_sta_id(sta);
/*
* mac80211 should not be passing a partially
* initialised station!
*/
WARN_ON(sta_id == IWL_INVALID_STATION);
return sta_id;
}
#endif /* __iwl_sta_h__ */ #endif /* __iwl_sta_h__ */
...@@ -77,21 +77,6 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) ...@@ -77,21 +77,6 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
} }
EXPORT_SYMBOL(iwl_txq_update_write_ptr); EXPORT_SYMBOL(iwl_txq_update_write_ptr);
void iwl_free_tfds_in_queue(struct iwl_priv *priv,
int sta_id, int tid, int freed)
{
if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
else {
IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n",
priv->stations[sta_id].tid[tid].tfds_in_queue,
freed);
priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
}
}
EXPORT_SYMBOL(iwl_free_tfds_in_queue);
/** /**
* iwl_tx_queue_free - Deallocate DMA queue. * iwl_tx_queue_free - Deallocate DMA queue.
* @txq: Transmit queue to deallocate. * @txq: Transmit queue to deallocate.
......
...@@ -197,6 +197,7 @@ static int iwl3945_set_wep_dynamic_key_info(struct iwl_priv *priv, ...@@ -197,6 +197,7 @@ static int iwl3945_set_wep_dynamic_key_info(struct iwl_priv *priv,
static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
{ {
unsigned long flags; unsigned long flags;
struct iwl_addsta_cmd sta_cmd;
spin_lock_irqsave(&priv->sta_lock, flags); spin_lock_irqsave(&priv->sta_lock, flags);
memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));
...@@ -205,11 +206,11 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) ...@@ -205,11 +206,11 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
spin_unlock_irqrestore(&priv->sta_lock, flags); spin_unlock_irqrestore(&priv->sta_lock, flags);
IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n"); IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n");
iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0); return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
return 0;
} }
static int iwl3945_set_dynamic_key(struct iwl_priv *priv, static int iwl3945_set_dynamic_key(struct iwl_priv *priv,
...@@ -474,10 +475,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -474,10 +475,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
u8 unicast; u8 unicast;
u8 sta_id; u8 sta_id;
u8 tid = 0; u8 tid = 0;
u16 seq_number = 0;
__le16 fc; __le16 fc;
u8 wait_write_ptr = 0; u8 wait_write_ptr = 0;
u8 *qc = NULL;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
...@@ -510,10 +509,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -510,10 +509,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
hdr_len = ieee80211_hdrlen(fc); hdr_len = ieee80211_hdrlen(fc);
/* Find index into station table for destination station */ /* Find index into station table for destination station */
if (!info->control.sta) sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta);
sta_id = priv->hw_params.bcast_sta_id;
else
sta_id = iwl_sta_id(info->control.sta);
if (sta_id == IWL_INVALID_STATION) { if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1); hdr->addr1);
...@@ -523,16 +519,10 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -523,16 +519,10 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id); IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id);
if (ieee80211_is_data_qos(fc)) { if (ieee80211_is_data_qos(fc)) {
qc = ieee80211_get_qos_ctl(hdr); u8 *qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
if (unlikely(tid >= MAX_TID_COUNT)) if (unlikely(tid >= MAX_TID_COUNT))
goto drop; goto drop;
seq_number = priv->stations[sta_id].tid[tid].seq_number &
IEEE80211_SCTL_SEQ;
hdr->seq_ctrl = cpu_to_le16(seq_number) |
(hdr->seq_ctrl &
cpu_to_le16(IEEE80211_SCTL_FRAG));
seq_number += 0x10;
} }
/* Descriptor for chosen Tx queue */ /* Descriptor for chosen Tx queue */
...@@ -591,8 +581,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -591,8 +581,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (!ieee80211_has_morefrags(hdr->frame_control)) { if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1; txq->need_update = 1;
if (qc)
priv->stations[sta_id].tid[tid].seq_number = seq_number;
} else { } else {
wait_write_ptr = 1; wait_write_ptr = 1;
txq->need_update = 0; txq->need_update = 0;
...@@ -3108,19 +3096,16 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) ...@@ -3108,19 +3096,16 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
vif->bss_conf.aid, vif->bss_conf.beacon_int); vif->bss_conf.aid, vif->bss_conf.beacon_int);
if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) if (vif->bss_conf.use_short_preamble)
priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else else
priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) if (vif->bss_conf.use_short_slot)
priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
else else
priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
if (vif->type == NL80211_IFTYPE_ADHOC)
priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
} }
iwlcore_commit_rxon(priv); iwlcore_commit_rxon(priv);
...@@ -3284,8 +3269,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) ...@@ -3284,8 +3269,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
priv->staging_rxon.assoc_id = 0; priv->staging_rxon.assoc_id = 0;
if (vif->bss_conf.assoc_capability & if (vif->bss_conf.use_short_preamble)
WLAN_CAPABILITY_SHORT_PREAMBLE)
priv->staging_rxon.flags |= priv->staging_rxon.flags |=
RXON_FLG_SHORT_PREAMBLE_MSK; RXON_FLG_SHORT_PREAMBLE_MSK;
else else
...@@ -3293,17 +3277,12 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) ...@@ -3293,17 +3277,12 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
~RXON_FLG_SHORT_PREAMBLE_MSK; ~RXON_FLG_SHORT_PREAMBLE_MSK;
if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
if (vif->bss_conf.assoc_capability & if (vif->bss_conf.use_short_slot)
WLAN_CAPABILITY_SHORT_SLOT_TIME)
priv->staging_rxon.flags |= priv->staging_rxon.flags |=
RXON_FLG_SHORT_SLOT_MSK; RXON_FLG_SHORT_SLOT_MSK;
else else
priv->staging_rxon.flags &= priv->staging_rxon.flags &=
~RXON_FLG_SHORT_SLOT_MSK; ~RXON_FLG_SHORT_SLOT_MSK;
if (vif->type == NL80211_IFTYPE_ADHOC)
priv->staging_rxon.flags &=
~RXON_FLG_SHORT_SLOT_MSK;
} }
/* restore RXON assoc */ /* restore RXON assoc */
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
...@@ -3336,18 +3315,10 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ...@@ -3336,18 +3315,10 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
static_key = !iwl_is_associated(priv); static_key = !iwl_is_associated(priv);
if (!static_key) { if (!static_key) {
if (!sta) { sta_id = iwl_sta_id_or_broadcast(priv, sta);
sta_id = priv->hw_params.bcast_sta_id; if (sta_id == IWL_INVALID_STATION)
} else {
sta_id = iwl_sta_id(sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_MAC80211(priv,
"leave - %pM not in station map.\n",
sta->addr);
return -EINVAL; return -EINVAL;
} }
}
}
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
iwl_scan_cancel_timeout(priv, 100); iwl_scan_cancel_timeout(priv, 100);
......
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