const union rtw89_fw_element_arg arg)
{
struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
- struct rtw89_phy_table *tbl;
+ struct rtw89_hal *hal = &rtwdev->hal;
+ struct rtw89_phy_table *tbl, **pp;
struct rtw89_reg2_def *regs;
- enum rtw89_rf_path rf_path;
+ bool radio = false;
u32 n_regs, i;
+ u16 aid;
u8 idx;
- tbl = kzalloc(sizeof(*tbl), GFP_KERNEL);
- if (!tbl)
- return -ENOMEM;
-
switch (le32_to_cpu(elm->id)) {
case RTW89_FW_ELEMENT_ID_BB_REG:
- elm_info->bb_tbl = tbl;
+ pp = &elm_info->bb_tbl;
break;
case RTW89_FW_ELEMENT_ID_BB_GAIN:
- elm_info->bb_gain = tbl;
+ pp = &elm_info->bb_gain;
break;
case RTW89_FW_ELEMENT_ID_RADIO_A:
case RTW89_FW_ELEMENT_ID_RADIO_B:
case RTW89_FW_ELEMENT_ID_RADIO_C:
case RTW89_FW_ELEMENT_ID_RADIO_D:
- rf_path = arg.rf_path;
idx = elm->u.reg2.idx;
+ pp = &elm_info->rf_radio[idx];
- elm_info->rf_radio[idx] = tbl;
- tbl->rf_path = rf_path;
- tbl->config = rtw89_phy_config_rf_reg_v1;
+ radio = true;
break;
case RTW89_FW_ELEMENT_ID_RF_NCTL:
- elm_info->rf_nctl = tbl;
+ pp = &elm_info->rf_nctl;
break;
default:
- kfree(tbl);
return -ENOENT;
}
+ aid = le16_to_cpu(elm->aid);
+ if (aid && aid != hal->aid)
+ return 1; /* ignore if aid not matched */
+ else if (*pp)
+ return 1; /* ignore if an element is existing */
+
+ tbl = kzalloc(sizeof(*tbl), GFP_KERNEL);
+ if (!tbl)
+ return -ENOMEM;
+
n_regs = le32_to_cpu(elm->size) / sizeof(tbl->regs[0]);
regs = kcalloc(n_regs, sizeof(*regs), GFP_KERNEL);
if (!regs)
tbl->n_regs = n_regs;
tbl->regs = regs;
+ if (radio) {
+ tbl->rf_path = arg.rf_path;
+ tbl->config = rtw89_phy_config_rf_reg_v1;
+ }
+
+ *pp = tbl;
+
return 0;
out: