aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c56
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.h29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c126
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h8
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c2
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/ieee80211_sta.c8
11 files changed, 167 insertions, 84 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 262ab0b55824..c48b1b537d2b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -71,19 +71,19 @@ struct iwl_rate_scale_priv {
71}; 71};
72 72
73static s32 iwl_expected_tpt_g[IWL_RATE_COUNT] = { 73static s32 iwl_expected_tpt_g[IWL_RATE_COUNT] = {
74 0, 0, 76, 104, 130, 168, 191, 202, 7, 13, 35, 58 74 7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202
75}; 75};
76 76
77static s32 iwl_expected_tpt_g_prot[IWL_RATE_COUNT] = { 77static s32 iwl_expected_tpt_g_prot[IWL_RATE_COUNT] = {
78 0, 0, 0, 80, 93, 113, 123, 125, 7, 13, 35, 58 78 7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125
79}; 79};
80 80
81static s32 iwl_expected_tpt_a[IWL_RATE_COUNT] = { 81static s32 iwl_expected_tpt_a[IWL_RATE_COUNT] = {
82 40, 57, 72, 98, 121, 154, 177, 186, 0, 0, 0, 0 82 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186
83}; 83};
84 84
85static s32 iwl_expected_tpt_b[IWL_RATE_COUNT] = { 85static s32 iwl_expected_tpt_b[IWL_RATE_COUNT] = {
86 0, 0, 0, 0, 0, 0, 0, 0, 7, 13, 35, 58 86 7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0
87}; 87};
88 88
89struct iwl_tpt_entry { 89struct iwl_tpt_entry {
@@ -350,6 +350,10 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
350 350
351 sta->last_txrate = sta->txrate; 351 sta->last_txrate = sta->txrate;
352 352
353 /* For MODE_IEEE80211A mode it start at IWL_FIRST_OFDM_RATE */
354 if (local->hw.conf.phymode == MODE_IEEE80211A)
355 sta->last_txrate += IWL_FIRST_OFDM_RATE;
356
353 IWL_DEBUG_RATE("leave\n"); 357 IWL_DEBUG_RATE("leave\n");
354} 358}
355 359
@@ -417,6 +421,33 @@ static void rs_free_sta(void *priv, void *priv_sta)
417 IWL_DEBUG_RATE("leave\n"); 421 IWL_DEBUG_RATE("leave\n");
418} 422}
419 423
424
425/*
426 * get ieee prev rate from rate scale table.
427 * for A and B mode we need to overright prev
428 * value
429 */
430static int rs_adjust_next_rate(struct iwl_priv *priv, int rate)
431{
432 int next_rate = iwl_get_prev_ieee_rate(rate);
433
434 switch (priv->phymode) {
435 case MODE_IEEE80211A:
436 if (rate == IWL_RATE_12M_INDEX)
437 next_rate = IWL_RATE_9M_INDEX;
438 else if (rate == IWL_RATE_6M_INDEX)
439 next_rate = IWL_RATE_6M_INDEX;
440 break;
441 case MODE_IEEE80211B:
442 if (rate == IWL_RATE_11M_INDEX_TABLE)
443 next_rate = IWL_RATE_5M_INDEX_TABLE;
444 break;
445 default:
446 break;
447 }
448
449 return next_rate;
450}
420/** 451/**
421 * rs_tx_status - Update rate control values based on Tx results 452 * rs_tx_status - Update rate control values based on Tx results
422 * 453 *
@@ -479,7 +510,8 @@ static void rs_tx_status(void *priv_rate,
479 last_index = scale_rate_index; 510 last_index = scale_rate_index;
480 } else { 511 } else {
481 current_count = priv->retry_rate; 512 current_count = priv->retry_rate;
482 last_index = iwl_get_prev_ieee_rate(scale_rate_index); 513 last_index = rs_adjust_next_rate(priv,
514 scale_rate_index);
483 } 515 }
484 516
485 /* Update this rate accounting for as many retries 517 /* Update this rate accounting for as many retries
@@ -494,9 +526,10 @@ static void rs_tx_status(void *priv_rate,
494 526
495 if (retries) 527 if (retries)
496 scale_rate_index = 528 scale_rate_index =
497 iwl_get_prev_ieee_rate(scale_rate_index); 529 rs_adjust_next_rate(priv, scale_rate_index);
498 } 530 }
499 531
532
500 /* Update the last index window with success/failure based on ACK */ 533 /* Update the last index window with success/failure based on ACK */
501 IWL_DEBUG_RATE("Update rate %d with %s.\n", 534 IWL_DEBUG_RATE("Update rate %d with %s.\n",
502 last_index, 535 last_index,
@@ -672,7 +705,10 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
672 } 705 }
673 706
674 rate_mask = sta->supp_rates; 707 rate_mask = sta->supp_rates;
675 index = min(sta->txrate & 0xffff, IWL_RATE_COUNT - 1); 708 index = min(sta->last_txrate & 0xffff, IWL_RATE_COUNT - 1);
709
710 if (priv->phymode == (u8) MODE_IEEE80211A)
711 rate_mask = rate_mask << IWL_FIRST_OFDM_RATE;
676 712
677 rs_priv = (void *)sta->rate_ctrl_priv; 713 rs_priv = (void *)sta->rate_ctrl_priv;
678 714
@@ -801,7 +837,11 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
801 out: 837 out:
802 838
803 sta->last_txrate = index; 839 sta->last_txrate = index;
804 sta->txrate = sta->last_txrate; 840 if (priv->phymode == (u8) MODE_IEEE80211A)
841 sta->txrate = sta->last_txrate - IWL_FIRST_OFDM_RATE;
842 else
843 sta->txrate = sta->last_txrate;
844
805 sta_info_put(sta); 845 sta_info_put(sta);
806 846
807 IWL_DEBUG_RATE("leave: %d\n", index); 847 IWL_DEBUG_RATE("leave: %d\n", index);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
index b926738e0ea1..bec4d3ffca1d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
@@ -36,10 +36,17 @@ struct iwl_rate_info {
36 u8 next_rs; /* next rate used in rs algo */ 36 u8 next_rs; /* next rate used in rs algo */
37 u8 prev_rs_tgg; /* previous rate used in TGG rs algo */ 37 u8 prev_rs_tgg; /* previous rate used in TGG rs algo */
38 u8 next_rs_tgg; /* next rate used in TGG rs algo */ 38 u8 next_rs_tgg; /* next rate used in TGG rs algo */
39 u8 table_rs_index; /* index in rate scale table cmd */
40 u8 prev_table_rs; /* prev in rate table cmd */
41
39}; 42};
40 43
41enum { 44enum {
42 IWL_RATE_6M_INDEX = 0, 45 IWL_RATE_1M_INDEX = 0,
46 IWL_RATE_2M_INDEX,
47 IWL_RATE_5M_INDEX,
48 IWL_RATE_11M_INDEX,
49 IWL_RATE_6M_INDEX,
43 IWL_RATE_9M_INDEX, 50 IWL_RATE_9M_INDEX,
44 IWL_RATE_12M_INDEX, 51 IWL_RATE_12M_INDEX,
45 IWL_RATE_18M_INDEX, 52 IWL_RATE_18M_INDEX,
@@ -47,16 +54,28 @@ enum {
47 IWL_RATE_36M_INDEX, 54 IWL_RATE_36M_INDEX,
48 IWL_RATE_48M_INDEX, 55 IWL_RATE_48M_INDEX,
49 IWL_RATE_54M_INDEX, 56 IWL_RATE_54M_INDEX,
50 IWL_RATE_1M_INDEX,
51 IWL_RATE_2M_INDEX,
52 IWL_RATE_5M_INDEX,
53 IWL_RATE_11M_INDEX,
54 IWL_RATE_COUNT, 57 IWL_RATE_COUNT,
55 IWL_RATE_INVM_INDEX, 58 IWL_RATE_INVM_INDEX,
56 IWL_RATE_INVALID = IWL_RATE_INVM_INDEX 59 IWL_RATE_INVALID = IWL_RATE_INVM_INDEX
57}; 60};
58 61
59enum { 62enum {
63 IWL_RATE_6M_INDEX_TABLE = 0,
64 IWL_RATE_9M_INDEX_TABLE,
65 IWL_RATE_12M_INDEX_TABLE,
66 IWL_RATE_18M_INDEX_TABLE,
67 IWL_RATE_24M_INDEX_TABLE,
68 IWL_RATE_36M_INDEX_TABLE,
69 IWL_RATE_48M_INDEX_TABLE,
70 IWL_RATE_54M_INDEX_TABLE,
71 IWL_RATE_1M_INDEX_TABLE,
72 IWL_RATE_2M_INDEX_TABLE,
73 IWL_RATE_5M_INDEX_TABLE,
74 IWL_RATE_11M_INDEX_TABLE,
75 IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX,
76};
77
78enum {
60 IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX, 79 IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
61 IWL_LAST_OFDM_RATE = IWL_RATE_54M_INDEX, 80 IWL_LAST_OFDM_RATE = IWL_RATE_54M_INDEX,
62 IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX, 81 IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 19bcb01e2784..3a45fe99a83e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -54,7 +54,9 @@
54 IWL_RATE_##rp##M_INDEX, \ 54 IWL_RATE_##rp##M_INDEX, \
55 IWL_RATE_##rn##M_INDEX, \ 55 IWL_RATE_##rn##M_INDEX, \
56 IWL_RATE_##pp##M_INDEX, \ 56 IWL_RATE_##pp##M_INDEX, \
57 IWL_RATE_##np##M_INDEX } 57 IWL_RATE_##np##M_INDEX, \
58 IWL_RATE_##r##M_INDEX_TABLE, \
59 IWL_RATE_##ip##M_INDEX_TABLE }
58 60
59/* 61/*
60 * Parameter order: 62 * Parameter order:
@@ -65,6 +67,10 @@
65 * 67 *
66 */ 68 */
67const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = { 69const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
70 IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2), /* 1mbps */
71 IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5), /* 2mbps */
72 IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11), /*5.5mbps */
73 IWL_DECLARE_RATE_INFO(11, 9, 12, 5, 12, 5, 18), /* 11mbps */
68 IWL_DECLARE_RATE_INFO(6, 5, 9, 5, 11, 5, 11), /* 6mbps */ 74 IWL_DECLARE_RATE_INFO(6, 5, 9, 5, 11, 5, 11), /* 6mbps */
69 IWL_DECLARE_RATE_INFO(9, 6, 11, 5, 11, 5, 11), /* 9mbps */ 75 IWL_DECLARE_RATE_INFO(9, 6, 11, 5, 11, 5, 11), /* 9mbps */
70 IWL_DECLARE_RATE_INFO(12, 11, 18, 11, 18, 11, 18), /* 12mbps */ 76 IWL_DECLARE_RATE_INFO(12, 11, 18, 11, 18, 11, 18), /* 12mbps */
@@ -73,10 +79,6 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
73 IWL_DECLARE_RATE_INFO(36, 24, 48, 24, 48, 24, 48), /* 36mbps */ 79 IWL_DECLARE_RATE_INFO(36, 24, 48, 24, 48, 24, 48), /* 36mbps */
74 IWL_DECLARE_RATE_INFO(48, 36, 54, 36, 54, 36, 54), /* 48mbps */ 80 IWL_DECLARE_RATE_INFO(48, 36, 54, 36, 54, 36, 54), /* 48mbps */
75 IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */ 81 IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */
76 IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2), /* 1mbps */
77 IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5), /* 2mbps */
78 IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11), /*5.5mbps */
79 IWL_DECLARE_RATE_INFO(11, 9, 12, 5, 12, 5, 18), /* 11mbps */
80}; 82};
81 83
82/* 1 = enable the iwl_disable_events() function */ 84/* 1 = enable the iwl_disable_events() function */
@@ -662,10 +664,11 @@ void iwl_hw_build_tx_cmd_rate(struct iwl_priv *priv,
662 cmd->cmd.tx.tx_flags = tx_flags; 664 cmd->cmd.tx.tx_flags = tx_flags;
663 665
664 /* OFDM */ 666 /* OFDM */
665 cmd->cmd.tx.supp_rates[0] = rate_mask & IWL_OFDM_RATES_MASK; 667 cmd->cmd.tx.supp_rates[0] =
668 ((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF;
666 669
667 /* CCK */ 670 /* CCK */
668 cmd->cmd.tx.supp_rates[1] = (rate_mask >> 8) & 0xF; 671 cmd->cmd.tx.supp_rates[1] = (rate_mask & 0xF);
669 672
670 IWL_DEBUG_RATE("Tx sta id: %d, rate: %d (plcp), flags: 0x%4X " 673 IWL_DEBUG_RATE("Tx sta id: %d, rate: %d (plcp), flags: 0x%4X "
671 "cck/ofdm mask: 0x%x/0x%x\n", sta_id, 674 "cck/ofdm mask: 0x%x/0x%x\n", sta_id,
@@ -1432,7 +1435,7 @@ static void iwl_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index,
1432 /* use this channel group's 6Mbit clipping/saturation pwr, 1435 /* use this channel group's 6Mbit clipping/saturation pwr,
1433 * but cap at regulatory scan power restriction (set during init 1436 * but cap at regulatory scan power restriction (set during init
1434 * based on eeprom channel data) for this channel. */ 1437 * based on eeprom channel data) for this channel. */
1435 power = min(ch_info->scan_power, clip_pwrs[IWL_RATE_6M_INDEX]); 1438 power = min(ch_info->scan_power, clip_pwrs[IWL_RATE_6M_INDEX_TABLE]);
1436 1439
1437 /* further limit to user's max power preference. 1440 /* further limit to user's max power preference.
1438 * FIXME: Other spectrum management power limitations do not 1441 * FIXME: Other spectrum management power limitations do not
@@ -1447,7 +1450,7 @@ static void iwl_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index,
1447 * *index*. */ 1450 * *index*. */
1448 power_index = ch_info->power_info[rate_index].power_table_index 1451 power_index = ch_info->power_info[rate_index].power_table_index
1449 - (power - ch_info->power_info 1452 - (power - ch_info->power_info
1450 [IWL_RATE_6M_INDEX].requested_power) * 2; 1453 [IWL_RATE_6M_INDEX_TABLE].requested_power) * 2;
1451 1454
1452 /* store reference index that we use when adjusting *all* scan 1455 /* store reference index that we use when adjusting *all* scan
1453 * powers. So we can accommodate user (all channel) or spectrum 1456 * powers. So we can accommodate user (all channel) or spectrum
@@ -1476,7 +1479,7 @@ static void iwl_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index,
1476 */ 1479 */
1477int iwl_hw_reg_send_txpower(struct iwl_priv *priv) 1480int iwl_hw_reg_send_txpower(struct iwl_priv *priv)
1478{ 1481{
1479 int rate_idx; 1482 int rate_idx, i;
1480 const struct iwl_channel_info *ch_info = NULL; 1483 const struct iwl_channel_info *ch_info = NULL;
1481 struct iwl_txpowertable_cmd txpower = { 1484 struct iwl_txpowertable_cmd txpower = {
1482 .channel = priv->active_rxon.channel, 1485 .channel = priv->active_rxon.channel,
@@ -1500,20 +1503,36 @@ int iwl_hw_reg_send_txpower(struct iwl_priv *priv)
1500 } 1503 }
1501 1504
1502 /* fill cmd with power settings for all rates for current channel */ 1505 /* fill cmd with power settings for all rates for current channel */
1503 for (rate_idx = 0; rate_idx < IWL_RATE_COUNT; rate_idx++) { 1506 /* Fill OFDM rate */
1504 txpower.power[rate_idx].tpc = ch_info->power_info[rate_idx].tpc; 1507 for (rate_idx = IWL_FIRST_OFDM_RATE, i = 0;
1505 txpower.power[rate_idx].rate = iwl_rates[rate_idx].plcp; 1508 rate_idx <= IWL_LAST_OFDM_RATE; rate_idx++, i++) {
1509
1510 txpower.power[i].tpc = ch_info->power_info[i].tpc;
1511 txpower.power[i].rate = iwl_rates[rate_idx].plcp;
1506 1512
1507 IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n", 1513 IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
1508 le16_to_cpu(txpower.channel), 1514 le16_to_cpu(txpower.channel),
1509 txpower.band, 1515 txpower.band,
1510 txpower.power[rate_idx].tpc.tx_gain, 1516 txpower.power[i].tpc.tx_gain,
1511 txpower.power[rate_idx].tpc.dsp_atten, 1517 txpower.power[i].tpc.dsp_atten,
1512 txpower.power[rate_idx].rate); 1518 txpower.power[i].rate);
1519 }
1520 /* Fill CCK rates */
1521 for (rate_idx = IWL_FIRST_CCK_RATE;
1522 rate_idx <= IWL_LAST_CCK_RATE; rate_idx++, i++) {
1523 txpower.power[i].tpc = ch_info->power_info[i].tpc;
1524 txpower.power[i].rate = iwl_rates[rate_idx].plcp;
1525
1526 IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
1527 le16_to_cpu(txpower.channel),
1528 txpower.band,
1529 txpower.power[i].tpc.tx_gain,
1530 txpower.power[i].tpc.dsp_atten,
1531 txpower.power[i].rate);
1513 } 1532 }
1514 1533
1515 return iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, 1534 return iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD,
1516 sizeof(struct iwl_txpowertable_cmd), &txpower); 1535 sizeof(struct iwl_txpowertable_cmd), &txpower);
1517 1536
1518} 1537}
1519 1538
@@ -1549,7 +1568,7 @@ static int iwl_hw_reg_set_new_power(struct iwl_priv *priv,
1549 power_info = ch_info->power_info; 1568 power_info = ch_info->power_info;
1550 1569
1551 /* update OFDM Txpower settings */ 1570 /* update OFDM Txpower settings */
1552 for (i = IWL_FIRST_OFDM_RATE; i <= IWL_LAST_OFDM_RATE; 1571 for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE;
1553 i++, ++power_info) { 1572 i++, ++power_info) {
1554 int delta_idx; 1573 int delta_idx;
1555 1574
@@ -1573,14 +1592,14 @@ static int iwl_hw_reg_set_new_power(struct iwl_priv *priv,
1573 * ... all CCK power settings for a given channel are the *same*. */ 1592 * ... all CCK power settings for a given channel are the *same*. */
1574 if (power_changed) { 1593 if (power_changed) {
1575 power = 1594 power =
1576 ch_info->power_info[IWL_RATE_12M_INDEX]. 1595 ch_info->power_info[IWL_RATE_12M_INDEX_TABLE].
1577 requested_power + IWL_CCK_FROM_OFDM_POWER_DIFF; 1596 requested_power + IWL_CCK_FROM_OFDM_POWER_DIFF;
1578 1597
1579 /* do all CCK rates' iwl_channel_power_info structures */ 1598 /* do all CCK rates' iwl_channel_power_info structures */
1580 for (i = IWL_FIRST_CCK_RATE; i <= IWL_LAST_CCK_RATE; i++) { 1599 for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++) {
1581 power_info->requested_power = power; 1600 power_info->requested_power = power;
1582 power_info->base_power_index = 1601 power_info->base_power_index =
1583 ch_info->power_info[IWL_RATE_12M_INDEX]. 1602 ch_info->power_info[IWL_RATE_12M_INDEX_TABLE].
1584 base_power_index + IWL_CCK_FROM_OFDM_INDEX_DIFF; 1603 base_power_index + IWL_CCK_FROM_OFDM_INDEX_DIFF;
1585 ++power_info; 1604 ++power_info;
1586 } 1605 }
@@ -1674,7 +1693,7 @@ static int iwl_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
1674 for (scan_tbl_index = 0; 1693 for (scan_tbl_index = 0;
1675 scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) { 1694 scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) {
1676 s32 actual_index = (scan_tbl_index == 0) ? 1695 s32 actual_index = (scan_tbl_index == 0) ?
1677 IWL_RATE_1M_INDEX : IWL_RATE_6M_INDEX; 1696 IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE;
1678 iwl_hw_reg_set_scan_power(priv, scan_tbl_index, 1697 iwl_hw_reg_set_scan_power(priv, scan_tbl_index,
1679 actual_index, clip_pwrs, 1698 actual_index, clip_pwrs,
1680 ch_info, a_band); 1699 ch_info, a_band);
@@ -1905,19 +1924,19 @@ static void iwl_hw_reg_init_channel_groups(struct iwl_priv *priv)
1905 for (rate_index = 0; 1924 for (rate_index = 0;
1906 rate_index < IWL_RATE_COUNT; rate_index++, clip_pwrs++) { 1925 rate_index < IWL_RATE_COUNT; rate_index++, clip_pwrs++) {
1907 switch (rate_index) { 1926 switch (rate_index) {
1908 case IWL_RATE_36M_INDEX: 1927 case IWL_RATE_36M_INDEX_TABLE:
1909 if (i == 0) /* B/G */ 1928 if (i == 0) /* B/G */
1910 *clip_pwrs = satur_pwr; 1929 *clip_pwrs = satur_pwr;
1911 else /* A */ 1930 else /* A */
1912 *clip_pwrs = satur_pwr - 5; 1931 *clip_pwrs = satur_pwr - 5;
1913 break; 1932 break;
1914 case IWL_RATE_48M_INDEX: 1933 case IWL_RATE_48M_INDEX_TABLE:
1915 if (i == 0) 1934 if (i == 0)
1916 *clip_pwrs = satur_pwr - 7; 1935 *clip_pwrs = satur_pwr - 7;
1917 else 1936 else
1918 *clip_pwrs = satur_pwr - 10; 1937 *clip_pwrs = satur_pwr - 10;
1919 break; 1938 break;
1920 case IWL_RATE_54M_INDEX: 1939 case IWL_RATE_54M_INDEX_TABLE:
1921 if (i == 0) 1940 if (i == 0)
1922 *clip_pwrs = satur_pwr - 9; 1941 *clip_pwrs = satur_pwr - 9;
1923 else 1942 else
@@ -2031,7 +2050,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
2031 } 2050 }
2032 2051
2033 /* set tx power for CCK rates, based on OFDM 12 Mbit settings*/ 2052 /* set tx power for CCK rates, based on OFDM 12 Mbit settings*/
2034 pwr_info = &ch_info->power_info[IWL_RATE_12M_INDEX]; 2053 pwr_info = &ch_info->power_info[IWL_RATE_12M_INDEX_TABLE];
2035 power = pwr_info->requested_power + 2054 power = pwr_info->requested_power +
2036 IWL_CCK_FROM_OFDM_POWER_DIFF; 2055 IWL_CCK_FROM_OFDM_POWER_DIFF;
2037 pwr_index = pwr_info->power_table_index + 2056 pwr_index = pwr_info->power_table_index +
@@ -2047,9 +2066,9 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
2047 /* fill each CCK rate's iwl_channel_power_info structure 2066 /* fill each CCK rate's iwl_channel_power_info structure
2048 * NOTE: All CCK-rate Txpwrs are the same for a given chnl! 2067 * NOTE: All CCK-rate Txpwrs are the same for a given chnl!
2049 * NOTE: CCK rates start at end of OFDM rates! */ 2068 * NOTE: CCK rates start at end of OFDM rates! */
2050 for (rate_index = IWL_OFDM_RATES; 2069 for (rate_index = 0;
2051 rate_index < IWL_RATE_COUNT; rate_index++) { 2070 rate_index < IWL_CCK_RATES; rate_index++) {
2052 pwr_info = &ch_info->power_info[rate_index]; 2071 pwr_info = &ch_info->power_info[rate_index+IWL_OFDM_RATES];
2053 pwr_info->requested_power = power; 2072 pwr_info->requested_power = power;
2054 pwr_info->power_table_index = pwr_index; 2073 pwr_info->power_table_index = pwr_index;
2055 pwr_info->base_power_index = base_pwr_index; 2074 pwr_info->base_power_index = base_pwr_index;
@@ -2061,7 +2080,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
2061 for (scan_tbl_index = 0; 2080 for (scan_tbl_index = 0;
2062 scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) { 2081 scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) {
2063 s32 actual_index = (scan_tbl_index == 0) ? 2082 s32 actual_index = (scan_tbl_index == 0) ?
2064 IWL_RATE_1M_INDEX : IWL_RATE_6M_INDEX; 2083 IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE;
2065 iwl_hw_reg_set_scan_power(priv, scan_tbl_index, 2084 iwl_hw_reg_set_scan_power(priv, scan_tbl_index,
2066 actual_index, clip_pwrs, ch_info, a_band); 2085 actual_index, clip_pwrs, ch_info, a_band);
2067 } 2086 }
@@ -2139,17 +2158,20 @@ int iwl_hw_get_rx_read(struct iwl_priv *priv)
2139 */ 2158 */
2140int iwl3945_init_hw_rate_table(struct iwl_priv *priv) 2159int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
2141{ 2160{
2142 int rc, i; 2161 int rc, i, index, prev_index;
2143 struct iwl_rate_scaling_cmd rate_cmd = { 2162 struct iwl_rate_scaling_cmd rate_cmd = {
2144 .reserved = {0, 0, 0}, 2163 .reserved = {0, 0, 0},
2145 }; 2164 };
2146 struct iwl_rate_scaling_info *table = rate_cmd.table; 2165 struct iwl_rate_scaling_info *table = rate_cmd.table;
2147 2166
2148 for (i = 0; i < ARRAY_SIZE(iwl_rates); i++) { 2167 for (i = 0; i < ARRAY_SIZE(iwl_rates); i++) {
2149 table[i].rate_n_flags = 2168 index = iwl_rates[i].table_rs_index;
2169
2170 table[index].rate_n_flags =
2150 iwl_hw_set_rate_n_flags(iwl_rates[i].plcp, 0); 2171 iwl_hw_set_rate_n_flags(iwl_rates[i].plcp, 0);
2151 table[i].try_cnt = priv->retry_rate; 2172 table[index].try_cnt = priv->retry_rate;
2152 table[i].next_rate_index = iwl_get_prev_ieee_rate(i); 2173 prev_index = iwl_get_prev_ieee_rate(i);
2174 table[index].next_rate_index = iwl_rates[prev_index].table_rs_index;
2153 } 2175 }
2154 2176
2155 switch (priv->phymode) { 2177 switch (priv->phymode) {
@@ -2157,26 +2179,26 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
2157 IWL_DEBUG_RATE("Select A mode rate scale\n"); 2179 IWL_DEBUG_RATE("Select A mode rate scale\n");
2158 /* If one of the following CCK rates is used, 2180 /* If one of the following CCK rates is used,
2159 * have it fall back to the 6M OFDM rate */ 2181 * have it fall back to the 6M OFDM rate */
2160 for (i = IWL_FIRST_CCK_RATE; i <= IWL_LAST_CCK_RATE; i++) 2182 for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++)
2161 table[i].next_rate_index = IWL_FIRST_OFDM_RATE; 2183 table[i].next_rate_index = iwl_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
2162 2184
2163 /* Don't fall back to CCK rates */ 2185 /* Don't fall back to CCK rates */
2164 table[IWL_RATE_12M_INDEX].next_rate_index = IWL_RATE_9M_INDEX; 2186 table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = IWL_RATE_9M_INDEX_TABLE;
2165 2187
2166 /* Don't drop out of OFDM rates */ 2188 /* Don't drop out of OFDM rates */
2167 table[IWL_FIRST_OFDM_RATE].next_rate_index = 2189 table[IWL_RATE_6M_INDEX_TABLE].next_rate_index =
2168 IWL_FIRST_OFDM_RATE; 2190 iwl_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
2169 break; 2191 break;
2170 2192
2171 case MODE_IEEE80211B: 2193 case MODE_IEEE80211B:
2172 IWL_DEBUG_RATE("Select B mode rate scale\n"); 2194 IWL_DEBUG_RATE("Select B mode rate scale\n");
2173 /* If an OFDM rate is used, have it fall back to the 2195 /* If an OFDM rate is used, have it fall back to the
2174 * 1M CCK rates */ 2196 * 1M CCK rates */
2175 for (i = IWL_FIRST_OFDM_RATE; i <= IWL_LAST_OFDM_RATE; i++) 2197 for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; i++)
2176 table[i].next_rate_index = IWL_FIRST_CCK_RATE; 2198 table[i].next_rate_index = iwl_rates[IWL_FIRST_CCK_RATE].table_rs_index;
2177 2199
2178 /* CCK shouldn't fall back to OFDM... */ 2200 /* CCK shouldn't fall back to OFDM... */
2179 table[IWL_RATE_11M_INDEX].next_rate_index = IWL_RATE_5M_INDEX; 2201 table[IWL_RATE_11M_INDEX_TABLE].next_rate_index = IWL_RATE_5M_INDEX_TABLE;
2180 break; 2202 break;
2181 2203
2182 default: 2204 default:
@@ -2248,22 +2270,12 @@ unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
2248 tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK | 2270 tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK |
2249 TX_CMD_FLG_TSF_MSK); 2271 TX_CMD_FLG_TSF_MSK);
2250 2272
2251 /* supp_rates[0] == OFDM */ 2273 /* supp_rates[0] == OFDM start at IWL_FIRST_OFDM_RATE*/
2252 tx_beacon_cmd->tx.supp_rates[0] = IWL_OFDM_BASIC_RATES_MASK; 2274 tx_beacon_cmd->tx.supp_rates[0] =
2253 2275 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
2254 /* supp_rates[1] == CCK 2276
2255 *
2256 * NOTE: IWL_*_RATES_MASK are not in the order that supp_rates
2257 * expects so we have to shift them around.
2258 *
2259 * supp_rates expects:
2260 * CCK rates are bit0..3
2261 *
2262 * However IWL_*_RATES_MASK has:
2263 * CCK rates are bit8..11
2264 */
2265 tx_beacon_cmd->tx.supp_rates[1] = 2277 tx_beacon_cmd->tx.supp_rates[1] =
2266 (IWL_CCK_BASIC_RATES_MASK >> 8) & 0xF; 2278 (IWL_CCK_BASIC_RATES_MASK & 0xF);
2267 2279
2268 return (sizeof(struct iwl_tx_beacon_cmd) + frame_size); 2280 return (sizeof(struct iwl_tx_beacon_cmd) + frame_size);
2269} 2281}
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index ee752f1e21dd..465da4f67ce7 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -5332,13 +5332,13 @@ static int iwl_init_geos(struct iwl_priv *priv)
5332 /* 5.2GHz channels start after the 2.4GHz channels */ 5332 /* 5.2GHz channels start after the 2.4GHz channels */
5333 modes[A].mode = MODE_IEEE80211A; 5333 modes[A].mode = MODE_IEEE80211A;
5334 modes[A].channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)]; 5334 modes[A].channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)];
5335 modes[A].rates = rates; 5335 modes[A].rates = &rates[4];
5336 modes[A].num_rates = 8; /* just OFDM */ 5336 modes[A].num_rates = 8; /* just OFDM */
5337 modes[A].num_channels = 0; 5337 modes[A].num_channels = 0;
5338 5338
5339 modes[B].mode = MODE_IEEE80211B; 5339 modes[B].mode = MODE_IEEE80211B;
5340 modes[B].channels = channels; 5340 modes[B].channels = channels;
5341 modes[B].rates = &rates[8]; 5341 modes[B].rates = rates;
5342 modes[B].num_rates = 4; /* just CCK */ 5342 modes[B].num_rates = 4; /* just CCK */
5343 modes[B].num_channels = 0; 5343 modes[B].num_channels = 0;
5344 5344
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 6757c6c1b25a..9918780f5e86 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -5156,9 +5156,10 @@ static irqreturn_t iwl_isr(int irq, void *data)
5156 } 5156 }
5157 5157
5158 if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { 5158 if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
5159 /* Hardware disappeared */ 5159 /* Hardware disappeared. It might have already raised
5160 * an interrupt */
5160 IWL_WARNING("HARDWARE GONE?? INTA == 0x%080x\n", inta); 5161 IWL_WARNING("HARDWARE GONE?? INTA == 0x%080x\n", inta);
5161 goto none; 5162 goto unplugged;
5162 } 5163 }
5163 5164
5164 IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", 5165 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 5167
5167 /* iwl_irq_tasklet() will service interrupts and re-enable them */ 5168 /* iwl_irq_tasklet() will service interrupts and re-enable them */
5168 tasklet_schedule(&priv->irq_tasklet); 5169 tasklet_schedule(&priv->irq_tasklet);
5169 spin_unlock(&priv->lock);
5170 5170
5171 unplugged:
5172 spin_unlock(&priv->lock);
5171 return IRQ_HANDLED; 5173 return IRQ_HANDLED;
5172 5174
5173 none: 5175 none:
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index ff2d63267b19..702321c30164 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -620,7 +620,7 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
620 * up to version C the link tuning should halt after 20 620 * up to version C the link tuning should halt after 20
621 * seconds. 621 * seconds.
622 */ 622 */
623 if (rt2x00_get_rev(&rt2x00dev->chip) < RT2560_VERSION_D && 623 if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D &&
624 rt2x00dev->link.count > 20) 624 rt2x00dev->link.count > 20)
625 return; 625 return;
626 626
@@ -630,7 +630,7 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
630 * Chipset versions C and lower should directly continue 630 * Chipset versions C and lower should directly continue
631 * to the dynamic CCA tuning. 631 * to the dynamic CCA tuning.
632 */ 632 */
633 if (rt2x00_get_rev(&rt2x00dev->chip) < RT2560_VERSION_D) 633 if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D)
634 goto dynamic_cca_tune; 634 goto dynamic_cca_tune;
635 635
636 /* 636 /*
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 7cdc80a122bb..277a020b35e9 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -753,7 +753,7 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
753 rt2x00_set_field16(&reg, MAC_CSR1_HOST_READY, 1); 753 rt2x00_set_field16(&reg, MAC_CSR1_HOST_READY, 1);
754 rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg); 754 rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg);
755 755
756 if (rt2x00_get_rev(&rt2x00dev->chip) >= RT2570_VERSION_C) { 756 if (rt2x00_rev(&rt2x00dev->chip) >= RT2570_VERSION_C) {
757 rt2500usb_register_read(rt2x00dev, PHY_CSR2, &reg); 757 rt2500usb_register_read(rt2x00dev, PHY_CSR2, &reg);
758 reg &= ~0x0002; 758 reg &= ~0x0002;
759 } else { 759 } else {
@@ -1257,7 +1257,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
1257 rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg); 1257 rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg);
1258 rt2x00_set_chip(rt2x00dev, RT2570, value, reg); 1258 rt2x00_set_chip(rt2x00dev, RT2570, value, reg);
1259 1259
1260 if (rt2x00_rev(&rt2x00dev->chip, 0xffff0)) { 1260 if (!rt2x00_check_rev(&rt2x00dev->chip, 0)) {
1261 ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); 1261 ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
1262 return -ENODEV; 1262 return -ENODEV;
1263 } 1263 }
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 9845e584b731..d1ad5251a77a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -751,14 +751,16 @@ static inline char rt2x00_rf(const struct rt2x00_chip *chipset, const u16 chip)
751 return (chipset->rf == chip); 751 return (chipset->rf == chip);
752} 752}
753 753
754static inline u16 rt2x00_get_rev(const struct rt2x00_chip *chipset) 754static inline u16 rt2x00_rev(const struct rt2x00_chip *chipset)
755{ 755{
756 return chipset->rev; 756 return chipset->rev;
757} 757}
758 758
759static inline u16 rt2x00_rev(const struct rt2x00_chip *chipset, const u32 mask) 759static inline u16 rt2x00_check_rev(const struct rt2x00_chip *chipset,
760 const u32 rev)
760{ 761{
761 return chipset->rev & mask; 762 return (((chipset->rev & 0xffff0) == rev) &&
763 !!(chipset->rev & 0x0000f));
762} 764}
763 765
764/* 766/*
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 46c8c0840a65..dc640bf6b5eb 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1486,7 +1486,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
1486 rt73usb_register_read(rt2x00dev, MAC_CSR0, &reg); 1486 rt73usb_register_read(rt2x00dev, MAC_CSR0, &reg);
1487 rt2x00_set_chip(rt2x00dev, RT2571, value, reg); 1487 rt2x00_set_chip(rt2x00dev, RT2571, value, reg);
1488 1488
1489 if (!rt2x00_rev(&rt2x00dev->chip, 0x25730)) { 1489 if (!rt2x00_check_rev(&rt2x00dev->chip, 0x25730)) {
1490 ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); 1490 ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
1491 return -ENODEV; 1491 return -ENODEV;
1492 } 1492 }
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index b4e32ab3664d..72e1c93dd87e 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -242,6 +242,8 @@ struct ieee80211_if_sta {
242 u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; 242 u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
243 u8 ssid[IEEE80211_MAX_SSID_LEN]; 243 u8 ssid[IEEE80211_MAX_SSID_LEN];
244 size_t ssid_len; 244 size_t ssid_len;
245 u8 scan_ssid[IEEE80211_MAX_SSID_LEN];
246 size_t scan_ssid_len;
245 u16 aid; 247 u16 aid;
246 u16 ap_capab, capab; 248 u16 ap_capab, capab;
247 u8 *extra_ie; /* to be added to the end of AssocReq */ 249 u8 *extra_ie; /* to be added to the end of AssocReq */
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 2079e988fc56..015b3f879aa9 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -2002,7 +2002,10 @@ void ieee80211_sta_work(struct work_struct *work)
2002 if (ifsta->state != IEEE80211_AUTHENTICATE && 2002 if (ifsta->state != IEEE80211_AUTHENTICATE &&
2003 ifsta->state != IEEE80211_ASSOCIATE && 2003 ifsta->state != IEEE80211_ASSOCIATE &&
2004 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) { 2004 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) {
2005 ieee80211_sta_start_scan(dev, NULL, 0); 2005 if (ifsta->scan_ssid_len)
2006 ieee80211_sta_start_scan(dev, ifsta->scan_ssid, ifsta->scan_ssid_len);
2007 else
2008 ieee80211_sta_start_scan(dev, NULL, 0);
2006 return; 2009 return;
2007 } 2010 }
2008 2011
@@ -2872,6 +2875,9 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len)
2872 return -EBUSY; 2875 return -EBUSY;
2873 } 2876 }
2874 2877
2878 ifsta->scan_ssid_len = ssid_len;
2879 if (ssid_len)
2880 memcpy(ifsta->scan_ssid, ssid, ssid_len);
2875 set_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request); 2881 set_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request);
2876 queue_work(local->hw.workqueue, &ifsta->work); 2882 queue_work(local->hw.workqueue, &ifsta->work);
2877 return 0; 2883 return 0;