00001
00017
00018
00019
00020
00021 #include "me.h"
00022 #include "mm.h"
00023 #include "me_utils.h"
00024
00025 #include "txl_cfm.h"
00026 #include "rc.h"
00027 #include "vif_mgmt.h"
00028 #if RW_BFMER_EN
00029 #include "bfr.h"
00030 #endif
00031
00032 extern struct me_env_tag me_env;
00033
00034
00035
00036
00037
00038
00040 struct rc_sta_stats sta_stats[NX_REMOTE_STA_MAX];
00041
00046 static const uint32_t rc_duration_ht_ampdu[10*4*2] =
00047 {
00048
00049 [ 0] = 1476923, [ 1] = 1329231, [ 2] = 711111, [ 3] = 640000,
00050 [ 8] = 738462, [ 9] = 664615, [ 10] = 355556, [ 11] = 320000,
00051 [ 16] = 492308, [ 17] = 443077, [ 18] = 237037, [ 19] = 213333,
00052 [ 24] = 369231, [ 25] = 332308, [ 26] = 177778, [ 27] = 160000,
00053 [ 32] = 246154, [ 33] = 221538, [ 34] = 118519, [ 35] = 106667,
00054 [ 40] = 184615, [ 41] = 166154, [ 42] = 88889, [ 43] = 80000,
00055 [ 48] = 164103, [ 49] = 147692, [ 50] = 79012, [ 51] = 71111,
00056 [ 56] = 147692, [ 57] = 132923, [ 58] = 71111, [ 59] = 64000,
00057 [ 64] = 123077, [ 65] = 110769, [ 66] = 59259, [ 67] = 53333,
00058 [ 72] = 110769, [ 73] = 99692, [ 74] = 53333, [ 75] = 48000,
00059
00060 [ 4] = 328205, [ 5] = 295385, [ 6] = 164103, [ 7] = 147692,
00061 [ 12] = 164103, [ 13] = 147692, [ 14] = 82051, [ 15] = 73846,
00062 [ 20] = 109402, [ 21] = 98462, [ 22] = 54701, [ 23] = 49231,
00063 [ 28] = 82051, [ 29] = 73846, [ 30] = 41026, [ 31] = 36923,
00064 [ 36] = 54701, [ 37] = 49231, [ 38] = 27350, [ 39] = 24615,
00065 [ 44] = 41026, [ 45] = 36923, [ 46] = 20513, [ 47] = 18462,
00066 [ 52] = 36467, [ 53] = 32821, [ 54] = 18234, [ 55] = 16410,
00067 [ 60] = 32821, [ 61] = 29538, [ 62] = 16410, [ 63] = 14769,
00068 [ 68] = 27350, [ 69] = 24615, [ 70] = 13675, [ 71] = 12308,
00069 [ 76] = 24615, [ 77] = 22154, [ 78] = 12308, [ 79] = 11077,
00070 };
00071
00072 #if NX_HE
00076 static const uint32_t rc_duration_he_ampdu[12*2*3] =
00077 {
00078
00079 [ 0] = 1115897, [ 1] = 1181538, [ 2] = 1312821,
00080 [ 6] = 557949, [ 7] = 590769, [ 8] = 656410,
00081 [ 12] = 371966, [ 13] = 393846, [ 14] = 437607,
00082 [ 18] = 278974, [ 19] = 295385, [ 20] = 328205,
00083 [ 24] = 185983, [ 25] = 196923, [ 26] = 218803,
00084 [ 30] = 139487, [ 31] = 147692, [ 32] = 164103,
00085 [ 36] = 123989, [ 37] = 131282, [ 38] = 145869,
00086 [ 42] = 111590, [ 43] = 118154, [ 44] = 131282,
00087 [ 48] = 92991, [ 49] = 98462, [ 50] = 109402,
00088 [ 54] = 83692, [ 55] = 88615, [ 56] = 98462,
00089 [ 60] = 74393, [ 61] = 78769, [ 62] = 87521,
00090 [ 66] = 66954, [ 67] = 70892, [ 68] = 78769,
00091
00092 [ 3] = 266449, [ 4] = 282122, [ 5] = 313469,
00093 [ 9] = 133224, [ 10] = 141061, [ 11] = 156735,
00094 [ 15] = 88816, [ 16] = 94041, [ 17] = 104490,
00095 [ 21] = 66612, [ 22] = 70531, [ 23] = 78367,
00096 [ 27] = 44408, [ 28] = 47020, [ 29] = 52245,
00097 [ 33] = 33306, [ 34] = 35265, [ 35] = 39184,
00098 [ 39] = 29605, [ 40] = 31347, [ 41] = 34830,
00099 [ 45] = 26645, [ 46] = 28212, [ 47] = 31347,
00100 [ 51] = 22204, [ 52] = 23510, [ 53] = 26122,
00101 [ 57] = 19985, [ 58] = 21160, [ 59] = 23511,
00102 [ 63] = 17763, [ 64] = 18808, [ 65] = 20898,
00103 [ 69] = 15988, [ 70] = 16929, [ 71] = 18810,
00104 };
00105
00109 static const uint32_t rc_duration_he_ru26[12*3] =
00110 {
00111
00112 [ 0] = 10880000, [ 1] = 11520000, [ 2] = 12800000,
00113 [ 3] = 5440000, [ 4] = 5760000, [ 5] = 6400000,
00114 [ 6] = 3626666, [ 7] = 3840000, [ 8] = 4266666,
00115 [ 9] = 2720000, [ 10] = 2880000, [ 11] = 3200000,
00116 [ 12] = 1813333, [ 13] = 1920000, [ 14] = 2133333,
00117 [ 15] = 1360000, [ 16] = 1440000, [ 17] = 1600000,
00118 [ 18] = 1208888, [ 19] = 1280000, [ 20] = 1422222,
00119 [ 21] = 1088000, [ 22] = 1152000, [ 23] = 1280000,
00120 [ 24] = 906666, [ 25] = 960000, [ 26] = 1066666,
00121 [ 27] = 816000, [ 28] = 864000, [ 29] = 960000,
00122 [ 30] = 725333, [ 31] = 768000, [ 32] = 853333,
00123 [ 33] = 652800, [ 34] = 691200, [ 35] = 768000,
00124 };
00125
00129 static const uint32_t rc_duration_he_ru52[12*3] =
00130 {
00131
00132 [ 0] = 5440000, [ 1] = 5760000, [ 2] = 6400000,
00133 [ 3] = 2720000, [ 4] = 2880000, [ 5] = 3200000,
00134 [ 6] = 1813333, [ 7] = 1920000, [ 8] = 2133333,
00135 [ 9] = 1360000, [ 10] = 1440000, [ 11] = 1600000,
00136 [ 12] = 906666, [ 13] = 960000, [ 14] = 1066666,
00137 [ 15] = 680000, [ 16] = 720000, [ 17] = 800000,
00138 [ 18] = 604444, [ 19] = 640000, [ 20] = 711111,
00139 [ 21] = 544000, [ 22] = 576000, [ 23] = 640000,
00140 [ 24] = 453333, [ 25] = 480000, [ 26] = 533333,
00141 [ 27] = 408000, [ 28] = 432000, [ 29] = 480000,
00142 [ 30] = 362666, [ 31] = 384000, [ 32] = 426666,
00143 [ 33] = 326400, [ 34] = 345600, [ 35] = 384000,
00144 };
00145
00149 static const uint32_t rc_duration_he_ru106[12*3] =
00150 {
00151
00152 [ 0] = 2560000, [ 1] = 2710588, [ 2] = 3011764,
00153 [ 3] = 1280000, [ 4] = 1355294, [ 5] = 1505882,
00154 [ 6] = 853333, [ 7] = 903529, [ 8] = 1003921,
00155 [ 9] = 640000, [ 10] = 677647, [ 11] = 752941,
00156 [ 12] = 426666, [ 13] = 451764, [ 14] = 501960,
00157 [ 15] = 320000, [ 16] = 338823, [ 17] = 376470,
00158 [ 18] = 284444, [ 19] = 301176, [ 20] = 334640,
00159 [ 21] = 256000, [ 22] = 271058, [ 23] = 301176,
00160 [ 24] = 213333, [ 25] = 225882, [ 26] = 250980,
00161 [ 27] = 192000, [ 28] = 203294, [ 29] = 225882,
00162 [ 30] = 170666, [ 31] = 180705, [ 32] = 200784,
00163 [ 33] = 153600, [ 34] = 162635, [ 35] = 180705,
00164 };
00165
00166 static const uint32_t *rc_ru_duration[3] =
00167 {
00168 [0] = rc_duration_he_ru26,
00169 [1] = rc_duration_he_ru52,
00170 [2] = rc_duration_he_ru106,
00171 };
00172
00173 #endif
00174
00179 static const uint32_t rc_duration_cck[4*2] =
00180 {
00181
00182 [ 0] = 10452000, [ 1] = 10548000,
00183 [ 2] = 5380000, [ 3] = 5476000,
00184 [ 4] = 2315000, [ 5] = 2411000,
00185 [ 6] = 1439000, [ 7] = 1535000,
00186 };
00187
00190 static const uint32_t rc_duration_non_ht[8] =
00191 {
00192
00193 [ 0] = 1600000,
00194 [ 1] = 1068000,
00195 [ 2] = 800000,
00196 [ 3] = 536000,
00197 [ 4] = 400000,
00198 [ 5] = 268000,
00199 [ 6] = 200000,
00200 [ 7] = 180000,
00201 };
00202
00203
00204
00205
00206
00207 static void rc_calc_prob_ewma(struct rc_rate_stats *rc_rs);
00208 static uint16_t rc_set_previous_mcs_index(struct rc_sta_stats *rc_ss, uint16_t rate_config);
00209 static uint16_t rc_set_next_mcs_index(struct rc_sta_stats *rc_ss, uint16_t rate_config);
00210 static bool rc_check_rate_duplicated(struct rc_sta_stats *rc_ss, uint16_t rate_config);
00211 static uint16_t rc_new_random_rate(struct rc_sta_stats *ss);
00212 static bool rc_set_trial_tx(struct rc_sta_stats *rc_ss);
00213 static bool rc_update_stats(struct rc_sta_stats *rc_ss, bool init);
00214 static void rc_update_retry_chain(struct rc_sta_stats *rc_ss, uint32_t *cur_tp);
00215 static void rc_get_new_samples(struct rc_sta_stats *rc_ss);
00216 static bool rc_update_stats_fixed_rate(struct rc_sta_stats *rc_ss);
00217
00218
00219
00220
00221
00222
00232 static inline uint32_t ewma(uint32_t old_val, uint32_t new_val, uint32_t weight)
00233 {
00234 return ((new_val * (EWMA_DIV - weight) + old_val * weight) / EWMA_DIV);
00235 }
00236
00244 static uint8_t rc_get_format_mod(uint16_t rate_config)
00245 {
00246 return (rate_config & FORMAT_MOD_TX_RCX_MASK) >> FORMAT_MOD_TX_RCX_OFT;
00247 }
00248
00256 static uint8_t rc_get_bw(uint16_t rate_config)
00257 {
00258 return (rate_config & BW_TX_RCX_MASK) >> BW_TX_RCX_OFT;
00259 }
00260
00268 static uint8_t rc_get_nss(uint16_t rate_config)
00269 {
00270 uint8_t nss = 0;
00271 uint8_t format_mod = rc_get_format_mod(rate_config);
00272
00273 switch (format_mod)
00274 {
00275 case FORMATMOD_HT_MF:
00276 case FORMATMOD_HT_GF:
00277 {
00278 nss = (rate_config & HT_NSS_MASK) >> HT_NSS_OFT;
00279 } break;
00280
00281 #if NX_VHT || NX_HE
00282 case FORMATMOD_VHT:
00283 case FORMATMOD_HE_SU:
00284 case FORMATMOD_HE_MU:
00285 {
00286 nss = (rate_config & VHT_NSS_MASK) >> VHT_NSS_OFT;
00287 } break;
00288 #endif
00289
00290 default:
00291 break;
00292 }
00293
00294 return nss;
00295 }
00296
00304 static uint8_t rc_get_mcs_index(uint16_t rate_config)
00305 {
00306 uint8_t format_mod = rc_get_format_mod(rate_config);
00307 uint8_t mcs = 0;
00308
00309 switch (format_mod)
00310 {
00311 case FORMATMOD_NON_HT:
00312 case FORMATMOD_NON_HT_DUP_OFDM:
00313 {
00314 mcs = (rate_config & MCS_INDEX_TX_RCX_MASK) >> MCS_INDEX_TX_RCX_OFT;
00315 } break;
00316 case FORMATMOD_HT_MF:
00317 case FORMATMOD_HT_GF:
00318 {
00319 mcs = (rate_config & HT_MCS_MASK) >> HT_MCS_OFT;
00320 } break;
00321
00322 #if NX_VHT || NX_HE
00323 case FORMATMOD_VHT:
00324 case FORMATMOD_HE_SU:
00325 case FORMATMOD_HE_MU:
00326 {
00327 mcs = (rate_config & VHT_MCS_MASK) >> VHT_MCS_OFT;
00328 } break;
00329 #endif
00330
00331 default:
00332 break;
00333 }
00334
00335 return mcs;
00336 }
00337
00338 #if NX_HE
00339
00346 static uint8_t rc_get_he_gi(uint32_t rate_config)
00347 {
00348 return ((rate_config & HE_GI_TYPE_TX_RCX_MASK) >> HE_GI_TYPE_TX_RCX_OFT);
00349 }
00350 #endif
00351
00359 static uint8_t rc_get_sgi(uint32_t rate_config)
00360 {
00361 return ((rate_config & SHORT_GI_TX_RCX_MASK) >> SHORT_GI_TX_RCX_OFT);
00362 }
00363
00371 static uint8_t rc_get_pre_type(uint16_t rate_config)
00372 {
00373 return (rate_config & PRE_TYPE_TX_RCX_MASK) >> PRE_TYPE_TX_RCX_OFT;
00374 }
00375
00382 static void rc_calc_prob_ewma(struct rc_rate_stats *rc_rs)
00383 {
00384 uint32_t success = rc_rs->success;
00385 uint32_t attempts = rc_rs->attempts;
00386
00387 if (attempts > 0)
00388 {
00389 rc_rs->sample_skipped = 0;
00390 uint32_t cur_prob = RC_FRAC(success, attempts);
00391
00392 if (0 == rc_rs->old_prob_available)
00393 {
00394 if (cur_prob > 0)
00395 {
00396 rc_rs->probability = cur_prob - 1;
00397 }
00398 else
00399 {
00400 rc_rs->probability = 0;
00401 }
00402 }
00403 else
00404 {
00405 rc_rs->probability = ewma(rc_rs->probability, cur_prob, EWMA_LEVEL);
00406 }
00407 rc_rs->old_prob_available = 1;
00408 }
00409 else
00410 {
00411 if (rc_rs->sample_skipped < 0xFF)
00412 {
00413 rc_rs->sample_skipped++;
00414 }
00415 }
00416 }
00417
00427 static uint16_t rc_set_previous_mcs_index(struct rc_sta_stats *rc_ss, uint16_t rate_config)
00428 {
00429 uint16_t new_config = rate_config;
00430 uint8_t format_mod = rc_get_format_mod(rate_config);
00431 uint8_t mcs = rc_get_mcs_index(rate_config);
00432
00433 switch (format_mod)
00434 {
00435 case FORMATMOD_NON_HT:
00436 case FORMATMOD_NON_HT_DUP_OFDM:
00437 {
00438 uint8_t mcs_min;
00439
00440 if (mcs < HW_RATE_6MBPS)
00441 mcs_min = rc_ss->r_idx_min;
00442 else
00443 mcs_min = co_max(HW_RATE_6MBPS, rc_ss->r_idx_min);
00444
00445 while(mcs > mcs_min)
00446 {
00447 mcs--;
00448 if (rc_ss->rate_map_l & CO_BIT(mcs))
00449 {
00450 new_config = (rate_config & ~MCS_INDEX_TX_RCX_MASK) | mcs;
00451 break;
00452 }
00453 }
00454 } break;
00455 case FORMATMOD_HT_MF:
00456 case FORMATMOD_HT_GF:
00457 {
00458 uint8_t nss = rc_get_nss(rate_config);
00459 while (mcs > 0)
00460 {
00461 mcs--;
00462 if (rc_ss->rate_map.ht[nss] & CO_BIT(mcs))
00463 {
00464 new_config = (rate_config & ~HT_MCS_MASK) | mcs;
00465 if (rc_ss->short_gi)
00466 {
00467 new_config |= SHORT_GI_TX_RCX_MASK;
00468 }
00469 break;
00470 }
00471 }
00472 } break;
00473
00474 #if NX_VHT
00475 case FORMATMOD_VHT:
00476 {
00477 if (mcs > 0)
00478 {
00479 new_config = (rate_config & ~VHT_MCS_MASK) | (mcs-1);
00480 if (rc_ss->short_gi)
00481 {
00482 new_config |= SHORT_GI_TX_RCX_MASK;
00483 }
00484 }
00485 } break;
00486 #endif
00487
00488 #if NX_HE
00489 case FORMATMOD_HE_SU:
00490 {
00491 if (mcs > 0)
00492 {
00493 new_config = (rate_config & ~VHT_MCS_MASK) | (mcs-1);
00494 }
00495 } break;
00496 #endif
00497
00498 default:
00499 break;
00500 }
00501
00502 return new_config;
00503 }
00504
00514 static uint16_t rc_set_next_mcs_index(struct rc_sta_stats *rc_ss, uint16_t rate_config)
00515 {
00516 uint16_t new_config = rate_config;
00517 uint8_t format_mod = rc_get_format_mod(rate_config);
00518 uint8_t mcs = rc_get_mcs_index(rate_config);
00519
00520 switch (format_mod)
00521 {
00522 case FORMATMOD_NON_HT:
00523 case FORMATMOD_NON_HT_DUP_OFDM:
00524 {
00525 uint8_t mcs_max;
00526
00527 if (mcs >= HW_RATE_6MBPS)
00528 mcs_max = rc_ss->r_idx_max;
00529 else
00530 mcs_max = co_min(HW_RATE_11MBPS, rc_ss->r_idx_max);
00531
00532 while(mcs < mcs_max)
00533 {
00534 mcs++;
00535 if (rc_ss->rate_map_l & CO_BIT(mcs))
00536 {
00537 new_config = (rate_config & ~MCS_INDEX_TX_RCX_MASK) | mcs;
00538 break;
00539 }
00540 }
00541 } break;
00542
00543 case FORMATMOD_HT_MF:
00544 case FORMATMOD_HT_GF:
00545 {
00546 uint8_t nss = rc_get_nss(rate_config);
00547 while (mcs < rc_ss->mcs_max)
00548 {
00549 mcs++;
00550 if (rc_ss->rate_map.ht[nss] & CO_BIT(mcs))
00551 {
00552 new_config = (rate_config & ~HT_MCS_MASK) | mcs;
00553 if (rc_ss->short_gi)
00554 {
00555 new_config |= SHORT_GI_TX_RCX_MASK;
00556 }
00557 break;
00558 }
00559 }
00560 } break;
00561
00562 #if NX_VHT
00563 case FORMATMOD_VHT:
00564 {
00565 uint8_t nss = rc_get_nss(rate_config);
00566 uint8_t mcs_max_ss = 7 + ((rc_ss->rate_map.vht >> (nss << 1)) & MAC_VHT_MCS_MAP_MSK);
00567 if ((mcs < rc_ss->mcs_max) && ((mcs+1) <= mcs_max_ss))
00568 {
00569 new_config = (rate_config & ~VHT_MCS_MASK) | (mcs+1);
00570 if (rc_ss->short_gi)
00571 {
00572 new_config |= SHORT_GI_TX_RCX_MASK;
00573 }
00574 }
00575 } break;
00576 #endif
00577
00578 #if NX_HE
00579 case FORMATMOD_HE_SU:
00580 {
00581 uint8_t nss = rc_get_nss(rate_config);
00582 uint8_t mcs_max_ss = 7 + 2 * ((rc_ss->rate_map.he >> (nss << 1)) & MAC_HE_MCS_MAP_MSK);
00583 if ((mcs < rc_ss->mcs_max) && ((mcs+1) <= mcs_max_ss))
00584 {
00585 new_config = (rate_config & ~VHT_MCS_MASK) | (mcs+1);
00586 }
00587 } break;
00588 #endif
00589
00590 default:
00591 break;
00592 }
00593
00594 return new_config;
00595 }
00596
00605 static bool rc_check_rate_duplicated(struct rc_sta_stats *rc_ss, uint16_t rate_config)
00606 {
00607 uint32_t i = 0;
00608 bool ret = 0;
00609
00610 while (i < rc_ss->no_samples)
00611 {
00612 if (rate_config == rc_ss->rate_stats[i].rate_config)
00613 {
00614 ret = 1;
00615 break;
00616 }
00617 i++;
00618 }
00619 return ret;
00620 }
00621
00622 #if NX_DEBUG
00623
00630 static void rc_check_rate_config(struct rc_sta_stats *rc_ss, uint16_t i)
00631 {
00632 uint16_t rate_config = rc_ss->rate_stats[i].rate_config;
00633 uint8_t format_mod = rc_get_format_mod(rate_config);
00634 uint8_t pre_type = rc_get_pre_type(rate_config);
00635 uint8_t sgi = rc_get_sgi(rate_config);
00636 uint8_t bw = rc_get_bw(rate_config);
00637 uint8_t nss = rc_get_nss(rate_config);
00638 uint8_t mcs = rc_get_mcs_index(rate_config);
00639
00640 #if NX_HE
00641 ASSERT_ERR(format_mod <= FORMATMOD_HE_SU);
00642 #elif NX_VHT
00643 ASSERT_ERR(format_mod <= FORMATMOD_VHT);
00644 #else
00645 ASSERT_ERR(format_mod <= FORMATMOD_HT_GF);
00646 #endif
00647
00648
00649 switch (rc_ss->format_mod)
00650 {
00651 case FORMATMOD_NON_HT:
00652 case FORMATMOD_NON_HT_DUP_OFDM:
00653 {
00654 ASSERT_ERR(format_mod < FORMATMOD_HT_MF);
00655 } break;
00656 case FORMATMOD_HT_MF:
00657 case FORMATMOD_HT_GF:
00658 {
00659 if (rc_ss->r_idx_min <= HW_RATE_11MBPS)
00660 {
00661
00662 ASSERT_ERR(format_mod < FORMATMOD_VHT);
00663 }
00664 else
00665 {
00666 ASSERT_ERR((format_mod == FORMATMOD_HT_MF) || (format_mod == FORMATMOD_HT_GF));
00667 }
00668 } break;
00669
00670 #if NX_VHT
00671 case FORMATMOD_VHT:
00672 {
00673 ASSERT_ERR(format_mod == FORMATMOD_VHT);
00674 } break;
00675 #endif
00676
00677 #if NX_HE
00678 case FORMATMOD_HE_SU:
00679 {
00680 if (rc_ss->r_idx_min <= HW_RATE_11MBPS)
00681 {
00682
00683 ASSERT_ERR((format_mod == FORMATMOD_HE_SU) || (format_mod == FORMATMOD_NON_HT));
00684 }
00685 else
00686 {
00687 ASSERT_ERR(format_mod == FORMATMOD_HE_SU);
00688 }
00689 } break;
00690 #endif
00691
00692 default:
00693 break;
00694 }
00695
00696 switch (format_mod)
00697 {
00698 case FORMATMOD_NON_HT:
00699 case FORMATMOD_NON_HT_DUP_OFDM:
00700 {
00701 if ((mcs <= HW_RATE_11MBPS) && (rc_ss->type == 1))
00702 {
00703 ASSERT_ERR(pre_type == 1);
00704 }
00705 else
00706 {
00707 ASSERT_ERR(pre_type <= 1);
00708 }
00709 ASSERT_ERR(sgi == 0);
00710 ASSERT_ERR(bw == BW_20MHZ);
00711 ASSERT_ERR(nss == 0);
00712 ASSERT_ERR(mcs >= rc_ss->r_idx_min);
00713 ASSERT_ERR(mcs <= rc_ss->r_idx_max);
00714 ASSERT_ERR((rc_ss->rate_map_l & CO_BIT(mcs)));
00715 }
00716 break;
00717
00718 case FORMATMOD_HT_MF:
00719 case FORMATMOD_HT_GF:
00720 {
00721 ASSERT_ERR(pre_type == 0);
00722 ASSERT_ERR(sgi <= rc_ss->short_gi);
00723 ASSERT_ERR(bw <= rc_ss->bw_max);
00724 ASSERT_ERR(nss <= rc_ss->no_ss);
00725 ASSERT_ERR(mcs <= rc_ss->mcs_max);
00726 ASSERT_ERR((rc_ss->rate_map.ht[nss] & CO_BIT(mcs)));
00727 }
00728 break;
00729
00730 #if NX_VHT
00731 case FORMATMOD_VHT:
00732 {
00733 ASSERT_ERR(pre_type == 0);
00734 ASSERT_ERR(sgi <= rc_ss->short_gi);
00735 ASSERT_ERR(bw <= rc_ss->bw_max);
00736 ASSERT_ERR(nss <= rc_ss->no_ss);
00737 ASSERT_ERR(mcs <= rc_ss->mcs_max);
00738 ASSERT_ERR(mcs <= (7 + (rc_ss->rate_map.vht >> (nss << 1) & MAC_VHT_MCS_MAP_MSK)));
00739 ASSERT_ERR(((mcs == 6) && (bw == BW_80MHZ) && ((nss == 3) || (nss == 6))) == 0);
00740 ASSERT_ERR(((mcs == 9) && (bw == BW_20MHZ) && (nss != 2) && (nss != 5)) == 0);
00741 ASSERT_ERR(((mcs == 9) && (bw == BW_80MHZ) && (nss == 5)) == 0);
00742 ASSERT_ERR(((mcs == 9) && (bw == BW_160MHZ) && (nss == 2)) == 0);
00743 }
00744 break;
00745 #endif
00746
00747 #if NX_HE
00748 case FORMATMOD_HE_SU:
00749 {
00750 uint8_t gi = rc_get_he_gi(rate_config);
00751 ASSERT_ERR(gi <= 2);
00752 ASSERT_ERR(bw <= rc_ss->bw_max);
00753 ASSERT_ERR(nss <= rc_ss->no_ss);
00754 ASSERT_ERR(mcs <= rc_ss->mcs_max);
00755 ASSERT_ERR(mcs <= (7 + 2 * (rc_ss->rate_map.he >> (nss << 1) & MAC_HE_MCS_MAP_MSK)));
00756 }
00757 break;
00758 #endif
00759
00760 default:
00761 break;
00762 }
00763 }
00764
00771 static void rc_check_stats_rate_config(struct rc_sta_stats *rc_ss)
00772 {
00773 uint32_t i;
00774
00775 for (i = 0; i < rc_ss->no_samples; i++)
00776 {
00777 rc_check_rate_config(rc_ss, i);
00778 }
00779 }
00780 #endif
00781
00789 static uint16_t rc_new_random_rate(struct rc_sta_stats *rc_ss)
00790 {
00791
00792 uint16_t rd = co_rand_hword();
00793 uint8_t format = rc_ss->format_mod;
00794 uint16_t rate_cfg = format << FORMAT_MOD_TX_RCX_OFT;
00795 uint8_t bw_min = rc_ss->bw_max > BW_20MHZ ? (rc_ss->bw_max - 1) : rc_ss->bw_max;
00796
00797 switch (format)
00798 {
00799 case FORMATMOD_NON_HT:
00800 case FORMATMOD_NON_HT_DUP_OFDM:
00801 {
00802 uint8_t r_idx_l_max = rc_ss->r_idx_max;
00803 uint8_t r_idx_l_min = rc_ss->r_idx_min;
00804 uint8_t r_idx = (((rd & MCS_INDEX_TX_RCX_MASK) >> MCS_INDEX_TX_RCX_OFT) %
00805 (r_idx_l_max - r_idx_l_min + 1)) + r_idx_l_min;
00806 if ((rc_ss->rate_map_l & CO_BIT(r_idx)) == 0)
00807 {
00808 r_idx = r_idx_l_max;
00809 }
00810
00811 rate_cfg |= r_idx << MCS_INDEX_TX_RCX_OFT;
00812
00813 if (r_idx == HW_RATE_1MBPS)
00814 {
00815 rate_cfg |= PRE_TYPE_TX_RCX_MASK;
00816 }
00817 else if ((r_idx > HW_RATE_1MBPS) && (r_idx <= HW_RATE_11MBPS))
00818 {
00819 rate_cfg |= (rd & PRE_TYPE_TX_RCX_MASK) | (rc_ss->type << PRE_TYPE_TX_RCX_OFT);
00820 }
00821 } break;
00822 case FORMATMOD_HT_MF:
00823 case FORMATMOD_HT_GF:
00824 {
00825 uint8_t r_idx_max = rc_ss->r_idx_max;
00826 uint8_t r_idx_min = rc_ss->r_idx_min;
00827
00828 if ((r_idx_min <= HW_RATE_11MBPS) &&
00829 (((rd & FORMAT_MOD_TX_RCX_MASK) >> FORMAT_MOD_TX_RCX_OFT) % 2))
00830 {
00831
00832 uint8_t r_idx = (((rd & MCS_INDEX_TX_RCX_MASK) >> MCS_INDEX_TX_RCX_OFT) %
00833 (r_idx_max - r_idx_min + 1)) + r_idx_min;
00834 rate_cfg = FORMATMOD_NON_HT << FORMAT_MOD_TX_RCX_OFT;
00835 if ((rc_ss->rate_map_l & CO_BIT(r_idx)) == 0)
00836 {
00837 r_idx = r_idx_max;
00838 }
00839 rate_cfg |= r_idx << MCS_INDEX_TX_RCX_OFT;
00840 if (r_idx == HW_RATE_1MBPS)
00841 {
00842 rate_cfg |= PRE_TYPE_TX_RCX_MASK;
00843 }
00844 else
00845 {
00846 rate_cfg |= (rd & PRE_TYPE_TX_RCX_MASK) | (rc_ss->type << PRE_TYPE_TX_RCX_OFT);
00847 }
00848 }
00849 else
00850 {
00851 uint8_t bw_max = rc_ss->bw_max;
00852 uint8_t short_gi = rc_ss->short_gi;
00853 uint8_t mcs_max = rc_ss->mcs_max;
00854 uint8_t no_ss_max = rc_ss->no_ss;
00855 uint8_t nss = ((rd & HT_NSS_MASK) >> HT_NSS_OFT) % (no_ss_max + 1);
00856 uint8_t mcs = ((rd & HT_MCS_MASK) >> HT_MCS_OFT) % (mcs_max + 1);
00857 if ((rc_ss->rate_map.ht[nss] & CO_BIT(mcs)) == 0)
00858 {
00859 mcs = mcs_max;
00860 }
00861 rate_cfg |= (((rd & SHORT_GI_TX_RCX_MASK) >> SHORT_GI_TX_RCX_OFT) % (short_gi + 1)) << SHORT_GI_TX_RCX_OFT;
00862 #if RC_USE_MAX_BW
00863 rate_cfg |= bw_max << BW_TX_RCX_OFT;
00864 #else
00865 rate_cfg |= ((((rd & BW_TX_RCX_MASK) >> BW_TX_RCX_OFT) % (bw_max - bw_min + 1)) + bw_min) << BW_TX_RCX_OFT;
00866 #endif
00867 rate_cfg |= nss << HT_NSS_OFT;
00868 rate_cfg |= mcs << HT_MCS_OFT;
00869 }
00870 } break;
00871
00872 #if NX_VHT
00873 case FORMATMOD_VHT:
00874 {
00875 uint8_t bw_max = rc_ss->bw_max;
00876 uint8_t short_gi = rc_ss->short_gi;
00877 uint8_t no_ss_max = rc_ss->no_ss;
00878 uint8_t mcs_max = rc_ss->mcs_max;
00879
00880 uint8_t mcs = ((rd & VHT_MCS_MASK) >> VHT_MCS_OFT) % (mcs_max + 1);
00881 uint8_t no_ss = ((rd & VHT_NSS_MASK) >> VHT_NSS_OFT) % (no_ss_max + 1);
00882 uint8_t bw = 0;
00883
00884 if (mcs > (7 + (rc_ss->rate_map.vht >> (no_ss << 1) & MAC_VHT_MCS_MAP_MSK)))
00885 {
00886 mcs = 7 + (rc_ss->rate_map.vht >> (no_ss << 1) & MAC_VHT_MCS_MAP_MSK);
00887 }
00888
00889 #if RC_USE_MAX_BW
00890 bw = bw_max;
00891 #else
00892 bw = (((rd & BW_TX_RCX_MASK) >> BW_TX_RCX_OFT) % (bw_max - bw_min + 1)) + bw_min;
00893 #endif
00894
00895 if ((mcs == 6) && (bw == BW_80MHZ) && ((no_ss == 3) || (no_ss == 6)))
00896 {
00897 no_ss = no_ss - 1;
00898 }
00899 if (mcs == 9)
00900 {
00901 if ((bw == BW_20MHZ) && (no_ss != 2) && (no_ss != 5))
00902 {
00903 mcs = 8;
00904 }
00905 if ((bw == BW_80MHZ) && (no_ss == 5))
00906 {
00907 no_ss = no_ss - 1;
00908 }
00909 if ((bw == BW_160MHZ) && (no_ss == 2))
00910 {
00911 no_ss = no_ss - 1;
00912 }
00913 }
00914 rate_cfg |= ((((rd & SHORT_GI_TX_RCX_MASK) >> SHORT_GI_TX_RCX_OFT) % (short_gi + 1)) << SHORT_GI_TX_RCX_OFT) |
00915 (bw << BW_TX_RCX_OFT) |
00916 (no_ss << VHT_NSS_OFT) |
00917 (mcs << MCS_INDEX_TX_RCX_OFT);
00918 } break;
00919 #endif
00920
00921 #if NX_HE
00922 case FORMATMOD_HE_SU:
00923 {
00924 uint8_t bw_max = rc_ss->bw_max;
00925 uint8_t no_ss_max = rc_ss->no_ss;
00926 uint8_t mcs_max = rc_ss->mcs_max;
00927
00928 uint8_t mcs = ((rd & VHT_MCS_MASK) >> VHT_MCS_OFT) % (mcs_max + 1);
00929 uint8_t no_ss = ((rd & VHT_NSS_MASK) >> VHT_NSS_OFT) % (no_ss_max + 1);
00930 uint8_t gi = (rd & HE_GI_TYPE_TX_RCX_MASK) >> HE_GI_TYPE_TX_RCX_OFT;
00931 uint8_t bw = 0;
00932
00933 if (mcs > (7 + 2 * (rc_ss->rate_map.he >> (no_ss << 1) & MAC_HE_MCS_MAP_MSK)))
00934 {
00935 mcs = 7 + 2* (rc_ss->rate_map.he >> (no_ss << 1) & MAC_HE_MCS_MAP_MSK);
00936 }
00937
00938 if (gi > 2)
00939 gi = 2;
00940
00941 #if RC_USE_MAX_BW
00942 bw = bw_max;
00943 #else
00944 bw = (((rd & BW_TX_RCX_MASK) >> BW_TX_RCX_OFT) % (bw_max - bw_min + 1)) + bw_min;
00945 #endif
00946 rate_cfg |= (gi << HE_GI_TYPE_TX_RCX_OFT) |
00947 (bw << BW_TX_RCX_OFT) |
00948 (no_ss << VHT_NSS_OFT) |
00949 (mcs << MCS_INDEX_TX_RCX_OFT);
00950 } break;
00951 #endif
00952
00953 default:
00954 break;
00955 }
00956
00957 return rate_cfg;
00958 }
00959
00967 static bool is_cck_group(uint16_t rate_config)
00968 {
00969 uint8_t format = rc_get_format_mod(rate_config);
00970 uint8_t mcs = rc_get_mcs_index(rate_config);
00971 bool is_cck = 0;
00972
00973 if ((format < FORMATMOD_HT_MF) && (mcs < HW_RATE_6MBPS))
00974 {
00975 is_cck = 1;
00976 }
00977
00978 return is_cck;
00979 }
00980
01005 static bool rc_set_trial_tx(struct rc_sta_stats *rc_ss)
01006 {
01007 struct rc_rate_stats *rc_rand = NULL;
01008 int i;
01009 uint16_t random_rate_idx = 0;
01010 uint32_t cur_max_tp_streams;
01011 uint32_t sample_streams;
01012 uint32_t sample_dur;
01013 uint32_t dur_retry_1;
01014 uint32_t dur_retry_2;
01015 uint32_t max_skipped;
01016 uint8_t format_mod = rc_ss->format_mod;
01017 #if NX_AMPDU_TX
01018 bool tx_ampdu = (rc_ss->info & RC_AGG_TX_MASK) != 0;
01019 #endif
01020
01021
01022 rc_ss->sample_wait = RC_TRIAL_PERIOD * RC_TRUNC(rc_ss->avg_ampdu_len);
01023
01024
01025 random_rate_idx = co_rand_hword() % rc_ss->no_samples;
01026 for (i = 0; i < rc_ss->no_samples; i++)
01027 {
01028 random_rate_idx = (random_rate_idx + i) % rc_ss->no_samples;
01029 rc_rand = &rc_ss->rate_stats[random_rate_idx];
01030
01031
01032
01033 if (random_rate_idx == rc_ss->retry_step_idx[0])
01034 {
01035 continue;
01036 }
01037
01038
01039 if (rc_rand->probability > RC_FRAC(95, 100))
01040 {
01041 continue;
01042 }
01043 #if NX_AMPDU_TX
01044
01045
01046 if (tx_ampdu && (rc_get_format_mod(rc_rand->rate_config) < FORMATMOD_HT_MF))
01047 {
01048 continue;
01049 }
01050 #endif
01051
01052
01053
01054 break;
01055 }
01056
01057
01058 if (i == rc_ss->no_samples)
01059 return false;
01060
01061 sample_dur = rc_get_duration(rc_rand);
01062 if (format_mod >= FORMATMOD_HT_MF)
01063 {
01064
01065
01066 cur_max_tp_streams = rc_get_nss(rc_ss->rate_stats[rc_ss->retry_step_idx[0]].rate_config);
01067 sample_streams = rc_get_nss(rc_rand->rate_config);
01068 dur_retry_1 = rc_get_duration(&rc_ss->rate_stats[rc_ss->retry_step_idx[1]]);
01069 dur_retry_2 = rc_get_duration(&rc_ss->rate_stats[rc_ss->retry_step_idx[2]]);
01070 max_skipped = rc_ss->rate_stats[random_rate_idx].old_prob_available ? 32 : RC_TRUNC(rc_ss->avg_ampdu_len);
01071 if ((sample_dur >= dur_retry_1) &&
01072 (((cur_max_tp_streams - 1) < sample_streams) ||
01073 (sample_dur >= dur_retry_2)))
01074 {
01075 if (rc_rand->sample_skipped < max_skipped)
01076 {
01077 return false;
01078 }
01079 rc_ss->sample_slow += 1;
01080 if (rc_ss->sample_slow > 2)
01081 {
01082 if (rc_ss->sample_slow > 0xF)
01083 {
01084 rc_ss->sample_slow = 0xF;
01085 }
01086 return false;
01087 }
01088 }
01089 }
01090
01091
01092 rc_ss->trial_idx = random_rate_idx;
01093 rc_ss->trial_status = RC_TRIAL_STATUS_WAIT_CFM;
01094
01095 return true;
01096 }
01097
01106 static bool rc_check_trial_tx(struct rc_sta_stats *rc_ss)
01107 {
01108
01109 if (rc_ss->info & RC_FIX_RATE_EN_MASK)
01110 return false;
01111
01112
01113 if (rc_ss->trial_status != RC_TRIAL_STATUS_WAIT)
01114 return false;
01115
01116
01117 if (rc_ss->sample_wait > 0)
01118 {
01119 rc_ss->sample_wait --;
01120 return false;
01121 }
01122
01123
01124 if ((rc_ss->info & RC_SS_UPD_REQ_MASK) == RC_SS_UPD_REQ_MASK)
01125 {
01126 rc_get_new_samples(rc_ss);
01127 rc_ss->info &= ~RC_SS_UPD_REQ_MASK;
01128 }
01129
01130
01131
01132 return (rc_set_trial_tx(rc_ss));
01133 }
01134
01142 static void rc_sort_samples_tp(struct rc_sta_stats *rc_ss, uint32_t *cur_tp)
01143 {
01144 struct rc_rate_stats rc_ss_tmp;
01145 uint32_t temp_tp;
01146 uint16_t i, j, last;
01147 uint32_t size = sizeof(rc_ss_tmp);
01148
01149 last = rc_ss->no_samples;
01150 j = rc_ss->no_samples - 1;
01151 while (last > 0)
01152 {
01153 last = 0;
01154 for (i = 1; i < j; i++)
01155 {
01156 if (cur_tp[i] > cur_tp[i + 1])
01157 {
01158 memmove(&rc_ss_tmp, &rc_ss->rate_stats[i], size);
01159 memmove(&rc_ss->rate_stats[i], &rc_ss->rate_stats[i+1], size);
01160 memmove(&rc_ss->rate_stats[i+1], &rc_ss_tmp, size);
01161 temp_tp = cur_tp[i];
01162 cur_tp[i] = cur_tp[i+1];
01163 cur_tp[i+1] = temp_tp;
01164 last = i;
01165 }
01166 }
01167 j = last;
01168 }
01169 }
01170
01183 static bool rc_update_stats(struct rc_sta_stats *rc_ss, bool init)
01184 {
01185 bool upd = 0;
01186 uint16_t i = 0;
01187 uint32_t cur_tp[RC_MAX_N_SAMPLE];
01188 uint16_t old_rate_cfg[RATE_CONTROL_STEPS];
01189 struct rc_rate_stats *rc_rs;
01190
01191
01192 for (i = 0; i < RATE_CONTROL_STEPS; i++)
01193 {
01194 old_rate_cfg[i] = rc_ss->rate_stats[rc_ss->retry_step_idx[i]].rate_config;
01195 }
01196
01197 if (rc_ss->ampdu_packets > 0)
01198 {
01199
01200 rc_ss->avg_ampdu_len = ewma(rc_ss->avg_ampdu_len,
01201 RC_FRAC(rc_ss->ampdu_len, rc_ss->ampdu_packets),
01202 EWMA_LEVEL);
01203 rc_ss->ampdu_len = 0;
01204 rc_ss->ampdu_packets = 0;
01205 }
01206
01207 #if NX_HE
01208
01209 rc_rs = &rc_ss->rate_stats[RC_HE_STATS_IDX];
01210
01211 rc_calc_prob_ewma(rc_rs);
01212 rc_rs->attempts = 0;
01213 rc_rs->success = 0;
01214 #endif
01215
01216 rc_ss->sample_slow = 0;
01217
01218
01219 for (i = 0; i < rc_ss->no_samples; i++)
01220 {
01221 cur_tp[i] = 0;
01222
01223
01224 rc_ss->rate_stats[i].rate_allowed = 1;
01225 }
01226
01227
01228
01229 if (rc_ss->fixed_rate_cfg == RC_FIXED_RATE_NOT_SET)
01230 {
01231 for (i = 0; i < rc_ss->no_samples; i++)
01232 {
01233 rc_rs = &rc_ss->rate_stats[i];
01234
01235 rc_calc_prob_ewma(rc_rs);
01236
01237
01238 cur_tp[i] = rc_calc_tp(rc_ss, i);
01239 }
01240
01241
01242 rc_sort_samples_tp(rc_ss, cur_tp);
01243
01244 rc_update_retry_chain(rc_ss, cur_tp);
01245
01246 if (init == 0)
01247 {
01248
01249 rc_ss->info |= RC_SS_UPD_REQ_MASK;
01250
01251 for (i = 0; i < rc_ss->no_samples; i++)
01252 {
01253
01254 rc_ss->rate_stats[i].attempts = 0;
01255 rc_ss->rate_stats[i].success = 0;
01256 }
01257 }
01258 }
01259 else
01260 {
01261 upd = rc_update_stats_fixed_rate(rc_ss);
01262 }
01263
01264
01265 for (i = 0; i < RATE_CONTROL_STEPS; i++)
01266 {
01267 if (old_rate_cfg[i] != rc_ss->rate_stats[rc_ss->retry_step_idx[i]].rate_config)
01268 {
01269 upd = 1;
01270 break;
01271 }
01272 }
01273
01274 return upd;
01275 }
01276
01290 static void rc_update_retry_chain(struct rc_sta_stats *rc_ss, uint32_t *cur_tp)
01291 {
01292 uint32_t max_prob_idx = 0;
01293 uint32_t max_tp = 0;
01294 uint32_t max_prob = 0;
01295 uint16_t i;
01296 uint16_t j;
01297
01298
01299 if (((rc_ss->info & RC_AGG_TX_MASK) == 0) && (cur_tp[0] > cur_tp[rc_ss->no_samples - 1]))
01300 {
01301 rc_ss->retry_step_idx[0] = 0;
01302 j = 1;
01303 }
01304 else
01305 {
01306 rc_ss->retry_step_idx[0] = rc_ss->no_samples - 1;
01307 j = 2;
01308 }
01309
01310 if (!is_cck_group(rc_ss->rate_stats[rc_ss->retry_step_idx[0]].rate_config))
01311 {
01312
01313 for (i = 0; i < (rc_ss->no_samples - 1); i++)
01314 {
01315 if (is_cck_group(rc_ss->rate_stats[i].rate_config))
01316 {
01317 rc_ss->rate_stats[i].rate_allowed = 0;
01318 }
01319 }
01320 rc_ss->rate_stats[rc_ss->retry_step_idx[0]].rate_allowed = 1;
01321 }
01322 rc_ss->retry_step_idx[1] = rc_ss->retry_step_idx[0];
01323 for (i = j; i < rc_ss->no_samples; i++)
01324 {
01325 if (rc_ss->rate_stats[rc_ss->no_samples - i].rate_allowed)
01326 {
01327 rc_ss->retry_step_idx[1] = rc_ss->no_samples - i;
01328 break;
01329 }
01330 }
01331
01332 max_prob_idx = rc_ss->retry_step_idx[1];
01333 for (i = i + 1; i < rc_ss->no_samples; i++)
01334 {
01335 if (rc_ss->rate_stats[rc_ss->no_samples - i].rate_allowed)
01336 {
01337 max_prob_idx = rc_ss->no_samples - i;
01338 break;
01339 }
01340 }
01341 max_tp = cur_tp[max_prob_idx];
01342 max_prob = rc_ss->rate_stats[max_prob_idx].probability;
01343 for (i = 0; i < rc_ss->retry_step_idx[1]; i++)
01344 {
01345 if (rc_ss->rate_stats[i].rate_allowed == 0)
01346 {
01347 continue;
01348 }
01349 if (i == rc_ss->retry_step_idx[0])
01350 {
01351 continue;
01352 }
01353 if (rc_ss->rate_stats[i].probability >= RC_FRAC(95, 100))
01354 {
01355 if (cur_tp[i] >= max_tp)
01356 {
01357 max_prob_idx = i;
01358 max_tp = cur_tp[i];
01359 max_prob = rc_ss->rate_stats[i].probability;
01360 }
01361 }
01362 else if (rc_ss->rate_stats[i].probability >= max_prob)
01363 {
01364 max_prob_idx = i;
01365 max_tp = cur_tp[i];
01366 max_prob = rc_ss->rate_stats[i].probability;
01367 }
01368 }
01369
01370 rc_ss->retry_step_idx[2] = max_prob_idx;
01371
01372 rc_ss->retry_step_idx[3] = 0;
01373 }
01374
01383 static bool rc_check_valid_rate(struct rc_sta_stats *rc_ss, uint16_t rate_config)
01384 {
01385 uint8_t format = rc_get_format_mod(rate_config);
01386 bool rate_allowed = 1;
01387
01388 switch (format)
01389 {
01390 case FORMATMOD_NON_HT:
01391 case FORMATMOD_NON_HT_DUP_OFDM:
01392 {
01393 uint8_t r_idx = rc_get_mcs_index(rate_config);
01394 if ((rc_ss->rate_map_l & CO_BIT(r_idx)) == 0)
01395 {
01396 rate_allowed = 0;
01397 }
01398 } break;
01399 case FORMATMOD_HT_MF:
01400 case FORMATMOD_HT_GF:
01401 {
01402 uint8_t nss = rc_get_nss(rate_config);
01403 uint8_t mcs = rc_get_mcs_index(rate_config);
01404 if ((rc_ss->rate_map.ht[nss] & CO_BIT(mcs)) == 0)
01405 {
01406 rate_allowed = 0;
01407 }
01408 } break;
01409
01410 #if NX_VHT
01411 case FORMATMOD_VHT:
01412 {
01413 uint8_t bw = rc_get_bw(rate_config);
01414 uint8_t nss = rc_get_nss(rate_config);
01415 uint8_t mcs = rc_get_mcs_index(rate_config);
01416
01417 if (mcs > (7 + (rc_ss->rate_map.vht >> (nss << 1) & MAC_VHT_MCS_MAP_MSK)))
01418 {
01419 rate_allowed = 0;
01420 }
01421
01422 if ((mcs == 6) && (bw == BW_80MHZ) && ((nss == 3) || (nss == 6)))
01423 {
01424 rate_allowed = 0;
01425 }
01426 else if (mcs == 9)
01427 {
01428 if ((bw == BW_20MHZ) && (nss != 2) && (nss != 5))
01429 {
01430 rate_allowed = 0;
01431 }
01432 else if ((bw == BW_80MHZ) && (nss == 5))
01433 {
01434 rate_allowed = 0;
01435 }
01436 else if ((bw == BW_160MHZ) && (nss == 2))
01437 {
01438 rate_allowed = 0;
01439 }
01440 }
01441 } break;
01442 #endif
01443
01444 #if NX_HE
01445 case FORMATMOD_HE_SU:
01446 {
01447 uint8_t nss = rc_get_nss(rate_config);
01448 uint8_t mcs = rc_get_mcs_index(rate_config);
01449
01450 if (mcs > (7 + 2 * (rc_ss->rate_map.vht >> (nss << 1) & MAC_VHT_MCS_MAP_MSK)))
01451 {
01452 rate_allowed = 0;
01453 }
01454 } break;
01455 #endif
01456
01457 default:
01458 break;
01459 }
01460
01461 return rate_allowed;
01462 }
01463
01481 static void rc_get_new_sample_rates(struct rc_sta_stats *rc_ss,
01482 uint16_t *new_rate_cfg_array,
01483 uint8_t n_new_samples)
01484 {
01485 uint8_t i = 0;
01486 uint16_t tmp_rate_cfg;
01487 uint16_t max_tp_rate_cfg = rc_ss->rate_stats[rc_ss->retry_step_idx[0]].rate_config;
01488 uint16_t max_tp_2_rate_cfg = rc_ss->rate_stats[rc_ss->retry_step_idx[1]].rate_config;
01489
01490 memset(new_rate_cfg_array, -1, n_new_samples*sizeof(*new_rate_cfg_array));
01491
01492 for (i = 0; i < n_new_samples; i++)
01493 {
01494 switch (i)
01495 {
01496
01497 case 0:
01498 {
01499 new_rate_cfg_array[i] = rc_new_random_rate(rc_ss);
01500 }
01501 break;
01502
01503
01504
01505 case 1:
01506 {
01507 #if NX_HE
01508 if (rc_get_format_mod(max_tp_rate_cfg) == FORMATMOD_HE_SU)
01509 {
01510 uint8_t gi = (rc_get_he_gi(max_tp_rate_cfg) + 1) % 3;
01511 max_tp_rate_cfg &= ~HE_GI_TYPE_TX_RCX_MASK;
01512 new_rate_cfg_array[i] = max_tp_rate_cfg | (gi << HE_GI_TYPE_TX_RCX_OFT);
01513 }
01514 else
01515 #endif
01516 if ((rc_get_format_mod(max_tp_rate_cfg) >= (uint8_t)FORMATMOD_HT_MF) &&
01517 (rc_ss->short_gi == 1))
01518 {
01519 new_rate_cfg_array[i] = max_tp_rate_cfg ^ SHORT_GI_TX_RCX_MASK;
01520 }
01521 }
01522 break;
01523
01524
01525 case 2:
01526 {
01527 tmp_rate_cfg = rc_set_next_mcs_index(rc_ss, max_tp_rate_cfg);
01528 if ((tmp_rate_cfg != max_tp_rate_cfg) &&
01529 (rc_check_valid_rate(rc_ss, tmp_rate_cfg)))
01530 {
01531 new_rate_cfg_array[i] = tmp_rate_cfg;
01532 }
01533 }
01534 break;
01535
01536
01537 case 3:
01538 {
01539 tmp_rate_cfg = rc_set_previous_mcs_index(rc_ss, max_tp_rate_cfg);
01540 if ((tmp_rate_cfg != max_tp_rate_cfg) &&
01541 (rc_check_valid_rate(rc_ss, tmp_rate_cfg)))
01542 {
01543 new_rate_cfg_array[i] = tmp_rate_cfg;
01544 }
01545 }
01546 break;
01547
01548
01549 case 4:
01550 {
01551 tmp_rate_cfg = rc_set_next_mcs_index(rc_ss, max_tp_2_rate_cfg);
01552 if ((tmp_rate_cfg != max_tp_2_rate_cfg) &&
01553 (rc_check_valid_rate(rc_ss, tmp_rate_cfg)))
01554 {
01555 new_rate_cfg_array[i] = tmp_rate_cfg;
01556 }
01557 }
01558 break;
01559
01560
01561 case 5:
01562 {
01563 tmp_rate_cfg = rc_set_previous_mcs_index(rc_ss, max_tp_2_rate_cfg);
01564 if ((tmp_rate_cfg != max_tp_2_rate_cfg) &&
01565 (rc_check_valid_rate(rc_ss, tmp_rate_cfg)))
01566 {
01567 new_rate_cfg_array[i] = tmp_rate_cfg;
01568 }
01569 }
01570 break;
01571
01572 default:
01573 break;
01574 }
01575 }
01576 }
01577
01590 static void rc_get_new_samples(struct rc_sta_stats *rc_ss)
01591 {
01592
01593 uint32_t new_sample = 0;
01594 uint16_t new_rate_cfg_array[RC_MAX_N_SAMPLE-4];
01595 uint16_t i = 1;
01596
01597 if (rc_ss->no_samples < RC_MAX_N_SAMPLE)
01598 {
01599 return;
01600 }
01601
01602 rc_get_new_sample_rates(rc_ss, new_rate_cfg_array, RC_MAX_N_SAMPLE-4);
01603
01604 while (i < rc_ss->no_samples)
01605 {
01606 struct rc_rate_stats *rc_rs = &rc_ss->rate_stats[i];
01607 uint16_t tmp_rate_cfg;
01608
01609
01610 if (((rc_rs->probability < RC_FRAC(50, 100)) || (rc_rs->sample_skipped > 10)) &&
01611 (i != rc_ss->retry_step_idx[0]) &&
01612 (i != rc_ss->retry_step_idx[1]) &&
01613 (i != rc_ss->retry_step_idx[2]) &&
01614 (new_sample < (RC_MAX_N_SAMPLE-4)))
01615 {
01616 tmp_rate_cfg = new_rate_cfg_array[new_sample];
01617 if ((tmp_rate_cfg != (uint16_t)-1) && (!rc_check_rate_duplicated(rc_ss, tmp_rate_cfg)))
01618 {
01619 rc_rs->rate_config = tmp_rate_cfg;
01620
01621 rc_rs->probability = 0;
01622 rc_rs->old_prob_available = 0;
01623 #if NX_DEBUG
01624
01625 rc_check_rate_config(rc_ss, i);
01626 #endif
01627
01628 i += 1;
01629 }
01630 new_sample += 1;
01631 }
01632 else
01633 {
01634
01635 i += 1;
01636 }
01637 }
01638 }
01639
01647 static uint16_t rc_get_lowest_rate_config(struct rc_sta_stats *rc_ss)
01648 {
01649 uint16_t rate_config = 0;
01650
01651 switch (rc_ss->format_mod)
01652 {
01653 case FORMATMOD_NON_HT:
01654 case FORMATMOD_NON_HT_DUP_OFDM:
01655 {
01656 if (rc_ss->r_idx_min == 0)
01657 {
01658
01659 rate_config = (FORMATMOD_NON_HT << FORMAT_MOD_TX_RCX_OFT) |
01660 (1 << PRE_TYPE_TX_RCX_OFT);
01661 }
01662 else
01663 {
01664
01665 rate_config = (FORMATMOD_NON_HT << FORMAT_MOD_TX_RCX_OFT) |
01666 (rc_ss->r_idx_min << MCS_INDEX_TX_RCX_OFT);
01667 }
01668 } break;
01669 case FORMATMOD_HT_MF:
01670 case FORMATMOD_HT_GF:
01671 {
01672 if (rc_ss->r_idx_min == 0)
01673 {
01674
01675 rate_config = (FORMATMOD_NON_HT << FORMAT_MOD_TX_RCX_OFT) |
01676 (1 << PRE_TYPE_TX_RCX_OFT);
01677 }
01678 else
01679 {
01680
01681 rate_config = (rc_ss->format_mod << FORMAT_MOD_TX_RCX_OFT);
01682 }
01683 } break;
01684
01685 #if NX_VHT
01686 case FORMATMOD_VHT:
01687 {
01688
01689 rate_config = (rc_ss->format_mod << FORMAT_MOD_TX_RCX_OFT);
01690 } break;
01691 #endif
01692
01693 #if NX_HE
01694 case FORMATMOD_HE_SU:
01695 {
01696 if (rc_ss->r_idx_min == 0)
01697 {
01698
01699 rate_config = (FORMATMOD_NON_HT << FORMAT_MOD_TX_RCX_OFT) |
01700 (1 << PRE_TYPE_TX_RCX_OFT);
01701 }
01702 else
01703 {
01704
01705 rate_config = (rc_ss->format_mod << FORMAT_MOD_TX_RCX_OFT) |
01706 GI_TYPE_1_6;
01707 }
01708 } break;
01709 #endif
01710
01711 default:
01712 break;
01713 }
01714
01715 return rate_config;
01716 }
01717
01727 static uint16_t rc_get_initial_rate_config(struct rc_sta_stats *rc_ss)
01728 {
01729 uint16_t rate_config = 0;
01730
01731 switch (rc_ss->format_mod)
01732 {
01733 case FORMATMOD_NON_HT:
01734 case FORMATMOD_NON_HT_DUP_OFDM:
01735 {
01736 rate_config = (rc_ss->format_mod << FORMAT_MOD_TX_RCX_OFT) |
01737 (rc_ss->type << PRE_TYPE_TX_RCX_OFT) |
01738 (rc_ss->r_idx_max << MCS_INDEX_TX_RCX_OFT);
01739 } break;
01740 case FORMATMOD_HT_MF:
01741 case FORMATMOD_HT_GF:
01742 {
01743 uint8_t mcs = 31 - co_clz((uint32_t)rc_ss->rate_map.ht[rc_ss->no_ss]);
01744 rate_config = (rc_ss->format_mod << FORMAT_MOD_TX_RCX_OFT) |
01745 (rc_ss->short_gi << SHORT_GI_TX_RCX_OFT) |
01746 (rc_ss->bw_max << BW_TX_RCX_OFT) |
01747 (rc_ss->no_ss << HT_NSS_OFT) |
01748 (mcs << MCS_INDEX_TX_RCX_OFT);
01749 } break;
01750
01751 #if NX_VHT
01752 case FORMATMOD_VHT:
01753 {
01754 rate_config = (rc_ss->format_mod << FORMAT_MOD_TX_RCX_OFT) |
01755 (rc_ss->short_gi << SHORT_GI_TX_RCX_OFT) |
01756 (rc_ss->bw_max << BW_TX_RCX_OFT) |
01757 (rc_ss->format_mod == FORMATMOD_VHT ? rc_ss->no_ss << VHT_NSS_OFT : rc_ss->no_ss << HT_NSS_OFT) |
01758 (7 << MCS_INDEX_TX_RCX_OFT);
01759 } break;
01760 #endif
01761
01762 #if NX_HE
01763 case FORMATMOD_HE_SU:
01764 {
01765 rate_config = (rc_ss->format_mod << FORMAT_MOD_TX_RCX_OFT) |
01766 (rc_ss->bw_max << BW_TX_RCX_OFT) |
01767 (rc_ss->no_ss << VHT_NSS_OFT) |
01768 (7 << MCS_INDEX_TX_RCX_OFT) | GI_TYPE_0_8;
01769 } break;
01770 #endif
01771
01772 default:
01773 break;
01774 }
01775
01776 return rate_config;
01777 }
01778
01789 static uint16_t rc_get_num_samples(struct rc_sta_stats *rc_ss)
01790 {
01791 uint32_t i, j;
01792 uint16_t n_sample = 0;
01793
01794 switch (rc_ss->format_mod)
01795 {
01796 case FORMATMOD_NON_HT:
01797 case FORMATMOD_NON_HT_DUP_OFDM:
01798 {
01799 uint16_t r_map = rc_ss->rate_map_l;
01800 n_sample += (r_map & 1);
01801 for (i = HW_RATE_2MBPS; i <= HW_RATE_11MBPS; i++)
01802 {
01803 n_sample += (((r_map >> i) & 1) << (1-rc_ss->type));
01804 }
01805 for (i = HW_RATE_6MBPS; i <= HW_RATE_54MBPS; i++)
01806 {
01807 n_sample += ((r_map >> i) & 1);
01808 }
01809 } break;
01810
01811 case FORMATMOD_HT_MF:
01812 case FORMATMOD_HT_GF:
01813 {
01814 uint32_t mult = ((rc_ss->bw_max + 1) << rc_ss->short_gi) * (rc_ss->no_ss + 1);
01815 uint8_t mcs_map = rc_ss->rate_map.ht[0];
01816 for (j = 0; j < 8; j++)
01817 {
01818 n_sample += ((mcs_map & 1) * mult);
01819 mcs_map = mcs_map >> 1;
01820 }
01821
01822 uint16_t r_map = rc_ss->rate_map_l;
01823 n_sample += (r_map & 1);
01824 for (i = HW_RATE_2MBPS; i <= HW_RATE_11MBPS; i++)
01825 {
01826 n_sample += (((r_map >> i) & 1) << (1-rc_ss->type));
01827 }
01828 } break;
01829
01830 #if NX_VHT
01831 case FORMATMOD_VHT:
01832 {
01833
01834 uint32_t mult = ((rc_ss->bw_max + 1) << rc_ss->short_gi) * (rc_ss->no_ss + 1);
01835 uint8_t n_mcs;
01836 switch (rc_ss->rate_map.vht & MAC_VHT_MCS_MAP_MSK)
01837 {
01838 case 0:
01839 n_mcs = 8;
01840 break;
01841 case 1:
01842 case 2:
01843 n_mcs = 9;
01844 break;
01845 default:
01846 n_mcs = 8;
01847 break;
01848 }
01849 n_sample = n_mcs * mult;
01850 } break;
01851 #endif
01852
01853 #if NX_HE
01854 case FORMATMOD_HE_SU:
01855 {
01856
01857 uint32_t mult = ((rc_ss->bw_max + 1) * (rc_ss->short_gi + 1)) * (rc_ss->no_ss + 1);
01858 uint8_t n_mcs;
01859 switch (rc_ss->rate_map.he & MAC_HE_MCS_MAP_MSK)
01860 {
01861 case 0:
01862 n_mcs = 8;
01863 break;
01864 case 1:
01865 n_mcs = 9;
01866 break;
01867 case 2:
01868 n_mcs = 10;
01869 break;
01870 default:
01871 n_mcs = 8;
01872 break;
01873 }
01874 n_sample = n_mcs * mult;
01875 } break;
01876 #endif
01877
01878 default:
01879 break;
01880 }
01881
01882 if (n_sample > RC_MAX_N_SAMPLE)
01883 {
01884 n_sample = RC_MAX_N_SAMPLE;
01885 }
01886
01887 return n_sample;
01888 }
01889
01900 static void rc_set_rate_configs(struct rc_sta_stats *rc_ss)
01901 {
01902 uint16_t i;
01903
01904
01905 for (i = 0; i < rc_ss->no_samples; i++)
01906 {
01907 struct rc_rate_stats *rc_rs = &rc_ss->rate_stats[i];
01908 rc_rs->rate_config = 0xFFFF;
01909 rc_rs->attempts = 0;
01910 rc_rs->success = 0;
01911 rc_rs->probability = 0;
01912 rc_rs->sample_skipped = 0;
01913 rc_rs->old_prob_available = 0;
01914 rc_rs->rate_allowed = 1;
01915 }
01916
01917
01918 rc_ss->rate_stats[0].rate_config = rc_get_lowest_rate_config(rc_ss);
01919
01920
01921 rc_ss->rate_stats[rc_ss->no_samples - 1].rate_config = rc_get_initial_rate_config(rc_ss);
01922
01923 for (i = 1; i < (rc_ss->no_samples - 1);)
01924 {
01925
01926 uint16_t tmp_rate = rc_new_random_rate(rc_ss);
01927
01928 if (!rc_check_rate_duplicated(rc_ss, tmp_rate))
01929 {
01930 rc_ss->rate_stats[i].rate_config = tmp_rate;
01931 i++;
01932 }
01933 }
01934 #if NX_DEBUG
01935 rc_check_stats_rate_config(rc_ss);
01936 #endif
01937 }
01938
01950 static void rc_init_rates(uint8_t sta_idx)
01951 {
01952 struct sta_info_tag *sta = &sta_info_tab[sta_idx];
01953 struct sta_pol_tbl_cntl *pt = &sta->pol_tbl;
01954 struct rc_sta_stats *rc_ss = pt->sta_stats;
01955 ASSERT_ERR(rc_ss != NULL);
01956 uint16_t i;
01957
01958
01959 rc_set_rate_configs(rc_ss);
01960
01961
01962 for (i = 0; i < (RATE_CONTROL_STEPS-1); i++)
01963 {
01964 rc_ss->retry_step_idx[i] = (rc_ss->no_samples - 1) - i;
01965 }
01966
01967 rc_ss->retry_step_idx[RATE_CONTROL_STEPS-1] = 0;
01968
01969 rc_ss->avg_ampdu_len = RC_FRAC(1, 1);
01970
01971 rc_ss->fixed_rate_cfg = RC_FIXED_RATE_NOT_SET;
01972
01973 rc_ss->info = 0;
01974
01975 rc_update_stats(rc_ss, 1);
01976
01977 rc_ss->sample_wait = 5;
01978
01979 rc_ss->trial_idx = rc_ss->no_samples - RATE_CONTROL_STEPS;
01980
01981 rc_ss->trial_status = RC_TRIAL_STATUS_WAIT;
01982 }
01983
01984 #if NX_AMSDU_TX
01985
01991 static void rc_set_max_amsdu_len(struct rc_sta_stats *rc_ss)
01992 {
01993 uint8_t step_0_idx = rc_ss->retry_step_idx[rc_ss->sw_retry_step];
01994 uint16_t rate_config = rc_ss->rate_stats[step_0_idx].rate_config;
01995 uint16_t max_amsdu_size = 0;
01996
01997
01998 if (rc_get_mcs_index(rate_config) >= 5)
01999 {
02000
02001
02002
02003
02004 if (rc_ss->no_ss == 0)
02005 {
02006 max_amsdu_size = 4;
02007 }
02008 else if (rc_ss->no_ss == 1)
02009 {
02010 max_amsdu_size = 6;
02011 }
02012 else
02013 {
02014 max_amsdu_size = 6;
02015 }
02016 }
02017 else
02018 {
02019 max_amsdu_size = 0;
02020 }
02021 rc_ss->curr_amsdu_len = co_min(rc_ss->max_amsdu_len, max_amsdu_size*1550);
02022 }
02023 #endif //NX_AMSDU_TX
02024
02025 #if NX_AMPDU_TX
02026
02038 static void rc_set_aggregation_flag(struct rc_sta_stats *rc_ss, bool *tx_ampdu)
02039 {
02040 bool agg_enabled = 1;
02041
02042
02043 do
02044 {
02045
02046 if (rc_ss->r_idx_min > HW_RATE_54MBPS)
02047 {
02048 break;
02049 }
02050
02051 uint16_t rate_0 = rc_ss->rate_stats[rc_ss->retry_step_idx[0]].rate_config;
02052 uint16_t rate_1 = rc_ss->rate_stats[rc_ss->retry_step_idx[1]].rate_config;
02053 uint16_t rate_2 = rc_ss->rate_stats[rc_ss->retry_step_idx[2]].rate_config;
02054 if (rc_get_format_mod(rate_0) < FORMATMOD_HT_MF ||
02055 rc_get_format_mod(rate_1) < FORMATMOD_HT_MF ||
02056 rc_get_format_mod(rate_2) < FORMATMOD_HT_MF)
02057 {
02058 agg_enabled = 0;
02059 break;
02060 }
02061
02062 if (rc_ss->info & RC_FIX_RATE_EN_MASK)
02063 {
02064 break;
02065 }
02066
02067
02068 uint8_t step_0 = rc_ss->sw_retry_step;
02069 uint16_t step_0_idx = rc_ss->retry_step_idx[step_0];
02070 struct rc_rate_stats *stats_step_0 = &rc_ss->rate_stats[step_0_idx];
02071 uint8_t step_0_mcs = rc_get_mcs_index(stats_step_0->rate_config);
02072 uint8_t step_0_nss = rc_get_nss(stats_step_0->rate_config);
02073 if (((step_0_mcs <= 2) &&
02074 (step_0_nss == 0) &&
02075 (stats_step_0->probability < RC_FRAC(10, 100))) ||
02076 (stats_step_0->probability < RC_FRAC(1, 100)))
02077 {
02078 agg_enabled = 0;
02079 }
02080 } while (0);
02081
02082 rc_ss->info &= ~RC_AGG_ALLOWED_MASK;
02083 rc_ss->info |= (agg_enabled << RC_AGG_ALLOWED_OFT);
02084
02085 if (tx_ampdu != NULL)
02086 *tx_ampdu = agg_enabled;
02087 }
02088 #endif //NX_AMPDU_TX
02089
02100 static bool rc_update_stats_fixed_rate(struct rc_sta_stats *rc_ss)
02101 {
02102 bool update_requested = 0;
02103 uint16_t i = 0;
02104
02105
02106 if (rc_ss->info & RC_FIX_RATE_REQ_MASK)
02107 {
02108 uint8_t idx = 0;
02109
02110 while (idx < rc_ss->no_samples)
02111 {
02112 if (rc_ss->fixed_rate_cfg == rc_ss->rate_stats[idx].rate_config)
02113 {
02114 break;
02115 }
02116 idx++;
02117 }
02118
02119 if (idx == rc_ss->no_samples)
02120 {
02121 idx = rc_ss->no_samples - 1;
02122 rc_ss->rate_stats[idx].rate_config = rc_ss->fixed_rate_cfg;
02123 rc_ss->rate_stats[idx].probability = 0;
02124 }
02125
02126 for (i = 0; i < 3; i++)
02127 {
02128 rc_ss->retry_step_idx[i] = idx;
02129 }
02130
02131 for (i = 0; i < rc_ss->no_samples; i++)
02132 {
02133 rc_ss->rate_stats[i].attempts = 0;
02134 rc_ss->rate_stats[i].success = 0;
02135 }
02136
02137 rc_ss->trial_status = RC_TRIAL_STATUS_WAIT;
02138
02139 rc_ss->info &= ~RC_FIX_RATE_STATUS_MASK;
02140 rc_ss->info |= RC_FIX_RATE_EN_MASK;
02141 update_requested = 1;
02142 }
02143
02144 else
02145 {
02146 uint8_t step_0_idx = rc_ss->retry_step_idx[0];
02147 struct rc_rate_stats *rc_rs = &rc_ss->rate_stats[step_0_idx];
02148
02149 rc_calc_prob_ewma(rc_rs);
02150
02151 for (i = 0; i < rc_ss->no_samples; i++)
02152 {
02153 rc_ss->rate_stats[i].attempts = 0;
02154 rc_ss->rate_stats[i].success = 0;
02155 }
02156 }
02157
02158 return update_requested;
02159 }
02160
02172 static void rc_update_counters(struct txdesc *txdesc, uint32_t attempts,
02173 uint32_t failures, bool tx_ampdu)
02174 {
02175 uint8_t sta_idx = txdesc->host.staid;
02176 bool trial_tx;
02177 #if NX_HE
02178 bool he_tb = false;
02179 #endif
02180 struct sta_info_tag *sta;
02181 struct sta_pol_tbl_cntl *rc;
02182 struct rc_sta_stats *rc_ss;
02183
02184 if (sta_idx >= NX_REMOTE_STA_MAX)
02185 return;
02186
02187 trial_tx = ((txdesc->host.flags & TXU_CNTRL_RC_TRIAL) == TXU_CNTRL_RC_TRIAL);
02188 #if NX_HE
02189 he_tb = (txdesc->lmac.hw_desc->thd.statinfo & HE_TB_TX_BIT) != 0;
02190 #endif
02191 sta = &sta_info_tab[sta_idx];
02192 if (sta->inst_nbr == 0xFF)
02193 return;
02194
02195 rc = &sta->pol_tbl;
02196 rc_ss = rc->sta_stats;
02197 ASSERT_ERR(rc_ss != NULL);
02198
02199
02200
02201
02202
02203 if ((RC_CONTROL_GET(txdesc->umac.rc_control, RETRY_CHAIN_VER) != rc_ss->retry_chain_ver)
02204 #if NX_HE
02205 && !he_tb
02206 #endif
02207 )
02208 {
02209 if (trial_tx)
02210 rc_ss->trial_status = RC_TRIAL_STATUS_WAIT;
02211 return;
02212 }
02213
02214 PROF_RC_UPD_COUNTERS_SET();
02215
02216
02217 rc_ss->ampdu_packets += 1;
02218
02219 #if NX_AMPDU_TX
02220 if (tx_ampdu)
02221 {
02222 struct rc_rate_stats *rc_rs;
02223
02224 rc_ss->ampdu_len += attempts;
02225 #if NX_HE
02226 if (he_tb)
02227 {
02228 rc_rs = &rc_ss->rate_stats[RC_HE_STATS_IDX];
02229 }
02230 else
02231 #endif
02232
02233 if (trial_tx)
02234 {
02235 PROF_RC_UPD_COUNTERS_TRIAL_SET();
02236
02237 rc_rs = &rc_ss->rate_stats[rc_ss->trial_idx];
02238 rc_ss->trial_status = RC_TRIAL_STATUS_WAIT;
02239 PROF_RC_UPD_COUNTERS_TRIAL_CLR();
02240 }
02241 else
02242 {
02243
02244 uint8_t retry_step = RC_CONTROL_GET(txdesc->umac.rc_control, SW_RETRY_STEP);
02245 uint16_t step_0_idx = rc_ss->retry_step_idx[retry_step];
02246 rc_rs = &rc_ss->rate_stats[step_0_idx];
02247
02248
02249
02250
02251
02252 if ((2 * failures) > attempts)
02253 {
02254 PROF_RC_SW_RETRY_SET();
02255 if (rc_ss->sw_retry_step < 2)
02256 rc_ss->sw_retry_step++;
02257 else if (rc_ss->sw_retry_step == 2)
02258
02259 rc_ss->last_rc_time -= (RC_PERIOD_TOUT * 3) / 4;
02260 PROF_RC_SW_RETRY_CLR();
02261 }
02262 else if (rc_ss->sw_retry_step)
02263 {
02264
02265 rc_ss->sw_retry_step--;
02266 }
02267 }
02268 rc_rs->attempts += attempts;
02269 rc_rs->success += (attempts - failures);
02270 ASSERT_ERR(rc_rs->attempts >= rc_rs->success);
02271 }
02272 else
02273 #endif
02274 {
02275
02276 rc_ss->ampdu_len += 1;
02277 #if NX_HE
02278 if (he_tb)
02279 {
02280 struct rc_rate_stats *rc_rs = &rc_ss->rate_stats[RC_HE_STATS_IDX];
02281 rc_rs->attempts += attempts;
02282 rc_rs->success += (attempts - failures);
02283 }
02284 else
02285 #endif
02286
02287 if (trial_tx)
02288 {
02289 PROF_RC_UPD_COUNTERS_TRIAL_SET();
02290
02291 for (uint32_t i = 0; (i < RATE_CONTROL_STEPS) && (attempts > 0); i++)
02292 {
02293 uint16_t rate_idx;
02294 struct rc_rate_stats *rc_rs;
02295 if (i == 0)
02296 rate_idx = rc_ss->trial_idx;
02297 else if (i == 1)
02298 rate_idx = rc_ss->retry_step_idx[0];
02299 else
02300 rate_idx = rc_ss->retry_step_idx[i];
02301
02302 rc_rs = &rc_ss->rate_stats[rate_idx];
02303 if (failures >= RC_MAX_NUM_RETRY)
02304 {
02305 rc_rs->attempts += RC_MAX_NUM_RETRY;
02306 attempts -= RC_MAX_NUM_RETRY;
02307 failures -= RC_MAX_NUM_RETRY;
02308 }
02309 else
02310 {
02311 rc_rs->attempts += attempts;
02312 rc_rs->success += (attempts - failures);
02313 attempts = 0;
02314 failures = 0;
02315 }
02316 ASSERT_ERR(rc_rs->attempts >= rc_rs->success);
02317 }
02318 rc_ss->trial_status = RC_TRIAL_STATUS_WAIT;
02319 PROF_RC_UPD_COUNTERS_TRIAL_CLR();
02320 }
02321 else
02322 {
02323
02324 for (uint32_t i = 0; (i < RATE_CONTROL_STEPS) && (attempts > 0); i++)
02325 {
02326 uint16_t rate_idx = rc_ss->retry_step_idx[i];
02327 struct rc_rate_stats *rc_rs = &rc_ss->rate_stats[rate_idx];
02328 if (failures >= RC_MAX_NUM_RETRY)
02329 {
02330 rc_rs->attempts += RC_MAX_NUM_RETRY;
02331 attempts -= RC_MAX_NUM_RETRY;
02332 failures -= RC_MAX_NUM_RETRY;
02333 }
02334 else
02335 {
02336 rc_rs->attempts += attempts;
02337 rc_rs->success += (attempts - failures);
02338 attempts = 0;
02339 failures = 0;
02340 }
02341 ASSERT_ERR(rc_rs->attempts >= rc_rs->success);
02342 }
02343 }
02344 }
02345 PROF_RC_UPD_COUNTERS_CLR();
02346 }
02347
02348
02349
02350
02351
02352 void rc_cfm_singleton(struct txdesc *txdesc)
02353 {
02354
02355 struct tx_cfm_tag *cfm = txl_cfm_tag_get(txdesc);
02356 uint32_t status = cfm->status;
02357 uint32_t retry_cnt = ((status & NUM_MPDU_RETRIES_MSK) >> NUM_MPDU_RETRIES_OFT);
02358 uint32_t trials;
02359 uint32_t failures;
02360
02361
02362 trials = retry_cnt + 1;
02363 failures = retry_cnt + ((status & RETRY_LIMIT_REACHED_BIT) != 0);
02364
02365
02366 rc_update_counters(txdesc, trials, failures, 0);
02367 }
02368
02369 void rc_cfm_ampdu(struct txdesc *txdesc, uint32_t txed, uint32_t txok)
02370 {
02371
02372 rc_update_counters(txdesc, txed, (txed - txok), 1);
02373 }
02374
02375 void rc_check(struct txdesc *txdesc)
02376 {
02377 struct hostdesc *host = &txdesc->host;
02378 uint8_t sta_idx = host->staid;
02379 struct sta_info_tag *sta;
02380 struct sta_pol_tbl_cntl *rc;
02381 struct rc_sta_stats *rc_ss;
02382 bool update = false;
02383 #if NX_AMPDU_TX
02384 bool tx_ampdu;
02385 #endif
02386
02387 if (sta_idx >= NX_REMOTE_STA_MAX)
02388 {
02389 txdesc->umac.rc_control = 0;
02390 return;
02391 }
02392
02393 sta = &sta_info_tab[sta_idx];
02394 rc = &sta->pol_tbl;
02395 rc_ss = rc->sta_stats;
02396 ASSERT_ERR(rc_ss != NULL);
02397
02398 #if NX_AMPDU_TX
02399 tx_ampdu = (txdesc->umac.flags & AMPDU_BIT) ? true : false;
02400
02401 if (((rc_ss->info & RC_AGG_ALLOWED_MASK) == 0) || !tx_ampdu)
02402 {
02403 rc_ss->info &= ~RC_AGG_TX_MASK;
02404 }
02405 else
02406 {
02407 rc_ss->info |= RC_AGG_TX_MASK;
02408 }
02409 #endif
02410
02411
02412 if (hal_machw_time_past(rc_ss->last_rc_time + RC_PERIOD_TOUT))
02413 {
02414 PROF_RC_STATS_CALC_SET();
02415
02416 update |= rc_update_stats(rc_ss, 0);
02417
02418 rc_ss->trial_status = RC_TRIAL_STATUS_WAIT;
02419
02420 rc_ss->sw_retry_step = 0;
02421
02422 rc_ss->retry_chain_ver = (rc_ss->retry_chain_ver + 1) % 4;
02423
02424 rc_ss->last_rc_time = hal_machw_time();
02425
02426 PROF_RC_STATS_CALC_CLR();
02427 }
02428
02429 txdesc->umac.rc_control = rc_ss->retry_chain_ver << RC_RETRY_CHAIN_VER_OFT;
02430 #if NX_AMPDU_TX
02431 txdesc->umac.rc_control |= rc_ss->sw_retry_step << RC_SW_RETRY_STEP_OFT;
02432 #endif
02433
02434 if (update)
02435 {
02436 #if NX_AMSDU_TX
02437
02438 rc_set_max_amsdu_len(rc_ss);
02439 #endif
02440 #if NX_AMPDU_TX
02441 rc_set_aggregation_flag(rc_ss, &tx_ampdu);
02442 if (!tx_ampdu)
02443 {
02444 txdesc->umac.flags &= ~AMPDU_BIT;
02445 }
02446 #endif
02447
02448 rc->upd_field |= CO_BIT(STA_MGMT_POL_UPD_RATE);
02449 }
02450
02451
02452 if (rc_check_trial_tx(rc_ss))
02453 {
02454 txdesc->host.flags |= TXU_CNTRL_RC_TRIAL;
02455 #if NX_AMPDU_TX
02456 txdesc->umac.rc_control &= ~RC_SW_RETRY_STEP_MSK;
02457 if (tx_ampdu)
02458 txdesc->umac.flags |= WHICHDESC_AMPDU_FIRST;
02459 #endif
02460
02461 rc->upd_field |= CO_BIT(STA_MGMT_POL_TRIAL_RATE);
02462 }
02463 }
02464
02465 void rc_init(struct sta_info_tag *sta)
02466 {
02467 struct sta_pol_tbl_cntl *rc = &sta->pol_tbl;
02468 struct tx_policy_tbl *pol = &rc->buf_ctrl->policy_tbl;
02469 uint8_t hw_key_idx = MM_STA_TO_KEY(sta->staid);
02470
02471
02472 ASSERT_ERR(sta->staid < NX_REMOTE_STA_MAX);
02473 rc->sta_stats = &sta_stats[sta->staid];
02474 ASSERT_ERR(rc->sta_stats != NULL);
02475
02476 struct rc_sta_stats *rc_ss = rc->sta_stats;
02477 uint32_t phy_cntrl_info1 = phy_get_ntx() << NX_TX_PT_OFT;
02478 uint32_t phy_cntrl_info2 = TX_NTX_2_ANTENNA_SET(phy_get_ntx());
02479 int i;
02480
02481 memset(rc_ss, 0, sizeof(*rc_ss));
02482
02483
02484
02485
02486
02487
02488
02489 if (STA_CAPA(sta, HT))
02490 {
02491 struct mac_htcapability *htcap = &sta->info.ht_cap;
02492 uint16_t max_mpdu_head_tail = MAC_LONG_QOS_HTC_MAC_HDR_LEN + MAC_FCS_LEN;
02493 #if RW_WAPI_EN
02494 max_mpdu_head_tail += WPI_IV_LEN + WPI_MIC_LEN;
02495 #else
02496 max_mpdu_head_tail += IV_LEN + EIV_LEN + MIC_LEN + ICV_LEN;
02497 #endif
02498
02499
02500 rc_ss->rate_map_l = me_legacy_rate_bitfield_build(&sta->info.rate_set, false);
02501 #if NX_HE
02502 if (STA_CAPA(sta, HE))
02503 {
02504 struct mac_hecapability *hecap = &sta->info.he_cap;
02505 struct mac_hecapability *hecaploc = &me_env.he_cap;
02506 uint8_t color = 0;
02507 struct vif_info_tag *vif = &vif_info_tab[sta->inst_nbr];
02508 struct me_bss_info *bss = &vif->bss_info;
02509
02510 rc_ss->format_mod = FORMATMOD_HE_SU;
02511 rc_ss->no_ss = co_min(me_11ac_nss_max(hecap->mcs_supp.rx_mcs_80),
02512 me_11ac_nss_max(hecaploc->mcs_supp.tx_mcs_80));
02513 ASSERT_ERR(rc_ss->no_ss < 8);
02514
02515 rc_ss->rate_map.he = me_rate_bitfield_vht_build(hecap->mcs_supp.rx_mcs_80,
02516 hecaploc->mcs_supp.tx_mcs_80);
02517 rc_ss->mcs_max = co_min(me_11ax_mcs_max(hecap->mcs_supp.rx_mcs_80),
02518 me_11ax_mcs_max(hecaploc->mcs_supp.tx_mcs_80));
02519 ASSERT_ERR(rc_ss->mcs_max < 12);
02520
02521 rc_ss->rate_map_l = rc_ss->rate_map_l & ~0xFF0;
02522 rc_ss->r_idx_min = me_legacy_ridx_min(rc_ss->rate_map_l);
02523 ASSERT_ERR((rc_ss->r_idx_min <= HW_RATE_11MBPS) || (rc_ss->r_idx_min == MAC_RATESET_LEN));
02524 rc_ss->r_idx_max = me_legacy_ridx_max(rc_ss->rate_map_l);
02525 ASSERT_ERR((rc_ss->r_idx_max <= HW_RATE_11MBPS) || (rc_ss->r_idx_max == MAC_RATESET_LEN));
02526 rc_ss->type = (rc->ppdu_tx_cfg & PRE_TYPE_TX_RCX_MASK) >> PRE_TYPE_TX_RCX_OFT;
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536 if (phy_ldpc_tx_supported() &&
02537 HE_PHY_CAPA_BIT_IS_SET(hecaploc, LDPC_CODING_IN_PAYLOAD) &&
02538 HE_PHY_CAPA_BIT_IS_SET(hecap, LDPC_CODING_IN_PAYLOAD))
02539 {
02540 phy_cntrl_info1 |= FEC_CODING_PT_BIT;
02541 }
02542
02543
02544 if (STA_CAPA(sta, VHT))
02545 {
02546 struct mac_vhtcapability *vhtcap = &sta->info.vht_cap;
02547 switch (vhtcap->vht_capa_info & MAC_VHTCAPA_MAX_MPDU_LENGTH_MSK)
02548 {
02549 case MAC_VHTCAPA_MAX_MPDU_LENGTH_3895:
02550 rc_ss->max_amsdu_len = 3895 - max_mpdu_head_tail;
02551 break;
02552 case MAC_VHTCAPA_MAX_MPDU_LENGTH_7991:
02553 rc_ss->max_amsdu_len = 7991 - max_mpdu_head_tail;
02554 break;
02555 case MAC_VHTCAPA_MAX_MPDU_LENGTH_11454:
02556 rc_ss->max_amsdu_len = 11454 - max_mpdu_head_tail;
02557 break;
02558 default:
02559 rc_ss->max_amsdu_len = 3895 - max_mpdu_head_tail;
02560 break;
02561 }
02562 }
02563 else
02564 {
02565 if (htcap->ht_capa_info & MAC_HTCAPA_AMSDU)
02566 {
02567 rc_ss->max_amsdu_len = 7935;
02568 }
02569 else
02570 {
02571 rc_ss->max_amsdu_len = 3839;
02572 }
02573 }
02574
02575 if (!(bss->he_oper & MAC_HE_OPER_BSS_COLOR_DISABLED_BIT))
02576 color = (bss->he_oper & MAC_HE_OPER_BSS_COLOR_MASK) >>
02577 MAC_HE_OPER_BSS_COLOR_OFT;
02578 phy_cntrl_info2 |= BMCHANGE_BIT | UPLINK_FLAG_BIT | (color << BSS_COLOR_OFT) |
02579 (4 << PKT_EXTENSION_OFT);
02580 }
02581 else
02582 #endif
02583 #if NX_VHT
02584 if (STA_CAPA(sta, VHT))
02585 {
02586 struct mac_vhtcapability *vhtcap = &sta->info.vht_cap;
02587 struct mac_vhtcapability *vhtcaploc = &me_env.vht_cap;
02588
02589 rc_ss->format_mod = FORMATMOD_VHT;
02590 rc_ss->no_ss = co_min(me_11ac_nss_max(vhtcap->rx_mcs_map),
02591 me_11ac_nss_max(vhtcaploc->tx_mcs_map));
02592 ASSERT_ERR(rc_ss->no_ss < 8);
02593
02594 rc_ss->rate_map.vht = me_rate_bitfield_vht_build(vhtcap->rx_mcs_map,
02595 vhtcaploc->tx_mcs_map);
02596 rc_ss->mcs_max = co_min(me_11ac_mcs_max(vhtcap->rx_mcs_map),
02597 me_11ac_mcs_max(vhtcaploc->tx_mcs_map));
02598 ASSERT_ERR(rc_ss->mcs_max < 10);
02599
02600 rc_ss->type = 0;
02601
02602 rc_ss->rate_map_l = 0;
02603 rc_ss->r_idx_min = me_legacy_ridx_min(rc_ss->rate_map_l);
02604 rc_ss->r_idx_max = me_legacy_ridx_max(rc_ss->rate_map_l);
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614 if (phy_ldpc_tx_supported() &&
02615 (vhtcaploc->vht_capa_info & MAC_VHTCAPA_RXLDPC) &&
02616 (vhtcap->vht_capa_info & MAC_VHTCAPA_RXLDPC))
02617 {
02618 phy_cntrl_info1 |= FEC_CODING_PT_BIT;
02619 }
02620
02621 switch (vhtcap->vht_capa_info & MAC_VHTCAPA_MAX_MPDU_LENGTH_MSK)
02622 {
02623 case MAC_VHTCAPA_MAX_MPDU_LENGTH_3895:
02624 rc_ss->max_amsdu_len = 3895 - max_mpdu_head_tail;
02625 break;
02626 case MAC_VHTCAPA_MAX_MPDU_LENGTH_7991:
02627 rc_ss->max_amsdu_len = 7991 - max_mpdu_head_tail;
02628 break;
02629 case MAC_VHTCAPA_MAX_MPDU_LENGTH_11454:
02630 rc_ss->max_amsdu_len = 11454 - max_mpdu_head_tail;
02631 break;
02632 default:
02633 rc_ss->max_amsdu_len = 3895 - max_mpdu_head_tail;
02634 break;
02635 }
02636 }
02637 else
02638 #endif
02639 {
02640 struct mac_htcapability *htcaploc = &me_env.ht_cap;
02641
02642 rc_ss->format_mod = FORMATMOD_HT_MF;
02643 rc_ss->no_ss = co_min(me_11n_nss_max(htcap->mcs_rate),
02644 me_11n_nss_max(htcaploc->mcs_rate));
02645 ASSERT_ERR(rc_ss->no_ss <= 3);
02646
02647 memcpy(rc_ss->rate_map.ht, htcap->mcs_rate, sizeof(rc_ss->rate_map.ht));
02648
02649 rc_ss->rate_map.ht[0] = 0xFF;
02650 rc_ss->mcs_max = 7;
02651
02652
02653
02654 rc_ss->rate_map_l = rc_ss->rate_map_l & ~0xFF0;
02655 rc_ss->r_idx_min = me_legacy_ridx_min(rc_ss->rate_map_l);
02656 ASSERT_ERR((rc_ss->r_idx_min <= HW_RATE_11MBPS) || (rc_ss->r_idx_min == MAC_RATESET_LEN));
02657 rc_ss->r_idx_max = me_legacy_ridx_max(rc_ss->rate_map_l);
02658 ASSERT_ERR((rc_ss->r_idx_max <= HW_RATE_11MBPS) || (rc_ss->r_idx_max == MAC_RATESET_LEN));
02659 rc_ss->type = (rc->ppdu_tx_cfg & PRE_TYPE_TX_RCX_MASK) >> PRE_TYPE_TX_RCX_OFT;
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669 if (phy_ldpc_tx_supported() &&
02670 (htcaploc->ht_capa_info & MAC_HTCAPA_LDPC) &&
02671 (htcap->ht_capa_info & MAC_HTCAPA_LDPC))
02672 {
02673 phy_cntrl_info1 |= FEC_CODING_PT_BIT;
02674 }
02675 if (htcap->ht_capa_info & MAC_HTCAPA_AMSDU)
02676 {
02677 #if NX_AMPDU_TX
02678 rc_ss->max_amsdu_len = 4095 - max_mpdu_head_tail;
02679 #else
02680 rc_ss->max_amsdu_len = 7935;
02681 #endif
02682 }
02683 else
02684 {
02685 rc_ss->max_amsdu_len = 3839;
02686 }
02687 }
02688
02689 rc_ss->bw_max = sta->info.bw_cur;
02690 ASSERT_ERR(rc_ss->bw_max <= BW_160MHZ);
02691
02692 switch(sta->info.bw_cur)
02693 {
02694 case BW_20MHZ:
02695 if (htcap->ht_capa_info & MAC_HTCAPA_SHORTGI_20)
02696 rc_ss->short_gi = 1;
02697 break;
02698 case BW_40MHZ:
02699 if (htcap->ht_capa_info & MAC_HTCAPA_SHORTGI_40)
02700 rc_ss->short_gi = 1;
02701 break;
02702 #if NX_VHT
02703 case BW_80MHZ:
02704 if (sta->info.vht_cap.vht_capa_info & MAC_VHTCAPA_SHORT_GI_80)
02705 rc_ss->short_gi = 1;
02706 break;
02707 case BW_160MHZ:
02708 if (sta->info.vht_cap.vht_capa_info & MAC_VHTCAPA_SHORT_GI_160)
02709 rc_ss->short_gi = 1;
02710 break;
02711 #endif
02712 default:
02713 break;
02714 }
02715 }
02716 else
02717 {
02718
02719 rc_ss->rate_map_l = me_legacy_rate_bitfield_build(&sta->info.rate_set, false);
02720 rc_ss->r_idx_min = me_legacy_ridx_min(rc_ss->rate_map_l);
02721 ASSERT_ERR(rc_ss->r_idx_min < MAC_RATESET_LEN);
02722 rc_ss->r_idx_max = me_legacy_ridx_max(rc_ss->rate_map_l);
02723 ASSERT_ERR(rc_ss->r_idx_max < MAC_RATESET_LEN);
02724 rc_ss->mcs_max = 0xFF;
02725 rc_ss->bw_max = sta->info.bw_cur;
02726 ASSERT_ERR(rc_ss->bw_max == BW_20MHZ);
02727
02728 rc_ss->type = (rc->ppdu_tx_cfg & PRE_TYPE_TX_RCX_MASK) >> PRE_TYPE_TX_RCX_OFT;
02729 }
02730
02731 rc_ss->no_samples = rc_get_num_samples(rc_ss);
02732 ASSERT_ERR(rc_ss->no_samples >= 1);
02733 ASSERT_ERR(rc_ss->no_samples <= RC_MAX_N_SAMPLE);
02734
02735 dbg(D_CRT "%s: station_id=%i format_mod=%i pre_type=%i short_gi=%i max_bw=%i\n",
02736 __func__, sta->staid, rc_ss->format_mod, rc_ss->type, rc_ss->short_gi, rc_ss->bw_max);
02737 dbg(D_CRT "%s: nss_max=%i mcs_max=%i r_idx_min=%i r_idx_max=%i no_samples=%i\n",
02738 __func__, rc_ss->no_ss, rc_ss->mcs_max, rc_ss->r_idx_min, rc_ss->r_idx_max, rc_ss->no_samples);
02739
02740
02741 rc_init_rates(sta->staid);
02742
02743
02744 for (i = 0; i < RATE_CONTROL_STEPS; i++)
02745 {
02746 uint8_t idx = rc_ss->retry_step_idx[i];
02747 pol->ratecntrlinfo[i] =
02748 (RC_MAX_NUM_RETRY << N_RETRY_RCX_OFT) | rc_ss->rate_stats[idx].rate_config;
02749 }
02750
02751 #if NX_AMSDU_TX
02752
02753 rc_set_max_amsdu_len(rc_ss);
02754 #endif
02755 #if NX_AMPDU_TX
02756 rc_set_aggregation_flag(rc_ss, NULL);
02757 #endif
02758
02759
02760 rc_ss->last_rc_time = hal_machw_time();
02761
02762 pol->upatterntx = POLICY_TABLE_PATTERN;
02763 pol->maccntrlinfo1 = hw_key_idx << KEYSRAM_INDEX_RA_OFT;
02764 pol->maccntrlinfo2 = 0xFFFF0704;
02765 pol->phycntrlinfo1 = phy_cntrl_info1;
02766 pol->phycntrlinfo2 = phy_cntrl_info2;
02767 #if RW_BFMER_EN
02768 if (bfr_is_enabled())
02769 {
02770
02771
02772
02773
02774
02775
02776 pol->phycntrlinfo2 |= 2 << SMM_INDEX_PT_OFT;
02777 }
02778 #endif
02779 rc->buf_ctrl->mac_control_info = EXPECTED_ACK_NORMAL_ACK | LOW_RATE_RETRY;
02780 rc->buf_ctrl->phy_control_info = sta->paid_gid;
02781
02782
02783 rc->upd_field |= CO_BIT(STA_MGMT_POL_UPD_RATE) | CO_BIT(STA_MGMT_POL_UPD_TX_POWER);
02784 }
02785
02786
02787 uint32_t rc_get_duration(struct rc_rate_stats *rate_stats)
02788 {
02789 uint32_t duration = 0;
02790 uint32_t idx;
02791 uint16_t rate_config = rate_stats->rate_config;
02792 uint8_t format_mod = rc_get_format_mod(rate_config);
02793 uint8_t mcs = rc_get_mcs_index(rate_config);
02794
02795 switch (format_mod)
02796 {
02797 case FORMATMOD_NON_HT:
02798 case FORMATMOD_NON_HT_DUP_OFDM:
02799 {
02800 if (mcs < HW_RATE_6MBPS)
02801 {
02802 uint8_t pre_type = rc_get_pre_type(rate_config);
02803 idx = (uint32_t)(mcs << 1) | pre_type;
02804 duration = rc_duration_cck[idx];
02805 }
02806 else
02807 {
02808 idx = (mcs - HW_RATE_6MBPS);
02809 duration = rc_duration_non_ht[idx];
02810 }
02811 } break;
02812
02813 case FORMATMOD_HT_MF:
02814 case FORMATMOD_HT_GF:
02815 #if NX_VHT
02816 case FORMATMOD_VHT:
02817 #endif
02818 {
02819 uint8_t bw = rc_get_bw(rate_config);
02820 uint8_t gi = rc_get_sgi(rate_config);
02821 idx = (mcs << 3) | (bw << 1) | gi;
02822 duration = rc_duration_ht_ampdu[idx] / (rc_get_nss(rate_config) + 1);
02823 } break;
02824
02825 #if NX_HE
02826 case FORMATMOD_HE_MU:
02827 {
02828 uint8_t ru_size = rate_stats->ru_and_length & 0x07;
02829 if (ru_size < 3)
02830 {
02831 duration = rc_ru_duration[ru_size][mcs * 3 + rc_get_he_gi(rate_config)] /
02832 (rc_get_nss(rate_config) + 1);
02833 }
02834 else
02835 {
02836 uint8_t bw = ru_size - 3;
02837 uint8_t gi = rc_get_he_gi(rate_config);
02838 int shift = bw & 0x01;
02839 idx = (mcs * 6) + ((bw >> 1) * 3) + gi;
02840 duration = (rc_duration_he_ampdu[idx] >> shift) / (rc_get_nss(rate_config) + 1);
02841 }
02842 } break;
02843
02844 case FORMATMOD_HE_SU:
02845 {
02846 uint8_t bw = rc_get_bw(rate_config);
02847 uint8_t gi = rc_get_he_gi(rate_config);
02848 int shift = bw & 0x01;
02849 idx = (mcs * 6) + ((bw >> 1) * 3) + gi;
02850 duration = (rc_duration_he_ampdu[idx] >> shift) / (rc_get_nss(rate_config) + 1);
02851 } break;
02852 #endif
02853
02854 default:
02855 break;
02856 }
02857
02858 return duration;
02859 }
02860
02861 void rc_update_sample_table(uint8_t sta_idx)
02862 {
02863 struct sta_info_tag *sta = &sta_info_tab[sta_idx];
02864 struct sta_pol_tbl_cntl *rc = &sta->pol_tbl;
02865 struct rc_sta_stats *rc_ss = rc->sta_stats;
02866 uint32_t cur_tp[RC_MAX_N_SAMPLE];
02867 ASSERT_ERR(rc_ss != NULL);
02868
02869
02870 rc_ss->no_samples = rc_get_num_samples(rc_ss);
02871 ASSERT_ERR(rc_ss->no_samples >= 1);
02872 ASSERT_ERR(rc_ss->no_samples <= RC_MAX_N_SAMPLE);
02873
02874
02875 rc_set_rate_configs(rc_ss);
02876
02877
02878 rc_update_retry_chain(rc_ss, cur_tp);
02879
02880 #if NX_AMSDU_TX
02881
02882 rc_set_max_amsdu_len(rc_ss);
02883 #endif
02884 #if NX_AMPDU_TX
02885 rc_set_aggregation_flag(rc_ss, NULL);
02886 #endif
02887
02888 rc->upd_field |= CO_BIT(STA_MGMT_POL_UPD_RATE);
02889 }
02890
02891 void rc_update_bw_nss_max(uint8_t sta_idx, uint8_t bw_max, uint8_t nss_max)
02892 {
02893 struct sta_info_tag *sta = &sta_info_tab[sta_idx];
02894 struct sta_pol_tbl_cntl *rc = &sta->pol_tbl;
02895 struct rc_sta_stats *rc_ss = rc->sta_stats;
02896 ASSERT_ERR(rc_ss != NULL);
02897
02898 if ((bw_max == rc_ss->bw_max) && (nss_max == rc_ss->no_ss))
02899 return;
02900
02901 rc_ss->bw_max = bw_max;
02902 ASSERT_ERR(rc_ss->bw_max <= BW_160MHZ);
02903 rc_ss->no_ss = nss_max;
02904 ASSERT_ERR(rc_ss->no_ss < 8);
02905
02906
02907 if (rc_ss->info & RC_FIX_RATE_EN_MASK)
02908 {
02909
02910 rc_ss->info |= RC_FIX_RATE_UPD_SS_REQ_MASK;
02911 return;
02912 }
02913
02914
02915 rc_update_sample_table(sta_idx);
02916
02917 }
02918
02919 void rc_update_preamble_type(uint8_t sta_idx, uint8_t preamble_type)
02920 {
02921 struct sta_info_tag *sta = &sta_info_tab[sta_idx];
02922 struct sta_pol_tbl_cntl *rc = &sta->pol_tbl;
02923 struct rc_sta_stats *rc_ss = rc->sta_stats;
02924 uint16_t i = 0;
02925 uint32_t cur_tp[RC_MAX_N_SAMPLE];
02926 ASSERT_ERR(rc_ss != NULL);
02927
02928 if (rc_ss->type == preamble_type)
02929 return;
02930
02931
02932 rc_ss->type = preamble_type;
02933
02934
02935 if (!preamble_type)
02936 return;
02937
02938
02939 if (rc_ss->info & RC_FIX_RATE_EN_MASK)
02940 {
02941
02942 rc_ss->info |= RC_FIX_RATE_UPD_SS_REQ_MASK;
02943 return;
02944 }
02945
02946 for (i = 0; i < rc_ss->no_samples; i++)
02947 {
02948 struct rc_rate_stats *rc_rs = &rc_ss->rate_stats[i];
02949 uint16_t rate_cfg = rc_rs->rate_config;
02950
02951
02952 if (is_cck_group(rc_rs->rate_config))
02953 {
02954
02955 rate_cfg |= PRE_TYPE_TX_RCX_MASK;
02956
02957 while (rc_check_rate_duplicated(rc_ss, rate_cfg))
02958 {
02959 rate_cfg = rc_new_random_rate(rc_ss);
02960 }
02961 }
02962
02963 rc_rs->rate_allowed = 1;
02964 rc_rs->rate_config = rate_cfg;
02965 rc_rs->probability = 0;
02966 rc_rs->old_prob_available = 0;
02967 cur_tp[i] = 0;
02968 }
02969
02970
02971 rc_sort_samples_tp(rc_ss, cur_tp);
02972
02973 rc_update_retry_chain(rc_ss, cur_tp);
02974
02975 #if NX_AMSDU_TX
02976
02977 rc_set_max_amsdu_len(rc_ss);
02978 #endif
02979
02980 rc->upd_field |= CO_BIT(STA_MGMT_POL_UPD_RATE);
02981 }
02982
02983 void rc_init_bcmc_rate(struct sta_info_tag *sta, uint8_t basic_rate_idx)
02984 {
02985 struct sta_pol_tbl_cntl *rc = &sta->pol_tbl;
02986 struct tx_policy_tbl *pol = &rc->buf_ctrl->policy_tbl;
02987 uint8_t i;
02988 uint16_t rate_config;
02989 uint8_t type = (rc->ppdu_tx_cfg & PRE_TYPE_TX_RCX_MASK) >> PRE_TYPE_TX_RCX_OFT;
02990
02991 rate_config = ((basic_rate_idx < HW_RATE_6MBPS ? type : 0) << PRE_TYPE_TX_RCX_OFT) |
02992 (basic_rate_idx << MCS_INDEX_TX_RCX_OFT);
02993
02994 for (i = 0; i < RATE_CONTROL_STEPS; i++)
02995 {
02996 pol->ratecntrlinfo[i] = (1 << N_RETRY_RCX_OFT) | rate_config;
02997 }
02998 }
02999
03000 bool rc_check_fixed_rate_config(struct rc_sta_stats *rc_ss, uint16_t fixed_rate_config)
03001 {
03002 uint8_t fixed_rate_ft = rc_get_format_mod(fixed_rate_config);
03003 bool update = 0;
03004
03005 do
03006 {
03007
03008 if (fixed_rate_ft > rc_ss->format_mod)
03009 {
03010 break;
03011 }
03012 if ((rc_ss->format_mod == FORMATMOD_HE_SU) && (fixed_rate_ft != FORMATMOD_HE_SU)
03013 && (rc_ss->r_idx_min > HW_RATE_11MBPS))
03014 {
03015 break;
03016 }
03017 if ((rc_ss->format_mod == FORMATMOD_VHT) && (fixed_rate_ft != FORMATMOD_VHT))
03018 {
03019 break;
03020 }
03021 if (((rc_ss->format_mod == FORMATMOD_HT_MF) || (rc_ss->format_mod == FORMATMOD_HT_GF)) &&
03022 ((fixed_rate_ft < FORMATMOD_HT_MF) && (rc_ss->r_idx_min > HW_RATE_11MBPS)))
03023 {
03024 break;
03025 }
03026 if (fixed_rate_ft < FORMATMOD_HT_MF)
03027 {
03028
03029 if ((rc_get_pre_type(fixed_rate_config) == 0) && (rc_ss->type == 1))
03030 {
03031 break;
03032 }
03033 }
03034 else
03035 {
03036
03037 if (fixed_rate_ft < FORMATMOD_HE_SU)
03038 {
03039 if ((rc_get_sgi(fixed_rate_config) == 1) && (rc_ss->short_gi == 0))
03040 {
03041 break;
03042 }
03043 }
03044
03045 if (rc_get_bw(fixed_rate_config) > rc_ss->bw_max)
03046 {
03047 break;
03048 }
03049
03050 if (rc_get_nss(fixed_rate_config) > rc_ss->no_ss)
03051 {
03052 break;
03053 }
03054 }
03055
03056 if (rc_check_valid_rate(rc_ss, fixed_rate_config) == 0)
03057 {
03058 break;
03059 }
03060
03061 update = 1;
03062
03063 } while (0);
03064
03065 return update;
03066 }
03067
03068 uint32_t rc_calc_tp(struct rc_sta_stats *rc_ss, uint8_t sample_idx)
03069 {
03070 uint64_t cur_tp;
03071 uint32_t nsecs = 0;
03072
03073 struct rc_rate_stats *rc_rs = &rc_ss->rate_stats[sample_idx];
03074 uint16_t rate_config = rc_rs->rate_config;
03075 uint32_t prob = rc_rs->probability;
03076 uint16_t avg_ampdu = RC_TRUNC(rc_ss->avg_ampdu_len);
03077
03078 if (prob < RC_FRAC(1, 10))
03079 {
03080 cur_tp = 0;
03081 }
03082 else
03083 {
03084 if (!is_cck_group(rate_config))
03085 {
03086
03087 uint32_t overhead = 218;
03088 if (rc_get_format_mod(rate_config) == FORMATMOD_HE_MU)
03089
03090 overhead = 330;
03091
03092 nsecs = 1000 * overhead / avg_ampdu;
03093 }
03094 nsecs += rc_get_duration(rc_rs);
03095
03096
03097
03098
03099 cur_tp = 910000 * ((prob * 1000) / nsecs);
03100 cur_tp = RC_TRUNC(cur_tp);
03101 }
03102
03103 return cur_tp;
03104 }
03105
03106 void rc_trial_check_bfm_stbc_htc(struct txl_buffer_control *buf_ctrl, uint32_t trial_rate,
03107 bool can_use_bfm, bool use_stbc, uint8_t stbc_nss,
03108 uint8_t nc, uint8_t ntx, bool can_use_htc)
03109 {
03110 uint8_t nss = 0;
03111 uint32_t trial_config = trial_rate &
03112 (MCS_INDEX_TX_RCX_MASK | BW_TX_RCX_MASK |
03113 SHORT_GI_TX_RCX_MASK | PRE_TYPE_TX_RCX_MASK |
03114 FORMAT_MOD_TX_RCX_MASK);
03115 uint32_t format = (trial_config & FORMAT_MOD_TX_RCX_MASK) >>
03116 FORMAT_MOD_TX_RCX_OFT;
03117
03118
03119 if (format >= FORMATMOD_HT_MF)
03120 {
03121 uint32_t mcs_idx = (trial_config & MCS_INDEX_TX_RCX_MASK) >>
03122 MCS_INDEX_TX_RCX_OFT;
03123 #if NX_VHT
03124 if (format == FORMATMOD_VHT)
03125 {
03126
03127 nss = (mcs_idx & VHT_NSS_MASK) >> VHT_NSS_OFT;
03128 }
03129 else
03130 #endif
03131 {
03132
03133 nss = (mcs_idx & HT_NSS_MASK) >> HT_NSS_OFT;
03134 }
03135
03136
03137 if (use_stbc && (nss == stbc_nss))
03138 {
03139 buf_ctrl->tx_flags |= TX_SWDESC_UMAC_TRIAL_STBC_BIT;
03140 }
03141 else
03142 {
03143 buf_ctrl->tx_flags &= ~TX_SWDESC_UMAC_TRIAL_STBC_BIT;
03144 }
03145
03146
03147 #if RW_BFMER_EN
03148 if (can_use_bfm)
03149 {
03150 if ((format != FORMATMOD_VHT) || (nss > nc) || (nss == ntx))
03151 {
03152 can_use_bfm = false;
03153 }
03154 }
03155 #endif //(RW_BFMER_EN)
03156 }
03157 else
03158 {
03159 #if RW_BFMER_EN
03160 can_use_bfm = false;
03161 #endif
03162 #if NX_HE
03163 can_use_htc = false;
03164 #endif
03165 }
03166
03167 #if RW_BFMER_EN
03168
03169 if (can_use_bfm)
03170 {
03171 buf_ctrl->tx_flags |= TX_SWDESC_UMAC_TRIAL_BEAMFORM_BIT;
03172 }
03173 else
03174 {
03175 buf_ctrl->tx_flags &= ~TX_SWDESC_UMAC_TRIAL_BEAMFORM_BIT;
03176 }
03177 #endif
03178
03179 #if NX_HE
03180
03181 if (can_use_htc)
03182 buf_ctrl->tx_flags |= TX_SWDESC_UMAC_TRIAL_HTC_BIT;
03183 else
03184 buf_ctrl->tx_flags &= ~TX_SWDESC_UMAC_TRIAL_HTC_BIT;
03185 #endif
03186 }
03187
03189