HE TB PPDU MU-RTS

  看起来像是MU-RTS的触发帧的应答不是HE TB PPDU,而是传统得的帧,应答CTS。

  非AP 的STA,是不能发送触发帧,也就是说,触发帧,只能是由AP发送给STA

/** **************************************************************************************** * @brief Concatenate a A-MPDU with the MPDU just following it. * * The function first checks if with the concatenated MPDU the A-MPDU will still fit * into the HE TB. If not the concatenation is not performed. * * @param[in] txdesc_ampdu First MPDU of the A-MPDU * @param[in, out] txdesc_next Pointer to the TX descriptor of the MPDU. If the * concatenation is done this pointer will be updated with the descriptor just following * the resulting A-MPDU. * @param[in] max_len Maximum length, in bytes, of the HE TB PPDU * @param[in] min_mpdu_len Minimum MPDU length inside the HE TB PPDU (for minimal MPDU * start spacing) * @param[in] ac Access category of the A-MPDU * * @return A boolean indicating if the concatenation was done. If false, then the caller * knows that no additional concatenation shall be attempted, and that the HE TB can be * programmed. **************************************************************************************** */ static bool txl_agg_he_tb_cat_ampdu_mpdu(struct txdesc *txdesc_ampdu, struct txdesc **txdesc_next, uint32_t max_len, uint16_t min_mpdu_len, uint8_t ac) { struct tx_agg_desc *agg_desc = txdesc_ampdu->lmac.agg_desc; struct txdesc *txdesc_mpdu = *txdesc_next; struct txdesc *txdesc_last = agg_desc->txdesc_last; struct txl_list *txlist = &txl_cntrl_env.txlist[ac]; struct tx_hd *thd = tx_desc_thd(txdesc_mpdu); struct tx_hd *thd_last = tx_desc_thd(txdesc_last); uint16_t nb_delims_new = 0, subfrm_len_new; struct tx_hd *a_thd; // Check if MPDU can be concatenated with the A-MPDU if (!(txdesc_mpdu->lmac.status & TXDESC_PUSHED) || (agg_desc->sta_idx != txdesc_mpdu->host.sta_idx) || (agg_desc->tid != txdesc_mpdu->host.tid)) return false; a_thd = &agg_desc->hw->a_thd; // Re-add the +HTC length and order bit in the MPDU buffer if necessary txl_buffer_add_htc(thd); // Compute the new number of delimiters and the sub-frame length #if !NX_MAC_HE_MU_AP nb_delims_new = txl_agg_mpdu_nb_delims(thd, min_mpdu_len); #endif subfrm_len_new = txl_mpdu_subframe_len(thd) + nb_delims_new * DELIMITER_LEN; if ((a_thd->frmx.frmlen + subfrm_len_new) > max_len) return false; // PPDUs will be concatenated, we'll have one less in the TX path txlist->ppdu_cnt--; set_mpdu_pos(txdesc_last, TX_AGG_MPDU_INT); thd_last->mpdu.nextmpdudesc_ptr = CPU2HW(&thd->mpdu); set_mpdu_pos(txdesc_mpdu, TX_AGG_MPDU_LAST); #if NX_MAC_HE_MU_AP agg_desc->nextfrmexseq_ptr = thd->frmx.nextfrmexseq_ptr; #else hal_desc_set_nbdelims(thd, nb_delims_new); #endif thd->frmx.nextfrmexseq_ptr = 0; thd->frmx.policyentryaddr = 0; hal_desc_mpdu_irq_set(thd); a_thd->frmx.frmlen += subfrm_len_new; txdesc_mpdu->lmac.agg_desc = agg_desc; agg_desc->txdesc_last = txdesc_mpdu; #if !NX_TX_FAST_PATH agg_desc->available_len += txdesc_mpdu->lmac.available_len; #endif *txdesc_next = tx_desc_next(agg_desc->txdesc_last); // Update the +HTC with the UPH txl_buffer_update_htc(thd, txl_he_tb_uph_get()); txl_cfm_tag_get(txdesc_mpdu)->ampdu_size++; return (a_thd->frmx.frmlen < max_len); }结合代码详细解释
最新发布
03-22
<think>嗯,我现在需要理解这段代码的作用。首先,这个函数是用于将A-MPDU和紧随其后的MPDU连接起来。让我仔细看看代码的结构和注释。 首先,函数名是txl_agg_he_tb_cat_ampdu_mpdu,参数包括txdesc_ampdu(A-MPDU的第一个MPDU)、txdesc_next(指向下一个MPDU的指针,可能被更新)、max_len(HE TB PPDU的最大长度)、min_mpdu_len(最小的MPDU长度)、ac(访问类别)。返回一个布尔值,表示是否成功连接。 函数开始声明了一些变量,比如agg_desc,txdesc_mpdu,txdesc_last等。然后检查三个条件:txdesc_mpdu是否已经被推送(PUSHED状态),STA索引是否相同,TID是否相同。如果任一条件不满足,返回false,不能连接。 接下来,处理HTC长度,可能是添加必要的头信息。然后计算新的分隔符数量和子帧长度。这里有个条件编译,如果NX_MAC_HE_MU_AP未定义,才计算nb_delims_new,否则可能不需要。subfrm_len_new是子帧长度加上分隔符的总长度。 然后检查如果加上新的子帧长度后,总长度是否超过max_len。如果超过,返回false,否则继续处理。 接着减少txlist中的ppdu_cnt,这表示成功合并后PPDU数量减少。然后设置最后一个MPDU的位置为内部节点,设置其下一个MPDU描述符指针指向当前MPDU。设置当前MPDU的位置为最后一个,并更新相关描述符字段,比如nextfrmexseq_ptr,分隔符数量,中断设置等。 更新总帧长度a_thd->frmx.frmlen,将当前MPDU加入agg_desc,更新txdesc_last为当前MPDU,调整可用长度。然后更新txdesc_next指向下一个描述符。 最后,更新HTC的UPH,增加ampdu_size的计数,并返回总长度是否仍小于max_len,以便判断是否还能继续合并。 可能需要注意的地方:条件编译部分可能影响不同环境下的行为,分隔符的计算方式,以及各个字段如何被设置。比如,HTC和分隔符的作用可能涉及物理层的格式要求。同时,状态位的检查确保只有符合条件的MPDU才能被合并,保证传输的正确性。</think>以下是该函数的详细解释,结合代码逐步分析其功能和实现逻辑: --- ### **功能概述** 该函数用于将**A-MPDU**(聚合的MAC协议数据单元)与紧随其后的**MPDU**(单个MAC协议数据单元)进行**动态拼接**,以优化传输效率。核心目标是:在满足**HE TB(高效触发型物理层协议数据单元)** 长度限制的前提下,尽可能合并数据单元,减少传输次数。 --- ### **输入参数说明** 1. **`txdesc_ampdu`**: 指向A-MPDU首个MPDU的TX描述符。 2. **`txdesc_next`**: 输入为待拼接的MPDU描述符指针;输出更新为下一个待处理的MPDU描述符。 3. **`max_len`**: HE TB PPDU的最大允许长度(字节)。 4. **`min_mpdu_len`**: HE TB内MPDU的最小长度(用于分隔符计算)。 5. **`ac`**: 访问类别(Access Category),用于确定传输队列。 --- ### **关键代码逻辑分析** #### **1. 前置条件检查** ```c if (!(txdesc_mpdu->lmac.status & TXDESC_PUSHED) || (agg_desc->sta_idx != txdesc_mpdu->host.sta_idx) || (agg_desc->tid != txdesc_mpdu->host.tid)) return false; ``` - **检查MPDU状态**:确认待拼接的MPDU已被推送(`TXDESC_PUSHED`标志位)。 - **STA一致性**:确保当前A-MPDU与MPDU属于同一站点(`sta_idx`匹配)。 - **TID一致性**:确保流量标识符(`tid`)相同,保证同一数据流。 --- #### **2. 长度计算与限制验证** ```c // 计算新的分隔符数量和子帧长度 #if !NX_MAC_HE_MU_AP nb_delims_new = txl_agg_mpdu_nb_delims(thd, min_mpdu_len); #endif subfrm_len_new = txl_mpdu_subframe_len(thd) + nb_delims_new * DELIMITER_LEN; // 检查总长度是否超出限制 if ((a_thd->frmx.frmlen + subfrm_len_new) > max_len) return false; ``` - **分隔符计算**:根据MPDU长度和最小间距要求(`min_mpdu_len`),确定需要插入的分隔符数量。 - **子帧总长度**:包含MPDU自身长度和分隔符占用长度。 - **长度限制**:若拼接后超出HE TB最大长度,则终止合并。 --- #### **3. 更新A-MPDU链表** ```c // 更新PPDU计数和链表指针 txlist->ppdu_cnt--; set_mpdu_pos(txdesc_last, TX_AGG_MPDU_INT); thd_last->mpdu.nextmpdudesc_ptr = CPU2HW(&thd->mpdu); // 设置当前MPDU为A-MPDU的最后一个单元 set_mpdu_pos(txdesc_mpdu, TX_AGG_MPDU_LAST); #if NX_MAC_HE_MU_AP agg_desc->nextfrmexseq_ptr = thd->frmx.nextfrmexseq_ptr; #else hal_desc_set_nbdelims(thd, nb_delims_new); #endif ``` - **链表操作**:将待拼接的MPDU加入A-MPDU链表尾部,并更新指针。 - **描述符配置**:根据编译条件设置分隔符数量或序列指针,确保硬件正确解析。 --- #### **4. 更新统计与状态** ```c // 更新总长度和可用缓冲区 a_thd->frmx.frmlen += subfrm_len_new; agg_desc->txdesc_last = txdesc_mpdu; #if !NX_TX_FAST_PATH agg_desc->available_len += txdesc_mpdu->lmac.available_len; #endif // 更新HTC头部和CFM计数 *txdesc_next = tx_desc_next(agg_desc->txdesc_last); txl_buffer_update_htc(thd, txl_he_tb_uph_get()); txl_cfm_tag_get(txdesc_mpdu)->ampdu_size++; ``` - **长度累计**:更新A-MPDU总长度和可用缓冲区空间。 - **HTC更新**:调整硬件传输控制字段(HTC)以匹配新拼接的帧结构。 - **统计计数**:增加A-MPDU大小计数器(`ampdu_size`)。 --- #### **5. 返回值** ```c return (a_thd->frmx.frmlen < max_len); ``` - **是否继续拼接**:返回当前A-MPDU总长度是否小于`max_len`,提示调用者是否还能继续尝试拼接。 --- ### **关键设计点** 1. **动态拼接策略**:通过实时计算剩余空间,动态决定是否合并,最大化HE TB利用率。 2. **硬件描述符管理**:通过操作`tx_hd`结构体中的指针和长度字段,确保硬件能正确解析拼接后的A-MPDU。 3. **条件编译适配**:根据`NX_MAC_HE_MU_AP`等宏定义,适配不同硬件版本的分隔符处理逻辑。 --- ### **应用场景** 该函数适用于**Wi-Fi 6(802.11ax)** 的**高效触发响应(HE TB)** 机制中,用于优化上行多用户传输(UL MU)的效率,减少资源浪费。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值