764 lines
24 KiB
C
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;
|
|
}
|