3291 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/******************************************************************************3 *4 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.5 * Copyright (C) 2019 - 2020, 2022 - 2023 Intel Corporation6 *****************************************************************************/7#include <linux/kernel.h>8#include <linux/skbuff.h>9#include <linux/slab.h>10#include <net/mac80211.h>11 12#include <linux/netdevice.h>13#include <linux/etherdevice.h>14#include <linux/delay.h>15 16#include <linux/workqueue.h>17 18#include "dev.h"19#include "agn.h"20 21#define RS_NAME "iwl-agn-rs"22 23#define NUM_TRY_BEFORE_ANT_TOGGLE 124#define IWL_NUMBER_TRY 125#define IWL_HT_NUMBER_TRY 326 27#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */28#define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */29#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */30 31/* max allowed rate miss before sync LQ cmd */32#define IWL_MISSED_RATE_MAX 1533/* max time to accum history 2 seconds */34#define IWL_RATE_SCALE_FLUSH_INTVL (3*HZ)35 36static u8 rs_ht_to_legacy[] = {37 IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,38 IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,39 IWL_RATE_6M_INDEX,40 IWL_RATE_6M_INDEX, IWL_RATE_9M_INDEX,41 IWL_RATE_12M_INDEX, IWL_RATE_18M_INDEX,42 IWL_RATE_24M_INDEX, IWL_RATE_36M_INDEX,43 IWL_RATE_48M_INDEX, IWL_RATE_54M_INDEX44};45 46static const u8 ant_toggle_lookup[] = {47 /*ANT_NONE -> */ ANT_NONE,48 /*ANT_A -> */ ANT_B,49 /*ANT_B -> */ ANT_C,50 /*ANT_AB -> */ ANT_BC,51 /*ANT_C -> */ ANT_A,52 /*ANT_AC -> */ ANT_AB,53 /*ANT_BC -> */ ANT_AC,54 /*ANT_ABC -> */ ANT_ABC,55};56 57#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \58 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \59 IWL_RATE_SISO_##s##M_PLCP, \60 IWL_RATE_MIMO2_##s##M_PLCP,\61 IWL_RATE_MIMO3_##s##M_PLCP,\62 IWL_RATE_##r##M_IEEE, \63 IWL_RATE_##ip##M_INDEX, \64 IWL_RATE_##in##M_INDEX, \65 IWL_RATE_##rp##M_INDEX, \66 IWL_RATE_##rn##M_INDEX, \67 IWL_RATE_##pp##M_INDEX, \68 IWL_RATE_##np##M_INDEX }69 70/*71 * Parameter order:72 * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate73 *74 * If there isn't a valid next or previous rate then INV is used which75 * maps to IWL_RATE_INVALID76 *77 */78const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {79 IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */80 IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */81 IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */82 IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */83 IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */84 IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */85 IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */86 IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */87 IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */88 IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */89 IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */90 IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */91 IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */92 /* FIXME:RS: ^^ should be INV (legacy) */93};94 95static inline u8 rs_extract_rate(u32 rate_n_flags)96{97 return (u8)(rate_n_flags & RATE_MCS_RATE_MSK);98}99 100static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)101{102 int idx = 0;103 104 /* HT rate format */105 if (rate_n_flags & RATE_MCS_HT_MSK) {106 idx = rs_extract_rate(rate_n_flags);107 108 if (idx >= IWL_RATE_MIMO3_6M_PLCP)109 idx = idx - IWL_RATE_MIMO3_6M_PLCP;110 else if (idx >= IWL_RATE_MIMO2_6M_PLCP)111 idx = idx - IWL_RATE_MIMO2_6M_PLCP;112 113 idx += IWL_FIRST_OFDM_RATE;114 /* skip 9M not supported in ht*/115 if (idx >= IWL_RATE_9M_INDEX)116 idx += 1;117 if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))118 return idx;119 120 /* legacy rate format, search for match in table */121 } else {122 for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)123 if (iwl_rates[idx].plcp ==124 rs_extract_rate(rate_n_flags))125 return idx;126 }127 128 return IWL_RATE_INVALID;129}130 131static void rs_rate_scale_perform(struct iwl_priv *priv,132 struct sk_buff *skb,133 struct ieee80211_sta *sta,134 struct iwl_lq_sta *lq_sta);135static void rs_fill_link_cmd(struct iwl_priv *priv,136 struct iwl_lq_sta *lq_sta, u32 rate_n_flags);137static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search);138 139 140#ifdef CONFIG_MAC80211_DEBUGFS141static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,142 u32 *rate_n_flags, int index);143#else144static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,145 u32 *rate_n_flags, int index)146{}147#endif148 149/*150 * The following tables contain the expected throughput metrics for all rates151 *152 * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits153 *154 * where invalid entries are zeros.155 *156 * CCK rates are only valid in legacy table and will only be used in G157 * (2.4 GHz) band.158 */159 160static const u16 expected_tpt_legacy[IWL_RATE_COUNT] = {161 7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 0162};163 164static const u16 expected_tpt_siso20MHz[4][IWL_RATE_COUNT] = {165 {0, 0, 0, 0, 42, 0, 76, 102, 124, 159, 183, 193, 202}, /* Norm */166 {0, 0, 0, 0, 46, 0, 82, 110, 132, 168, 192, 202, 210}, /* SGI */167 {0, 0, 0, 0, 47, 0, 91, 133, 171, 242, 305, 334, 362}, /* AGG */168 {0, 0, 0, 0, 52, 0, 101, 145, 187, 264, 330, 361, 390}, /* AGG+SGI */169};170 171static const u16 expected_tpt_siso40MHz[4][IWL_RATE_COUNT] = {172 {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257}, /* Norm */173 {0, 0, 0, 0, 83, 0, 135, 169, 193, 229, 250, 257, 264}, /* SGI */174 {0, 0, 0, 0, 94, 0, 177, 249, 313, 423, 512, 550, 586}, /* AGG */175 {0, 0, 0, 0, 104, 0, 193, 270, 338, 454, 545, 584, 620}, /* AGG+SGI */176};177 178static const u16 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = {179 {0, 0, 0, 0, 74, 0, 123, 155, 179, 214, 236, 244, 251}, /* Norm */180 {0, 0, 0, 0, 81, 0, 131, 164, 188, 223, 243, 251, 257}, /* SGI */181 {0, 0, 0, 0, 89, 0, 167, 235, 296, 402, 488, 526, 560}, /* AGG */182 {0, 0, 0, 0, 97, 0, 182, 255, 320, 431, 520, 558, 593}, /* AGG+SGI*/183};184 185static const u16 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = {186 {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289}, /* Norm */187 {0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293}, /* SGI */188 {0, 0, 0, 0, 171, 0, 305, 410, 496, 634, 731, 771, 805}, /* AGG */189 {0, 0, 0, 0, 186, 0, 329, 439, 527, 667, 764, 803, 838}, /* AGG+SGI */190};191 192static const u16 expected_tpt_mimo3_20MHz[4][IWL_RATE_COUNT] = {193 {0, 0, 0, 0, 99, 0, 153, 186, 208, 239, 256, 263, 268}, /* Norm */194 {0, 0, 0, 0, 106, 0, 162, 194, 215, 246, 262, 268, 273}, /* SGI */195 {0, 0, 0, 0, 134, 0, 249, 346, 431, 574, 685, 732, 775}, /* AGG */196 {0, 0, 0, 0, 148, 0, 272, 376, 465, 614, 727, 775, 818}, /* AGG+SGI */197};198 199static const u16 expected_tpt_mimo3_40MHz[4][IWL_RATE_COUNT] = {200 {0, 0, 0, 0, 152, 0, 211, 239, 255, 279, 290, 294, 297}, /* Norm */201 {0, 0, 0, 0, 160, 0, 219, 245, 261, 284, 294, 297, 300}, /* SGI */202 {0, 0, 0, 0, 254, 0, 443, 584, 695, 868, 984, 1030, 1070}, /* AGG */203 {0, 0, 0, 0, 277, 0, 478, 624, 737, 911, 1026, 1070, 1109}, /* AGG+SGI */204};205 206#define MCS_INDEX_PER_STREAM (8)207 208static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)209{210 window->data = 0;211 window->success_counter = 0;212 window->success_ratio = IWL_INVALID_VALUE;213 window->counter = 0;214 window->average_tpt = IWL_INVALID_VALUE;215 window->stamp = 0;216}217 218static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)219{220 return (ant_type & valid_antenna) == ant_type;221}222 223/*224 * removes the old data from the statistics. All data that is older than225 * TID_MAX_TIME_DIFF, will be deleted.226 */227static void rs_tl_rm_old_stats(struct iwl_traffic_load *tl, u32 curr_time)228{229 /* The oldest age we want to keep */230 u32 oldest_time = curr_time - TID_MAX_TIME_DIFF;231 232 while (tl->queue_count &&233 (tl->time_stamp < oldest_time)) {234 tl->total -= tl->packet_count[tl->head];235 tl->packet_count[tl->head] = 0;236 tl->time_stamp += TID_QUEUE_CELL_SPACING;237 tl->queue_count--;238 tl->head++;239 if (tl->head >= TID_QUEUE_MAX_SIZE)240 tl->head = 0;241 }242}243 244/*245 * increment traffic load value for tid and also remove246 * any old values if passed the certain time period247 */248static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,249 struct ieee80211_hdr *hdr)250{251 u32 curr_time = jiffies_to_msecs(jiffies);252 u32 time_diff;253 s32 index;254 struct iwl_traffic_load *tl = NULL;255 u8 tid;256 257 if (ieee80211_is_data_qos(hdr->frame_control)) {258 u8 *qc = ieee80211_get_qos_ctl(hdr);259 tid = qc[0] & 0xf;260 } else261 return IWL_MAX_TID_COUNT;262 263 if (unlikely(tid >= IWL_MAX_TID_COUNT))264 return IWL_MAX_TID_COUNT;265 266 tl = &lq_data->load[tid];267 268 curr_time -= curr_time % TID_ROUND_VALUE;269 270 /* Happens only for the first packet. Initialize the data */271 if (!(tl->queue_count)) {272 tl->total = 1;273 tl->time_stamp = curr_time;274 tl->queue_count = 1;275 tl->head = 0;276 tl->packet_count[0] = 1;277 return IWL_MAX_TID_COUNT;278 }279 280 time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time);281 index = time_diff / TID_QUEUE_CELL_SPACING;282 283 /* The history is too long: remove data that is older than */284 /* TID_MAX_TIME_DIFF */285 if (index >= TID_QUEUE_MAX_SIZE)286 rs_tl_rm_old_stats(tl, curr_time);287 288 index = (tl->head + index) % TID_QUEUE_MAX_SIZE;289 tl->packet_count[index] = tl->packet_count[index] + 1;290 tl->total = tl->total + 1;291 292 if ((index + 1) > tl->queue_count)293 tl->queue_count = index + 1;294 295 return tid;296}297 298#ifdef CONFIG_MAC80211_DEBUGFS299/*300 * Program the device to use fixed rate for frame transmit301 * This is for debugging/testing only302 * once the device start use fixed rate, we need to reload the module303 * to being back the normal operation.304 */305static void rs_program_fix_rate(struct iwl_priv *priv,306 struct iwl_lq_sta *lq_sta)307{308 struct iwl_station_priv *sta_priv =309 container_of(lq_sta, struct iwl_station_priv, lq_sta);310 struct iwl_rxon_context *ctx = sta_priv->ctx;311 312 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */313 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */314 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */315 lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */316 317 IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",318 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);319 320 if (lq_sta->dbg_fixed_rate) {321 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);322 iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC,323 false);324 }325}326#endif327 328/*329 get the traffic load value for tid330*/331static void rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)332{333 u32 curr_time = jiffies_to_msecs(jiffies);334 u32 time_diff;335 s32 index;336 struct iwl_traffic_load *tl = NULL;337 338 if (tid >= IWL_MAX_TID_COUNT)339 return;340 341 tl = &(lq_data->load[tid]);342 343 curr_time -= curr_time % TID_ROUND_VALUE;344 345 if (!(tl->queue_count))346 return;347 348 time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time);349 index = time_diff / TID_QUEUE_CELL_SPACING;350 351 /* The history is too long: remove data that is older than */352 /* TID_MAX_TIME_DIFF */353 if (index >= TID_QUEUE_MAX_SIZE)354 rs_tl_rm_old_stats(tl, curr_time);355}356 357static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,358 struct iwl_lq_sta *lq_data, u8 tid,359 struct ieee80211_sta *sta)360{361 int ret = -EAGAIN;362 363 /*364 * Don't create TX aggregation sessions when in high365 * BT traffic, as they would just be disrupted by BT.366 */367 if (priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) {368 IWL_DEBUG_COEX(priv,369 "BT traffic (%d), no aggregation allowed\n",370 priv->bt_traffic_load);371 return ret;372 }373 374 rs_tl_get_load(lq_data, tid);375 376 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",377 sta->addr, tid);378 ret = ieee80211_start_tx_ba_session(sta, tid, 5000);379 if (ret == -EAGAIN) {380 /*381 * driver and mac80211 is out of sync382 * this might be cause by reloading firmware383 * stop the tx ba session here384 */385 IWL_ERR(priv, "Fail start Tx agg on tid: %d\n",386 tid);387 ieee80211_stop_tx_ba_session(sta, tid);388 }389 return ret;390}391 392static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,393 struct iwl_lq_sta *lq_data,394 struct ieee80211_sta *sta)395{396 if (tid < IWL_MAX_TID_COUNT)397 rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);398 else399 IWL_ERR(priv, "tid exceeds max TID count: %d/%d\n",400 tid, IWL_MAX_TID_COUNT);401}402 403static inline int get_num_of_ant_from_rate(u32 rate_n_flags)404{405 return !!(rate_n_flags & RATE_MCS_ANT_A_MSK) +406 !!(rate_n_flags & RATE_MCS_ANT_B_MSK) +407 !!(rate_n_flags & RATE_MCS_ANT_C_MSK);408}409 410/*411 * Static function to get the expected throughput from an iwl_scale_tbl_info412 * that wraps a NULL pointer check413 */414static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)415{416 if (tbl->expected_tpt)417 return tbl->expected_tpt[rs_index];418 return 0;419}420 421/*422 * rs_collect_tx_data - Update the success/failure sliding window423 *424 * We keep a sliding window of the last 62 packets transmitted425 * at this rate. window->data contains the bitmask of successful426 * packets.427 */428static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,429 int scale_index, int attempts, int successes)430{431 struct iwl_rate_scale_data *window = NULL;432 static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));433 s32 fail_count, tpt;434 435 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)436 return -EINVAL;437 438 /* Select window for current tx bit rate */439 window = &(tbl->win[scale_index]);440 441 /* Get expected throughput */442 tpt = get_expected_tpt(tbl, scale_index);443 444 /*445 * Keep track of only the latest 62 tx frame attempts in this rate's446 * history window; anything older isn't really relevant any more.447 * If we have filled up the sliding window, drop the oldest attempt;448 * if the oldest attempt (highest bit in bitmap) shows "success",449 * subtract "1" from the success counter (this is the main reason450 * we keep these bitmaps!).451 */452 while (attempts > 0) {453 if (window->counter >= IWL_RATE_MAX_WINDOW) {454 455 /* remove earliest */456 window->counter = IWL_RATE_MAX_WINDOW - 1;457 458 if (window->data & mask) {459 window->data &= ~mask;460 window->success_counter--;461 }462 }463 464 /* Increment frames-attempted counter */465 window->counter++;466 467 /* Shift bitmap by one frame to throw away oldest history */468 window->data <<= 1;469 470 /* Mark the most recent #successes attempts as successful */471 if (successes > 0) {472 window->success_counter++;473 window->data |= 0x1;474 successes--;475 }476 477 attempts--;478 }479 480 /* Calculate current success ratio, avoid divide-by-0! */481 if (window->counter > 0)482 window->success_ratio = 128 * (100 * window->success_counter)483 / window->counter;484 else485 window->success_ratio = IWL_INVALID_VALUE;486 487 fail_count = window->counter - window->success_counter;488 489 /* Calculate average throughput, if we have enough history. */490 if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) ||491 (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH))492 window->average_tpt = (window->success_ratio * tpt + 64) / 128;493 else494 window->average_tpt = IWL_INVALID_VALUE;495 496 /* Tag this window as having been updated */497 window->stamp = jiffies;498 499 return 0;500}501 502/*503 * Fill uCode API rate_n_flags field, based on "search" or "active" table.504 */505/* FIXME:RS:remove this function and put the flags statically in the table */506static u32 rate_n_flags_from_tbl(struct iwl_priv *priv,507 struct iwl_scale_tbl_info *tbl,508 int index, u8 use_green)509{510 u32 rate_n_flags = 0;511 512 if (is_legacy(tbl->lq_type)) {513 rate_n_flags = iwl_rates[index].plcp;514 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)515 rate_n_flags |= RATE_MCS_CCK_MSK;516 517 } else if (is_Ht(tbl->lq_type)) {518 if (index > IWL_LAST_OFDM_RATE) {519 IWL_ERR(priv, "Invalid HT rate index %d\n", index);520 index = IWL_LAST_OFDM_RATE;521 }522 rate_n_flags = RATE_MCS_HT_MSK;523 524 if (is_siso(tbl->lq_type))525 rate_n_flags |= iwl_rates[index].plcp_siso;526 else if (is_mimo2(tbl->lq_type))527 rate_n_flags |= iwl_rates[index].plcp_mimo2;528 else529 rate_n_flags |= iwl_rates[index].plcp_mimo3;530 } else {531 IWL_ERR(priv, "Invalid tbl->lq_type %d\n", tbl->lq_type);532 }533 534 rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) &535 RATE_MCS_ANT_ABC_MSK);536 537 if (is_Ht(tbl->lq_type)) {538 if (tbl->is_ht40) {539 if (tbl->is_dup)540 rate_n_flags |= RATE_MCS_DUP_MSK;541 else542 rate_n_flags |= RATE_MCS_HT40_MSK;543 }544 if (tbl->is_SGI)545 rate_n_flags |= RATE_MCS_SGI_MSK;546 547 if (use_green) {548 rate_n_flags |= RATE_MCS_GF_MSK;549 if (is_siso(tbl->lq_type) && tbl->is_SGI) {550 rate_n_flags &= ~RATE_MCS_SGI_MSK;551 IWL_ERR(priv, "GF was set with SGI:SISO\n");552 }553 }554 }555 return rate_n_flags;556}557 558/*559 * Interpret uCode API's rate_n_flags format,560 * fill "search" or "active" tx mode table.561 */562static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,563 enum nl80211_band band,564 struct iwl_scale_tbl_info *tbl,565 int *rate_idx)566{567 u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK);568 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags);569 u8 mcs;570 571 memset(tbl, 0, sizeof(struct iwl_scale_tbl_info));572 *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);573 574 if (*rate_idx == IWL_RATE_INVALID) {575 *rate_idx = -1;576 return -EINVAL;577 }578 tbl->is_SGI = 0; /* default legacy setup */579 tbl->is_ht40 = 0;580 tbl->is_dup = 0;581 tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);582 tbl->lq_type = LQ_NONE;583 tbl->max_search = IWL_MAX_SEARCH;584 585 /* legacy rate format */586 if (!(rate_n_flags & RATE_MCS_HT_MSK)) {587 if (num_of_ant == 1) {588 if (band == NL80211_BAND_5GHZ)589 tbl->lq_type = LQ_A;590 else591 tbl->lq_type = LQ_G;592 }593 /* HT rate format */594 } else {595 if (rate_n_flags & RATE_MCS_SGI_MSK)596 tbl->is_SGI = 1;597 598 if ((rate_n_flags & RATE_MCS_HT40_MSK) ||599 (rate_n_flags & RATE_MCS_DUP_MSK))600 tbl->is_ht40 = 1;601 602 if (rate_n_flags & RATE_MCS_DUP_MSK)603 tbl->is_dup = 1;604 605 mcs = rs_extract_rate(rate_n_flags);606 607 /* SISO */608 if (mcs <= IWL_RATE_SISO_60M_PLCP) {609 if (num_of_ant == 1)610 tbl->lq_type = LQ_SISO; /*else NONE*/611 /* MIMO2 */612 } else if (mcs <= IWL_RATE_MIMO2_60M_PLCP) {613 if (num_of_ant == 2)614 tbl->lq_type = LQ_MIMO2;615 /* MIMO3 */616 } else {617 if (num_of_ant == 3) {618 tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;619 tbl->lq_type = LQ_MIMO3;620 }621 }622 }623 return 0;624}625 626/* switch to another antenna/antennas and return 1 */627/* if no other valid antenna found, return 0 */628static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,629 struct iwl_scale_tbl_info *tbl)630{631 u8 new_ant_type;632 633 if (!tbl->ant_type || tbl->ant_type > ANT_ABC)634 return 0;635 636 if (!rs_is_valid_ant(valid_ant, tbl->ant_type))637 return 0;638 639 new_ant_type = ant_toggle_lookup[tbl->ant_type];640 641 while ((new_ant_type != tbl->ant_type) &&642 !rs_is_valid_ant(valid_ant, new_ant_type))643 new_ant_type = ant_toggle_lookup[new_ant_type];644 645 if (new_ant_type == tbl->ant_type)646 return 0;647 648 tbl->ant_type = new_ant_type;649 *rate_n_flags &= ~RATE_MCS_ANT_ABC_MSK;650 *rate_n_flags |= new_ant_type << RATE_MCS_ANT_POS;651 return 1;652}653 654/*655 * Green-field mode is valid if the station supports it and656 * there are no non-GF stations present in the BSS.657 */658static bool rs_use_green(struct ieee80211_sta *sta)659{660 /*661 * There's a bug somewhere in this code that causes the662 * scaling to get stuck because GF+SGI can't be combined663 * in SISO rates. Until we find that bug, disable GF, it664 * has only limited benefit and we still interoperate with665 * GF APs since we can always receive GF transmissions.666 */667 return false;668}669 670/*671 * rs_get_supported_rates - get the available rates672 *673 * if management frame or broadcast frame only return674 * basic available rates.675 *676 */677static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,678 struct ieee80211_hdr *hdr,679 enum iwl_table_type rate_type)680{681 if (is_legacy(rate_type)) {682 return lq_sta->active_legacy_rate;683 } else {684 if (is_siso(rate_type))685 return lq_sta->active_siso_rate;686 else if (is_mimo2(rate_type))687 return lq_sta->active_mimo2_rate;688 else689 return lq_sta->active_mimo3_rate;690 }691}692 693static u16 rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask,694 int rate_type)695{696 u8 high = IWL_RATE_INVALID;697 u8 low = IWL_RATE_INVALID;698 699 /* 802.11A or ht walks to the next literal adjacent rate in700 * the rate table */701 if (is_a_band(rate_type) || !is_legacy(rate_type)) {702 int i;703 u32 mask;704 705 /* Find the previous rate that is in the rate mask */706 i = index - 1;707 if (i >= 0)708 mask = BIT(i);709 710 for (; i >= 0; i--, mask >>= 1) {711 if (rate_mask & mask) {712 low = i;713 break;714 }715 }716 717 /* Find the next rate that is in the rate mask */718 i = index + 1;719 for (mask = (1 << i); i < IWL_RATE_COUNT; i++, mask <<= 1) {720 if (rate_mask & mask) {721 high = i;722 break;723 }724 }725 726 return (high << 8) | low;727 }728 729 low = index;730 while (low != IWL_RATE_INVALID) {731 low = iwl_rates[low].prev_rs;732 if (low == IWL_RATE_INVALID)733 break;734 if (rate_mask & (1 << low))735 break;736 IWL_DEBUG_RATE(priv, "Skipping masked lower rate: %d\n", low);737 }738 739 high = index;740 while (high != IWL_RATE_INVALID) {741 high = iwl_rates[high].next_rs;742 if (high == IWL_RATE_INVALID)743 break;744 if (rate_mask & (1 << high))745 break;746 IWL_DEBUG_RATE(priv, "Skipping masked higher rate: %d\n", high);747 }748 749 return (high << 8) | low;750}751 752static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,753 struct iwl_scale_tbl_info *tbl,754 u8 scale_index, u8 ht_possible)755{756 s32 low;757 u16 rate_mask;758 u16 high_low;759 u8 switch_to_legacy = 0;760 u8 is_green = lq_sta->is_green;761 struct iwl_priv *priv = lq_sta->drv;762 763 /* check if we need to switch from HT to legacy rates.764 * assumption is that mandatory rates (1Mbps or 6Mbps)765 * are always supported (spec demand) */766 if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) {767 switch_to_legacy = 1;768 scale_index = rs_ht_to_legacy[scale_index];769 if (lq_sta->band == NL80211_BAND_5GHZ)770 tbl->lq_type = LQ_A;771 else772 tbl->lq_type = LQ_G;773 774 if (num_of_ant(tbl->ant_type) > 1)775 tbl->ant_type =776 first_antenna(priv->nvm_data->valid_tx_ant);777 778 tbl->is_ht40 = 0;779 tbl->is_SGI = 0;780 tbl->max_search = IWL_MAX_SEARCH;781 }782 783 rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type);784 785 /* Mask with station rate restriction */786 if (is_legacy(tbl->lq_type)) {787 /* supp_rates has no CCK bits in A mode */788 if (lq_sta->band == NL80211_BAND_5GHZ)789 rate_mask = (u16)(rate_mask &790 (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));791 else792 rate_mask = (u16)(rate_mask & lq_sta->supp_rates);793 }794 795 /* If we switched from HT to legacy, check current rate */796 if (switch_to_legacy && (rate_mask & (1 << scale_index))) {797 low = scale_index;798 goto out;799 }800 801 high_low = rs_get_adjacent_rate(lq_sta->drv, scale_index, rate_mask,802 tbl->lq_type);803 low = high_low & 0xff;804 805 if (low == IWL_RATE_INVALID)806 low = scale_index;807 808out:809 return rate_n_flags_from_tbl(lq_sta->drv, tbl, low, is_green);810}811 812/*813 * Simple function to compare two rate scale table types814 */815static bool table_type_matches(struct iwl_scale_tbl_info *a,816 struct iwl_scale_tbl_info *b)817{818 return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&819 (a->is_SGI == b->is_SGI);820}821 822static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,823 struct iwl_lq_sta *lq_sta)824{825 struct iwl_scale_tbl_info *tbl;826 bool full_concurrent = priv->bt_full_concurrent;827 828 if ((priv->bt_traffic_load != priv->last_bt_traffic_load) ||829 (priv->bt_full_concurrent != full_concurrent)) {830 priv->bt_full_concurrent = full_concurrent;831 priv->last_bt_traffic_load = priv->bt_traffic_load;832 833 /* Update uCode's rate table. */834 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);835 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);836 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);837 838 queue_work(priv->workqueue, &priv->bt_full_concurrency);839 }840}841 842/*843 * mac80211 sends us Tx status844 */845static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,846 struct ieee80211_sta *sta, void *priv_sta,847 struct sk_buff *skb)848{849 int legacy_success;850 int retries;851 int rs_index, mac_index, i;852 struct iwl_lq_sta *lq_sta = priv_sta;853 struct iwl_link_quality_cmd *table;854 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;855 struct iwl_op_mode *op_mode = (struct iwl_op_mode *)priv_r;856 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);857 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);858 enum mac80211_rate_control_flags mac_flags;859 u32 tx_rate;860 struct iwl_scale_tbl_info tbl_type;861 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;862 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;863 struct iwl_rxon_context *ctx = sta_priv->ctx;864 865 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");866 867 /* Treat uninitialized rate scaling data same as non-existing. */868 if (!lq_sta) {869 IWL_DEBUG_RATE(priv, "Station rate scaling not created yet.\n");870 return;871 } else if (!lq_sta->drv) {872 IWL_DEBUG_RATE(priv, "Rate scaling not initialized yet.\n");873 return;874 }875 876 if (!ieee80211_is_data(hdr->frame_control) ||877 info->flags & IEEE80211_TX_CTL_NO_ACK)878 return;879 880 /* This packet was aggregated but doesn't carry status info */881 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&882 !(info->flags & IEEE80211_TX_STAT_AMPDU))883 return;884 885 /*886 * Ignore this Tx frame response if its initial rate doesn't match887 * that of latest Link Quality command. There may be stragglers888 * from a previous Link Quality command, but we're no longer interested889 * in those; they're either from the "active" mode while we're trying890 * to check "search" mode, or a prior "search" mode after we've moved891 * to a new "search" mode (which might become the new "active" mode).892 */893 table = &lq_sta->lq;894 tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);895 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index);896 if (priv->band == NL80211_BAND_5GHZ)897 rs_index -= IWL_FIRST_OFDM_RATE;898 mac_flags = info->status.rates[0].flags;899 mac_index = info->status.rates[0].idx;900 /* For HT packets, map MCS to PLCP */901 if (mac_flags & IEEE80211_TX_RC_MCS) {902 mac_index &= RATE_MCS_CODE_MSK; /* Remove # of streams */903 if (mac_index >= (IWL_RATE_9M_INDEX - IWL_FIRST_OFDM_RATE))904 mac_index++;905 /*906 * mac80211 HT index is always zero-indexed; we need to move907 * HT OFDM rates after CCK rates in 2.4 GHz band908 */909 if (priv->band == NL80211_BAND_2GHZ)910 mac_index += IWL_FIRST_OFDM_RATE;911 }912 /* Here we actually compare this rate to the latest LQ command */913 if ((mac_index < 0) ||914 (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||915 (tbl_type.is_ht40 != !!(mac_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) ||916 (tbl_type.is_dup != !!(mac_flags & IEEE80211_TX_RC_DUP_DATA)) ||917 (tbl_type.ant_type != info->status.antenna) ||918 (!!(tx_rate & RATE_MCS_HT_MSK) != !!(mac_flags & IEEE80211_TX_RC_MCS)) ||919 (!!(tx_rate & RATE_MCS_GF_MSK) != !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) ||920 (rs_index != mac_index)) {921 IWL_DEBUG_RATE(priv, "initial rate %d does not match %d (0x%x)\n", mac_index, rs_index, tx_rate);922 /*923 * Since rates mis-match, the last LQ command may have failed.924 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with925 * ... driver.926 */927 lq_sta->missed_rate_counter++;928 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {929 lq_sta->missed_rate_counter = 0;930 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);931 }932 /* Regardless, ignore this status info for outdated rate */933 return;934 } else935 /* Rate did match, so reset the missed_rate_counter */936 lq_sta->missed_rate_counter = 0;937 938 /* Figure out if rate scale algorithm is in active or search table */939 if (table_type_matches(&tbl_type,940 &(lq_sta->lq_info[lq_sta->active_tbl]))) {941 curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);942 other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);943 } else if (table_type_matches(&tbl_type,944 &lq_sta->lq_info[1 - lq_sta->active_tbl])) {945 curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);946 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);947 } else {948 IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");949 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);950 IWL_DEBUG_RATE(priv, "active- lq:%x, ant:%x, SGI:%d\n",951 tmp_tbl->lq_type, tmp_tbl->ant_type, tmp_tbl->is_SGI);952 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);953 IWL_DEBUG_RATE(priv, "search- lq:%x, ant:%x, SGI:%d\n",954 tmp_tbl->lq_type, tmp_tbl->ant_type, tmp_tbl->is_SGI);955 IWL_DEBUG_RATE(priv, "actual- lq:%x, ant:%x, SGI:%d\n",956 tbl_type.lq_type, tbl_type.ant_type, tbl_type.is_SGI);957 /*958 * no matching table found, let's by-pass the data collection959 * and continue to perform rate scale to find the rate table960 */961 rs_stay_in_table(lq_sta, true);962 goto done;963 }964 965 /*966 * Updating the frame history depends on whether packets were967 * aggregated.968 *969 * For aggregation, all packets were transmitted at the same rate, the970 * first index into rate scale table.971 */972 if (info->flags & IEEE80211_TX_STAT_AMPDU) {973 tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);974 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type,975 &rs_index);976 rs_collect_tx_data(curr_tbl, rs_index,977 info->status.ampdu_len,978 info->status.ampdu_ack_len);979 980 /* Update success/fail counts if not searching for new mode */981 if (lq_sta->stay_in_tbl) {982 lq_sta->total_success += info->status.ampdu_ack_len;983 lq_sta->total_failed += (info->status.ampdu_len -984 info->status.ampdu_ack_len);985 }986 } else {987 /*988 * For legacy, update frame history with for each Tx retry.989 */990 retries = info->status.rates[0].count - 1;991 /* HW doesn't send more than 15 retries */992 retries = min(retries, 15);993 994 /* The last transmission may have been successful */995 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);996 /* Collect data for each rate used during failed TX attempts */997 for (i = 0; i <= retries; ++i) {998 tx_rate = le32_to_cpu(table->rs_table[i].rate_n_flags);999 rs_get_tbl_info_from_mcs(tx_rate, priv->band,1000 &tbl_type, &rs_index);1001 /*1002 * Only collect stats if retried rate is in the same RS1003 * table as active/search.1004 */1005 if (table_type_matches(&tbl_type, curr_tbl))1006 tmp_tbl = curr_tbl;1007 else if (table_type_matches(&tbl_type, other_tbl))1008 tmp_tbl = other_tbl;1009 else1010 continue;1011 rs_collect_tx_data(tmp_tbl, rs_index, 1,1012 i < retries ? 0 : legacy_success);1013 }1014 1015 /* Update success/fail counts if not searching for new mode */1016 if (lq_sta->stay_in_tbl) {1017 lq_sta->total_success += legacy_success;1018 lq_sta->total_failed += retries + (1 - legacy_success);1019 }1020 }1021 /* The last TX rate is cached in lq_sta; it's set in if/else above */1022 lq_sta->last_rate_n_flags = tx_rate;1023done:1024 /* See if there's a better rate or modulation mode to try. */1025 if (sta && sta->deflink.supp_rates[sband->band])1026 rs_rate_scale_perform(priv, skb, sta, lq_sta);1027 1028 if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist)1029 rs_bt_update_lq(priv, ctx, lq_sta);1030}1031 1032/*1033 * Begin a period of staying with a selected modulation mode.1034 * Set "stay_in_tbl" flag to prevent any mode switches.1035 * Set frame tx success limits according to legacy vs. high-throughput,1036 * and reset overall (spanning all rates) tx success history statistics.1037 * These control how long we stay using same modulation mode before1038 * searching for a new mode.1039 */1040static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,1041 struct iwl_lq_sta *lq_sta)1042{1043 IWL_DEBUG_RATE(priv, "we are staying in the same table\n");1044 lq_sta->stay_in_tbl = 1; /* only place this gets set */1045 if (is_legacy) {1046 lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT;1047 lq_sta->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT;1048 lq_sta->max_success_limit = IWL_LEGACY_SUCCESS_LIMIT;1049 } else {1050 lq_sta->table_count_limit = IWL_NONE_LEGACY_TABLE_COUNT;1051 lq_sta->max_failure_limit = IWL_NONE_LEGACY_FAILURE_LIMIT;1052 lq_sta->max_success_limit = IWL_NONE_LEGACY_SUCCESS_LIMIT;1053 }1054 lq_sta->table_count = 0;1055 lq_sta->total_failed = 0;1056 lq_sta->total_success = 0;1057 lq_sta->flush_timer = jiffies;1058 lq_sta->action_counter = 0;1059}1060 1061/*1062 * Find correct throughput table for given mode of modulation1063 */1064static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,1065 struct iwl_scale_tbl_info *tbl)1066{1067 /* Used to choose among HT tables */1068 const u16 (*ht_tbl_pointer)[IWL_RATE_COUNT];1069 1070 /* Check for invalid LQ type */1071 if (WARN_ON_ONCE(!is_legacy(tbl->lq_type) && !is_Ht(tbl->lq_type))) {1072 tbl->expected_tpt = expected_tpt_legacy;1073 return;1074 }1075 1076 /* Legacy rates have only one table */1077 if (is_legacy(tbl->lq_type)) {1078 tbl->expected_tpt = expected_tpt_legacy;1079 return;1080 }1081 1082 /* Choose among many HT tables depending on number of streams1083 * (SISO/MIMO2/MIMO3), channel width (20/40), SGI, and aggregation1084 * status */1085 if (is_siso(tbl->lq_type) && (!tbl->is_ht40 || lq_sta->is_dup))1086 ht_tbl_pointer = expected_tpt_siso20MHz;1087 else if (is_siso(tbl->lq_type))1088 ht_tbl_pointer = expected_tpt_siso40MHz;1089 else if (is_mimo2(tbl->lq_type) && (!tbl->is_ht40 || lq_sta->is_dup))1090 ht_tbl_pointer = expected_tpt_mimo2_20MHz;1091 else if (is_mimo2(tbl->lq_type))1092 ht_tbl_pointer = expected_tpt_mimo2_40MHz;1093 else if (is_mimo3(tbl->lq_type) && (!tbl->is_ht40 || lq_sta->is_dup))1094 ht_tbl_pointer = expected_tpt_mimo3_20MHz;1095 else /* if (is_mimo3(tbl->lq_type)) <-- must be true */1096 ht_tbl_pointer = expected_tpt_mimo3_40MHz;1097 1098 if (!tbl->is_SGI && !lq_sta->is_agg) /* Normal */1099 tbl->expected_tpt = ht_tbl_pointer[0];1100 else if (tbl->is_SGI && !lq_sta->is_agg) /* SGI */1101 tbl->expected_tpt = ht_tbl_pointer[1];1102 else if (!tbl->is_SGI && lq_sta->is_agg) /* AGG */1103 tbl->expected_tpt = ht_tbl_pointer[2];1104 else /* AGG+SGI */1105 tbl->expected_tpt = ht_tbl_pointer[3];1106}1107 1108/*1109 * Find starting rate for new "search" high-throughput mode of modulation.1110 * Goal is to find lowest expected rate (under perfect conditions) that is1111 * above the current measured throughput of "active" mode, to give new mode1112 * a fair chance to prove itself without too many challenges.1113 *1114 * This gets called when transitioning to more aggressive modulation1115 * (i.e. legacy to SISO or MIMO, or SISO to MIMO), as well as less aggressive1116 * (i.e. MIMO to SISO). When moving to MIMO, bit rate will typically need1117 * to decrease to match "active" throughput. When moving from MIMO to SISO,1118 * bit rate will typically need to increase, but not if performance was bad.1119 */1120static s32 rs_get_best_rate(struct iwl_priv *priv,1121 struct iwl_lq_sta *lq_sta,1122 struct iwl_scale_tbl_info *tbl, /* "search" */1123 u16 rate_mask, s8 index)1124{1125 /* "active" values */1126 struct iwl_scale_tbl_info *active_tbl =1127 &(lq_sta->lq_info[lq_sta->active_tbl]);1128 s32 active_sr = active_tbl->win[index].success_ratio;1129 s32 active_tpt = active_tbl->expected_tpt[index];1130 /* expected "search" throughput */1131 const u16 *tpt_tbl = tbl->expected_tpt;1132 1133 s32 new_rate, high, low, start_hi;1134 u16 high_low;1135 s8 rate = index;1136 1137 new_rate = high = low = start_hi = IWL_RATE_INVALID;1138 1139 for (; ;) {1140 high_low = rs_get_adjacent_rate(priv, rate, rate_mask,1141 tbl->lq_type);1142 1143 low = high_low & 0xff;1144 high = (high_low >> 8) & 0xff;1145 1146 /*1147 * Lower the "search" bit rate, to give new "search" mode1148 * approximately the same throughput as "active" if:1149 *1150 * 1) "Active" mode has been working modestly well (but not1151 * great), and expected "search" throughput (under perfect1152 * conditions) at candidate rate is above the actual1153 * measured "active" throughput (but less than expected1154 * "active" throughput under perfect conditions).1155 * OR1156 * 2) "Active" mode has been working perfectly or very well1157 * and expected "search" throughput (under perfect1158 * conditions) at candidate rate is above expected1159 * "active" throughput (under perfect conditions).1160 */1161 if ((((100 * tpt_tbl[rate]) > lq_sta->last_tpt) &&1162 ((active_sr > IWL_RATE_DECREASE_TH) &&1163 (active_sr <= IWL_RATE_HIGH_TH) &&1164 (tpt_tbl[rate] <= active_tpt))) ||1165 ((active_sr >= IWL_RATE_SCALE_SWITCH) &&1166 (tpt_tbl[rate] > active_tpt))) {1167 1168 /* (2nd or later pass)1169 * If we've already tried to raise the rate, and are1170 * now trying to lower it, use the higher rate. */1171 if (start_hi != IWL_RATE_INVALID) {1172 new_rate = start_hi;1173 break;1174 }1175 1176 new_rate = rate;1177 1178 /* Loop again with lower rate */1179 if (low != IWL_RATE_INVALID)1180 rate = low;1181 1182 /* Lower rate not available, use the original */1183 else1184 break;1185 1186 /* Else try to raise the "search" rate to match "active" */1187 } else {1188 /* (2nd or later pass)1189 * If we've already tried to lower the rate, and are1190 * now trying to raise it, use the lower rate. */1191 if (new_rate != IWL_RATE_INVALID)1192 break;1193 1194 /* Loop again with higher rate */1195 else if (high != IWL_RATE_INVALID) {1196 start_hi = high;1197 rate = high;1198 1199 /* Higher rate not available, use the original */1200 } else {1201 new_rate = rate;1202 break;1203 }1204 }1205 }1206 1207 return new_rate;1208}1209 1210/*1211 * Set up search table for MIMO21212 */1213static int rs_switch_to_mimo2(struct iwl_priv *priv,1214 struct iwl_lq_sta *lq_sta,1215 struct ieee80211_conf *conf,1216 struct ieee80211_sta *sta,1217 struct iwl_scale_tbl_info *tbl, int index)1218{1219 u16 rate_mask;1220 s32 rate;1221 s8 is_green = lq_sta->is_green;1222 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;1223 struct iwl_rxon_context *ctx = sta_priv->ctx;1224 1225 if (!conf_is_ht(conf) || !sta->deflink.ht_cap.ht_supported)1226 return -1;1227 1228 if (sta->deflink.smps_mode == IEEE80211_SMPS_STATIC)1229 return -1;1230 1231 /* Need both Tx chains/antennas to support MIMO */1232 if (priv->hw_params.tx_chains_num < 2)1233 return -1;1234 1235 IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO2\n");1236 1237 tbl->lq_type = LQ_MIMO2;1238 tbl->is_dup = lq_sta->is_dup;1239 tbl->action = 0;1240 tbl->max_search = IWL_MAX_SEARCH;1241 rate_mask = lq_sta->active_mimo2_rate;1242 1243 if (iwl_is_ht40_tx_allowed(priv, ctx, sta))1244 tbl->is_ht40 = 1;1245 else1246 tbl->is_ht40 = 0;1247 1248 rs_set_expected_tpt_table(lq_sta, tbl);1249 1250 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);1251 1252 IWL_DEBUG_RATE(priv, "LQ: MIMO2 best rate %d mask %X\n", rate, rate_mask);1253 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {1254 IWL_DEBUG_RATE(priv, "Can't switch with index %d rate mask %x\n",1255 rate, rate_mask);1256 return -1;1257 }1258 tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);1259 1260 IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n",1261 tbl->current_rate, is_green);1262 return 0;1263}1264 1265/*1266 * Set up search table for MIMO31267 */1268static int rs_switch_to_mimo3(struct iwl_priv *priv,1269 struct iwl_lq_sta *lq_sta,1270 struct ieee80211_conf *conf,1271 struct ieee80211_sta *sta,1272 struct iwl_scale_tbl_info *tbl, int index)1273{1274 u16 rate_mask;1275 s32 rate;1276 s8 is_green = lq_sta->is_green;1277 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;1278 struct iwl_rxon_context *ctx = sta_priv->ctx;1279 1280 if (!conf_is_ht(conf) || !sta->deflink.ht_cap.ht_supported)1281 return -1;1282 1283 if (sta->deflink.smps_mode == IEEE80211_SMPS_STATIC)1284 return -1;1285 1286 /* Need both Tx chains/antennas to support MIMO */1287 if (priv->hw_params.tx_chains_num < 3)1288 return -1;1289 1290 IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO3\n");1291 1292 tbl->lq_type = LQ_MIMO3;1293 tbl->is_dup = lq_sta->is_dup;1294 tbl->action = 0;1295 tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;1296 rate_mask = lq_sta->active_mimo3_rate;1297 1298 if (iwl_is_ht40_tx_allowed(priv, ctx, sta))1299 tbl->is_ht40 = 1;1300 else1301 tbl->is_ht40 = 0;1302 1303 rs_set_expected_tpt_table(lq_sta, tbl);1304 1305 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);1306 1307 IWL_DEBUG_RATE(priv, "LQ: MIMO3 best rate %d mask %X\n",1308 rate, rate_mask);1309 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {1310 IWL_DEBUG_RATE(priv, "Can't switch with index %d rate mask %x\n",1311 rate, rate_mask);1312 return -1;1313 }1314 tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);1315 1316 IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n",1317 tbl->current_rate, is_green);1318 return 0;1319}1320 1321/*1322 * Set up search table for SISO1323 */1324static int rs_switch_to_siso(struct iwl_priv *priv,1325 struct iwl_lq_sta *lq_sta,1326 struct ieee80211_conf *conf,1327 struct ieee80211_sta *sta,1328 struct iwl_scale_tbl_info *tbl, int index)1329{1330 u16 rate_mask;1331 u8 is_green = lq_sta->is_green;1332 s32 rate;1333 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;1334 struct iwl_rxon_context *ctx = sta_priv->ctx;1335 1336 if (!conf_is_ht(conf) || !sta->deflink.ht_cap.ht_supported)1337 return -1;1338 1339 IWL_DEBUG_RATE(priv, "LQ: try to switch to SISO\n");1340 1341 tbl->is_dup = lq_sta->is_dup;1342 tbl->lq_type = LQ_SISO;1343 tbl->action = 0;1344 tbl->max_search = IWL_MAX_SEARCH;1345 rate_mask = lq_sta->active_siso_rate;1346 1347 if (iwl_is_ht40_tx_allowed(priv, ctx, sta))1348 tbl->is_ht40 = 1;1349 else1350 tbl->is_ht40 = 0;1351 1352 if (is_green)1353 tbl->is_SGI = 0; /*11n spec: no SGI in SISO+Greenfield*/1354 1355 rs_set_expected_tpt_table(lq_sta, tbl);1356 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);1357 1358 IWL_DEBUG_RATE(priv, "LQ: get best rate %d mask %X\n", rate, rate_mask);1359 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {1360 IWL_DEBUG_RATE(priv, "can not switch with index %d rate mask %x\n",1361 rate, rate_mask);1362 return -1;1363 }1364 tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);1365 IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n",1366 tbl->current_rate, is_green);1367 return 0;1368}1369 1370/*1371 * Try to switch to new modulation mode from legacy1372 */1373static void rs_move_legacy_other(struct iwl_priv *priv,1374 struct iwl_lq_sta *lq_sta,1375 struct ieee80211_conf *conf,1376 struct ieee80211_sta *sta,1377 int index)1378{1379 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);1380 struct iwl_scale_tbl_info *search_tbl =1381 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);1382 struct iwl_rate_scale_data *window = &(tbl->win[index]);1383 u32 sz = (sizeof(struct iwl_scale_tbl_info) -1384 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));1385 u8 start_action;1386 u8 valid_tx_ant = priv->nvm_data->valid_tx_ant;1387 u8 tx_chains_num = priv->hw_params.tx_chains_num;1388 int ret = 0;1389 u8 update_search_tbl_counter = 0;1390 1391 switch (priv->bt_traffic_load) {1392 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:1393 /* nothing */1394 break;1395 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:1396 /* avoid antenna B unless MIMO */1397 if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2)1398 tbl->action = IWL_LEGACY_SWITCH_SISO;1399 break;1400 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:1401 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:1402 /* avoid antenna B and MIMO */1403 valid_tx_ant =1404 first_antenna(priv->nvm_data->valid_tx_ant);1405 if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 &&1406 tbl->action != IWL_LEGACY_SWITCH_SISO)1407 tbl->action = IWL_LEGACY_SWITCH_SISO;1408 break;1409 default:1410 IWL_ERR(priv, "Invalid BT load %d\n", priv->bt_traffic_load);1411 break;1412 }1413 1414 if (!iwl_ht_enabled(priv))1415 /* stay in Legacy */1416 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;1417 else if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE &&1418 tbl->action > IWL_LEGACY_SWITCH_SISO)1419 tbl->action = IWL_LEGACY_SWITCH_SISO;1420 1421 /* configure as 1x1 if bt full concurrency */1422 if (priv->bt_full_concurrent) {1423 if (!iwl_ht_enabled(priv))1424 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;1425 else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2)1426 tbl->action = IWL_LEGACY_SWITCH_SISO;1427 valid_tx_ant =1428 first_antenna(priv->nvm_data->valid_tx_ant);1429 }1430 1431 start_action = tbl->action;1432 for (; ;) {1433 lq_sta->action_counter++;1434 switch (tbl->action) {1435 case IWL_LEGACY_SWITCH_ANTENNA1:1436 case IWL_LEGACY_SWITCH_ANTENNA2:1437 IWL_DEBUG_RATE(priv, "LQ: Legacy toggle Antenna\n");1438 1439 if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 &&1440 tx_chains_num <= 1) ||1441 (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 &&1442 tx_chains_num <= 2))1443 break;1444 1445 /* Don't change antenna if success has been great */1446 if (window->success_ratio >= IWL_RS_GOOD_RATIO &&1447 !priv->bt_full_concurrent &&1448 priv->bt_traffic_load ==1449 IWL_BT_COEX_TRAFFIC_LOAD_NONE)1450 break;1451 1452 /* Set up search table to try other antenna */1453 memcpy(search_tbl, tbl, sz);1454 1455 if (rs_toggle_antenna(valid_tx_ant,1456 &search_tbl->current_rate, search_tbl)) {1457 update_search_tbl_counter = 1;1458 rs_set_expected_tpt_table(lq_sta, search_tbl);1459 goto out;1460 }1461 break;1462 case IWL_LEGACY_SWITCH_SISO:1463 IWL_DEBUG_RATE(priv, "LQ: Legacy switch to SISO\n");1464 1465 /* Set up search table to try SISO */1466 memcpy(search_tbl, tbl, sz);1467 search_tbl->is_SGI = 0;1468 ret = rs_switch_to_siso(priv, lq_sta, conf, sta,1469 search_tbl, index);1470 if (!ret) {1471 lq_sta->action_counter = 0;1472 goto out;1473 }1474 1475 break;1476 case IWL_LEGACY_SWITCH_MIMO2_AB:1477 case IWL_LEGACY_SWITCH_MIMO2_AC:1478 case IWL_LEGACY_SWITCH_MIMO2_BC:1479 IWL_DEBUG_RATE(priv, "LQ: Legacy switch to MIMO2\n");1480 1481 /* Set up search table to try MIMO */1482 memcpy(search_tbl, tbl, sz);1483 search_tbl->is_SGI = 0;1484 1485 if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AB)1486 search_tbl->ant_type = ANT_AB;1487 else if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AC)1488 search_tbl->ant_type = ANT_AC;1489 else1490 search_tbl->ant_type = ANT_BC;1491 1492 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))1493 break;1494 1495 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,1496 search_tbl, index);1497 if (!ret) {1498 lq_sta->action_counter = 0;1499 goto out;1500 }1501 break;1502 1503 case IWL_LEGACY_SWITCH_MIMO3_ABC:1504 IWL_DEBUG_RATE(priv, "LQ: Legacy switch to MIMO3\n");1505 1506 /* Set up search table to try MIMO3 */1507 memcpy(search_tbl, tbl, sz);1508 search_tbl->is_SGI = 0;1509 1510 search_tbl->ant_type = ANT_ABC;1511 1512 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))1513 break;1514 1515 ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,1516 search_tbl, index);1517 if (!ret) {1518 lq_sta->action_counter = 0;1519 goto out;1520 }1521 break;1522 }1523 tbl->action++;1524 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)1525 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;1526 1527 if (tbl->action == start_action)1528 break;1529 1530 }1531 search_tbl->lq_type = LQ_NONE;1532 return;1533 1534out:1535 lq_sta->search_better_tbl = 1;1536 tbl->action++;1537 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)1538 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;1539 if (update_search_tbl_counter)1540 search_tbl->action = tbl->action;1541}1542 1543/*1544 * Try to switch to new modulation mode from SISO1545 */1546static void rs_move_siso_to_other(struct iwl_priv *priv,1547 struct iwl_lq_sta *lq_sta,1548 struct ieee80211_conf *conf,1549 struct ieee80211_sta *sta, int index)1550{1551 u8 is_green = lq_sta->is_green;1552 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);1553 struct iwl_scale_tbl_info *search_tbl =1554 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);1555 struct iwl_rate_scale_data *window = &(tbl->win[index]);1556 struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;1557 u32 sz = (sizeof(struct iwl_scale_tbl_info) -1558 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));1559 u8 start_action;1560 u8 valid_tx_ant = priv->nvm_data->valid_tx_ant;1561 u8 tx_chains_num = priv->hw_params.tx_chains_num;1562 u8 update_search_tbl_counter = 0;1563 int ret;1564 1565 switch (priv->bt_traffic_load) {1566 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:1567 /* nothing */1568 break;1569 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:1570 /* avoid antenna B unless MIMO */1571 if (tbl->action == IWL_SISO_SWITCH_ANTENNA2)1572 tbl->action = IWL_SISO_SWITCH_MIMO2_AB;1573 break;1574 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:1575 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:1576 /* avoid antenna B and MIMO */1577 valid_tx_ant =1578 first_antenna(priv->nvm_data->valid_tx_ant);1579 if (tbl->action != IWL_SISO_SWITCH_ANTENNA1)1580 tbl->action = IWL_SISO_SWITCH_ANTENNA1;1581 break;1582 default:1583 IWL_ERR(priv, "Invalid BT load %d\n", priv->bt_traffic_load);1584 break;1585 }1586 1587 if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE &&1588 tbl->action > IWL_SISO_SWITCH_ANTENNA2) {1589 /* stay in SISO */1590 tbl->action = IWL_SISO_SWITCH_ANTENNA1;1591 }1592 1593 /* configure as 1x1 if bt full concurrency */1594 if (priv->bt_full_concurrent) {1595 valid_tx_ant =1596 first_antenna(priv->nvm_data->valid_tx_ant);1597 if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2)1598 tbl->action = IWL_SISO_SWITCH_ANTENNA1;1599 }1600 1601 start_action = tbl->action;1602 for (;;) {1603 lq_sta->action_counter++;1604 switch (tbl->action) {1605 case IWL_SISO_SWITCH_ANTENNA1:1606 case IWL_SISO_SWITCH_ANTENNA2:1607 IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n");1608 if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 &&1609 tx_chains_num <= 1) ||1610 (tbl->action == IWL_SISO_SWITCH_ANTENNA2 &&1611 tx_chains_num <= 2))1612 break;1613 1614 if (window->success_ratio >= IWL_RS_GOOD_RATIO &&1615 !priv->bt_full_concurrent &&1616 priv->bt_traffic_load ==1617 IWL_BT_COEX_TRAFFIC_LOAD_NONE)1618 break;1619 1620 memcpy(search_tbl, tbl, sz);1621 if (rs_toggle_antenna(valid_tx_ant,1622 &search_tbl->current_rate, search_tbl)) {1623 update_search_tbl_counter = 1;1624 goto out;1625 }1626 break;1627 case IWL_SISO_SWITCH_MIMO2_AB:1628 case IWL_SISO_SWITCH_MIMO2_AC:1629 case IWL_SISO_SWITCH_MIMO2_BC:1630 IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO2\n");1631 memcpy(search_tbl, tbl, sz);1632 search_tbl->is_SGI = 0;1633 1634 if (tbl->action == IWL_SISO_SWITCH_MIMO2_AB)1635 search_tbl->ant_type = ANT_AB;1636 else if (tbl->action == IWL_SISO_SWITCH_MIMO2_AC)1637 search_tbl->ant_type = ANT_AC;1638 else1639 search_tbl->ant_type = ANT_BC;1640 1641 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))1642 break;1643 1644 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,1645 search_tbl, index);1646 if (!ret)1647 goto out;1648 break;1649 case IWL_SISO_SWITCH_GI:1650 if (!tbl->is_ht40 && !(ht_cap->cap &1651 IEEE80211_HT_CAP_SGI_20))1652 break;1653 if (tbl->is_ht40 && !(ht_cap->cap &1654 IEEE80211_HT_CAP_SGI_40))1655 break;1656 1657 IWL_DEBUG_RATE(priv, "LQ: SISO toggle SGI/NGI\n");1658 1659 memcpy(search_tbl, tbl, sz);1660 if (is_green) {1661 if (!tbl->is_SGI)1662 break;1663 else1664 IWL_ERR(priv,1665 "SGI was set in GF+SISO\n");1666 }1667 search_tbl->is_SGI = !tbl->is_SGI;1668 rs_set_expected_tpt_table(lq_sta, search_tbl);1669 if (tbl->is_SGI) {1670 s32 tpt = lq_sta->last_tpt / 100;1671 if (tpt >= search_tbl->expected_tpt[index])1672 break;1673 }1674 search_tbl->current_rate =1675 rate_n_flags_from_tbl(priv, search_tbl,1676 index, is_green);1677 update_search_tbl_counter = 1;1678 goto out;1679 case IWL_SISO_SWITCH_MIMO3_ABC:1680 IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO3\n");1681 memcpy(search_tbl, tbl, sz);1682 search_tbl->is_SGI = 0;1683 search_tbl->ant_type = ANT_ABC;1684 1685 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))1686 break;1687 1688 ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,1689 search_tbl, index);1690 if (!ret)1691 goto out;1692 break;1693 }1694 tbl->action++;1695 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)1696 tbl->action = IWL_SISO_SWITCH_ANTENNA1;1697 1698 if (tbl->action == start_action)1699 break;1700 }1701 search_tbl->lq_type = LQ_NONE;1702 return;1703 1704 out:1705 lq_sta->search_better_tbl = 1;1706 tbl->action++;1707 if (tbl->action > IWL_SISO_SWITCH_MIMO3_ABC)1708 tbl->action = IWL_SISO_SWITCH_ANTENNA1;1709 if (update_search_tbl_counter)1710 search_tbl->action = tbl->action;1711}1712 1713/*1714 * Try to switch to new modulation mode from MIMO21715 */1716static void rs_move_mimo2_to_other(struct iwl_priv *priv,1717 struct iwl_lq_sta *lq_sta,1718 struct ieee80211_conf *conf,1719 struct ieee80211_sta *sta, int index)1720{1721 s8 is_green = lq_sta->is_green;1722 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);1723 struct iwl_scale_tbl_info *search_tbl =1724 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);1725 struct iwl_rate_scale_data *window = &(tbl->win[index]);1726 struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;1727 u32 sz = (sizeof(struct iwl_scale_tbl_info) -1728 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));1729 u8 start_action;1730 u8 valid_tx_ant = priv->nvm_data->valid_tx_ant;1731 u8 tx_chains_num = priv->hw_params.tx_chains_num;1732 u8 update_search_tbl_counter = 0;1733 int ret;1734 1735 switch (priv->bt_traffic_load) {1736 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:1737 /* nothing */1738 break;1739 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:1740 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:1741 /* avoid antenna B and MIMO */1742 if (tbl->action != IWL_MIMO2_SWITCH_SISO_A)1743 tbl->action = IWL_MIMO2_SWITCH_SISO_A;1744 break;1745 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:1746 /* avoid antenna B unless MIMO */1747 if (tbl->action == IWL_MIMO2_SWITCH_SISO_B ||1748 tbl->action == IWL_MIMO2_SWITCH_SISO_C)1749 tbl->action = IWL_MIMO2_SWITCH_SISO_A;1750 break;1751 default:1752 IWL_ERR(priv, "Invalid BT load %d\n", priv->bt_traffic_load);1753 break;1754 }1755 1756 if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) &&1757 (tbl->action < IWL_MIMO2_SWITCH_SISO_A ||1758 tbl->action > IWL_MIMO2_SWITCH_SISO_C)) {1759 /* switch in SISO */1760 tbl->action = IWL_MIMO2_SWITCH_SISO_A;1761 }1762 1763 /* configure as 1x1 if bt full concurrency */1764 if (priv->bt_full_concurrent &&1765 (tbl->action < IWL_MIMO2_SWITCH_SISO_A ||1766 tbl->action > IWL_MIMO2_SWITCH_SISO_C))1767 tbl->action = IWL_MIMO2_SWITCH_SISO_A;1768 1769 start_action = tbl->action;1770 for (;;) {1771 lq_sta->action_counter++;1772 switch (tbl->action) {1773 case IWL_MIMO2_SWITCH_ANTENNA1:1774 case IWL_MIMO2_SWITCH_ANTENNA2:1775 IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle Antennas\n");1776 1777 if (tx_chains_num <= 2)1778 break;1779 1780 if (window->success_ratio >= IWL_RS_GOOD_RATIO)1781 break;1782 1783 memcpy(search_tbl, tbl, sz);1784 if (rs_toggle_antenna(valid_tx_ant,1785 &search_tbl->current_rate, search_tbl)) {1786 update_search_tbl_counter = 1;1787 goto out;1788 }1789 break;1790 case IWL_MIMO2_SWITCH_SISO_A:1791 case IWL_MIMO2_SWITCH_SISO_B:1792 case IWL_MIMO2_SWITCH_SISO_C:1793 IWL_DEBUG_RATE(priv, "LQ: MIMO2 switch to SISO\n");1794 1795 /* Set up new search table for SISO */1796 memcpy(search_tbl, tbl, sz);1797 1798 if (tbl->action == IWL_MIMO2_SWITCH_SISO_A)1799 search_tbl->ant_type = ANT_A;1800 else if (tbl->action == IWL_MIMO2_SWITCH_SISO_B)1801 search_tbl->ant_type = ANT_B;1802 else1803 search_tbl->ant_type = ANT_C;1804 1805 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))1806 break;1807 1808 ret = rs_switch_to_siso(priv, lq_sta, conf, sta,1809 search_tbl, index);1810 if (!ret)1811 goto out;1812 1813 break;1814 1815 case IWL_MIMO2_SWITCH_GI:1816 if (!tbl->is_ht40 && !(ht_cap->cap &1817 IEEE80211_HT_CAP_SGI_20))1818 break;1819 if (tbl->is_ht40 && !(ht_cap->cap &1820 IEEE80211_HT_CAP_SGI_40))1821 break;1822 1823 IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle SGI/NGI\n");1824 1825 /* Set up new search table for MIMO2 */1826 memcpy(search_tbl, tbl, sz);1827 search_tbl->is_SGI = !tbl->is_SGI;1828 rs_set_expected_tpt_table(lq_sta, search_tbl);1829 /*1830 * If active table already uses the fastest possible1831 * modulation (dual stream with short guard interval),1832 * and it's working well, there's no need to look1833 * for a better type of modulation!1834 */1835 if (tbl->is_SGI) {1836 s32 tpt = lq_sta->last_tpt / 100;1837 if (tpt >= search_tbl->expected_tpt[index])1838 break;1839 }1840 search_tbl->current_rate =1841 rate_n_flags_from_tbl(priv, search_tbl,1842 index, is_green);1843 update_search_tbl_counter = 1;1844 goto out;1845 1846 case IWL_MIMO2_SWITCH_MIMO3_ABC:1847 IWL_DEBUG_RATE(priv, "LQ: MIMO2 switch to MIMO3\n");1848 memcpy(search_tbl, tbl, sz);1849 search_tbl->is_SGI = 0;1850 search_tbl->ant_type = ANT_ABC;1851 1852 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))1853 break;1854 1855 ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,1856 search_tbl, index);1857 if (!ret)1858 goto out;1859 1860 break;1861 }1862 tbl->action++;1863 if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC)1864 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;1865 1866 if (tbl->action == start_action)1867 break;1868 }1869 search_tbl->lq_type = LQ_NONE;1870 return;1871 out:1872 lq_sta->search_better_tbl = 1;1873 tbl->action++;1874 if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC)1875 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;1876 if (update_search_tbl_counter)1877 search_tbl->action = tbl->action;1878 1879}1880 1881/*1882 * Try to switch to new modulation mode from MIMO31883 */1884static void rs_move_mimo3_to_other(struct iwl_priv *priv,1885 struct iwl_lq_sta *lq_sta,1886 struct ieee80211_conf *conf,1887 struct ieee80211_sta *sta, int index)1888{1889 s8 is_green = lq_sta->is_green;1890 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);1891 struct iwl_scale_tbl_info *search_tbl =1892 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);1893 struct iwl_rate_scale_data *window = &(tbl->win[index]);1894 struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;1895 u32 sz = (sizeof(struct iwl_scale_tbl_info) -1896 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));1897 u8 start_action;1898 u8 valid_tx_ant = priv->nvm_data->valid_tx_ant;1899 u8 tx_chains_num = priv->hw_params.tx_chains_num;1900 int ret;1901 u8 update_search_tbl_counter = 0;1902 1903 switch (priv->bt_traffic_load) {1904 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:1905 /* nothing */1906 break;1907 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:1908 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:1909 /* avoid antenna B and MIMO */1910 if (tbl->action != IWL_MIMO3_SWITCH_SISO_A)1911 tbl->action = IWL_MIMO3_SWITCH_SISO_A;1912 break;1913 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:1914 /* avoid antenna B unless MIMO */1915 if (tbl->action == IWL_MIMO3_SWITCH_SISO_B ||1916 tbl->action == IWL_MIMO3_SWITCH_SISO_C)1917 tbl->action = IWL_MIMO3_SWITCH_SISO_A;1918 break;1919 default:1920 IWL_ERR(priv, "Invalid BT load %d\n", priv->bt_traffic_load);1921 break;1922 }1923 1924 if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) &&1925 (tbl->action < IWL_MIMO3_SWITCH_SISO_A ||1926 tbl->action > IWL_MIMO3_SWITCH_SISO_C)) {1927 /* switch in SISO */1928 tbl->action = IWL_MIMO3_SWITCH_SISO_A;1929 }1930 1931 /* configure as 1x1 if bt full concurrency */1932 if (priv->bt_full_concurrent &&1933 (tbl->action < IWL_MIMO3_SWITCH_SISO_A ||1934 tbl->action > IWL_MIMO3_SWITCH_SISO_C))1935 tbl->action = IWL_MIMO3_SWITCH_SISO_A;1936 1937 start_action = tbl->action;1938 for (;;) {1939 lq_sta->action_counter++;1940 switch (tbl->action) {1941 case IWL_MIMO3_SWITCH_ANTENNA1:1942 case IWL_MIMO3_SWITCH_ANTENNA2:1943 IWL_DEBUG_RATE(priv, "LQ: MIMO3 toggle Antennas\n");1944 1945 if (tx_chains_num <= 3)1946 break;1947 1948 if (window->success_ratio >= IWL_RS_GOOD_RATIO)1949 break;1950 1951 memcpy(search_tbl, tbl, sz);1952 if (rs_toggle_antenna(valid_tx_ant,1953 &search_tbl->current_rate, search_tbl))1954 goto out;1955 break;1956 case IWL_MIMO3_SWITCH_SISO_A:1957 case IWL_MIMO3_SWITCH_SISO_B:1958 case IWL_MIMO3_SWITCH_SISO_C:1959 IWL_DEBUG_RATE(priv, "LQ: MIMO3 switch to SISO\n");1960 1961 /* Set up new search table for SISO */1962 memcpy(search_tbl, tbl, sz);1963 1964 if (tbl->action == IWL_MIMO3_SWITCH_SISO_A)1965 search_tbl->ant_type = ANT_A;1966 else if (tbl->action == IWL_MIMO3_SWITCH_SISO_B)1967 search_tbl->ant_type = ANT_B;1968 else1969 search_tbl->ant_type = ANT_C;1970 1971 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))1972 break;1973 1974 ret = rs_switch_to_siso(priv, lq_sta, conf, sta,1975 search_tbl, index);1976 if (!ret)1977 goto out;1978 1979 break;1980 1981 case IWL_MIMO3_SWITCH_MIMO2_AB:1982 case IWL_MIMO3_SWITCH_MIMO2_AC:1983 case IWL_MIMO3_SWITCH_MIMO2_BC:1984 IWL_DEBUG_RATE(priv, "LQ: MIMO3 switch to MIMO2\n");1985 1986 memcpy(search_tbl, tbl, sz);1987 search_tbl->is_SGI = 0;1988 if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AB)1989 search_tbl->ant_type = ANT_AB;1990 else if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AC)1991 search_tbl->ant_type = ANT_AC;1992 else1993 search_tbl->ant_type = ANT_BC;1994 1995 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))1996 break;1997 1998 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,1999 search_tbl, index);2000 if (!ret)2001 goto out;2002 2003 break;2004 2005 case IWL_MIMO3_SWITCH_GI:2006 if (!tbl->is_ht40 && !(ht_cap->cap &2007 IEEE80211_HT_CAP_SGI_20))2008 break;2009 if (tbl->is_ht40 && !(ht_cap->cap &2010 IEEE80211_HT_CAP_SGI_40))2011 break;2012 2013 IWL_DEBUG_RATE(priv, "LQ: MIMO3 toggle SGI/NGI\n");2014 2015 /* Set up new search table for MIMO */2016 memcpy(search_tbl, tbl, sz);2017 search_tbl->is_SGI = !tbl->is_SGI;2018 rs_set_expected_tpt_table(lq_sta, search_tbl);2019 /*2020 * If active table already uses the fastest possible2021 * modulation (dual stream with short guard interval),2022 * and it's working well, there's no need to look2023 * for a better type of modulation!2024 */2025 if (tbl->is_SGI) {2026 s32 tpt = lq_sta->last_tpt / 100;2027 if (tpt >= search_tbl->expected_tpt[index])2028 break;2029 }2030 search_tbl->current_rate =2031 rate_n_flags_from_tbl(priv, search_tbl,2032 index, is_green);2033 update_search_tbl_counter = 1;2034 goto out;2035 }2036 tbl->action++;2037 if (tbl->action > IWL_MIMO3_SWITCH_GI)2038 tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;2039 2040 if (tbl->action == start_action)2041 break;2042 }2043 search_tbl->lq_type = LQ_NONE;2044 return;2045 out:2046 lq_sta->search_better_tbl = 1;2047 tbl->action++;2048 if (tbl->action > IWL_MIMO3_SWITCH_GI)2049 tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;2050 if (update_search_tbl_counter)2051 search_tbl->action = tbl->action;2052}2053 2054/*2055 * Check whether we should continue using same modulation mode, or2056 * begin search for a new mode, based on:2057 * 1) # tx successes or failures while using this mode2058 * 2) # times calling this function2059 * 3) elapsed time in this mode (not used, for now)2060 */2061static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)2062{2063 struct iwl_scale_tbl_info *tbl;2064 int i;2065 int active_tbl;2066 int flush_interval_passed = 0;2067 struct iwl_priv *priv;2068 2069 priv = lq_sta->drv;2070 active_tbl = lq_sta->active_tbl;2071 2072 tbl = &(lq_sta->lq_info[active_tbl]);2073 2074 /* If we've been disallowing search, see if we should now allow it */2075 if (lq_sta->stay_in_tbl) {2076 2077 /* Elapsed time using current modulation mode */2078 if (lq_sta->flush_timer)2079 flush_interval_passed =2080 time_after(jiffies,2081 (unsigned long)(lq_sta->flush_timer +2082 IWL_RATE_SCALE_FLUSH_INTVL));2083 2084 /*2085 * Check if we should allow search for new modulation mode.2086 * If many frames have failed or succeeded, or we've used2087 * this same modulation for a long time, allow search, and2088 * reset history stats that keep track of whether we should2089 * allow a new search. Also (below) reset all bitmaps and2090 * stats in active history.2091 */2092 if (force_search ||2093 (lq_sta->total_failed > lq_sta->max_failure_limit) ||2094 (lq_sta->total_success > lq_sta->max_success_limit) ||2095 ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer)2096 && (flush_interval_passed))) {2097 IWL_DEBUG_RATE(priv, "LQ: stay is expired %d %d %d\n",2098 lq_sta->total_failed,2099 lq_sta->total_success,2100 flush_interval_passed);2101 2102 /* Allow search for new mode */2103 lq_sta->stay_in_tbl = 0; /* only place reset */2104 lq_sta->total_failed = 0;2105 lq_sta->total_success = 0;2106 lq_sta->flush_timer = 0;2107 2108 /*2109 * Else if we've used this modulation mode enough repetitions2110 * (regardless of elapsed time or success/failure), reset2111 * history bitmaps and rate-specific stats for all rates in2112 * active table.2113 */2114 } else {2115 lq_sta->table_count++;2116 if (lq_sta->table_count >=2117 lq_sta->table_count_limit) {2118 lq_sta->table_count = 0;2119 2120 IWL_DEBUG_RATE(priv, "LQ: stay in table clear win\n");2121 for (i = 0; i < IWL_RATE_COUNT; i++)2122 rs_rate_scale_clear_window(2123 &(tbl->win[i]));2124 }2125 }2126 2127 /* If transitioning to allow "search", reset all history2128 * bitmaps and stats in active table (this will become the new2129 * "search" table). */2130 if (!lq_sta->stay_in_tbl) {2131 for (i = 0; i < IWL_RATE_COUNT; i++)2132 rs_rate_scale_clear_window(&(tbl->win[i]));2133 }2134 }2135}2136 2137/*2138 * setup rate table in uCode2139 */2140static void rs_update_rate_tbl(struct iwl_priv *priv,2141 struct iwl_rxon_context *ctx,2142 struct iwl_lq_sta *lq_sta,2143 struct iwl_scale_tbl_info *tbl,2144 int index, u8 is_green)2145{2146 u32 rate;2147 2148 /* Update uCode's rate table. */2149 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);2150 rs_fill_link_cmd(priv, lq_sta, rate);2151 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);2152}2153 2154/*2155 * Do rate scaling and search for new modulation mode.2156 */2157static void rs_rate_scale_perform(struct iwl_priv *priv,2158 struct sk_buff *skb,2159 struct ieee80211_sta *sta,2160 struct iwl_lq_sta *lq_sta)2161{2162 struct ieee80211_hw *hw = priv->hw;2163 struct ieee80211_conf *conf = &hw->conf;2164 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);2165 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;2166 int low = IWL_RATE_INVALID;2167 int high = IWL_RATE_INVALID;2168 int index;2169 int i;2170 struct iwl_rate_scale_data *window = NULL;2171 int current_tpt = IWL_INVALID_VALUE;2172 int low_tpt = IWL_INVALID_VALUE;2173 int high_tpt = IWL_INVALID_VALUE;2174 u32 fail_count;2175 s8 scale_action = 0;2176 u16 rate_mask;2177 u8 update_lq = 0;2178 struct iwl_scale_tbl_info *tbl, *tbl1;2179 u16 rate_scale_index_msk = 0;2180 u8 is_green = 0;2181 u8 active_tbl = 0;2182 u8 done_search = 0;2183 u16 high_low;2184 s32 sr;2185 u8 tid = IWL_MAX_TID_COUNT;2186 struct iwl_tid_data *tid_data;2187 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;2188 struct iwl_rxon_context *ctx = sta_priv->ctx;2189 2190 IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n");2191 2192 /* Send management frames and NO_ACK data using lowest rate. */2193 /* TODO: this could probably be improved.. */2194 if (!ieee80211_is_data(hdr->frame_control) ||2195 info->flags & IEEE80211_TX_CTL_NO_ACK)2196 return;2197 2198 lq_sta->supp_rates = sta->deflink.supp_rates[lq_sta->band];2199 2200 tid = rs_tl_add_packet(lq_sta, hdr);2201 if ((tid != IWL_MAX_TID_COUNT) &&2202 (lq_sta->tx_agg_tid_en & (1 << tid))) {2203 tid_data = &priv->tid_data[lq_sta->lq.sta_id][tid];2204 if (tid_data->agg.state == IWL_AGG_OFF)2205 lq_sta->is_agg = 0;2206 else2207 lq_sta->is_agg = 1;2208 } else2209 lq_sta->is_agg = 0;2210 2211 /*2212 * Select rate-scale / modulation-mode table to work with in2213 * the rest of this function: "search" if searching for better2214 * modulation mode, or "active" if doing rate scaling within a mode.2215 */2216 if (!lq_sta->search_better_tbl)2217 active_tbl = lq_sta->active_tbl;2218 else2219 active_tbl = 1 - lq_sta->active_tbl;2220 2221 tbl = &(lq_sta->lq_info[active_tbl]);2222 if (is_legacy(tbl->lq_type))2223 lq_sta->is_green = 0;2224 else2225 lq_sta->is_green = rs_use_green(sta);2226 is_green = lq_sta->is_green;2227 2228 /* current tx rate */2229 index = lq_sta->last_txrate_idx;2230 2231 IWL_DEBUG_RATE(priv, "Rate scale index %d for type %d\n", index,2232 tbl->lq_type);2233 2234 /* rates available for this association, and for modulation mode */2235 rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type);2236 2237 IWL_DEBUG_RATE(priv, "mask 0x%04X\n", rate_mask);2238 2239 /* mask with station rate restriction */2240 if (is_legacy(tbl->lq_type)) {2241 if (lq_sta->band == NL80211_BAND_5GHZ)2242 /* supp_rates has no CCK bits in A mode */2243 rate_scale_index_msk = (u16) (rate_mask &2244 (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));2245 else2246 rate_scale_index_msk = (u16) (rate_mask &2247 lq_sta->supp_rates);2248 2249 } else2250 rate_scale_index_msk = rate_mask;2251 2252 if (!rate_scale_index_msk)2253 rate_scale_index_msk = rate_mask;2254 2255 if (!((1 << index) & rate_scale_index_msk)) {2256 IWL_ERR(priv, "Current Rate is not valid\n");2257 if (lq_sta->search_better_tbl) {2258 /* revert to active table if search table is not valid*/2259 tbl->lq_type = LQ_NONE;2260 lq_sta->search_better_tbl = 0;2261 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);2262 /* get "active" rate info */2263 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);2264 rs_update_rate_tbl(priv, ctx, lq_sta, tbl,2265 index, is_green);2266 }2267 return;2268 }2269 2270 /* Get expected throughput table and history window for current rate */2271 if (!tbl->expected_tpt) {2272 IWL_ERR(priv, "tbl->expected_tpt is NULL\n");2273 return;2274 }2275 2276 /* force user max rate if set by user */2277 if ((lq_sta->max_rate_idx != -1) &&2278 (lq_sta->max_rate_idx < index)) {2279 index = lq_sta->max_rate_idx;2280 update_lq = 1;2281 window = &(tbl->win[index]);2282 goto lq_update;2283 }2284 2285 window = &(tbl->win[index]);2286 2287 /*2288 * If there is not enough history to calculate actual average2289 * throughput, keep analyzing results of more tx frames, without2290 * changing rate or mode (bypass most of the rest of this function).2291 * Set up new rate table in uCode only if old rate is not supported2292 * in current association (use new rate found above).2293 */2294 fail_count = window->counter - window->success_counter;2295 if ((fail_count < IWL_RATE_MIN_FAILURE_TH) &&2296 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) {2297 IWL_DEBUG_RATE(priv, "LQ: still below TH. succ=%d total=%d "2298 "for index %d\n",2299 window->success_counter, window->counter, index);2300 2301 /* Can't calculate this yet; not enough history */2302 window->average_tpt = IWL_INVALID_VALUE;2303 2304 /* Should we stay with this modulation mode,2305 * or search for a new one? */2306 rs_stay_in_table(lq_sta, false);2307 2308 goto out;2309 }2310 /* Else we have enough samples; calculate estimate of2311 * actual average throughput */2312 if (window->average_tpt != ((window->success_ratio *2313 tbl->expected_tpt[index] + 64) / 128)) {2314 IWL_ERR(priv, "expected_tpt should have been calculated by now\n");2315 window->average_tpt = ((window->success_ratio *2316 tbl->expected_tpt[index] + 64) / 128);2317 }2318 2319 /* If we are searching for better modulation mode, check success. */2320 if (lq_sta->search_better_tbl &&2321 (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI)) {2322 /* If good success, continue using the "search" mode;2323 * no need to send new link quality command, since we're2324 * continuing to use the setup that we've been trying. */2325 if (window->average_tpt > lq_sta->last_tpt) {2326 2327 IWL_DEBUG_RATE(priv, "LQ: SWITCHING TO NEW TABLE "2328 "suc=%d cur-tpt=%d old-tpt=%d\n",2329 window->success_ratio,2330 window->average_tpt,2331 lq_sta->last_tpt);2332 2333 if (!is_legacy(tbl->lq_type))2334 lq_sta->enable_counter = 1;2335 2336 /* Swap tables; "search" becomes "active" */2337 lq_sta->active_tbl = active_tbl;2338 current_tpt = window->average_tpt;2339 2340 /* Else poor success; go back to mode in "active" table */2341 } else {2342 2343 IWL_DEBUG_RATE(priv, "LQ: GOING BACK TO THE OLD TABLE "2344 "suc=%d cur-tpt=%d old-tpt=%d\n",2345 window->success_ratio,2346 window->average_tpt,2347 lq_sta->last_tpt);2348 2349 /* Nullify "search" table */2350 tbl->lq_type = LQ_NONE;2351 2352 /* Revert to "active" table */2353 active_tbl = lq_sta->active_tbl;2354 tbl = &(lq_sta->lq_info[active_tbl]);2355 2356 /* Revert to "active" rate and throughput info */2357 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);2358 current_tpt = lq_sta->last_tpt;2359 2360 /* Need to set up a new rate table in uCode */2361 update_lq = 1;2362 }2363 2364 /* Either way, we've made a decision; modulation mode2365 * search is done, allow rate adjustment next time. */2366 lq_sta->search_better_tbl = 0;2367 done_search = 1; /* Don't switch modes below! */2368 goto lq_update;2369 }2370 2371 /* (Else) not in search of better modulation mode, try for better2372 * starting rate, while staying in this mode. */2373 high_low = rs_get_adjacent_rate(priv, index, rate_scale_index_msk,2374 tbl->lq_type);2375 low = high_low & 0xff;2376 high = (high_low >> 8) & 0xff;2377 2378 /* If user set max rate, dont allow higher than user constrain */2379 if ((lq_sta->max_rate_idx != -1) &&2380 (lq_sta->max_rate_idx < high))2381 high = IWL_RATE_INVALID;2382 2383 sr = window->success_ratio;2384 2385 /* Collect measured throughputs for current and adjacent rates */2386 current_tpt = window->average_tpt;2387 if (low != IWL_RATE_INVALID)2388 low_tpt = tbl->win[low].average_tpt;2389 if (high != IWL_RATE_INVALID)2390 high_tpt = tbl->win[high].average_tpt;2391 2392 scale_action = 0;2393 2394 /* Too many failures, decrease rate */2395 if ((sr <= IWL_RATE_DECREASE_TH) || (current_tpt == 0)) {2396 IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n");2397 scale_action = -1;2398 2399 /* No throughput measured yet for adjacent rates; try increase. */2400 } else if ((low_tpt == IWL_INVALID_VALUE) &&2401 (high_tpt == IWL_INVALID_VALUE)) {2402 2403 if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH)2404 scale_action = 1;2405 else if (low != IWL_RATE_INVALID)2406 scale_action = 0;2407 }2408 2409 /* Both adjacent throughputs are measured, but neither one has better2410 * throughput; we're using the best rate, don't change it! */2411 else if ((low_tpt != IWL_INVALID_VALUE) &&2412 (high_tpt != IWL_INVALID_VALUE) &&2413 (low_tpt < current_tpt) &&2414 (high_tpt < current_tpt))2415 scale_action = 0;2416 2417 /* At least one adjacent rate's throughput is measured,2418 * and may have better performance. */2419 else {2420 /* Higher adjacent rate's throughput is measured */2421 if (high_tpt != IWL_INVALID_VALUE) {2422 /* Higher rate has better throughput */2423 if (high_tpt > current_tpt &&2424 sr >= IWL_RATE_INCREASE_TH) {2425 scale_action = 1;2426 } else {2427 scale_action = 0;2428 }2429 2430 /* Lower adjacent rate's throughput is measured */2431 } else if (low_tpt != IWL_INVALID_VALUE) {2432 /* Lower rate has better throughput */2433 if (low_tpt > current_tpt) {2434 IWL_DEBUG_RATE(priv,2435 "decrease rate because of low tpt\n");2436 scale_action = -1;2437 } else if (sr >= IWL_RATE_INCREASE_TH) {2438 scale_action = 1;2439 }2440 }2441 }2442 2443 /* Sanity check; asked for decrease, but success rate or throughput2444 * has been good at old rate. Don't change it. */2445 if ((scale_action == -1) && (low != IWL_RATE_INVALID) &&2446 ((sr > IWL_RATE_HIGH_TH) ||2447 (current_tpt > (100 * tbl->expected_tpt[low]))))2448 scale_action = 0;2449 if (!iwl_ht_enabled(priv) && !is_legacy(tbl->lq_type))2450 scale_action = -1;2451 if (iwl_tx_ant_restriction(priv) != IWL_ANT_OK_MULTI &&2452 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type)))2453 scale_action = -1;2454 2455 if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&2456 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {2457 if (lq_sta->last_bt_traffic > priv->bt_traffic_load) {2458 /*2459 * don't set scale_action, don't want to scale up if2460 * the rate scale doesn't otherwise think that is a2461 * good idea.2462 */2463 } else if (lq_sta->last_bt_traffic <= priv->bt_traffic_load) {2464 scale_action = -1;2465 }2466 }2467 lq_sta->last_bt_traffic = priv->bt_traffic_load;2468 2469 if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&2470 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {2471 /* search for a new modulation */2472 rs_stay_in_table(lq_sta, true);2473 goto lq_update;2474 }2475 2476 switch (scale_action) {2477 case -1:2478 /* Decrease starting rate, update uCode's rate table */2479 if (low != IWL_RATE_INVALID) {2480 update_lq = 1;2481 index = low;2482 }2483 2484 break;2485 case 1:2486 /* Increase starting rate, update uCode's rate table */2487 if (high != IWL_RATE_INVALID) {2488 update_lq = 1;2489 index = high;2490 }2491 2492 break;2493 case 0:2494 /* No change */2495 default:2496 break;2497 }2498 2499 IWL_DEBUG_RATE(priv, "choose rate scale index %d action %d low %d "2500 "high %d type %d\n",2501 index, scale_action, low, high, tbl->lq_type);2502 2503lq_update:2504 /* Replace uCode's rate table for the destination station. */2505 if (update_lq)2506 rs_update_rate_tbl(priv, ctx, lq_sta, tbl, index, is_green);2507 2508 if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) {2509 /* Should we stay with this modulation mode,2510 * or search for a new one? */2511 rs_stay_in_table(lq_sta, false);2512 }2513 /*2514 * Search for new modulation mode if we're:2515 * 1) Not changing rates right now2516 * 2) Not just finishing up a search2517 * 3) Allowing a new search2518 */2519 if (!update_lq && !done_search && !lq_sta->stay_in_tbl && window->counter) {2520 /* Save current throughput to compare with "search" throughput*/2521 lq_sta->last_tpt = current_tpt;2522 2523 /* Select a new "search" modulation mode to try.2524 * If one is found, set up the new "search" table. */2525 if (is_legacy(tbl->lq_type))2526 rs_move_legacy_other(priv, lq_sta, conf, sta, index);2527 else if (is_siso(tbl->lq_type))2528 rs_move_siso_to_other(priv, lq_sta, conf, sta, index);2529 else if (is_mimo2(tbl->lq_type))2530 rs_move_mimo2_to_other(priv, lq_sta, conf, sta, index);2531 else2532 rs_move_mimo3_to_other(priv, lq_sta, conf, sta, index);2533 2534 /* If new "search" mode was selected, set up in uCode table */2535 if (lq_sta->search_better_tbl) {2536 /* Access the "search" table, clear its history. */2537 tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);2538 for (i = 0; i < IWL_RATE_COUNT; i++)2539 rs_rate_scale_clear_window(&(tbl->win[i]));2540 2541 /* Use new "search" start rate */2542 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);2543 2544 IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n",2545 tbl->current_rate, index);2546 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);2547 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);2548 } else2549 done_search = 1;2550 }2551 2552 if (done_search && !lq_sta->stay_in_tbl) {2553 /* If the "active" (non-search) mode was legacy,2554 * and we've tried switching antennas,2555 * but we haven't been able to try HT modes (not available),2556 * stay with best antenna legacy modulation for a while2557 * before next round of mode comparisons. */2558 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);2559 if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) &&2560 lq_sta->action_counter > tbl1->max_search) {2561 IWL_DEBUG_RATE(priv, "LQ: STAY in legacy table\n");2562 rs_set_stay_in_table(priv, 1, lq_sta);2563 }2564 2565 /* If we're in an HT mode, and all 3 mode switch actions2566 * have been tried and compared, stay in this best modulation2567 * mode for a while before next round of mode comparisons. */2568 if (lq_sta->enable_counter &&2569 (lq_sta->action_counter >= tbl1->max_search) &&2570 iwl_ht_enabled(priv)) {2571 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&2572 (lq_sta->tx_agg_tid_en & (1 << tid)) &&2573 (tid != IWL_MAX_TID_COUNT)) {2574 u8 sta_id = lq_sta->lq.sta_id;2575 tid_data = &priv->tid_data[sta_id][tid];2576 if (tid_data->agg.state == IWL_AGG_OFF) {2577 IWL_DEBUG_RATE(priv,2578 "try to aggregate tid %d\n",2579 tid);2580 rs_tl_turn_on_agg(priv, tid,2581 lq_sta, sta);2582 }2583 }2584 rs_set_stay_in_table(priv, 0, lq_sta);2585 }2586 }2587 2588out:2589 tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);2590 lq_sta->last_txrate_idx = index;2591}2592 2593/*2594 * rs_initialize_lq - Initialize a station's hardware rate table2595 *2596 * The uCode's station table contains a table of fallback rates2597 * for automatic fallback during transmission.2598 *2599 * NOTE: This sets up a default set of values. These will be replaced later2600 * if the driver's iwl-agn-rs rate scaling algorithm is used, instead of2601 * rc80211_simple.2602 *2603 * NOTE: Run REPLY_ADD_STA command to set up station table entry, before2604 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,2605 * which requires station table entry to exist).2606 */2607static void rs_initialize_lq(struct iwl_priv *priv,2608 struct ieee80211_sta *sta,2609 struct iwl_lq_sta *lq_sta)2610{2611 struct iwl_scale_tbl_info *tbl;2612 int rate_idx;2613 int i;2614 u32 rate;2615 u8 use_green = rs_use_green(sta);2616 u8 active_tbl = 0;2617 u8 valid_tx_ant;2618 struct iwl_station_priv *sta_priv;2619 struct iwl_rxon_context *ctx;2620 2621 if (!sta || !lq_sta)2622 return;2623 2624 sta_priv = (void *)sta->drv_priv;2625 ctx = sta_priv->ctx;2626 2627 i = lq_sta->last_txrate_idx;2628 2629 valid_tx_ant = priv->nvm_data->valid_tx_ant;2630 2631 if (!lq_sta->search_better_tbl)2632 active_tbl = lq_sta->active_tbl;2633 else2634 active_tbl = 1 - lq_sta->active_tbl;2635 2636 tbl = &(lq_sta->lq_info[active_tbl]);2637 2638 if ((i < 0) || (i >= IWL_RATE_COUNT))2639 i = 0;2640 2641 rate = iwl_rates[i].plcp;2642 tbl->ant_type = first_antenna(valid_tx_ant);2643 rate |= tbl->ant_type << RATE_MCS_ANT_POS;2644 2645 if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE)2646 rate |= RATE_MCS_CCK_MSK;2647 2648 rs_get_tbl_info_from_mcs(rate, priv->band, tbl, &rate_idx);2649 if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type))2650 rs_toggle_antenna(valid_tx_ant, &rate, tbl);2651 2652 rate = rate_n_flags_from_tbl(priv, tbl, rate_idx, use_green);2653 tbl->current_rate = rate;2654 rs_set_expected_tpt_table(lq_sta, tbl);2655 rs_fill_link_cmd(NULL, lq_sta, rate);2656 priv->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq;2657 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, 0, true);2658}2659 2660static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,2661 struct ieee80211_tx_rate_control *txrc)2662{2663 2664 struct sk_buff *skb = txrc->skb;2665 struct ieee80211_supported_band *sband = txrc->sband;2666 struct iwl_op_mode *op_mode __maybe_unused =2667 (struct iwl_op_mode *)priv_r;2668 struct iwl_priv *priv __maybe_unused = IWL_OP_MODE_GET_DVM(op_mode);2669 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);2670 struct iwl_lq_sta *lq_sta = priv_sta;2671 int rate_idx;2672 2673 IWL_DEBUG_RATE_LIMIT(priv, "rate scale calculate new rate for skb\n");2674 2675 /* Get max rate if user set max rate */2676 lq_sta->max_rate_idx = fls(txrc->rate_idx_mask) - 1;2677 if (sband->band == NL80211_BAND_5GHZ && lq_sta->max_rate_idx != -1)2678 lq_sta->max_rate_idx += IWL_FIRST_OFDM_RATE;2679 if (lq_sta->max_rate_idx < 0 || lq_sta->max_rate_idx >= IWL_RATE_COUNT)2680 lq_sta->max_rate_idx = -1;2681 2682 if (!lq_sta->drv) {2683 IWL_DEBUG_RATE(priv, "Rate scaling not initialized yet.\n");2684 /* mac80211 already set up the data for using low rates */2685 return;2686 }2687 2688 rate_idx = lq_sta->last_txrate_idx;2689 2690 if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) {2691 rate_idx -= IWL_FIRST_OFDM_RATE;2692 /* 6M and 9M shared same MCS index */2693 rate_idx = (rate_idx > 0) ? (rate_idx - 1) : 0;2694 if (rs_extract_rate(lq_sta->last_rate_n_flags) >=2695 IWL_RATE_MIMO3_6M_PLCP)2696 rate_idx = rate_idx + (2 * MCS_INDEX_PER_STREAM);2697 else if (rs_extract_rate(lq_sta->last_rate_n_flags) >=2698 IWL_RATE_MIMO2_6M_PLCP)2699 rate_idx = rate_idx + MCS_INDEX_PER_STREAM;2700 info->control.rates[0].flags = IEEE80211_TX_RC_MCS;2701 if (lq_sta->last_rate_n_flags & RATE_MCS_SGI_MSK)2702 info->control.rates[0].flags |= IEEE80211_TX_RC_SHORT_GI;2703 if (lq_sta->last_rate_n_flags & RATE_MCS_DUP_MSK)2704 info->control.rates[0].flags |= IEEE80211_TX_RC_DUP_DATA;2705 if (lq_sta->last_rate_n_flags & RATE_MCS_HT40_MSK)2706 info->control.rates[0].flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;2707 if (lq_sta->last_rate_n_flags & RATE_MCS_GF_MSK)2708 info->control.rates[0].flags |= IEEE80211_TX_RC_GREEN_FIELD;2709 } else {2710 /* Check for invalid rates */2711 if ((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT_LEGACY) ||2712 ((sband->band == NL80211_BAND_5GHZ) &&2713 (rate_idx < IWL_FIRST_OFDM_RATE)))2714 rate_idx = rate_lowest_index(sband, sta);2715 /* On valid 5 GHz rate, adjust index */2716 else if (sband->band == NL80211_BAND_5GHZ)2717 rate_idx -= IWL_FIRST_OFDM_RATE;2718 info->control.rates[0].flags = 0;2719 }2720 info->control.rates[0].idx = rate_idx;2721 info->control.rates[0].count = 1;2722}2723 2724static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,2725 gfp_t gfp)2726{2727 struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv;2728 struct iwl_op_mode *op_mode __maybe_unused =2729 (struct iwl_op_mode *)priv_rate;2730 struct iwl_priv *priv __maybe_unused = IWL_OP_MODE_GET_DVM(op_mode);2731 2732 IWL_DEBUG_RATE(priv, "create station rate scale window\n");2733 2734 return &sta_priv->lq_sta;2735}2736 2737/*2738 * Called after adding a new station to initialize rate scaling2739 */2740void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_id)2741{2742 int i, j;2743 struct ieee80211_hw *hw = priv->hw;2744 struct ieee80211_conf *conf = &priv->hw->conf;2745 struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;2746 struct iwl_station_priv *sta_priv;2747 struct iwl_lq_sta *lq_sta;2748 struct ieee80211_supported_band *sband;2749 unsigned long supp; /* must be unsigned long for for_each_set_bit */2750 2751 sta_priv = (struct iwl_station_priv *) sta->drv_priv;2752 lq_sta = &sta_priv->lq_sta;2753 sband = hw->wiphy->bands[conf->chandef.chan->band];2754 2755 lq_sta->lq.sta_id = sta_id;2756 2757 for (j = 0; j < LQ_SIZE; j++)2758 for (i = 0; i < IWL_RATE_COUNT; i++)2759 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);2760 2761 lq_sta->flush_timer = 0;2762 lq_sta->supp_rates = sta->deflink.supp_rates[sband->band];2763 2764 IWL_DEBUG_RATE(priv, "LQ: *** rate scale station global init for station %d ***\n",2765 sta_id);2766 /* TODO: what is a good starting rate for STA? About middle? Maybe not2767 * the lowest or the highest rate.. Could consider using RSSI from2768 * previous packets? Need to have IEEE 802.1X auth succeed immediately2769 * after assoc.. */2770 2771 lq_sta->is_dup = 0;2772 lq_sta->max_rate_idx = -1;2773 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;2774 lq_sta->is_green = rs_use_green(sta);2775 lq_sta->band = sband->band;2776 /*2777 * active legacy rates as per supported rates bitmap2778 */2779 supp = sta->deflink.supp_rates[sband->band];2780 lq_sta->active_legacy_rate = 0;2781 for_each_set_bit(i, &supp, BITS_PER_LONG)2782 lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value);2783 2784 /*2785 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),2786 * supp_rates[] does not; shift to convert format, force 9 MBits off.2787 */2788 lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1;2789 lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1;2790 lq_sta->active_siso_rate &= ~((u16)0x2);2791 lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;2792 2793 /* Same here */2794 lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1;2795 lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1;2796 lq_sta->active_mimo2_rate &= ~((u16)0x2);2797 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;2798 2799 lq_sta->active_mimo3_rate = ht_cap->mcs.rx_mask[2] << 1;2800 lq_sta->active_mimo3_rate |= ht_cap->mcs.rx_mask[2] & 0x1;2801 lq_sta->active_mimo3_rate &= ~((u16)0x2);2802 lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;2803 2804 IWL_DEBUG_RATE(priv, "SISO-RATE=%X MIMO2-RATE=%X MIMO3-RATE=%X\n",2805 lq_sta->active_siso_rate,2806 lq_sta->active_mimo2_rate,2807 lq_sta->active_mimo3_rate);2808 2809 /* These values will be overridden later */2810 lq_sta->lq.general_params.single_stream_ant_msk =2811 first_antenna(priv->nvm_data->valid_tx_ant);2812 lq_sta->lq.general_params.dual_stream_ant_msk =2813 priv->nvm_data->valid_tx_ant &2814 ~first_antenna(priv->nvm_data->valid_tx_ant);2815 if (!lq_sta->lq.general_params.dual_stream_ant_msk) {2816 lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB;2817 } else if (num_of_ant(priv->nvm_data->valid_tx_ant) == 2) {2818 lq_sta->lq.general_params.dual_stream_ant_msk =2819 priv->nvm_data->valid_tx_ant;2820 }2821 2822 /* as default allow aggregation for all tids */2823 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;2824 lq_sta->drv = priv;2825 2826 /* Set last_txrate_idx to lowest rate */2827 lq_sta->last_txrate_idx = rate_lowest_index(sband, sta);2828 if (sband->band == NL80211_BAND_5GHZ)2829 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;2830 lq_sta->is_agg = 0;2831#ifdef CONFIG_MAC80211_DEBUGFS2832 lq_sta->dbg_fixed_rate = 0;2833#endif2834 2835 rs_initialize_lq(priv, sta, lq_sta);2836}2837 2838static void rs_fill_link_cmd(struct iwl_priv *priv,2839 struct iwl_lq_sta *lq_sta, u32 new_rate)2840{2841 struct iwl_scale_tbl_info tbl_type;2842 int index = 0;2843 int rate_idx;2844 int repeat_rate = 0;2845 u8 ant_toggle_cnt = 0;2846 u8 use_ht_possible = 1;2847 u8 valid_tx_ant = 0;2848 struct iwl_station_priv *sta_priv =2849 container_of(lq_sta, struct iwl_station_priv, lq_sta);2850 struct iwl_link_quality_cmd *lq_cmd = &lq_sta->lq;2851 2852 /* Override starting rate (index 0) if needed for debug purposes */2853 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);2854 2855 /* Interpret new_rate (rate_n_flags) */2856 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,2857 &tbl_type, &rate_idx);2858 2859 if (priv && priv->bt_full_concurrent) {2860 /* 1x1 only */2861 tbl_type.ant_type =2862 first_antenna(priv->nvm_data->valid_tx_ant);2863 }2864 2865 /* How many times should we repeat the initial rate? */2866 if (is_legacy(tbl_type.lq_type)) {2867 ant_toggle_cnt = 1;2868 repeat_rate = IWL_NUMBER_TRY;2869 } else {2870 repeat_rate = min(IWL_HT_NUMBER_TRY,2871 LINK_QUAL_AGG_DISABLE_START_DEF - 1);2872 }2873 2874 lq_cmd->general_params.mimo_delimiter =2875 is_mimo(tbl_type.lq_type) ? 1 : 0;2876 2877 /* Fill 1st table entry (index 0) */2878 lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate);2879 2880 if (num_of_ant(tbl_type.ant_type) == 1) {2881 lq_cmd->general_params.single_stream_ant_msk =2882 tbl_type.ant_type;2883 } else if (num_of_ant(tbl_type.ant_type) == 2) {2884 lq_cmd->general_params.dual_stream_ant_msk =2885 tbl_type.ant_type;2886 } /* otherwise we don't modify the existing value */2887 2888 index++;2889 repeat_rate--;2890 if (priv) {2891 if (priv->bt_full_concurrent)2892 valid_tx_ant = ANT_A;2893 else2894 valid_tx_ant = priv->nvm_data->valid_tx_ant;2895 }2896 2897 /* Fill rest of rate table */2898 while (index < LINK_QUAL_MAX_RETRY_NUM) {2899 /* Repeat initial/next rate.2900 * For legacy IWL_NUMBER_TRY == 1, this loop will not execute.2901 * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */2902 while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) {2903 if (is_legacy(tbl_type.lq_type)) {2904 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)2905 ant_toggle_cnt++;2906 else if (priv &&2907 rs_toggle_antenna(valid_tx_ant,2908 &new_rate, &tbl_type))2909 ant_toggle_cnt = 1;2910 }2911 2912 /* Override next rate if needed for debug purposes */2913 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);2914 2915 /* Fill next table entry */2916 lq_cmd->rs_table[index].rate_n_flags =2917 cpu_to_le32(new_rate);2918 repeat_rate--;2919 index++;2920 }2921 2922 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type,2923 &rate_idx);2924 2925 if (priv && priv->bt_full_concurrent) {2926 /* 1x1 only */2927 tbl_type.ant_type =2928 first_antenna(priv->nvm_data->valid_tx_ant);2929 }2930 2931 /* Indicate to uCode which entries might be MIMO.2932 * If initial rate was MIMO, this will finally end up2933 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */2934 if (is_mimo(tbl_type.lq_type))2935 lq_cmd->general_params.mimo_delimiter = index;2936 2937 /* Get next rate */2938 new_rate = rs_get_lower_rate(lq_sta, &tbl_type, rate_idx,2939 use_ht_possible);2940 2941 /* How many times should we repeat the next rate? */2942 if (is_legacy(tbl_type.lq_type)) {2943 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)2944 ant_toggle_cnt++;2945 else if (priv &&2946 rs_toggle_antenna(valid_tx_ant,2947 &new_rate, &tbl_type))2948 ant_toggle_cnt = 1;2949 2950 repeat_rate = IWL_NUMBER_TRY;2951 } else {2952 repeat_rate = IWL_HT_NUMBER_TRY;2953 }2954 2955 /* Don't allow HT rates after next pass.2956 * rs_get_lower_rate() will change type to LQ_A or LQ_G. */2957 use_ht_possible = 0;2958 2959 /* Override next rate if needed for debug purposes */2960 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);2961 2962 /* Fill next table entry */2963 lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate);2964 2965 index++;2966 repeat_rate--;2967 }2968 2969 lq_cmd->agg_params.agg_frame_cnt_limit =2970 sta_priv->max_agg_bufsize ?: LINK_QUAL_AGG_FRAME_LIMIT_DEF;2971 lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;2972 2973 lq_cmd->agg_params.agg_time_limit =2974 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);2975 /*2976 * overwrite if needed, pass aggregation time limit2977 * to uCode in uSec2978 */2979 if (priv && priv->lib->bt_params &&2980 priv->lib->bt_params->agg_time_limit &&2981 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)2982 lq_cmd->agg_params.agg_time_limit =2983 cpu_to_le16(priv->lib->bt_params->agg_time_limit);2984}2985 2986static void *rs_alloc(struct ieee80211_hw *hw)2987{2988 return hw->priv;2989}2990/* rate scale requires free function to be implemented */2991static void rs_free(void *priv_rate)2992{2993 return;2994}2995 2996static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,2997 void *priv_sta)2998{2999 struct iwl_op_mode *op_mode __maybe_unused = priv_r;3000 struct iwl_priv *priv __maybe_unused = IWL_OP_MODE_GET_DVM(op_mode);3001 3002 IWL_DEBUG_RATE(priv, "enter\n");3003 IWL_DEBUG_RATE(priv, "leave\n");3004}3005 3006#ifdef CONFIG_MAC80211_DEBUGFS3007static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,3008 u32 *rate_n_flags, int index)3009{3010 struct iwl_priv *priv;3011 u8 valid_tx_ant;3012 u8 ant_sel_tx;3013 3014 priv = lq_sta->drv;3015 valid_tx_ant = priv->nvm_data->valid_tx_ant;3016 if (lq_sta->dbg_fixed_rate) {3017 ant_sel_tx =3018 ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK)3019 >> RATE_MCS_ANT_POS);3020 if ((valid_tx_ant & ant_sel_tx) == ant_sel_tx) {3021 *rate_n_flags = lq_sta->dbg_fixed_rate;3022 IWL_DEBUG_RATE(priv, "Fixed rate ON\n");3023 } else {3024 lq_sta->dbg_fixed_rate = 0;3025 IWL_ERR(priv,3026 "Invalid antenna selection 0x%X, Valid is 0x%X\n",3027 ant_sel_tx, valid_tx_ant);3028 IWL_DEBUG_RATE(priv, "Fixed rate OFF\n");3029 }3030 } else {3031 IWL_DEBUG_RATE(priv, "Fixed rate OFF\n");3032 }3033}3034 3035static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,3036 const char __user *user_buf, size_t count, loff_t *ppos)3037{3038 struct iwl_lq_sta *lq_sta = file->private_data;3039 struct iwl_priv *priv;3040 char buf[64];3041 size_t buf_size;3042 u32 parsed_rate;3043 3044 3045 priv = lq_sta->drv;3046 memset(buf, 0, sizeof(buf));3047 buf_size = min(count, sizeof(buf) - 1);3048 if (copy_from_user(buf, user_buf, buf_size))3049 return -EFAULT;3050 3051 if (sscanf(buf, "%x", &parsed_rate) == 1)3052 lq_sta->dbg_fixed_rate = parsed_rate;3053 else3054 lq_sta->dbg_fixed_rate = 0;3055 3056 rs_program_fix_rate(priv, lq_sta);3057 3058 return count;3059}3060 3061static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,3062 char __user *user_buf, size_t count, loff_t *ppos)3063{3064 char *buff;3065 int desc = 0;3066 int i = 0;3067 int index = 0;3068 ssize_t ret;3069 3070 /* mbps, mcs */3071 static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {3072 { "1", "BPSK DSSS"},3073 { "2", "QPSK DSSS"},3074 {"5.5", "BPSK CCK"},3075 { "11", "QPSK CCK"},3076 { "6", "BPSK 1/2"},3077 { "9", "BPSK 1/2"},3078 { "12", "QPSK 1/2"},3079 { "18", "QPSK 3/4"},3080 { "24", "16QAM 1/2"},3081 { "36", "16QAM 3/4"},3082 { "48", "64QAM 2/3"},3083 { "54", "64QAM 3/4"},3084 { "60", "64QAM 5/6"},3085 };3086 3087 struct iwl_lq_sta *lq_sta = file->private_data;3088 struct iwl_priv *priv;3089 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);3090 3091 priv = lq_sta->drv;3092 buff = kmalloc(1024, GFP_KERNEL);3093 if (!buff)3094 return -ENOMEM;3095 3096 desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);3097 desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",3098 lq_sta->total_failed, lq_sta->total_success,3099 lq_sta->active_legacy_rate);3100 desc += sprintf(buff+desc, "fixed rate 0x%X\n",3101 lq_sta->dbg_fixed_rate);3102 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",3103 (priv->nvm_data->valid_tx_ant & ANT_A) ? "ANT_A," : "",3104 (priv->nvm_data->valid_tx_ant & ANT_B) ? "ANT_B," : "",3105 (priv->nvm_data->valid_tx_ant & ANT_C) ? "ANT_C" : "");3106 desc += sprintf(buff+desc, "lq type %s\n",3107 (is_legacy(tbl->lq_type)) ? "legacy" : "HT");3108 if (is_Ht(tbl->lq_type)) {3109 desc += sprintf(buff + desc, " %s",3110 (is_siso(tbl->lq_type)) ? "SISO" :3111 ((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3"));3112 desc += sprintf(buff + desc, " %s",3113 (tbl->is_ht40) ? "40MHz" : "20MHz");3114 desc += sprintf(buff + desc, " %s %s %s\n",3115 (tbl->is_SGI) ? "SGI" : "",3116 (lq_sta->is_green) ? "GF enabled" : "",3117 (lq_sta->is_agg) ? "AGG on" : "");3118 }3119 desc += sprintf(buff+desc, "last tx rate=0x%X\n",3120 lq_sta->last_rate_n_flags);3121 desc += sprintf(buff+desc, "general:"3122 "flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",3123 lq_sta->lq.general_params.flags,3124 lq_sta->lq.general_params.mimo_delimiter,3125 lq_sta->lq.general_params.single_stream_ant_msk,3126 lq_sta->lq.general_params.dual_stream_ant_msk);3127 3128 desc += sprintf(buff+desc, "agg:"3129 "time_limit=%d dist_start_th=%d frame_cnt_limit=%d\n",3130 le16_to_cpu(lq_sta->lq.agg_params.agg_time_limit),3131 lq_sta->lq.agg_params.agg_dis_start_th,3132 lq_sta->lq.agg_params.agg_frame_cnt_limit);3133 3134 desc += sprintf(buff+desc,3135 "Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n",3136 lq_sta->lq.general_params.start_rate_index[0],3137 lq_sta->lq.general_params.start_rate_index[1],3138 lq_sta->lq.general_params.start_rate_index[2],3139 lq_sta->lq.general_params.start_rate_index[3]);3140 3141 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {3142 index = iwl_hwrate_to_plcp_idx(3143 le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));3144 if (index == IWL_RATE_INVALID) {3145 desc += sprintf(buff + desc, " rate[%d] 0x%X invalid rate\n",3146 i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));3147 } else if (is_legacy(tbl->lq_type)) {3148 desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps\n",3149 i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags),3150 iwl_rate_mcs[index].mbps);3151 } else {3152 desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps (%s)\n",3153 i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags),3154 iwl_rate_mcs[index].mbps, iwl_rate_mcs[index].mcs);3155 }3156 }3157 3158 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);3159 kfree(buff);3160 return ret;3161}3162 3163static const struct file_operations rs_sta_dbgfs_scale_table_ops = {3164 .write = rs_sta_dbgfs_scale_table_write,3165 .read = rs_sta_dbgfs_scale_table_read,3166 .open = simple_open,3167 .llseek = default_llseek,3168};3169static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,3170 char __user *user_buf, size_t count, loff_t *ppos)3171{3172 char *buff;3173 int desc = 0;3174 int i, j;3175 ssize_t ret;3176 3177 struct iwl_lq_sta *lq_sta = file->private_data;3178 3179 buff = kmalloc(1024, GFP_KERNEL);3180 if (!buff)3181 return -ENOMEM;3182 3183 for (i = 0; i < LQ_SIZE; i++) {3184 desc += sprintf(buff+desc,3185 "%s type=%d SGI=%d HT40=%d DUP=%d GF=%d\n"3186 "rate=0x%X\n",3187 lq_sta->active_tbl == i ? "*" : "x",3188 lq_sta->lq_info[i].lq_type,3189 lq_sta->lq_info[i].is_SGI,3190 lq_sta->lq_info[i].is_ht40,3191 lq_sta->lq_info[i].is_dup,3192 lq_sta->is_green,3193 lq_sta->lq_info[i].current_rate);3194 for (j = 0; j < IWL_RATE_COUNT; j++) {3195 desc += sprintf(buff+desc,3196 "counter=%d success=%d %%=%d\n",3197 lq_sta->lq_info[i].win[j].counter,3198 lq_sta->lq_info[i].win[j].success_counter,3199 lq_sta->lq_info[i].win[j].success_ratio);3200 }3201 }3202 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);3203 kfree(buff);3204 return ret;3205}3206 3207static const struct file_operations rs_sta_dbgfs_stats_table_ops = {3208 .read = rs_sta_dbgfs_stats_table_read,3209 .open = simple_open,3210 .llseek = default_llseek,3211};3212 3213static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,3214 char __user *user_buf, size_t count, loff_t *ppos)3215{3216 struct iwl_lq_sta *lq_sta = file->private_data;3217 struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl];3218 char buff[120];3219 int desc = 0;3220 3221 if (is_Ht(tbl->lq_type))3222 desc += sprintf(buff+desc,3223 "Bit Rate= %d Mb/s\n",3224 tbl->expected_tpt[lq_sta->last_txrate_idx]);3225 else3226 desc += sprintf(buff+desc,3227 "Bit Rate= %d Mb/s\n",3228 iwl_rates[lq_sta->last_txrate_idx].ieee >> 1);3229 3230 return simple_read_from_buffer(user_buf, count, ppos, buff, desc);3231}3232 3233static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {3234 .read = rs_sta_dbgfs_rate_scale_data_read,3235 .open = simple_open,3236 .llseek = default_llseek,3237};3238 3239static void rs_add_debugfs(void *priv, void *priv_sta,3240 struct dentry *dir)3241{3242 struct iwl_lq_sta *lq_sta = priv_sta;3243 3244 debugfs_create_file("rate_scale_table", 0600, dir, lq_sta,3245 &rs_sta_dbgfs_scale_table_ops);3246 debugfs_create_file("rate_stats_table", 0400, dir, lq_sta,3247 &rs_sta_dbgfs_stats_table_ops);3248 debugfs_create_file("rate_scale_data", 0400, dir, lq_sta,3249 &rs_sta_dbgfs_rate_scale_data_ops);3250 debugfs_create_u8("tx_agg_tid_enable", 0600, dir,3251 &lq_sta->tx_agg_tid_en);3252 3253}3254#endif3255 3256/*3257 * Initialization of rate scaling information is done by driver after3258 * the station is added. Since mac80211 calls this function before a3259 * station is added we ignore it.3260 */3261static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sband,3262 struct cfg80211_chan_def *chandef,3263 struct ieee80211_sta *sta, void *priv_sta)3264{3265}3266 3267static const struct rate_control_ops rs_ops = {3268 .name = RS_NAME,3269 .tx_status = rs_tx_status,3270 .get_rate = rs_get_rate,3271 .rate_init = rs_rate_init_stub,3272 .alloc = rs_alloc,3273 .free = rs_free,3274 .alloc_sta = rs_alloc_sta,3275 .free_sta = rs_free_sta,3276#ifdef CONFIG_MAC80211_DEBUGFS3277 .add_sta_debugfs = rs_add_debugfs,3278#endif3279};3280 3281int iwlagn_rate_control_register(void)3282{3283 return ieee80211_rate_control_register(&rs_ops);3284}3285 3286void iwlagn_rate_control_unregister(void)3287{3288 ieee80211_rate_control_unregister(&rs_ops);3289}3290 3291