Commit d06fc1d9 authored by David S. Miller's avatar David S. Miller
parents 99fee6d7 66fbb541
...@@ -71,19 +71,19 @@ struct iwl_rate_scale_priv { ...@@ -71,19 +71,19 @@ struct iwl_rate_scale_priv {
}; };
static s32 iwl_expected_tpt_g[IWL_RATE_COUNT] = { static s32 iwl_expected_tpt_g[IWL_RATE_COUNT] = {
0, 0, 76, 104, 130, 168, 191, 202, 7, 13, 35, 58 7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202
}; };
static s32 iwl_expected_tpt_g_prot[IWL_RATE_COUNT] = { static s32 iwl_expected_tpt_g_prot[IWL_RATE_COUNT] = {
0, 0, 0, 80, 93, 113, 123, 125, 7, 13, 35, 58 7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125
}; };
static s32 iwl_expected_tpt_a[IWL_RATE_COUNT] = { static s32 iwl_expected_tpt_a[IWL_RATE_COUNT] = {
40, 57, 72, 98, 121, 154, 177, 186, 0, 0, 0, 0 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186
}; };
static s32 iwl_expected_tpt_b[IWL_RATE_COUNT] = { static s32 iwl_expected_tpt_b[IWL_RATE_COUNT] = {
0, 0, 0, 0, 0, 0, 0, 0, 7, 13, 35, 58 7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0
}; };
struct iwl_tpt_entry { struct iwl_tpt_entry {
...@@ -350,6 +350,10 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, ...@@ -350,6 +350,10 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
sta->last_txrate = sta->txrate; sta->last_txrate = sta->txrate;
/* For MODE_IEEE80211A mode it start at IWL_FIRST_OFDM_RATE */
if (local->hw.conf.phymode == MODE_IEEE80211A)
sta->last_txrate += IWL_FIRST_OFDM_RATE;
IWL_DEBUG_RATE("leave\n"); IWL_DEBUG_RATE("leave\n");
} }
...@@ -417,6 +421,33 @@ static void rs_free_sta(void *priv, void *priv_sta) ...@@ -417,6 +421,33 @@ static void rs_free_sta(void *priv, void *priv_sta)
IWL_DEBUG_RATE("leave\n"); IWL_DEBUG_RATE("leave\n");
} }
/*
* get ieee prev rate from rate scale table.
* for A and B mode we need to overright prev
* value
*/
static int rs_adjust_next_rate(struct iwl_priv *priv, int rate)
{
int next_rate = iwl_get_prev_ieee_rate(rate);
switch (priv->phymode) {
case MODE_IEEE80211A:
if (rate == IWL_RATE_12M_INDEX)
next_rate = IWL_RATE_9M_INDEX;
else if (rate == IWL_RATE_6M_INDEX)
next_rate = IWL_RATE_6M_INDEX;
break;
case MODE_IEEE80211B:
if (rate == IWL_RATE_11M_INDEX_TABLE)
next_rate = IWL_RATE_5M_INDEX_TABLE;
break;
default:
break;
}
return next_rate;
}
/** /**
* rs_tx_status - Update rate control values based on Tx results * rs_tx_status - Update rate control values based on Tx results
* *
...@@ -479,7 +510,8 @@ static void rs_tx_status(void *priv_rate, ...@@ -479,7 +510,8 @@ static void rs_tx_status(void *priv_rate,
last_index = scale_rate_index; last_index = scale_rate_index;
} else { } else {
current_count = priv->retry_rate; current_count = priv->retry_rate;
last_index = iwl_get_prev_ieee_rate(scale_rate_index); last_index = rs_adjust_next_rate(priv,
scale_rate_index);
} }
/* Update this rate accounting for as many retries /* Update this rate accounting for as many retries
...@@ -494,9 +526,10 @@ static void rs_tx_status(void *priv_rate, ...@@ -494,9 +526,10 @@ static void rs_tx_status(void *priv_rate,
if (retries) if (retries)
scale_rate_index = scale_rate_index =
iwl_get_prev_ieee_rate(scale_rate_index); rs_adjust_next_rate(priv, scale_rate_index);
} }
/* Update the last index window with success/failure based on ACK */ /* Update the last index window with success/failure based on ACK */
IWL_DEBUG_RATE("Update rate %d with %s.\n", IWL_DEBUG_RATE("Update rate %d with %s.\n",
last_index, last_index,
...@@ -672,7 +705,10 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate, ...@@ -672,7 +705,10 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
} }
rate_mask = sta->supp_rates; rate_mask = sta->supp_rates;
index = min(sta->txrate & 0xffff, IWL_RATE_COUNT - 1); index = min(sta->last_txrate & 0xffff, IWL_RATE_COUNT - 1);
if (priv->phymode == (u8) MODE_IEEE80211A)
rate_mask = rate_mask << IWL_FIRST_OFDM_RATE;
rs_priv = (void *)sta->rate_ctrl_priv; rs_priv = (void *)sta->rate_ctrl_priv;
...@@ -801,7 +837,11 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate, ...@@ -801,7 +837,11 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
out: out:
sta->last_txrate = index; sta->last_txrate = index;
sta->txrate = sta->last_txrate; if (priv->phymode == (u8) MODE_IEEE80211A)
sta->txrate = sta->last_txrate - IWL_FIRST_OFDM_RATE;
else
sta->txrate = sta->last_txrate;
sta_info_put(sta); sta_info_put(sta);
IWL_DEBUG_RATE("leave: %d\n", index); IWL_DEBUG_RATE("leave: %d\n", index);
......
...@@ -36,10 +36,17 @@ struct iwl_rate_info { ...@@ -36,10 +36,17 @@ struct iwl_rate_info {
u8 next_rs; /* next rate used in rs algo */ u8 next_rs; /* next rate used in rs algo */
u8 prev_rs_tgg; /* previous rate used in TGG rs algo */ u8 prev_rs_tgg; /* previous rate used in TGG rs algo */
u8 next_rs_tgg; /* next rate used in TGG rs algo */ u8 next_rs_tgg; /* next rate used in TGG rs algo */
u8 table_rs_index; /* index in rate scale table cmd */
u8 prev_table_rs; /* prev in rate table cmd */
}; };
enum { enum {
IWL_RATE_6M_INDEX = 0, IWL_RATE_1M_INDEX = 0,
IWL_RATE_2M_INDEX,
IWL_RATE_5M_INDEX,
IWL_RATE_11M_INDEX,
IWL_RATE_6M_INDEX,
IWL_RATE_9M_INDEX, IWL_RATE_9M_INDEX,
IWL_RATE_12M_INDEX, IWL_RATE_12M_INDEX,
IWL_RATE_18M_INDEX, IWL_RATE_18M_INDEX,
...@@ -47,15 +54,27 @@ enum { ...@@ -47,15 +54,27 @@ enum {
IWL_RATE_36M_INDEX, IWL_RATE_36M_INDEX,
IWL_RATE_48M_INDEX, IWL_RATE_48M_INDEX,
IWL_RATE_54M_INDEX, IWL_RATE_54M_INDEX,
IWL_RATE_1M_INDEX,
IWL_RATE_2M_INDEX,
IWL_RATE_5M_INDEX,
IWL_RATE_11M_INDEX,
IWL_RATE_COUNT, IWL_RATE_COUNT,
IWL_RATE_INVM_INDEX, IWL_RATE_INVM_INDEX,
IWL_RATE_INVALID = IWL_RATE_INVM_INDEX IWL_RATE_INVALID = IWL_RATE_INVM_INDEX
}; };
enum {
IWL_RATE_6M_INDEX_TABLE = 0,
IWL_RATE_9M_INDEX_TABLE,
IWL_RATE_12M_INDEX_TABLE,
IWL_RATE_18M_INDEX_TABLE,
IWL_RATE_24M_INDEX_TABLE,
IWL_RATE_36M_INDEX_TABLE,
IWL_RATE_48M_INDEX_TABLE,
IWL_RATE_54M_INDEX_TABLE,
IWL_RATE_1M_INDEX_TABLE,
IWL_RATE_2M_INDEX_TABLE,
IWL_RATE_5M_INDEX_TABLE,
IWL_RATE_11M_INDEX_TABLE,
IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX,
};
enum { enum {
IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX, IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
IWL_LAST_OFDM_RATE = IWL_RATE_54M_INDEX, IWL_LAST_OFDM_RATE = IWL_RATE_54M_INDEX,
......
This diff is collapsed.
...@@ -5332,13 +5332,13 @@ static int iwl_init_geos(struct iwl_priv *priv) ...@@ -5332,13 +5332,13 @@ static int iwl_init_geos(struct iwl_priv *priv)
/* 5.2GHz channels start after the 2.4GHz channels */ /* 5.2GHz channels start after the 2.4GHz channels */
modes[A].mode = MODE_IEEE80211A; modes[A].mode = MODE_IEEE80211A;
modes[A].channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)]; modes[A].channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)];
modes[A].rates = rates; modes[A].rates = &rates[4];
modes[A].num_rates = 8; /* just OFDM */ modes[A].num_rates = 8; /* just OFDM */
modes[A].num_channels = 0; modes[A].num_channels = 0;
modes[B].mode = MODE_IEEE80211B; modes[B].mode = MODE_IEEE80211B;
modes[B].channels = channels; modes[B].channels = channels;
modes[B].rates = &rates[8]; modes[B].rates = rates;
modes[B].num_rates = 4; /* just CCK */ modes[B].num_rates = 4; /* just CCK */
modes[B].num_channels = 0; modes[B].num_channels = 0;
......
...@@ -5156,9 +5156,10 @@ static irqreturn_t iwl_isr(int irq, void *data) ...@@ -5156,9 +5156,10 @@ static irqreturn_t iwl_isr(int irq, void *data)
} }
if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
/* Hardware disappeared */ /* Hardware disappeared. It might have already raised
* an interrupt */
IWL_WARNING("HARDWARE GONE?? INTA == 0x%080x\n", inta); IWL_WARNING("HARDWARE GONE?? INTA == 0x%080x\n", inta);
goto none; goto unplugged;
} }
IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
...@@ -5166,8 +5167,9 @@ static irqreturn_t iwl_isr(int irq, void *data) ...@@ -5166,8 +5167,9 @@ static irqreturn_t iwl_isr(int irq, void *data)
/* iwl_irq_tasklet() will service interrupts and re-enable them */ /* iwl_irq_tasklet() will service interrupts and re-enable them */
tasklet_schedule(&priv->irq_tasklet); tasklet_schedule(&priv->irq_tasklet);
spin_unlock(&priv->lock);
unplugged:
spin_unlock(&priv->lock);
return IRQ_HANDLED; return IRQ_HANDLED;
none: none:
......
...@@ -620,7 +620,7 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) ...@@ -620,7 +620,7 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* up to version C the link tuning should halt after 20 * up to version C the link tuning should halt after 20
* seconds. * seconds.
*/ */
if (rt2x00_get_rev(&rt2x00dev->chip) < RT2560_VERSION_D && if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D &&
rt2x00dev->link.count > 20) rt2x00dev->link.count > 20)
return; return;
...@@ -630,7 +630,7 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) ...@@ -630,7 +630,7 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* Chipset versions C and lower should directly continue * Chipset versions C and lower should directly continue
* to the dynamic CCA tuning. * to the dynamic CCA tuning.
*/ */
if (rt2x00_get_rev(&rt2x00dev->chip) < RT2560_VERSION_D) if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D)
goto dynamic_cca_tune; goto dynamic_cca_tune;
/* /*
......
...@@ -753,7 +753,7 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) ...@@ -753,7 +753,7 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field16(&reg, MAC_CSR1_HOST_READY, 1); rt2x00_set_field16(&reg, MAC_CSR1_HOST_READY, 1);
rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg); rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg);
if (rt2x00_get_rev(&rt2x00dev->chip) >= RT2570_VERSION_C) { if (rt2x00_rev(&rt2x00dev->chip) >= RT2570_VERSION_C) {
rt2500usb_register_read(rt2x00dev, PHY_CSR2, &reg); rt2500usb_register_read(rt2x00dev, PHY_CSR2, &reg);
reg &= ~0x0002; reg &= ~0x0002;
} else { } else {
...@@ -1257,7 +1257,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) ...@@ -1257,7 +1257,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg); rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg);
rt2x00_set_chip(rt2x00dev, RT2570, value, reg); rt2x00_set_chip(rt2x00dev, RT2570, value, reg);
if (rt2x00_rev(&rt2x00dev->chip, 0xffff0)) { if (!rt2x00_check_rev(&rt2x00dev->chip, 0)) {
ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
return -ENODEV; return -ENODEV;
} }
......
...@@ -751,14 +751,16 @@ static inline char rt2x00_rf(const struct rt2x00_chip *chipset, const u16 chip) ...@@ -751,14 +751,16 @@ static inline char rt2x00_rf(const struct rt2x00_chip *chipset, const u16 chip)
return (chipset->rf == chip); return (chipset->rf == chip);
} }
static inline u16 rt2x00_get_rev(const struct rt2x00_chip *chipset) static inline u16 rt2x00_rev(const struct rt2x00_chip *chipset)
{ {
return chipset->rev; return chipset->rev;
} }
static inline u16 rt2x00_rev(const struct rt2x00_chip *chipset, const u32 mask) static inline u16 rt2x00_check_rev(const struct rt2x00_chip *chipset,
const u32 rev)
{ {
return chipset->rev & mask; return (((chipset->rev & 0xffff0) == rev) &&
!!(chipset->rev & 0x0000f));
} }
/* /*
......
...@@ -1486,7 +1486,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) ...@@ -1486,7 +1486,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
rt73usb_register_read(rt2x00dev, MAC_CSR0, &reg); rt73usb_register_read(rt2x00dev, MAC_CSR0, &reg);
rt2x00_set_chip(rt2x00dev, RT2571, value, reg); rt2x00_set_chip(rt2x00dev, RT2571, value, reg);
if (!rt2x00_rev(&rt2x00dev->chip, 0x25730)) { if (!rt2x00_check_rev(&rt2x00dev->chip, 0x25730)) {
ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
return -ENODEV; return -ENODEV;
} }
......
...@@ -242,6 +242,8 @@ struct ieee80211_if_sta { ...@@ -242,6 +242,8 @@ struct ieee80211_if_sta {
u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
u8 ssid[IEEE80211_MAX_SSID_LEN]; u8 ssid[IEEE80211_MAX_SSID_LEN];
size_t ssid_len; size_t ssid_len;
u8 scan_ssid[IEEE80211_MAX_SSID_LEN];
size_t scan_ssid_len;
u16 aid; u16 aid;
u16 ap_capab, capab; u16 ap_capab, capab;
u8 *extra_ie; /* to be added to the end of AssocReq */ u8 *extra_ie; /* to be added to the end of AssocReq */
......
...@@ -2002,7 +2002,10 @@ void ieee80211_sta_work(struct work_struct *work) ...@@ -2002,7 +2002,10 @@ void ieee80211_sta_work(struct work_struct *work)
if (ifsta->state != IEEE80211_AUTHENTICATE && if (ifsta->state != IEEE80211_AUTHENTICATE &&
ifsta->state != IEEE80211_ASSOCIATE && ifsta->state != IEEE80211_ASSOCIATE &&
test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) { test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) {
ieee80211_sta_start_scan(dev, NULL, 0); if (ifsta->scan_ssid_len)
ieee80211_sta_start_scan(dev, ifsta->scan_ssid, ifsta->scan_ssid_len);
else
ieee80211_sta_start_scan(dev, NULL, 0);
return; return;
} }
...@@ -2872,6 +2875,9 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len) ...@@ -2872,6 +2875,9 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len)
return -EBUSY; return -EBUSY;
} }
ifsta->scan_ssid_len = ssid_len;
if (ssid_len)
memcpy(ifsta->scan_ssid, ssid, ssid_len);
set_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request); set_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request);
queue_work(local->hw.workqueue, &ifsta->work); queue_work(local->hw.workqueue, &ifsta->work);
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