1026 lines
32 KiB
C
1026 lines
32 KiB
C
/******************************************************************************
|
|
*
|
|
* Copyright(c) 2019 Realtek Corporation.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of version 2 of the GNU General Public License as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
*****************************************************************************/
|
|
#define _HAL_SOUND_C_
|
|
|
|
#include "hal_headers.h"
|
|
|
|
struct csi_rpt_na {
|
|
u8 nr;
|
|
u8 nc;
|
|
u8 na;
|
|
};
|
|
|
|
#define CSI_NA_MATRIX_SIZE 35
|
|
static const struct csi_rpt_na csi_na[CSI_NA_MATRIX_SIZE] =
|
|
{
|
|
{2, 1, 2}, {2, 2, 2},
|
|
{3, 1, 4}, {3, 2, 6}, {3, 3, 6},
|
|
{4, 1, 6}, {4, 2, 10}, {4, 3, 12}, {4, 4, 12},
|
|
{5, 1, 8}, {5, 2, 14}, {5, 3, 18}, {5, 4, 20}, {5, 5, 20},
|
|
{6, 1, 10}, {6, 2, 18}, {6, 3, 24}, {6, 4, 28}, {6, 5, 30},
|
|
{6, 6, 30},
|
|
{7, 1, 12}, {7, 2, 22}, {7, 3, 30}, {7, 4, 36},
|
|
{7, 5, 40}, {7, 6, 42}, {7, 7, 42},
|
|
{8, 1, 14}, {8, 2, 26}, {8, 3, 36}, {8, 4, 55},
|
|
{8, 5, 50}, {8, 6, 54}, {8, 7, 56}, {8, 8, 56}
|
|
};
|
|
|
|
|
|
u32 _cal_he_csi_size(u8 mu, enum channel_width bw, u8 nr, u8 nc, u8 ng, u8 cb)
|
|
{
|
|
u8 na = 0;
|
|
u8 ns = 0;
|
|
u8 i = 0;
|
|
u32 csi_size = 0;
|
|
u8 cb_s = 0;
|
|
PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
|
|
"%s : mu(%d) ; bw(%d) ; nr(%d) ; nc(%d), ng(%d), cb(%d)\n",
|
|
__func__, mu, bw, nr, nc, ng ,cb);
|
|
do {
|
|
if (CHANNEL_WIDTH_80 == bw)
|
|
ns = (ng == 4) ? 250 : 64;
|
|
else if(CHANNEL_WIDTH_40 == bw)
|
|
ns = (ng == 4) ? 122 : 32;
|
|
else if(CHANNEL_WIDTH_20 == bw)
|
|
ns = (ng == 4) ? 64 : 20;
|
|
else
|
|
break;
|
|
|
|
for (i = 0; i < CSI_NA_MATRIX_SIZE; i++) {
|
|
if ((nr == csi_na[i].nr) && (nc ==csi_na[i].nc)) {
|
|
na = csi_na[i].na;
|
|
break;
|
|
}
|
|
}
|
|
if (na == 0)
|
|
break;
|
|
|
|
if (cb) {
|
|
if(mu)
|
|
cb_s = 8;
|
|
else
|
|
cb_s = 5;
|
|
} else {
|
|
if(mu)
|
|
cb_s = 6;
|
|
else
|
|
cb_s = 3;
|
|
}
|
|
} while(0);
|
|
|
|
PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
|
|
"%s : na %d ; ns %d ; cb_s %d",__func__, na, ns, cb_s);
|
|
|
|
if ((0 != na) && (0 != ns) && (0 != cb_s)) {
|
|
csi_size = ((8 * (u32)nc) +
|
|
((u32)na * (u32)cb_s * (u32)ns)) / 8;
|
|
if(mu)
|
|
csi_size += (4 * (u32)nc * (u32)ns) / 8;
|
|
}
|
|
|
|
PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
|
|
"%s : expected he csi report size = %d byte",
|
|
__func__, csi_size);
|
|
return csi_size;
|
|
}
|
|
|
|
u32 _cal_he_cqi_only_rpt_size(enum channel_width bw, u8 nc)
|
|
{
|
|
u32 ret = 0;
|
|
if (CHANNEL_WIDTH_80 == bw)
|
|
ret = (u32)nc * 37;
|
|
else if(CHANNEL_WIDTH_40 == bw)
|
|
ret = (u32)nc * 18;
|
|
else if(CHANNEL_WIDTH_20 == bw)
|
|
ret = (u32)nc * 9;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*1. BF Resource Related*/
|
|
u8 _get_bw_ru_end_idx(enum channel_width bw) {
|
|
u8 ru_end_idx = 0;
|
|
|
|
switch (bw) {
|
|
case CHANNEL_WIDTH_20:
|
|
ru_end_idx = HAL_NPDA_RU_IDX_END_20MHZ;
|
|
break;
|
|
case CHANNEL_WIDTH_40:
|
|
ru_end_idx = HAL_NPDA_RU_IDX_END_40MHZ;
|
|
break;
|
|
case CHANNEL_WIDTH_80:
|
|
ru_end_idx = HAL_NPDA_RU_IDX_END_80MHZ;
|
|
break;
|
|
case CHANNEL_WIDTH_160:
|
|
case CHANNEL_WIDTH_80_80:
|
|
ru_end_idx = HAL_NPDA_RU_IDX_END_160MHZ;
|
|
default:
|
|
break;
|
|
}
|
|
return ru_end_idx;
|
|
}
|
|
|
|
void _hal_snd_set_default_var(struct hal_snd_obj *snd_obj)
|
|
{
|
|
snd_obj->ndpa_xpara.bw = CHANNEL_WIDTH_20;
|
|
snd_obj->ndpa_xpara.rate = RTW_DATA_RATE_OFDM6;
|
|
snd_obj->ndpa_xpara.gi_ltf = RTW_GILTF_LGI_4XHE32;
|
|
snd_obj->ndpa_xpara.stbc = 0;
|
|
snd_obj->ndpa_xpara.ldpc = 0;
|
|
|
|
snd_obj->bfrp_xpara.bw = CHANNEL_WIDTH_20;
|
|
snd_obj->bfrp_xpara.rate = RTW_DATA_RATE_OFDM6;
|
|
snd_obj->bfrp_xpara.gi_ltf = RTW_GILTF_LGI_4XHE32;
|
|
snd_obj->bfrp_xpara.stbc = 0;
|
|
snd_obj->bfrp_xpara.ldpc = 0;
|
|
}
|
|
|
|
enum rtw_hal_status
|
|
hal_snd_obj_init(void *hal)
|
|
{
|
|
enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
struct rtw_hal_com_t *hal_com = hal_info->hal_com;
|
|
struct hal_snd_obj *snd_obj = NULL;
|
|
|
|
do {
|
|
hal_com->snd_obj = _os_mem_alloc(hal_to_drvpriv(hal_info),
|
|
sizeof(struct hal_snd_obj));
|
|
if (NULL == hal_com->snd_obj) {
|
|
break;
|
|
}
|
|
snd_obj = hal_com->snd_obj;
|
|
/* preset hal sounding default values */
|
|
_hal_snd_set_default_var(snd_obj);
|
|
|
|
hstatus = RTW_HAL_STATUS_SUCCESS;
|
|
} while (0);
|
|
return hstatus;
|
|
}
|
|
|
|
|
|
enum rtw_hal_status
|
|
hal_snd_obj_deinit(void *hal)
|
|
{
|
|
enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
struct rtw_hal_com_t *hal_com = hal_info->hal_com;
|
|
|
|
do {
|
|
if (hal_com->snd_obj == NULL)
|
|
break;
|
|
_os_mem_free(hal_to_drvpriv(hal_info), hal_com->snd_obj,
|
|
sizeof(struct hal_snd_obj));
|
|
hal_com->snd_obj = NULL;
|
|
} while (0);
|
|
|
|
return hstatus;
|
|
}
|
|
|
|
/**
|
|
* rtw_hal_snd_release_proc_sta_res
|
|
* free the resource for a STA used in sounding process
|
|
* input:
|
|
* @hal: (struct hal_info_t *)
|
|
* @sta: (struct rtw_phl_stainfo_t *)
|
|
**/
|
|
enum rtw_hal_status
|
|
rtw_hal_snd_release_proc_sta_res(void *hal, struct rtw_phl_stainfo_t *sta)
|
|
{
|
|
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
struct rtw_hal_stainfo_t *hal_sta = sta->hal_sta;
|
|
do {
|
|
if (hal_sta->bf_entry != NULL) {
|
|
hal_status = hal_bf_release_target_bf_entry(
|
|
hal_info, hal_sta->bf_entry);
|
|
}
|
|
|
|
if (hal_is_csi_buf_valid(hal_info, &hal_sta->bf_csi_buf)) {
|
|
hal_status = hal_csi_release_csi_buf(
|
|
hal_info, &hal_sta->bf_csi_buf);
|
|
}
|
|
if (hal_is_csi_buf_valid(hal_info, &hal_sta->bf_csi_buf_swap)) {
|
|
hal_status = hal_csi_release_csi_buf(
|
|
hal_info, &hal_sta->bf_csi_buf_swap);
|
|
}
|
|
} while(0);
|
|
|
|
return hal_status;
|
|
}
|
|
|
|
|
|
/**
|
|
* rtw_hal_snd_query_proc_sta_res
|
|
* input:
|
|
* @hal: hal_info
|
|
* @sta: rtw_phl_stainfo_t
|
|
* @mu: is this MU-MIMO STA resource request
|
|
* @bw: enum channel_width sounding bandwidth
|
|
**/
|
|
enum rtw_hal_status
|
|
rtw_hal_snd_query_proc_sta_res(
|
|
void *hal,
|
|
struct rtw_phl_stainfo_t *sta,
|
|
bool mu,
|
|
enum channel_width bw,
|
|
bool en_swap)
|
|
{
|
|
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
struct rtw_hal_stainfo_t *hal_sta = sta->hal_sta;
|
|
|
|
do {
|
|
if (hal_sta->bf_entry != NULL) {
|
|
PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "[WARNING] sta->bf_entry != NULL\n");
|
|
/* TODO:Shall Release First ?*/
|
|
/* rtw_hal_snd_release_proc_sta_res(hal, sta); */
|
|
}
|
|
|
|
hal_sta->bf_entry =
|
|
(void *)hal_bf_query_idle_bf_entry(hal_info, mu);
|
|
|
|
if (hal_sta->bf_entry == NULL)
|
|
break;
|
|
|
|
hal_status = hal_csi_query_idle_csi_buf(
|
|
hal_info, mu, bw, &hal_sta->bf_csi_buf);
|
|
|
|
if (hal_status != RTW_HAL_STATUS_SUCCESS)
|
|
break;
|
|
|
|
if (mu && en_swap) {
|
|
hal_status = hal_csi_query_idle_csi_buf(
|
|
hal_info, mu, bw, &hal_sta->bf_csi_buf_swap);
|
|
}
|
|
if (hal_status == RTW_HAL_STATUS_FAILURE) {
|
|
PHL_INFO("Cannot Enable Swap Mode! Because of the CSI resource is not enougth.\n");
|
|
break;
|
|
}
|
|
|
|
PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "sta->bf_csi_buf 0x%x \n",
|
|
hal_sta->bf_csi_buf);
|
|
PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "sta->bf_csi_buf_swap 0x%x \n",
|
|
hal_sta->bf_csi_buf_swap);
|
|
|
|
/* Set STA-INFO info to BF Entry */
|
|
hal_status = hal_bf_cfg_swbf_entry(sta, en_swap);
|
|
} while (0);
|
|
|
|
if (hal_status != RTW_HAL_STATUS_SUCCESS) {
|
|
PHL_INFO("rtw_hal_snd_query_proc_sta_res FAIL \n");
|
|
rtw_hal_snd_release_proc_sta_res(hal, sta);
|
|
}
|
|
|
|
return hal_status;
|
|
}
|
|
|
|
/**
|
|
* rtw_hal_snd_proc_pre_cfg_sta
|
|
* hw preconfiguration for a sounding sta
|
|
* input:
|
|
* @hal: hal_info
|
|
* @sta: (struct rtw_phl_stainfo_t *)
|
|
**/
|
|
enum rtw_hal_status
|
|
rtw_hal_snd_proc_pre_cfg_sta(
|
|
void *hal,
|
|
struct rtw_phl_stainfo_t *sta)
|
|
{
|
|
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
struct rtw_hal_stainfo_t *hal_sta = sta->hal_sta;
|
|
|
|
/* 1. MAC HW BF Entry Settings */
|
|
hal_status = hal_bf_set_entry_hwcfg(
|
|
hal_info, hal_sta->bf_entry);
|
|
|
|
/* 2. Add other HAL setting here */
|
|
/*TODO:*/
|
|
|
|
return hal_status;
|
|
}
|
|
|
|
|
|
/**
|
|
* rtw_hal_snd_proc_post_cfg
|
|
* hw/fw post configuration for a sounding event
|
|
* input:
|
|
* @hal: hal_info
|
|
**/
|
|
enum rtw_hal_status
|
|
rtw_hal_snd_proc_post_cfg(void *hal, bool he, bool mu, bool en_fixed_mode)
|
|
{
|
|
enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
struct hal_mu_score_tbl *hal_score_table = &hal_info->hal_com->bb_mu_score_tbl;
|
|
if (mu) {
|
|
/*1. MU Score Board */
|
|
hal_status = rtw_hal_mac_ax_set_mu_table_whole(
|
|
hal_info->mac, hal_score_table);
|
|
|
|
/*2. (optional) MU Fixed Mode */
|
|
if (en_fixed_mode)
|
|
hal_status = rtw_hal_bf_set_fix_mode(hal, mu, he);
|
|
}
|
|
|
|
return hal_status;
|
|
}
|
|
|
|
|
|
/**
|
|
* rtw_hal_snd_proc_post_cfg_gid
|
|
* hw/fw post configuration for a vht/he gid
|
|
* input:
|
|
* @hal: hal_info
|
|
* @gid: wifi protolcol gid (PLCP) for configuration
|
|
* @ba_info: pointer of struct rtw_hal_muba_info
|
|
**/
|
|
enum rtw_hal_status
|
|
rtw_hal_snd_proc_post_cfg_gid(void *hal, u8 gid, void *ba_info)
|
|
{
|
|
enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
|
|
/*
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
struct rtw_hal_muba_info *hal_ba_info = (struct rtw_hal_muba_info *)ba_info;
|
|
*/
|
|
|
|
/*TODO:*/
|
|
/*1. MU BAR Table : Table ID = GID, GID = STA-x + sSTA-y*/
|
|
return hal_status;
|
|
}
|
|
|
|
/**
|
|
* rtw_hal_snd_proc_post_cfg_sta
|
|
* hw/fw post configuration for a single sounding sta
|
|
* input:
|
|
* @hal: hal_info
|
|
* @sta: (struct rtw_phl_stainfo_t *)
|
|
**/
|
|
enum rtw_hal_status
|
|
rtw_hal_snd_proc_post_cfg_sta(
|
|
void *hal,
|
|
struct rtw_phl_stainfo_t *sta,
|
|
bool mu)
|
|
{
|
|
enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
|
|
/* MAC/FW Settings */
|
|
if (mu) {
|
|
/*1. FW MU STA Update */
|
|
hal_status = hal_bf_set_mu_sta_fw(hal, sta);
|
|
/*2. MU Score Board */
|
|
/* mac->mac_set_mu_table_single_sta */
|
|
}
|
|
|
|
/* BB/FW Settings */
|
|
/*TODO:*/
|
|
|
|
/* 2. Add other setting here */
|
|
/*TODO:*/
|
|
|
|
return hal_status;
|
|
}
|
|
|
|
/**
|
|
* rtw_hal_snd_mac_ctrl
|
|
* control sounding process : pause or start.
|
|
* @hal: hal_info
|
|
* @band: band0 / band1
|
|
* @ctrl: 0 = pause souning / 1 = start sounding
|
|
**/
|
|
enum rtw_hal_status
|
|
rtw_hal_snd_mac_ctrl(void *hal, u8 band, u8 ctrl)
|
|
{
|
|
enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
|
|
hstatus = rtw_hal_mac_ax_hw_snd_control(hal_info->mac, band, ctrl);
|
|
|
|
return hstatus;
|
|
}
|
|
|
|
/**
|
|
* rtw_hal_snd_chk_bf_res
|
|
* check the sta's sounding resource is enough for sounding
|
|
* input :
|
|
* @hal: hal_info
|
|
* @sta: (struct rtw_hal_stainfo_t *)
|
|
* @mu: true = mu / false = su
|
|
* @bw: enum channel_width
|
|
* return :
|
|
* @hstatus: RTW_HAL_STATUS_FAILURE = need release and query bf entry and CSI buffer
|
|
* RTW_HAL_STATUS_SUCCESS = STA's BF Entry and CSI Buffer is same to condition.
|
|
**/
|
|
enum rtw_hal_status
|
|
rtw_hal_snd_chk_bf_res(void *hal, struct rtw_phl_stainfo_t *sta,
|
|
bool mu, enum channel_width bw)
|
|
{
|
|
enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
|
|
struct rtw_hal_stainfo_t *hal_sta = sta->hal_sta;
|
|
do {
|
|
if (sta == NULL)
|
|
break;
|
|
|
|
if (false == rtw_hal_bf_chk_bf_type(hal, sta, mu))
|
|
break;
|
|
if (mu != rtw_hal_get_csi_buf_type(&hal_sta->bf_csi_buf))
|
|
break;
|
|
if (bw != rtw_hal_get_csi_buf_bw(&hal_sta->bf_csi_buf))
|
|
break;
|
|
|
|
hstatus = RTW_HAL_STATUS_SUCCESS;
|
|
} while (0);
|
|
|
|
return hstatus;
|
|
}
|
|
|
|
/**
|
|
* rtw_hal_snd_polling_snd_sts
|
|
* update the sta's sounding status into sta->hal_sta->bf_entry->bfee
|
|
* input :
|
|
* @hal: hal_info
|
|
* @sta: (struct rtw_hal_stainfo_t *)
|
|
**/
|
|
void
|
|
rtw_hal_snd_polling_snd_sts(void *hal, struct rtw_phl_stainfo_t *sta)
|
|
{
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
do {
|
|
if (sta == NULL)
|
|
break;
|
|
|
|
hal_bf_update_entry_snd_sts(hal_info, sta->hal_sta->bf_entry);
|
|
|
|
} while (0);
|
|
}
|
|
|
|
/* SND H2C CMD related functions */
|
|
void
|
|
rtw_hal_snd_ndpa_sta_info_vht(struct rtw_phl_stainfo_t *psta_info,
|
|
u32 *ndpa, u8 mu)
|
|
{
|
|
struct hal_vht_ndpa_sta_info *ndpa_sta =
|
|
(struct hal_vht_ndpa_sta_info *)ndpa;
|
|
if (PHL_RTYPE_STATION == psta_info->wrole->type)
|
|
ndpa_sta->aid12 = 0; /* Target is an AP, AID = 0 */
|
|
else
|
|
ndpa_sta->aid12 = psta_info->aid;
|
|
ndpa_sta->feedback_type = (mu == 0) ? HAL_NPDA_AC_SU : HAL_NPDA_AC_MU;
|
|
/* Nc shall alwary <= Nr */
|
|
if (psta_info->asoc_cap.max_nc >
|
|
psta_info->wrole->proto_role_cap.num_snd_dim) {
|
|
ndpa_sta->nc = psta_info->wrole->proto_role_cap.num_snd_dim;
|
|
} else {
|
|
ndpa_sta->nc = psta_info->asoc_cap.max_nc;
|
|
}
|
|
PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "vht ndpa_sta aid12 0x%x ; fb 0x%x ; nc 0x%x\n",
|
|
ndpa_sta->aid12, ndpa_sta->feedback_type, ndpa_sta->nc);
|
|
}
|
|
|
|
void
|
|
rtw_hal_snd_ndpa_sta_info_he(struct rtw_phl_stainfo_t *psta_info,
|
|
u32 *ndpa, enum channel_width bw, u8 fb_type)
|
|
{
|
|
|
|
struct hal_he_ndpa_sta_info *ndpa_sta =
|
|
(struct hal_he_ndpa_sta_info *)ndpa;
|
|
u16 ru_start = HAL_NPDA_RU_IDX_START;
|
|
u16 ru_end = _get_bw_ru_end_idx(bw);
|
|
|
|
if (PHL_RTYPE_STATION == psta_info->wrole->type)
|
|
ndpa_sta->aid = 0; /* Target is and AP, AID = 0 */
|
|
else
|
|
ndpa_sta->aid = (psta_info->aid&0x7FF);
|
|
ndpa_sta->bw = ((ru_start&0x7F) << 0) | ((ru_end&0x7F) << 7);
|
|
if (0 == fb_type) {
|
|
ndpa_sta->fb_ng = psta_info->asoc_cap.ng_16_su_fb ?
|
|
HAL_NDPA_AX_FB_SU_NG_16 : HAL_NDPA_AX_FB_SU_NG_4;
|
|
ndpa_sta->cb = psta_info->asoc_cap.cb_sz_su_fb ?
|
|
HAL_NPDA_AX_CB_SU42_MU75 : HAL_NPDA_AX_CB_SU64_MU97;
|
|
} else if (1 == fb_type) {
|
|
ndpa_sta->fb_ng = psta_info->asoc_cap.ng_16_mu_fb ?
|
|
HAL_NDPA_AX_FB_MU_NG_16 : HAL_NDPA_AX_FB_MU_NG_4;
|
|
ndpa_sta->cb = psta_info->asoc_cap.cb_sz_mu_fb ?
|
|
HAL_NPDA_AX_CB_SU42_MU75 : HAL_NPDA_AX_CB_SU64_MU97;
|
|
} else {
|
|
ndpa_sta->fb_ng = HAL_NDPA_AX_FB_CQI;
|
|
ndpa_sta->cb = 1;
|
|
}
|
|
ndpa_sta->disambiguation = 1;
|
|
/* Nc shall alwary <= Nr */
|
|
if (psta_info->asoc_cap.max_nc >
|
|
psta_info->wrole->proto_role_cap.num_snd_dim) {
|
|
ndpa_sta->nc = psta_info->wrole->proto_role_cap.num_snd_dim;
|
|
} else {
|
|
ndpa_sta->nc = psta_info->asoc_cap.max_nc;
|
|
}
|
|
PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "HE NDPA : aid 0x%x fb_ng 0x%x cb 0x%x nc 0x%x \n",
|
|
ndpa_sta->aid, ndpa_sta->fb_ng, ndpa_sta->cb, ndpa_sta->nc);
|
|
}
|
|
|
|
|
|
/**
|
|
* rtw_hal_snd_set_fw_cmd_dialogtkn()
|
|
* Set cmd dialog token value in NDPA
|
|
* input
|
|
* @he: is NDPA HE or not(VHT).
|
|
* @token: dialog token value.
|
|
**/
|
|
void rtw_hal_snd_set_fw_cmd_dialogtkn(void *hal, u8 *buf, u8 he, u8 token)
|
|
{
|
|
struct hal_ax_fwcmd_snd *cmd = (struct hal_ax_fwcmd_snd *)buf;
|
|
|
|
cmd->ndpa.snd_dialog.he = he;
|
|
cmd->ndpa.snd_dialog.token = token;
|
|
}
|
|
|
|
/**
|
|
* rtw_hal_snd_vht_fwcmd_su()
|
|
* Prepared VHT SU Sounding Fw Cmd.
|
|
* @hal:
|
|
* @buf: (struct hal_ax_fwcmd_snd *) cmd buffer pointer.
|
|
* @psta: (struct rtw_phl_stainfo_t *) STA to be sounding.
|
|
* @npda_sta: NPDA sta_info value
|
|
**/
|
|
void rtw_hal_snd_vht_fwcmd_su(void *hal, u8 *buf, enum channel_width bw,
|
|
struct rtw_phl_stainfo_t *psta, u32 *npda_sta)
|
|
{
|
|
struct hal_ax_fwcmd_snd *cmd = (struct hal_ax_fwcmd_snd *)buf;
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
struct hal_snd_obj *snd_obj =
|
|
(struct hal_snd_obj *)hal_info->hal_com->snd_obj;
|
|
u8 i = 0;
|
|
|
|
cmd->frame_ex_type = HAL_FEXG_TYPE_AC_SU;
|
|
cmd->macid[0] = psta->macid;
|
|
cmd->ndpa.common.frame_ctl = HAL_SND_VHT_NDPA_FRM_CTRL; /*TODO*/
|
|
for (i = 0; i < 6;i++) {
|
|
cmd->ndpa.common.addr1[i] = psta->mac_addr[i]; /* NDPA-RA*/
|
|
cmd->ndpa.common.addr2[i] = psta->wrole->mac_addr[i]; /* NDPA-TA*/
|
|
}
|
|
cmd->ndpa.common.duration = 100;
|
|
cmd->ndpa.ndpa_sta_info[0] = *npda_sta;
|
|
/* NDPA WD */
|
|
cmd->wd[0].txpktsize = 21;/* 2 + 2 + 6 + 6 + 1 + 4, NO FCS */
|
|
cmd->wd[0].ndpa_duration = 100;
|
|
cmd->wd[0].disdatafb = 1;
|
|
cmd->wd[0].datarate = snd_obj->ndpa_xpara.rate;
|
|
cmd->wd[0].data_bw = snd_obj->ndpa_xpara.bw;
|
|
cmd->wd[0].macid = psta->macid;
|
|
cmd->wd[0].gi_ltf = snd_obj->ndpa_xpara.gi_ltf;
|
|
cmd->wd[0].data_stbc = snd_obj->ndpa_xpara.stbc;
|
|
cmd->wd[0].data_ldpc = snd_obj->ndpa_xpara.ldpc;
|
|
cmd->wd[0].sifs_tx = 1;
|
|
cmd->wd[0].snd_pkt_sel = HAL_SND_PKT_SEL_UST_NDPA;/* unicast ndpa */
|
|
cmd->wd[0].ndpa = HAL_SND_PKT_NDPA_VHT;
|
|
/* NDP WD */
|
|
cmd->wd[1].disdatafb = 1;
|
|
if (1 == psta->wrole->proto_role_cap.num_snd_dim)
|
|
cmd->wd[1].datarate = RTW_DATA_RATE_VHT_NSS2_MCS0;
|
|
else if (2 ==psta->wrole->proto_role_cap.num_snd_dim)
|
|
cmd->wd[1].datarate = RTW_DATA_RATE_VHT_NSS3_MCS0;
|
|
else if (3 == psta->wrole->proto_role_cap.num_snd_dim)
|
|
cmd->wd[1].datarate = RTW_DATA_RATE_VHT_NSS4_MCS0;
|
|
else
|
|
cmd->wd[1].datarate = RTW_DATA_RATE_VHT_NSS2_MCS0;
|
|
PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "psta->asoc_cap.nss_rx = 0x%x\n", psta->asoc_cap.nss_rx);
|
|
PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "cmd->wd[1].datarate = 0x%x\n", cmd->wd[1].datarate);
|
|
cmd->wd[1].data_bw = bw;
|
|
cmd->wd[1].macid = psta->macid;
|
|
cmd->wd[1].gi_ltf = RTW_GILTF_LGI_4XHE32;
|
|
cmd->wd[1].sifs_tx = 0;
|
|
cmd->wd[1].snd_pkt_sel = HAL_SND_PKT_SEL_LAST_NDP;
|
|
cmd->wd[1].ndpa = HAL_SND_PKT_NDPA_VHT;
|
|
}
|
|
|
|
void rtw_hal_snd_vht_fwcmd_mu_add_sta(void *hal, u8 *buf, u32 *ndpa_sta,
|
|
struct rtw_phl_stainfo_t *sta,
|
|
u8 ndpa_idx, u8 last)
|
|
{
|
|
struct hal_ax_fwcmd_snd *cmd = (struct hal_ax_fwcmd_snd *)buf;
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
struct hal_snd_obj *snd_obj =
|
|
(struct hal_snd_obj *)hal_info->hal_com->snd_obj;
|
|
u8 i = 0;
|
|
PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "==> rtw_hal_snd_vht_fwcmd_mu_add_sta\n");
|
|
|
|
if (ndpa_idx >= HAL_MAX_VHT_SND_STA_NUM)
|
|
return;
|
|
|
|
cmd->macid[ndpa_idx] = sta->macid;
|
|
/* NDPA sta_info*/
|
|
cmd->ndpa.ndpa_sta_info[ndpa_idx] = *ndpa_sta;
|
|
PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "mac id 0x%x ; ndpa sta_info 0x%x\n",
|
|
cmd->macid[ndpa_idx], cmd->ndpa.ndpa_sta_info[ndpa_idx]);
|
|
|
|
/* VHT BFRP */
|
|
cmd->bfrp.hdr[ndpa_idx - 1].frame_ctl = HAL_SND_VHT_BFRP_FRM_CTRL;
|
|
cmd->bfrp.hdr[ndpa_idx - 1].duration = 100;
|
|
for (i = 0; i < 6; i++) {
|
|
cmd->bfrp.hdr[ndpa_idx - 1].addr1[i] = sta->mac_addr[i]; /* NDPA-RA = Broadcast*/
|
|
cmd->bfrp.hdr[ndpa_idx - 1].addr2[i] = sta->wrole->mac_addr[i]; /* NDPA-TA*/
|
|
}
|
|
cmd->bfrp.vht_para[ndpa_idx - 1].rexmit_bmp = 0;
|
|
/*BFRP WD*/
|
|
cmd->wd[1 + ndpa_idx].txpktsize = 17; /* 2 + 2 + 6 + 6 + 1 */
|
|
cmd->wd[1 + ndpa_idx].ndpa_duration = 100;
|
|
cmd->wd[1 + ndpa_idx].datarate = snd_obj->bfrp_xpara.rate;
|
|
cmd->wd[1 + ndpa_idx].data_ldpc = snd_obj->bfrp_xpara.ldpc;
|
|
cmd->wd[1 + ndpa_idx].data_stbc = snd_obj->bfrp_xpara.stbc;
|
|
cmd->wd[1 + ndpa_idx].macid = sta->macid;
|
|
cmd->wd[1 + ndpa_idx].data_bw = snd_obj->bfrp_xpara.bw;
|
|
cmd->wd[1 + ndpa_idx].gi_ltf = snd_obj->bfrp_xpara.gi_ltf;
|
|
cmd->wd[1 + ndpa_idx].disdatafb = 1;
|
|
if(last) {
|
|
cmd->wd[1 + ndpa_idx].sifs_tx = 0;
|
|
cmd->wd[1 + ndpa_idx].snd_pkt_sel = HAL_SND_PKT_SEL_LAST_BFRP;/* Final BFRP */
|
|
} else {
|
|
cmd->wd[1 + ndpa_idx].sifs_tx = 1;
|
|
cmd->wd[1 + ndpa_idx].snd_pkt_sel = HAL_SND_PKT_SEL_MID_BFRP;
|
|
}
|
|
cmd->wd[1 + ndpa_idx].ndpa = HAL_SND_PKT_NDPA_VHT;
|
|
|
|
}
|
|
|
|
void rtw_hal_snd_vht_fwcmd_mu_pri(void *hal, u8 *buf, enum channel_width bw,
|
|
struct rtw_phl_stainfo_t *psta, u8 sta_nr, u32 *ndpa_sta)
|
|
{
|
|
struct hal_ax_fwcmd_snd *cmd = (struct hal_ax_fwcmd_snd *)buf;
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
struct hal_snd_obj *snd_obj =
|
|
(struct hal_snd_obj *)hal_info->hal_com->snd_obj;
|
|
u8 i = 0;
|
|
|
|
if (sta_nr == 4)
|
|
cmd->frame_ex_type = HAL_FEXG_TYPE_AC_MU_3;
|
|
else if(sta_nr == 3)
|
|
cmd->frame_ex_type = HAL_FEXG_TYPE_AC_MU_2;
|
|
else if(sta_nr == 2)
|
|
cmd->frame_ex_type = HAL_FEXG_TYPE_AC_MU_1;
|
|
else
|
|
PHL_INFO("rtw_hal_snd_vht_fwcmd_mu_pri : ERROR!!!!!!!!!!!!!!!");
|
|
cmd->macid[0] = psta->macid;
|
|
|
|
/* NDPA */
|
|
cmd->ndpa.common.frame_ctl = HAL_SND_VHT_NDPA_FRM_CTRL;
|
|
for (i = 0; i < 6;i++) {
|
|
/**
|
|
* Addr1: In VHT Case, Fill User_0's MAC Address to match BF Entry,
|
|
* HW will auto re-fill to Broadcast Address
|
|
**/
|
|
cmd->ndpa.common.addr1[i] = psta->mac_addr[i];
|
|
cmd->ndpa.common.addr2[i] = psta->wrole->mac_addr[i]; /* NDPA-TA*/
|
|
}
|
|
cmd->ndpa.common.duration = 150;/*TODO:*/
|
|
/* primary sta ndpa sta_info*/
|
|
cmd->ndpa.ndpa_sta_info[0] = *ndpa_sta;
|
|
|
|
/* VHT BFRP ==> by STA */
|
|
|
|
/* NDPA WD */
|
|
cmd->wd[0].txpktsize = 17 + HAL_SND_VHT_NDPA_STA_SZ * sta_nr;/* 2 + 2 + 6 + 6 + 1 + 2, NO FCS */
|
|
cmd->wd[0].ndpa_duration = 150;
|
|
cmd->wd[0].disdatafb = 1;
|
|
cmd->wd[0].datarate = snd_obj->ndpa_xpara.rate;
|
|
cmd->wd[0].data_bw = snd_obj->ndpa_xpara.bw;
|
|
cmd->wd[0].data_ldpc = snd_obj->ndpa_xpara.ldpc;
|
|
cmd->wd[0].data_stbc = snd_obj->ndpa_xpara.stbc;
|
|
cmd->wd[0].macid = psta->macid;
|
|
cmd->wd[0].gi_ltf = snd_obj->ndpa_xpara.gi_ltf;
|
|
cmd->wd[0].sifs_tx = 1;
|
|
cmd->wd[0].snd_pkt_sel = HAL_SND_PKT_SEL_BST_NDPA;
|
|
cmd->wd[0].ndpa = HAL_SND_PKT_NDPA_VHT;
|
|
/* NDP WD */
|
|
cmd->wd[1].disdatafb = 1;
|
|
if (1 == psta->wrole->proto_role_cap.num_snd_dim)
|
|
cmd->wd[1].datarate = RTW_DATA_RATE_VHT_NSS2_MCS0;
|
|
else if (2 == psta->wrole->proto_role_cap.num_snd_dim)
|
|
cmd->wd[1].datarate = RTW_DATA_RATE_VHT_NSS3_MCS0;
|
|
else if (3 == psta->wrole->proto_role_cap.num_snd_dim)
|
|
cmd->wd[1].datarate = RTW_DATA_RATE_VHT_NSS4_MCS0;
|
|
else
|
|
cmd->wd[1].datarate = RTW_DATA_RATE_VHT_NSS2_MCS0;
|
|
cmd->wd[1].data_bw = bw;
|
|
cmd->wd[1].macid = psta->macid;
|
|
cmd->wd[1].gi_ltf = RTW_GILTF_LGI_4XHE32;
|
|
cmd->wd[1].sifs_tx = 1;
|
|
cmd->wd[1].snd_pkt_sel = HAL_SND_PKT_SEL_MID_NDP;/*Last NDP*/
|
|
cmd->wd[1].ndpa = HAL_SND_PKT_NDPA_VHT;
|
|
}
|
|
|
|
/* HE FW Command */
|
|
/**
|
|
* rtw_hal_snd_ax_fwcmd_su()
|
|
* fill the fw cmd for HE sounding type HE Non-TB : NDPA - NDP - CSI Report
|
|
*
|
|
**/
|
|
void rtw_hal_snd_ax_fwcmd_nontb(void *hal, u8 *buf, enum channel_width bw,
|
|
struct rtw_phl_stainfo_t *psta, u32 *npda_sta)
|
|
{
|
|
struct hal_ax_fwcmd_snd *cmd = (struct hal_ax_fwcmd_snd *)buf;
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
struct hal_snd_obj *snd_obj =
|
|
(struct hal_snd_obj *)hal_info->hal_com->snd_obj;
|
|
u8 i = 0;
|
|
|
|
cmd->frame_ex_type = HAL_FEXG_TYPE_AX_SU;
|
|
cmd->macid[0] = psta->macid;
|
|
cmd->ndpa.common.frame_ctl = HAL_SND_HE_NDPA_FRM_CTRL;
|
|
for (i = 0; i < 6;i++) {
|
|
cmd->ndpa.common.addr1[i] = psta->mac_addr[i]; /* NDPA-RA*/
|
|
cmd->ndpa.common.addr2[i] = psta->wrole->mac_addr[i]; /* NDPA-TA*/
|
|
}
|
|
cmd->ndpa.common.duration = 100;
|
|
cmd->ndpa.ndpa_sta_info[0] = *npda_sta;
|
|
/* NDPA WD */
|
|
cmd->wd[0].txpktsize = 21;/* 2 + 2 + 6 + 6 + 1 + 4, NO FCS */
|
|
cmd->wd[0].ndpa_duration = 100;
|
|
cmd->wd[0].disdatafb = 1;
|
|
cmd->wd[0].datarate = snd_obj->ndpa_xpara.rate;
|
|
cmd->wd[0].data_bw = snd_obj->ndpa_xpara.bw;
|
|
cmd->wd[0].data_stbc = snd_obj->ndpa_xpara.stbc;
|
|
cmd->wd[0].data_ldpc = snd_obj->ndpa_xpara.ldpc;
|
|
cmd->wd[0].macid = psta->macid;
|
|
cmd->wd[0].gi_ltf = snd_obj->ndpa_xpara.gi_ltf;
|
|
cmd->wd[0].sifs_tx = 1;
|
|
cmd->wd[0].snd_pkt_sel = HAL_SND_PKT_SEL_UST_NDPA;/*unicast ndpa*/
|
|
cmd->wd[0].ndpa = HAL_SND_PKT_NDPA_HE;
|
|
/* NDP WD */
|
|
cmd->wd[1].disdatafb = 1;
|
|
if (1 == psta->wrole->proto_role_cap.num_snd_dim)
|
|
cmd->wd[1].datarate = RTW_DATA_RATE_HE_NSS2_MCS0;
|
|
else if (2 == psta->wrole->proto_role_cap.num_snd_dim)
|
|
cmd->wd[1].datarate = RTW_DATA_RATE_HE_NSS3_MCS0;
|
|
else if (3 == psta->wrole->proto_role_cap.num_snd_dim)
|
|
cmd->wd[1].datarate = RTW_DATA_RATE_HE_NSS4_MCS0;
|
|
else
|
|
cmd->wd[1].datarate = RTW_DATA_RATE_HE_NSS2_MCS0;
|
|
cmd->wd[1].data_bw = bw;
|
|
cmd->wd[1].macid = psta->macid;
|
|
cmd->wd[1].gi_ltf = RTW_GILTF_2XHE16; /* TODO: if psta->asoc_cap.ltf_gi support NDP 4XHE32;*/
|
|
cmd->wd[1].sifs_tx = 0;
|
|
cmd->wd[1].snd_pkt_sel = HAL_SND_PKT_SEL_LAST_NDP;
|
|
cmd->wd[1].ndpa = HAL_SND_PKT_NDPA_HE;
|
|
}
|
|
|
|
/**
|
|
* rtw_hal_snd_ax_fwcmd_tb_add_sta()
|
|
* fill fw cmd for HE sounding with TB case.
|
|
* shall call rtw_hal_snd_ax_fwcmd_tb_pri() first, and add STA by this api.
|
|
* Note that RU-Allocation shall dicide from phl caller,
|
|
* and shall avoid same with others
|
|
* function input:
|
|
* @hal:
|
|
* @buf: (struct hal_ax_fwcmd_snd *) command buf pointer.
|
|
* @ndpa_sta:
|
|
* @sta: (struct rtw_phl_stainfo_t *)
|
|
* @ru_idx: RU Allocation index;
|
|
* @ndpa_idx: 0-7 for 8852a
|
|
* @bfrp_idx: 0-1 for 8852a
|
|
* @bfrp_u_idx: 0-3 for 8852a
|
|
**/
|
|
void rtw_hal_snd_ax_fwcmd_tb_add_sta(void *hal, u8 *buf, u32 *ndpa_sta,
|
|
struct rtw_phl_stainfo_t *sta, u8 ru_idx,
|
|
u8 ndpa_idx, u8 bfrp_idx, u8 bfrp_u_idx)
|
|
{
|
|
struct hal_ax_fwcmd_snd *cmd = (struct hal_ax_fwcmd_snd *)buf;
|
|
struct hal_he_ndpa_sta_info *ndpa =
|
|
(struct hal_he_ndpa_sta_info *)ndpa_sta;
|
|
u8 mu = 0, ng = 4;
|
|
u32 rpt_size = 0;
|
|
|
|
if (ndpa_idx >= HAL_MAX_HE_SND_STA_NUM)
|
|
return;
|
|
if (bfrp_idx >= HAL_MAX_HE_BFRP_NUM)
|
|
return;
|
|
cmd->macid[ndpa_idx] = sta->macid;
|
|
/* NDPA sta_info*/
|
|
cmd->ndpa.ndpa_sta_info[ndpa_idx] = *ndpa_sta;
|
|
/* BFRP user_info */
|
|
cmd->bfrp.he_para[bfrp_idx].fbseg_rexmit_bmp[bfrp_u_idx] = 0;
|
|
cmd->bfrp.he_para[bfrp_idx].user[bfrp_u_idx].aid12 = sta->aid;
|
|
if (cmd->bfrp.he_para[bfrp_idx].common.ul_bw > CHANNEL_WIDTH_80) {
|
|
ru_idx = (ru_idx << 1) | BIT(0);
|
|
} else {
|
|
ru_idx = (ru_idx << 1) &(~BIT(0));
|
|
}
|
|
cmd->bfrp.he_para[bfrp_idx].user[bfrp_u_idx].ru_pos = ru_idx;
|
|
|
|
cmd->bfrp.he_para[bfrp_idx].user[bfrp_u_idx].ul_fec_code = 0;
|
|
cmd->bfrp.he_para[bfrp_idx].user[bfrp_u_idx].ul_mcs = 3;/* HE-MCS3, TODO: Default value of golden */
|
|
cmd->bfrp.he_para[bfrp_idx].user[bfrp_u_idx].ul_dcm = 0 ;
|
|
cmd->bfrp.he_para[bfrp_idx].user[bfrp_u_idx].ss_alloc = 0;/* 1SS, TODO: Default value of golden */
|
|
cmd->bfrp.he_para[bfrp_idx].user[bfrp_u_idx].ul_tgt_rssi =
|
|
(u8)(sta->hal_sta->rssi_stat.rssi >> 1);/*TODO: From Rx ST SU RSSI */
|
|
if (ndpa->fb_ng == HAL_NDPA_AX_FB_MU_NG_4) {
|
|
mu = 1;
|
|
ng = 4;
|
|
} else if (ndpa->fb_ng == HAL_NDPA_AX_FB_MU_NG_16) {
|
|
mu = 1;
|
|
ng = 16;
|
|
} else if (ndpa->fb_ng == HAL_NDPA_AX_FB_SU_NG_4) {
|
|
mu = 0;
|
|
ng = 4;
|
|
} else if (ndpa->fb_ng == HAL_NDPA_AX_FB_SU_NG_16) {
|
|
mu = 0;
|
|
ng = 4;
|
|
}
|
|
rpt_size = _cal_he_csi_size(mu, sta->chandef.bw,
|
|
(sta->wrole->proto_role_cap.num_snd_dim + 1),
|
|
((u8)ndpa->nc + 1), ng, (u8)ndpa->cb);
|
|
if (cmd->bfrp.he_para[bfrp_idx].f2p_info.csi_len_bfrp < (rpt_size/64))
|
|
cmd->bfrp.he_para[bfrp_idx].f2p_info.csi_len_bfrp =
|
|
(u16)(rpt_size / 64); /*unit 64 byte*/
|
|
}
|
|
|
|
void rtw_hal_snd_ax_fwcmd_tb_pri(void *hal, u8 *buf, enum channel_width bw,
|
|
struct rtw_phl_stainfo_t *psta, u8 sta_nr1, u8 sta_nr2)
|
|
{
|
|
struct hal_ax_fwcmd_snd *cmd = (struct hal_ax_fwcmd_snd *)buf;
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
struct hal_snd_obj *snd_obj =
|
|
(struct hal_snd_obj *)hal_info->hal_com->snd_obj;
|
|
u8 i = 0;
|
|
u8 sta_nr = sta_nr1 + sta_nr2;
|
|
|
|
if (sta_nr2 != 0)
|
|
cmd->frame_ex_type = HAL_FEXG_TYPE_AX_MU_2;
|
|
else
|
|
cmd->frame_ex_type = HAL_FEXG_TYPE_AX_MU_1;
|
|
cmd->bfrp0_sta_nr = sta_nr1;
|
|
cmd->bfrp1_sta_nr = sta_nr2;
|
|
cmd->macid[0] = psta->macid;
|
|
|
|
/* NDPA */
|
|
cmd->ndpa.common.frame_ctl = HAL_SND_HE_NDPA_FRM_CTRL; /*TODO:*/
|
|
for (i = 0; i < 6;i++) {
|
|
cmd->ndpa.common.addr1[i] = 0xFF; /* NDPA-RA = Broadcast*/
|
|
cmd->ndpa.common.addr2[i] = psta->wrole->mac_addr[i]; /* NDPA-TA*/
|
|
/* BFRP - 1*/
|
|
cmd->bfrp.hdr[0].addr1[i] = 0xFF;
|
|
cmd->bfrp.hdr[0].addr2[i] = psta->wrole->mac_addr[i];
|
|
if (sta_nr2 != 0) {
|
|
/* BFRP - 2*/
|
|
cmd->bfrp.hdr[1].addr1[i] = 0xFF;
|
|
cmd->bfrp.hdr[1].addr2[i] = psta->wrole->mac_addr[i];
|
|
}
|
|
}
|
|
cmd->ndpa.common.duration = 150;/*TODO:*/
|
|
/*TODO: ndpa user info in other api */
|
|
|
|
/* BFRP #1 */
|
|
cmd->bfrp.hdr[0].frame_ctl = HAL_SND_HE_BFRP_FRM_CTRL; /* Trigger Frame */
|
|
cmd->bfrp.hdr[0].duration = 100;
|
|
cmd->bfrp.he_para[0].common.tgr_info = HAL_SND_TRIG_INFO_BFRP;/*BFRP*/
|
|
cmd->bfrp.he_para[0].common.ul_len = 0xFFF;/*TODO: LSIG Length : sw provide or fw calculate */
|
|
cmd->bfrp.he_para[0].common.more_tf = 0;
|
|
cmd->bfrp.he_para[0].common.cs_rqd = 1;
|
|
cmd->bfrp.he_para[0].common.ul_bw = bw;
|
|
cmd->bfrp.he_para[0].common.gi_ltf = RTW_TB_GILTF_4XHE32;/* 8852A Limitation of UL OFDMA */
|
|
cmd->bfrp.he_para[0].common.num_heltf = 0;/* TODO: Default value of golden */
|
|
cmd->bfrp.he_para[0].common.ul_pktext = 0;/* TODO: fw? hw? */
|
|
cmd->bfrp.he_para[0].common.ap_tx_pwr = 0x3C;/* TODO: Default value of golden */
|
|
|
|
/* F2P cmd parameters */
|
|
cmd->bfrp.he_para[0].f2p_info.tb_t_pe_bfrp = 2;
|
|
cmd->bfrp.he_para[0].f2p_info.tri_pad_bfrp = 2;
|
|
cmd->bfrp.he_para[0].f2p_info.ul_cqi_rpt_tri_bfrp = 0;
|
|
cmd->bfrp.he_para[0].f2p_info.rf_gain_idx_bfrp = 0;/* ?? */
|
|
cmd->bfrp.he_para[0].f2p_info.fix_gain_en_bfrp = 0;/* ?? */
|
|
|
|
if (sta_nr2) {
|
|
cmd->bfrp.hdr[1].frame_ctl = HAL_SND_HE_BFRP_FRM_CTRL; /* Trigger Frame */
|
|
cmd->bfrp.hdr[1].duration = 100;
|
|
cmd->bfrp.he_para[1].common.tgr_info = HAL_SND_TRIG_INFO_BFRP;/*BFRP*/
|
|
cmd->bfrp.he_para[1].common.ul_len = 0xFFF;/*TODO: LSIG Length : sw provide or fw calculate */
|
|
cmd->bfrp.he_para[1].common.more_tf = 0;
|
|
cmd->bfrp.he_para[1].common.cs_rqd = 1;
|
|
cmd->bfrp.he_para[1].common.ul_bw = bw;
|
|
cmd->bfrp.he_para[1].common.gi_ltf = RTW_TB_GILTF_4XHE32;/* 8852A Limitation of UL OFDMA */
|
|
cmd->bfrp.he_para[1].common.num_heltf = 0;/* TODO: Default value of golden */
|
|
cmd->bfrp.he_para[1].common.ul_pktext = 0;/* TODO: fw? hw? */
|
|
cmd->bfrp.he_para[1].common.ap_tx_pwr = 0x32;/* TODO: Default value of golden */
|
|
|
|
cmd->bfrp.he_para[1].f2p_info.tb_t_pe_bfrp = 2;
|
|
cmd->bfrp.he_para[1].f2p_info.tri_pad_bfrp = 2;
|
|
cmd->bfrp.he_para[1].f2p_info.ul_cqi_rpt_tri_bfrp = 0;
|
|
cmd->bfrp.he_para[1].f2p_info.rf_gain_idx_bfrp = 0;
|
|
cmd->bfrp.he_para[1].f2p_info.fix_gain_en_bfrp = 0;
|
|
}
|
|
/* NDPA WD */
|
|
cmd->wd[0].txpktsize = 17 + HAL_SND_HE_NDPA_STA_SZ * sta_nr;/* 2 + 2 + 6 + 6 + 1 + 4, NO FCS */
|
|
cmd->wd[0].ndpa_duration = 100;
|
|
cmd->wd[0].disdatafb = 1;
|
|
cmd->wd[0].datarate = snd_obj->ndpa_xpara.rate;
|
|
cmd->wd[0].data_bw = snd_obj->ndpa_xpara.bw;
|
|
cmd->wd[0].data_stbc = snd_obj->ndpa_xpara.stbc;
|
|
cmd->wd[0].data_ldpc = snd_obj->ndpa_xpara.ldpc;
|
|
cmd->wd[0].macid = psta->macid;
|
|
cmd->wd[0].gi_ltf = snd_obj->ndpa_xpara.gi_ltf;
|
|
cmd->wd[0].sifs_tx = 1;
|
|
cmd->wd[0].snd_pkt_sel = HAL_SND_PKT_SEL_BST_NDPA;
|
|
cmd->wd[0].ndpa = HAL_SND_PKT_NDPA_HE;
|
|
/* NDP WD */
|
|
cmd->wd[1].disdatafb = 1;
|
|
if (1 == psta->wrole->proto_role_cap.num_snd_dim)
|
|
cmd->wd[1].datarate = RTW_DATA_RATE_HE_NSS2_MCS0;
|
|
else if (2 == psta->wrole->proto_role_cap.num_snd_dim)
|
|
cmd->wd[1].datarate = RTW_DATA_RATE_HE_NSS3_MCS0;
|
|
else if(3 == psta->wrole->proto_role_cap.num_snd_dim)
|
|
cmd->wd[1].datarate = RTW_DATA_RATE_HE_NSS4_MCS0;
|
|
else
|
|
cmd->wd[1].datarate = RTW_DATA_RATE_HE_NSS2_MCS0;
|
|
cmd->wd[1].data_bw = bw;
|
|
cmd->wd[1].macid = psta->macid;
|
|
cmd->wd[1].gi_ltf = RTW_GILTF_2XHE16; /* TODO: if support 4x32 NDP */
|
|
cmd->wd[1].sifs_tx = 0;
|
|
cmd->wd[1].snd_pkt_sel = HAL_SND_PKT_SEL_MID_NDP;
|
|
cmd->wd[1].ndpa = HAL_SND_PKT_NDPA_HE;
|
|
/* BFRP #1 WD */
|
|
cmd->wd[2].txpktsize = 24 + HAL_SND_HE_BFRP_STA_SZ * sta_nr1; /* 2 + 2 + 6 + 6 + 8 + 5*N */
|
|
cmd->wd[2].ndpa_duration = 100;
|
|
cmd->wd[2].datarate = snd_obj->bfrp_xpara.rate;
|
|
//cmd->wd[2].macid
|
|
cmd->wd[2].data_bw = snd_obj->bfrp_xpara.bw;
|
|
cmd->wd[2].data_stbc = snd_obj->bfrp_xpara.stbc;
|
|
cmd->wd[2].data_ldpc = snd_obj->bfrp_xpara.ldpc;
|
|
cmd->wd[2].gi_ltf = snd_obj->bfrp_xpara.gi_ltf;
|
|
cmd->wd[2].disdatafb = 1;
|
|
if(sta_nr2) {
|
|
cmd->wd[2].sifs_tx = 1;
|
|
cmd->wd[2].snd_pkt_sel = HAL_SND_PKT_SEL_MID_BFRP;
|
|
} else {
|
|
cmd->wd[2].sifs_tx = 0;/* Final BFRP */
|
|
cmd->wd[2].snd_pkt_sel = HAL_SND_PKT_SEL_LAST_BFRP;
|
|
}
|
|
cmd->wd[2].ndpa = HAL_SND_PKT_NDPA_HE;
|
|
if (sta_nr2) {
|
|
cmd->wd[3].txpktsize = 24 + HAL_SND_HE_BFRP_STA_SZ * sta_nr2; /* 2 + 2 + 6 + 6 + 8 + 5*N */
|
|
cmd->wd[3].ndpa_duration = 100;
|
|
cmd->wd[3].datarate = snd_obj->bfrp_xpara.rate;
|
|
cmd->wd[3].data_bw = snd_obj->bfrp_xpara.bw;
|
|
cmd->wd[3].data_stbc = snd_obj->bfrp_xpara.stbc;
|
|
cmd->wd[3].data_ldpc = snd_obj->bfrp_xpara.ldpc;
|
|
cmd->wd[3].gi_ltf = snd_obj->bfrp_xpara.gi_ltf;
|
|
cmd->wd[3].disdatafb = 1;
|
|
cmd->wd[3].sifs_tx = 0;/* Final BFRP */
|
|
cmd->wd[3].snd_pkt_sel = HAL_SND_PKT_SEL_LAST_BFRP;
|
|
cmd->wd[3].ndpa = HAL_SND_PKT_NDPA_HE;
|
|
}
|
|
}
|
|
|
|
u8 *
|
|
rtw_hal_snd_prepare_snd_cmd(void *hal)
|
|
{
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
u8 *buf = NULL;
|
|
|
|
buf = _os_mem_alloc(hal_to_drvpriv(hal_info),
|
|
sizeof(struct hal_ax_fwcmd_snd));
|
|
|
|
return buf;
|
|
}
|
|
|
|
|
|
enum rtw_hal_status
|
|
rtw_hal_snd_release_snd_cmd(void *hal, u8 *buf)
|
|
{
|
|
enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
|
|
do {
|
|
if (buf == NULL)
|
|
break;
|
|
_os_mem_free(hal_to_drvpriv(hal_info), buf,
|
|
sizeof(struct hal_ax_fwcmd_snd));
|
|
} while (0);
|
|
|
|
return hstatus;
|
|
}
|
|
|
|
|
|
enum rtw_hal_status
|
|
rtw_hal_snd_send_fw_cmd(void *hal, u8 *cmd)
|
|
{
|
|
enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
|
|
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
|
|
PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "==> rtw_hal_snd_send_fw_cmd \n");
|
|
hstatus = hal_mac_ax_send_fw_snd(hal_info,
|
|
(struct hal_ax_fwcmd_snd *)cmd);
|
|
/*TODO: Dump CMD content */
|
|
PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "<== rtw_hal_snd_send_fw_cmd \n");
|
|
return hstatus;
|
|
}
|