aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rs.c81
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rs.h1
2 files changed, 60 insertions, 22 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index 7aecf46e2ab8..227c5ed9cbe6 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -211,6 +211,9 @@ static bool rs_sgi_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
211 if (is_ht80(rate) && (vht_cap->cap & 211 if (is_ht80(rate) && (vht_cap->cap &
212 IEEE80211_VHT_CAP_SHORT_GI_80)) 212 IEEE80211_VHT_CAP_SHORT_GI_80))
213 return true; 213 return true;
214 if (is_ht160(rate) && (vht_cap->cap &
215 IEEE80211_VHT_CAP_SHORT_GI_160))
216 return true;
214 217
215 return false; 218 return false;
216} 219}
@@ -445,6 +448,13 @@ static const u16 expected_tpt_siso_80MHz[4][IWL_RATE_COUNT] = {
445 {0, 0, 0, 0, 241, 0, 475, 701, 921, 1343, 1741, 1931, 2117, 2468, 2691}, 448 {0, 0, 0, 0, 241, 0, 475, 701, 921, 1343, 1741, 1931, 2117, 2468, 2691},
446}; 449};
447 450
451static const u16 expected_tpt_siso_160MHz[4][IWL_RATE_COUNT] = {
452 {0, 0, 0, 0, 191, 0, 244, 288, 298, 308, 313, 318, 323, 328, 330},
453 {0, 0, 0, 0, 200, 0, 251, 293, 302, 312, 317, 322, 327, 332, 334},
454 {0, 0, 0, 0, 439, 0, 875, 1307, 1736, 2584, 3419, 3831, 4240, 5049, 5581},
455 {0, 0, 0, 0, 488, 0, 972, 1451, 1925, 2864, 3785, 4240, 4691, 5581, 6165},
456};
457
448static const u16 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = { 458static const u16 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = {
449 {0, 0, 0, 0, 74, 0, 123, 155, 179, 213, 235, 243, 250, 261, 0}, 459 {0, 0, 0, 0, 74, 0, 123, 155, 179, 213, 235, 243, 250, 261, 0},
450 {0, 0, 0, 0, 81, 0, 131, 164, 187, 221, 242, 250, 256, 267, 0}, 460 {0, 0, 0, 0, 81, 0, 131, 164, 187, 221, 242, 250, 256, 267, 0},
@@ -466,6 +476,13 @@ static const u16 expected_tpt_mimo2_80MHz[4][IWL_RATE_COUNT] = {
466 {0, 0, 0, 0, 474, 0, 920, 1338, 1732, 2464, 3116, 3418, 3705, 4225, 4545}, 476 {0, 0, 0, 0, 474, 0, 920, 1338, 1732, 2464, 3116, 3418, 3705, 4225, 4545},
467}; 477};
468 478
479static const u16 expected_tpt_mimo2_160MHz[4][IWL_RATE_COUNT] = {
480 {0, 0, 0, 0, 240, 0, 278, 308, 313, 319, 322, 324, 328, 330, 334},
481 {0, 0, 0, 0, 247, 0, 282, 310, 315, 320, 323, 325, 329, 332, 338},
482 {0, 0, 0, 0, 875, 0, 1735, 2582, 3414, 5043, 6619, 7389, 8147, 9629, 10592},
483 {0, 0, 0, 0, 971, 0, 1925, 2861, 3779, 5574, 7304, 8147, 8976, 10592, 11640},
484};
485
469/* mbps, mcs */ 486/* mbps, mcs */
470static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { 487static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
471 { "1", "BPSK DSSS"}, 488 { "1", "BPSK DSSS"},
@@ -901,7 +918,6 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
901 } 918 }
902 } 919 }
903 920
904 WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_160);
905 WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_80 && 921 WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_80 &&
906 !is_vht(rate)); 922 !is_vht(rate));
907 923
@@ -1495,6 +1511,9 @@ static const u16 *rs_get_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1495 case RATE_MCS_CHAN_WIDTH_80: 1511 case RATE_MCS_CHAN_WIDTH_80:
1496 ht_tbl_pointer = expected_tpt_siso_80MHz; 1512 ht_tbl_pointer = expected_tpt_siso_80MHz;
1497 break; 1513 break;
1514 case RATE_MCS_CHAN_WIDTH_160:
1515 ht_tbl_pointer = expected_tpt_siso_160MHz;
1516 break;
1498 default: 1517 default:
1499 WARN_ON_ONCE(1); 1518 WARN_ON_ONCE(1);
1500 } 1519 }
@@ -1509,6 +1528,9 @@ static const u16 *rs_get_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1509 case RATE_MCS_CHAN_WIDTH_80: 1528 case RATE_MCS_CHAN_WIDTH_80:
1510 ht_tbl_pointer = expected_tpt_mimo2_80MHz; 1529 ht_tbl_pointer = expected_tpt_mimo2_80MHz;
1511 break; 1530 break;
1531 case RATE_MCS_CHAN_WIDTH_160:
1532 ht_tbl_pointer = expected_tpt_mimo2_160MHz;
1533 break;
1512 default: 1534 default:
1513 WARN_ON_ONCE(1); 1535 WARN_ON_ONCE(1);
1514 } 1536 }
@@ -1583,12 +1605,17 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1583 1605
1584static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta) 1606static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta)
1585{ 1607{
1586 if (sta->bandwidth >= IEEE80211_STA_RX_BW_80) 1608 switch (sta->bandwidth) {
1609 case IEEE80211_STA_RX_BW_160:
1610 return RATE_MCS_CHAN_WIDTH_160;
1611 case IEEE80211_STA_RX_BW_80:
1587 return RATE_MCS_CHAN_WIDTH_80; 1612 return RATE_MCS_CHAN_WIDTH_80;
1588 else if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) 1613 case IEEE80211_STA_RX_BW_40:
1589 return RATE_MCS_CHAN_WIDTH_40; 1614 return RATE_MCS_CHAN_WIDTH_40;
1590 1615 case IEEE80211_STA_RX_BW_20:
1591 return RATE_MCS_CHAN_WIDTH_20; 1616 default:
1617 return RATE_MCS_CHAN_WIDTH_20;
1618 }
1592} 1619}
1593 1620
1594/* 1621/*
@@ -2566,6 +2593,9 @@ static const struct rs_init_rate_info rs_optimal_rates_ht[] = {
2566 { S8_MIN, IWL_RATE_MCS_0_INDEX}, 2593 { S8_MIN, IWL_RATE_MCS_0_INDEX},
2567}; 2594};
2568 2595
2596/* MCS index 9 is not valid for 20MHz VHT channel width,
2597 * but is ok for 40, 80 and 160MHz channels.
2598 */
2569static const struct rs_init_rate_info rs_optimal_rates_vht_20mhz[] = { 2599static const struct rs_init_rate_info rs_optimal_rates_vht_20mhz[] = {
2570 { -60, IWL_RATE_MCS_8_INDEX }, 2600 { -60, IWL_RATE_MCS_8_INDEX },
2571 { -64, IWL_RATE_MCS_7_INDEX }, 2601 { -64, IWL_RATE_MCS_7_INDEX },
@@ -2578,7 +2608,7 @@ static const struct rs_init_rate_info rs_optimal_rates_vht_20mhz[] = {
2578 { S8_MIN, IWL_RATE_MCS_0_INDEX}, 2608 { S8_MIN, IWL_RATE_MCS_0_INDEX},
2579}; 2609};
2580 2610
2581static const struct rs_init_rate_info rs_optimal_rates_vht_40_80mhz[] = { 2611static const struct rs_init_rate_info rs_optimal_rates_vht[] = {
2582 { -60, IWL_RATE_MCS_9_INDEX }, 2612 { -60, IWL_RATE_MCS_9_INDEX },
2583 { -64, IWL_RATE_MCS_8_INDEX }, 2613 { -64, IWL_RATE_MCS_8_INDEX },
2584 { -68, IWL_RATE_MCS_7_INDEX }, 2614 { -68, IWL_RATE_MCS_7_INDEX },
@@ -2641,9 +2671,9 @@ static void rs_init_optimal_rate(struct iwl_mvm *mvm,
2641 lq_sta->optimal_nentries = 2671 lq_sta->optimal_nentries =
2642 ARRAY_SIZE(rs_optimal_rates_vht_20mhz); 2672 ARRAY_SIZE(rs_optimal_rates_vht_20mhz);
2643 } else { 2673 } else {
2644 lq_sta->optimal_rates = rs_optimal_rates_vht_40_80mhz; 2674 lq_sta->optimal_rates = rs_optimal_rates_vht;
2645 lq_sta->optimal_nentries = 2675 lq_sta->optimal_nentries =
2646 ARRAY_SIZE(rs_optimal_rates_vht_40_80mhz); 2676 ARRAY_SIZE(rs_optimal_rates_vht);
2647 } 2677 }
2648 } else if (is_ht(rate)) { 2678 } else if (is_ht(rate)) {
2649 lq_sta->optimal_rates = rs_optimal_rates_ht; 2679 lq_sta->optimal_rates = rs_optimal_rates_ht;
@@ -2735,23 +2765,25 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm,
2735 */ 2765 */
2736 if (sta->vht_cap.vht_supported && 2766 if (sta->vht_cap.vht_supported &&
2737 best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) { 2767 best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) {
2738 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) { 2768 switch (sta->bandwidth) {
2739 initial_rates = rs_optimal_rates_vht_40_80mhz; 2769 case IEEE80211_STA_RX_BW_160:
2740 nentries = ARRAY_SIZE(rs_optimal_rates_vht_40_80mhz); 2770 case IEEE80211_STA_RX_BW_80:
2741 if (sta->bandwidth >= IEEE80211_STA_RX_BW_80) 2771 case IEEE80211_STA_RX_BW_40:
2742 rate->bw = RATE_MCS_CHAN_WIDTH_80; 2772 initial_rates = rs_optimal_rates_vht;
2743 else 2773 nentries = ARRAY_SIZE(rs_optimal_rates_vht);
2744 rate->bw = RATE_MCS_CHAN_WIDTH_40; 2774 break;
2745 } else if (sta->bandwidth == IEEE80211_STA_RX_BW_20) { 2775 case IEEE80211_STA_RX_BW_20:
2746 initial_rates = rs_optimal_rates_vht_20mhz; 2776 initial_rates = rs_optimal_rates_vht_20mhz;
2747 nentries = ARRAY_SIZE(rs_optimal_rates_vht_20mhz); 2777 nentries = ARRAY_SIZE(rs_optimal_rates_vht_20mhz);
2748 rate->bw = RATE_MCS_CHAN_WIDTH_20; 2778 break;
2749 } else { 2779 default:
2750 IWL_ERR(mvm, "Invalid BW %d\n", sta->bandwidth); 2780 IWL_ERR(mvm, "Invalid BW %d\n", sta->bandwidth);
2751 goto out; 2781 goto out;
2752 } 2782 }
2783
2753 active_rate = lq_sta->active_siso_rate; 2784 active_rate = lq_sta->active_siso_rate;
2754 rate->type = LQ_VHT_SISO; 2785 rate->type = LQ_VHT_SISO;
2786 rate->bw = rs_bw_from_sta_bw(sta);
2755 } else if (sta->ht_cap.ht_supported && 2787 } else if (sta->ht_cap.ht_supported &&
2756 best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) { 2788 best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) {
2757 initial_rates = rs_optimal_rates_ht; 2789 initial_rates = rs_optimal_rates_ht;
@@ -3058,6 +3090,9 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)
3058 case RATE_MCS_CHAN_WIDTH_80: 3090 case RATE_MCS_CHAN_WIDTH_80:
3059 mvm->drv_rx_stats.bw_80_frames++; 3091 mvm->drv_rx_stats.bw_80_frames++;
3060 break; 3092 break;
3093 case RATE_MCS_CHAN_WIDTH_160:
3094 mvm->drv_rx_stats.bw_160_frames++;
3095 break;
3061 default: 3096 default:
3062 WARN_ONCE(1, "bad BW. rate 0x%x", rate); 3097 WARN_ONCE(1, "bad BW. rate 0x%x", rate);
3063 } 3098 }
@@ -3706,7 +3741,8 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
3706 desc += sprintf(buff + desc, " %s", 3741 desc += sprintf(buff + desc, " %s",
3707 (is_ht20(rate)) ? "20MHz" : 3742 (is_ht20(rate)) ? "20MHz" :
3708 (is_ht40(rate)) ? "40MHz" : 3743 (is_ht40(rate)) ? "40MHz" :
3709 (is_ht80(rate)) ? "80Mhz" : "BAD BW"); 3744 (is_ht80(rate)) ? "80MHz" :
3745 (is_ht160(rate)) ? "160MHz" : "BAD BW");
3710 desc += sprintf(buff + desc, " %s %s %s %s\n", 3746 desc += sprintf(buff + desc, " %s %s %s %s\n",
3711 (rate->sgi) ? "SGI" : "NGI", 3747 (rate->sgi) ? "SGI" : "NGI",
3712 (rate->ldpc) ? "LDPC" : "BCC", 3748 (rate->ldpc) ? "LDPC" : "BCC",
@@ -3788,9 +3824,10 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
3788 lq_sta->active_tbl == i ? "*" : "x", 3824 lq_sta->active_tbl == i ? "*" : "x",
3789 rate->type, 3825 rate->type,
3790 rate->sgi, 3826 rate->sgi,
3791 is_ht20(rate) ? "20Mhz" : 3827 is_ht20(rate) ? "20MHz" :
3792 is_ht40(rate) ? "40Mhz" : 3828 is_ht40(rate) ? "40MHz" :
3793 is_ht80(rate) ? "80Mhz" : "ERR", 3829 is_ht80(rate) ? "80MHz" :
3830 is_ht160(rate) ? "160MHz" : "ERR",
3794 rate->index); 3831 rate->index);
3795 for (j = 0; j < IWL_RATE_COUNT; j++) { 3832 for (j = 0; j < IWL_RATE_COUNT; j++) {
3796 desc += sprintf(buff+desc, 3833 desc += sprintf(buff+desc,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
index d4a7fe2e9aca..ee207f2c0a90 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
@@ -205,6 +205,7 @@ struct rs_rate {
205#define is_ht20(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_20) 205#define is_ht20(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_20)
206#define is_ht40(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_40) 206#define is_ht40(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_40)
207#define is_ht80(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_80) 207#define is_ht80(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_80)
208#define is_ht160(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_160)
208 209
209#define IWL_MAX_MCS_DISPLAY_SIZE 12 210#define IWL_MAX_MCS_DISPLAY_SIZE 12
210 211