Files
kunlun/plc/halmac/rate/rate_control.c
2024-09-28 14:24:04 +08:00

764 lines
24 KiB
C

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
#include "rate_control.h"
#include "phy_chn.h"
#include "phy_txrx_pwr.h"
#include "hw_desc.h"
#include "mac_peer.h"
#include "mpdu_header.h"
#include "iot_io.h"
#include "hw_tonemap.h"
#include "phy_txrx_pwr.h"
#include "iot_dbglog_api.h"
#include "iot_dbglog_parser.h"
#include "phy_chn.h"
#include "os_utils_api.h"
static uint8_t mac_rate_is_special_narrow_band(uint32_t band_id)
{
switch (band_id) {
case IOT_SUPPORT_TONE_72_120:
case IOT_SUPPORT_TONE_100_230_CE:
return 1;
default:
return 0;
}
}
static uint8_t mac_rate_get_fix_rid_by_msdu_len(uint32_t proto, uint32_t bandid,
uint32_t rate_level, uint32_t msdu_len)
{
uint32_t pb_pl_136, pb_pl_520, pb_pl_264, pb_pl_72;
pb_pl_136 = mac_get_sof_pb_valid_payload_sz(proto, 136);
#if SUPPORT_IEEE_1901
pb_pl_264 = 0;
pb_pl_72 = mac_get_sof_pb_valid_payload_sz(proto, 72);
#else
pb_pl_264 = mac_get_sof_pb_valid_payload_sz(proto, 264);
#if IOT_SMART_CONFIG
pb_pl_72 = mac_get_sof_pb_valid_payload_sz(proto, 72);
#else
pb_pl_72 = 0;
#endif
#endif
pb_pl_520 = mac_get_sof_pb_valid_payload_sz(proto, 520);
/* override the fix rate table idx for avoid sending
* symbol num > 511's rate under narrow band
*/
if (mac_rate_is_special_narrow_band(bandid)) {
if (msdu_len <= pb_pl_136) {
return 2; /* 136 */
} else if (msdu_len <= pb_pl_264) {
return 7; /* 264 */
} else if (msdu_len <= pb_pl_520) {
return 10; /* 520 */
} else {
return 12; /* 1040 - 1560 - 2080 */
}
} else {
if (rate_level == PLC_RATE_ADAPT_RATE_MEDIUM) {
/* medium rate */
if (msdu_len <= pb_pl_72) {
return g_fix_mid_ra_tbl->sof_72_idx; /* 72 */
} else if (msdu_len <= pb_pl_136) {
return g_fix_mid_ra_tbl->sof_136_idx; /* 136 */
} else if (msdu_len <= pb_pl_264){
return g_fix_mid_ra_tbl->sof_264_idx; /* 264 */
} else if (msdu_len <= pb_pl_520){
return g_fix_mid_ra_tbl->sof_520_idx; /* 520 */
} else if (msdu_len <= (pb_pl_520 * 2)){
return g_fix_mid_ra_tbl->sof_1040_idx; /* 1040 */
} else if (msdu_len <= (pb_pl_520 * 3)){
return g_fix_mid_ra_tbl->sof_1560_idx; /* 1560 */
} else {
return g_fix_mid_ra_tbl->sof_2080_idx; /* 2080 */
}
} else if (rate_level == PLC_RATE_ADAPT_RATE_HIGH) {
/* high rate */
if (msdu_len <= pb_pl_72) {
return g_fix_high_ra_tbl->sof_72_idx; /* 72 */
} else if (msdu_len <= pb_pl_136) {
return g_fix_high_ra_tbl->sof_136_idx; /* 136 */
} else if (msdu_len <= pb_pl_264){
return g_fix_high_ra_tbl->sof_264_idx; /* 264 */
} else if (msdu_len <= pb_pl_520){
return g_fix_high_ra_tbl->sof_520_idx; /* 520 */
} else if (msdu_len <= (pb_pl_520 * 2)){
return g_fix_high_ra_tbl->sof_1040_idx; /* 1040 */
} else if (msdu_len <= (pb_pl_520 * 3)){
return g_fix_high_ra_tbl->sof_1560_idx; /* 1560 */
} else {
return g_fix_high_ra_tbl->sof_2080_idx; /* 2080 */
}
} else {
/* low rate */
if (msdu_len <= pb_pl_72) {
return g_fix_ra_tbl->sof_72_idx; /* 72 */
} else if (msdu_len <= pb_pl_136) {
return g_fix_ra_tbl->sof_136_idx; /* 136 */
} else if (msdu_len <= pb_pl_264){
return g_fix_ra_tbl->sof_264_idx; /* 264 */
} else if (msdu_len <= pb_pl_520){
return g_fix_ra_tbl->sof_520_idx; /* 520 */
} else if (msdu_len <= (pb_pl_520 * 2)){
return g_fix_ra_tbl->sof_1040_idx; /* 1040 */
} else if (msdu_len <= (pb_pl_520 * 3)){
return g_fix_ra_tbl->sof_1560_idx; /* 1560 */
} else {
return g_fix_ra_tbl->sof_2080_idx; /* 2080 */
}
}
}
}
uint32_t mac_rate_ctxt_init(mac_peer_t *peer)
{
if (peer == NULL) {
IOT_ASSERT(0);
return ERR_INVAL;
}
peer->rate_info.avg_snr = INVALID_SNR;
peer->rate_info.last_rx_ts = os_boot_time32();
peer->rate_info.con_no_sack_cnt = 0;
peer->rate_info.con_sack_err_cnt = 0;
peer->rate_info.tx_power = PHY_FULL_PWR_DBUV;
return ERR_OK;
}
uint32_t mac_rate_update(void *peer_in, void *arg)
{
IOT_ASSERT(peer_in && arg);
mac_peer_t *peer = (mac_peer_t*)peer_in;
rx_fc_msg_t *sack = (rx_fc_msg_t*)arg;
int8_t snr = sack->snr_in_sack;
#if (PLC_MAC_RX_DEBUG_LOG >= PLC_MAC_LOG_LEVEL_1)
iot_printf("---snr=%d,load=%d," \
"result=0x%x," \
"bitmap=0x%x," \
"dtei=0x%x," \
"stei=0x%x," \
"nid=0x%x," \
"rx_pb=0x%x," \
"peer_tei=%d," \
"peer_sub=%d," \
"peer_power=%d," \
"peer_snr=%d\n", \
sack->snr_in_sack, \
sack->load_in_sack, \
sack->result_in_sack, \
sack->bitmap_in_sack, \
sack->dst_tei, \
sack->src_tei, \
sack->nid, \
sack->pb_num, \
peer->tei, \
peer->is_sub_peer, \
peer->rate_info.tx_power, \
peer->rate_info.avg_snr);
iot_dbglog_input(PLC_MAC_RATE_MID, DBGLOG_INFO_LVL_2,
IOT_MAC_RATE_UPDATA_ID, 5, \
sack->snr_in_sack, \
sack->load_in_sack, \
peer->tei, \
peer->is_sub_peer, \
peer->rate_info.avg_snr);
#endif
#if WAR_QJWY_MUL_MPDU_ISSUE
/* war for qianjing, sack snr always equal 100 */
if (snr == WAR_QJWY_SNR_INPUT) {
snr = WAR_QJWY_SNR_OUTPUT;
}
#endif
if (snr > MAX_FD_SNR) {
/* snr is greater than MAX_FD_SNR, rewrite snr = MAX_FD_SNR */
snr = MAX_FD_SNR;
} else if (snr < MIN_FD_SNR) {
/* snr is less than MIN_FD_SNR, rewrite snr = MIN_FD_SNR */
snr = MIN_FD_SNR;
}
if (peer->rate_info.avg_snr == INVALID_SNR)
{
/* for the first time */
peer->rate_info.avg_snr = snr;
}
else if (sack->result_in_sack == 0) {
/* if all pb success */
int8_t avg = peer->rate_info.avg_snr;
avg = (avg - (avg >> 3)) + (snr >> 3);
peer->rate_info.avg_snr = avg;
}
else {
/* if at least one pb fail */
ra_inc_con_sack_err_cnt(&peer->rate_info);
}
return 0;
}
typedef enum _ra_action {
RA_ACTION_UNKOWN,
RA_ACTION_DOWN,
RA_ACTION_UP,
RA_ACTION_KEEP,
} ra_action_t;
/* rate_idx - get rate_idx of tmi or ex_tmi
* pb_num_in_mpdu - get pb_num in this mpdu
*/
uint32_t mac_data_get_rate(mac_vdev_t *vdev, mac_peer_t *peer,
uint32_t proto, uint8_t is_fixed_rate, uint32_t msdu_len,
uint32_t single_proto_band, uint32_t is_fixed_pbsz,
uint8_t *rate_idx,
uint32_t *pb_num_in_each_mpdu,
uint32_t *mpdu_num_to_send, uint32_t *rate_mode, uint8_t retry_cnt)
{
uint32_t tmi, ext_tmi;
uint32_t sym_ppb;
uint32_t fl_ppb, fl_ms=0;
uint32_t max_fl_limitation;
(void)vdev;
/* default value */
*mpdu_num_to_send = 4;
*rate_mode = 0; /* 0: SR, 1:QR, 2:XR, 3: FSK */
#if PLC_MAC_RA_DEBUG_LOG >= PLC_MAC_LOG_LEVEL_1
/* for debug */
char c_str_buf[80] = { 0 };
uint32_t idx = 0;
#endif
uint32_t pbsz = 0;
uint32_t ret;
uint8_t is_chk_next;
uint8_t phcl = mac_get_pb_hdr_resv_crc_len(FC_DELIM_SOF, proto);
uint32_t t_pbsz = \
(\
(msdu_len >= (uint32_t)(264 - phcl)) ? 520 : \
(msdu_len >= (uint32_t)(136 - phcl)) ? 264 : \
(msdu_len >= (uint32_t)(72 - phcl)) ? 136 : 72 \
);
if (proto == PLC_PROTO_TYPE_SPG) {
t_pbsz = (msdu_len >= (uint32_t)(136 - phcl)) ? 520 : 136;
}
if (is_fixed_rate) {
*rate_idx = mac_rate_get_fix_rid_by_msdu_len(proto,
single_proto_band, vdev_get_fixed_rate_level(vdev), msdu_len);
} else {
// auto rate
int8_t avg = peer->rate_info.avg_snr;
uint8_t rid = (uint8_t)peer->rate_info.rate_idx;
int8_t delta;
uint32_t start_idx, end_idx;
uint8_t action = RA_ACTION_UNKOWN;
uint32_t org_pbsz;
ret = phy_get_rt_pbsz(proto, rid, &org_pbsz);
if (ret != ERR_OK) {
IOT_ASSERT(0);
return ERR_FAIL;
}
if (is_fixed_pbsz) {
t_pbsz = org_pbsz;
}
phy_ra_tbl_band_range_get(single_proto_band, &start_idx, &end_idx);
if (rid < (uint8_t)start_idx) {
rid = (uint8_t)start_idx;
}
int8_t i,j; // j is the last i
for (i = rid, j = i; i >= (int8_t)start_idx && i <= (int8_t)end_idx; ) {
#if PLC_MAC_RA_DEBUG_LOG >= PLC_MAC_LOG_LEVEL_1
{
/* must be top of this for loop */
int32_t remain = sizeof(c_str_buf) - idx;
if (remain > 0) {
idx += iot_snprintf(c_str_buf + idx, \
remain, "r%d", i);
}
else
{
IOT_ASSERT(0);
break;
}
}
#endif
if (INV_IDX == RAGET_PRID(proto, i)) {
is_chk_next = 1;
} else {
ret = phy_get_rt_pbsz(proto, i, &pbsz);
/* get the tmi and ext tmi */
phy_get_tmi_by_rid(proto, i, &tmi, &ext_tmi);
/* get the sym per pb */
sym_ppb = phy_get_symppb_from_table(\
phy_def_hw_band_id_get(), tmi, ext_tmi);
/* if the rate is not enabled, next one */
/* if the pbsz is not as expected */
/* if this rate is symppb > 511(SG) */
if (!RAGET_ENA(i)
|| (is_fixed_pbsz && (ret != ERR_OK || pbsz != t_pbsz))
|| !sym_ppb) {
is_chk_next = 1;
} else {
is_chk_next = 0;
}
}
if (is_chk_next) {
if (j == i) {
if (i != rid) {
IOT_ASSERT(0);
}
else {
/* if first time */
i++;
}
}
else {
if (j < i) {
i++;
}
else {
i--;
}
}
continue;
}
delta = avg - RAGET_THRE(i);
if (delta >= 3) {
/* get better SNR now */
if (action == RA_ACTION_UNKOWN) {
action = RA_ACTION_UP;
j = i++;
continue;
}
if (action == RA_ACTION_DOWN || action == RA_ACTION_KEEP) {
i = j;
break;
} else {
/* continue if UP */
j = i++;
continue;
}
}
else if (delta < 0) {
/* get worse SNR, drop */
if (action == RA_ACTION_UNKOWN) {
action = RA_ACTION_DOWN;
j = i--;
continue;
}
if (action == RA_ACTION_UP || \
action == RA_ACTION_KEEP) {
i = j;
break;
}
else {
/* continue if DOWN */
j = i--;
continue;
}
}
else {
/* SNR in the range,
* 0 <= delta < 3,
* find a proper pb sz
*/
if (action == RA_ACTION_UNKOWN) {
action = RA_ACTION_KEEP;
}
if (action == RA_ACTION_KEEP) {
if (ret != ERR_OK) {
/* if failed, should continue search */
if (i > j) {
i++;
continue;
}
if (i < j) {
i--;
continue;
}
if (i == j) {
/* should not happen */
IOT_ASSERT(0);
}
}
if (pbsz < t_pbsz) {
if (j >= (i + 1)) {
/* use former i that
* just bigger than t_pbsz
*/
i = j;
break;
}
j = i++;
continue;
}
else if (pbsz > t_pbsz) {
if (j <= (i - 1)) {
/* use current i that
* just bigger than t_pbsz
*/
break;
}
j = i--;
continue;
} else if (pbsz == t_pbsz) {
/* then pbsz == t_pbsz */
break;
}
}
else if (action == RA_ACTION_UP) {
if (ret != ERR_OK) {
j = i++;
continue;
}
if (pbsz == t_pbsz) {
/* this rate could just accommdate
* the msdu if action up, use this one
*/
break;
} else if (pbsz > t_pbsz) {
/* this rate could just accommdate
* the msdu if action up, use this one
*/
break;
} else {
/* if goes up, but found can't accommdate
* just continue search.
* NOTE: the step of SNR should be small enough
*/
j = i++;
continue;
}
}
else if (action == RA_ACTION_DOWN) {
if (ret != ERR_OK) {
j = i--;
continue;
}
if (pbsz == t_pbsz) {
/* good one */
break;
} else if (pbsz < t_pbsz) {
i = j;
break;
} else {
j = i--;
continue;
}
}
}
} // for (i)
if (i < (int8_t)start_idx || i >= ((int8_t)end_idx + 1)) {
i = j;
}
*rate_idx = i;
} // auto rate
if (!is_fixed_rate && is_fixed_pbsz) {
/* double check the pbsz if auto rate */
ret = phy_get_rt_pbsz(proto, *rate_idx, &pbsz);
if (ret != ERR_OK || pbsz != t_pbsz) {
iot_printf("double check pbsz failed. rid:%d\n", *rate_idx);
IOT_ASSERT(0);
}
}
/* save the rate */
peer->rate_info.rate_idx = *rate_idx;
/* calculate the max pb in one mpdu */
if (peer->tei == 1) {
/* for to CCo's unicast, the limitation is 16 ms */
max_fl_limitation = RA_MAX_WAR_MSDU_SEND_FL_MS;
} else {
max_fl_limitation = RA_MAX_MSDU_SEND_FL_MS;
}
/* get the tmi and ext tmi */
phy_get_tmi_by_rid(proto, *rate_idx, &tmi, &ext_tmi);
/* get the sym per pb */
sym_ppb = phy_get_symppb_from_table(\
phy_def_hw_band_id_get(), tmi, ext_tmi);
if (sym_ppb == 0) {
uint32_t tmp = 0;
iot_printf("%s,sym_ppb or fl_ppb = 0,single_band:%d, rid=%d, "
"tmi:%d, exttmi:%d\n",\
__FUNCTION__, single_proto_band, *rate_idx, tmi, ext_tmi);
tmp = (uint8_t)(*rate_idx << 24) | (uint8_t)(single_proto_band << 16) \
| (uint8_t)(tmi << 8) | (uint8_t)(ext_tmi << 0);
IOT_ASSERT_DUMP(0, &tmp, 1);
}
/* calculate the max pb supported for this tmi in the band */
if (proto == PLC_PROTO_TYPE_SPG || proto == PLC_PROTO_TYPE_SG) {
#if SUPPORT_IEEE_1901
*pb_num_in_each_mpdu = min(MAC_MPDU_PL_SYMBOL_NUM_I1901 / sym_ppb, 4);
#else
*pb_num_in_each_mpdu = min(MAC_MPDU_PL_SYMBOL_NUM_SG_SPG / sym_ppb, 4);
#endif
IOT_ASSERT(*pb_num_in_each_mpdu);
} else {
/* TODO: check GP's self extension rate */
*pb_num_in_each_mpdu = 4; /* force 4 pb max */
}
fl_ppb = phy_get_flppb_from_table(\
phy_def_hw_band_id_get(), tmi, ext_tmi);
if (fl_ppb == 0) {
iot_printf("get fl failed, tmi=%d, etmi=%d\n", tmi, ext_tmi);
IOT_ASSERT(0);
} else {
fl_ms = (fl_ppb * (*pb_num_in_each_mpdu) + mac_get_tx_rifs()
+ mac_get_tx_cifs()
+ mac_rx_get_delim((uint8_t)*rate_mode, \
phy_proto_band_to_hw_band(single_proto_band))) / 1000;
*mpdu_num_to_send = max_fl_limitation / fl_ms;
/* TODO: get smaller pb number if mpdu num less than 1 */
if (0 == *mpdu_num_to_send) {
*pb_num_in_each_mpdu = (*pb_num_in_each_mpdu)
* max_fl_limitation / fl_ms;
if (*pb_num_in_each_mpdu == 0) {
iot_printf("frame (len=%d) is too long (> %d ms) in rid %d\n",
msdu_len, max_fl_limitation, *rate_idx);
IOT_ASSERT(0);
return ERR_FAIL;
}
*mpdu_num_to_send = 1;
}
}
#if PLC_MAC_RA_DEBUG_LOG >= PLC_MAC_LOG_LEVEL_1
iot_printf("%s\n---ra fix_rate=%d, msdu_len:%d, avg:%d, rid:%d, max_pb=%d, max_mpdu=%d, " \
"fix_pbsz=%d, retry_cnt = %d, max_fl=%d, dtei=%d\n", \
c_str_buf, is_fixed_rate, msdu_len, peer->rate_info.avg_snr, \
*rate_idx, *pb_num_in_each_mpdu, *mpdu_num_to_send, \
is_fixed_pbsz, retry_cnt, fl_ms, peer->tei);
#endif
(void)retry_cnt;
return 0;
}
uint32_t mac_bcn_get_rate(mac_vdev_t *vdev,
uint32_t proto, uint8_t is_fixed_rate,
uint32_t bcn_len, uint32_t band_id,
uint8_t *rate_idx, uint32_t *rate_mode)
{
(void)vdev;
(void)bcn_len;
uint32_t t_pbsz = bcn_len;
if (is_fixed_rate) {
switch (proto) {
case PLC_PROTO_TYPE_SG:
case PLC_PROTO_TYPE_SPG:
{
if (t_pbsz > 136) {
if (mac_rate_is_special_narrow_band(band_id)) {
*rate_idx = 10;
} else {
*rate_idx = g_fix_ra_tbl->bcn_520_idx;
}
} else {
*rate_idx = g_fix_ra_tbl->bcn_136_idx;
}
break;
}
default:
{
IOT_ASSERT(0);
}
}//switch
}
else {
//is not fixed rate
}
*rate_mode = 0; /* 0: SR, 1:QR, 2:XR, 3: FSK */
return 0;
}
uint32_t mac_data_get_bcast_rate(mac_vdev_t *vdev,
uint32_t proto, uint8_t is_fixed_rate,
uint32_t pkt_len, uint32_t single_proto_band, uint32_t retry_cnt,
uint8_t *rate_idx, uint32_t *rate_mode,
uint32_t *mpdu_num_to_send, uint32_t *pb_num_per_mpdu,
uint32_t is_dbg_pkt, uint32_t is_retry, uint8_t rd_retry_cnt)
{
(void)vdev;
(void)pkt_len;
uint32_t tmi, ext_tmi, pbsz, sym_ppb;
/* for bcast, the pkt-len should be considered, as currently default
* bcast only support one mpdu and max 4 pb in one mpdu
*/
*mpdu_num_to_send = 1;
*pb_num_per_mpdu = PLC_MAX_PB_PER_MPDU;
if (is_fixed_rate) {
*rate_idx = mac_rate_get_fix_rid_by_msdu_len(proto,
single_proto_band, vdev_get_fixed_rate_level(vdev), pkt_len);
} else {
//is not fixed rate
}
/* NOTE: note for dbg pkt.
* the performance of ppm in tmi10 surpasses that of tmi9,
* so dbg pkt try to use tmi10.
* but the anti-attenuation performance of tmi9 surpasses that of
* tmi10 on band2, so tmi9 and tmi10 are utilized intermittently.
*/
if (SUPPORT_IEEE_1901 == 0 && is_dbg_pkt && is_retry &&
((uint8_t)retry_cnt%2 != rd_retry_cnt%2) && *rate_idx == 9) {
*rate_idx = 10;
}
phy_get_tmi_by_rid(proto, *rate_idx, &tmi, &ext_tmi);
sym_ppb = phy_get_symppb_from_table(
phy_proto_band_to_hw_band(single_proto_band), tmi, ext_tmi);
IOT_ASSERT(sym_ppb);
*pb_num_per_mpdu = min(511 / sym_ppb, 4);
phy_get_rt_pbsz(proto, *rate_idx, &pbsz);
*mpdu_num_to_send = iot_ceil(pkt_len, pbsz * (*pb_num_per_mpdu));
*rate_mode = 0; /* 0: SR, 1:QR, 2:XR, 3: FSK */
#if PLC_MAC_RA_DEBUG_LOG >= PLC_MAC_LOG_LEVEL_1
iot_printf("---ra bc_rid:%d, retry_cnt=%d, pb_num=%d, mpdu_num=%d\n",
*rate_idx, retry_cnt, *pb_num_per_mpdu, *mpdu_num_to_send);
#endif
/* we suppose currently all band not support multi mpdu except band3/13 */
if (!mac_rate_is_special_narrow_band(phy_band_id_get())) {
IOT_ASSERT(*mpdu_num_to_send == 1);
}
(void)retry_cnt;
(void)is_dbg_pkt;
(void)is_retry;
(void)rd_retry_cnt;
return 0;
}
uint32_t ra_init(mac_vdev_t * vdev, uint32_t ena_ra)
{
/* set cb when rx sack */
vdev_set_ra_cb(vdev, mac_rate_update);
/* set ra enable/disable, if enable
* then fixed rate = false, else true
*/
vdev_set_fixed_rate(vdev, !ena_ra);
return (0);
}
void ra_add_no_sack_cnt(rate_info_t *ra)
{
if (!ra) {
return;
}
if (++ra->con_no_sack_cnt > RA_CON_NOSACK_PENALTY_CNT_THRE) {
if (ra->avg_snr > RA_LOW_THRE_SNR_VAL) {
ra->avg_snr -= RA_CON_NOSACK_PENALTY_SNR_STEP;
iot_printf("reduce snr to %d\n", ra->avg_snr);
}
}
return;
}
void ra_clr_no_sack_cnt(rate_info_t *ra)
{
if (!ra) {
return;
}
ra->con_no_sack_cnt = 0;
return;
}
void ra_inc_con_sack_err_cnt(rate_info_t *ra)
{
if (!ra) {
return;
}
if (++ra->con_sack_err_cnt > RA_CON_SACKERR_PENALTY_CNT_THRE) {
if (ra->avg_snr > RA_LOW_THRE_SNR_VAL) {
ra->avg_snr -= RA_CON_SACKERR_PENALTY_SNR_STEP;
iot_printf("reduce snr to %d\n", ra->avg_snr);
}
}
return;
}
void ra_clr_con_sack_err_cnt(rate_info_t *ra)
{
if (!ra) {
return;
}
ra->con_sack_err_cnt = 0;
return;
}
uint8_t mac_get_tx_retry_cnt_by_band(mac_vdev_t *vdev,
uint32_t proto_band, uint8_t tx_cnt)
{
/* current just sg need ciu application */
if (proto_band >= IOT_SUPPORT_TONE_MULTI_BAND021) {
nid_t nid;
vdev_get_nid(vdev, &nid);
if (PLC_NID_INVALID == nid) {
switch (proto_band) {
case IOT_SUPPORT_TONE_MULTI_BAND021:
return (uint8_t)(tx_cnt ? (tx_cnt << 1) : tx_cnt);
default:
IOT_ASSERT(0);
}
} else {
return tx_cnt;
}
}
return tx_cnt;
}
uint32_t mac_tx_hw_band_id_get(mac_vdev_t *vdev,
uint32_t proto_band, uint32_t tx_cnt)
{
/* multiband */
if (IOT_SUPPORT_TONE_MULTI_BAND021 == proto_band) {
/* not try to join network -> CKQ */
nid_t nid;
vdev_get_nid(vdev, &nid);
if (PLC_NID_INVALID == nid) {
if (tx_cnt & 0x01) {
return HW_LOW_BAND;
} else {
return HW_HIGH_BAND;
}
} else {
return HW_LOW_BAND;
}
}
return HW_FULL_BAND;
}