Commit d60e73e5 authored by Ping-Ke Shih's avatar Ping-Ke Shih Committed by Kalle Valo

wifi: rtw89: fw: load TX power track tables from fw_element

The TX power track tables are used to define compensation power reflected
to thermal value. Currently, we have 16 (2 * 4 * 2) tables made by
combinations of
  {negative/positive thermal value, 2GHz/2GHz-CCK/5GHz/6GHz, path A/B}
Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://msgid.link/20231213005054.10568-2-pkshih@realtek.com
parent f0dd488e
......@@ -17,6 +17,7 @@ struct rtw89_pci_info;
struct rtw89_mac_gen_def;
struct rtw89_phy_gen_def;
struct rtw89_efuse_block_cfg;
struct rtw89_fw_txpwr_track_cfg;
extern const struct ieee80211_ops rtw89_ops;
......@@ -38,6 +39,8 @@ extern const struct ieee80211_ops rtw89_ops;
#define RSSI_FACTOR 1
#define RTW89_RSSI_RAW_TO_DBM(rssi) ((s8)((rssi) >> RSSI_FACTOR) - MAX_RSSI)
#define RTW89_TX_DIV_RSSI_RAW_TH (2 << RSSI_FACTOR)
#define DELTA_SWINGIDX_SIZE 30
#define RTW89_RADIOTAP_ROOM_HE sizeof(struct ieee80211_radiotap_he)
#define RTW89_RADIOTAP_ROOM_EHT \
(sizeof(struct ieee80211_radiotap_tlv) + \
......@@ -3948,6 +3951,7 @@ struct rtw89_fw_elm_info {
struct rtw89_phy_table *bb_gain;
struct rtw89_phy_table *rf_radio[RF_PATH_MAX];
struct rtw89_phy_table *rf_nctl;
struct rtw89_fw_txpwr_track_cfg *txpwr_trk;
};
struct rtw89_fw_info {
......
......@@ -659,6 +659,72 @@ int rtw89_fw_recognize_txpwr_from_elm(struct rtw89_dev *rtwdev,
return 0;
}
static
int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev,
const struct rtw89_fw_element_hdr *elm,
const union rtw89_fw_element_arg arg)
{
struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
const struct rtw89_chip_info *chip = rtwdev->chip;
u32 needed_bitmap = 0;
u32 offset = 0;
int subband;
u32 bitmap;
int type;
if (chip->support_bands & BIT(NL80211_BAND_6GHZ))
needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_6GHZ;
if (chip->support_bands & BIT(NL80211_BAND_5GHZ))
needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_5GHZ;
if (chip->support_bands & BIT(NL80211_BAND_2GHZ))
needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_2GHZ;
bitmap = le32_to_cpu(elm->u.txpwr_trk.bitmap);
if ((bitmap & needed_bitmap) != needed_bitmap) {
rtw89_warn(rtwdev, "needed txpwr trk bitmap %08x but %0x8x\n",
needed_bitmap, bitmap);
return -ENOENT;
}
elm_info->txpwr_trk = kzalloc(sizeof(*elm_info->txpwr_trk), GFP_KERNEL);
if (!elm_info->txpwr_trk)
return -ENOMEM;
for (type = 0; bitmap; type++, bitmap >>= 1) {
if (!(bitmap & BIT(0)))
continue;
if (type >= __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_START &&
type <= __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_MAX)
subband = 4;
else if (type >= __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_START &&
type <= __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_MAX)
subband = 3;
else if (type >= __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_START &&
type <= __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_MAX)
subband = 1;
else
break;
elm_info->txpwr_trk->delta[type] = &elm->u.txpwr_trk.contents[offset];
offset += subband;
if (offset * DELTA_SWINGIDX_SIZE > le32_to_cpu(elm->size))
goto err;
}
return 0;
err:
rtw89_warn(rtwdev, "unexpected txpwr trk offset %d over size %d\n",
offset, le32_to_cpu(elm->size));
kfree(elm_info->txpwr_trk);
elm_info->txpwr_trk = NULL;
return -EFAULT;
}
static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
[RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm,
{ .fw_type = RTW89_FW_BBMCU0 }, NULL},
......@@ -711,6 +777,9 @@ static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
rtw89_fw_recognize_txpwr_from_elm,
{ .offset = offsetof(struct rtw89_rfe_data, tx_shape_lmt_ru.conf) }, NULL,
},
[RTW89_FW_ELEMENT_ID_TXPWR_TRK] = {
rtw89_build_txpwr_trk_tbl_from_elm, {}, "PWR_TRK",
},
};
int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev)
......@@ -1144,6 +1213,8 @@ static void rtw89_unload_firmware_elements(struct rtw89_dev *rtwdev)
for (i = 0; i < ARRAY_SIZE(elm_info->rf_radio); i++)
rtw89_free_phy_tbl_from_elm(elm_info->rf_radio[i]);
rtw89_free_phy_tbl_from_elm(elm_info->rf_nctl);
kfree(elm_info->txpwr_trk);
}
void rtw89_unload_firmware(struct rtw89_dev *rtwdev)
......
......@@ -3426,6 +3426,7 @@ enum rtw89_fw_element_id {
RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_6GHZ = 15,
RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT = 16,
RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT_RU = 17,
RTW89_FW_ELEMENT_ID_TXPWR_TRK = 18,
RTW89_FW_ELEMENT_ID_NUM,
};
......@@ -3446,6 +3447,7 @@ enum rtw89_fw_element_id {
BIT(RTW89_FW_ELEMENT_ID_RADIO_A) | \
BIT(RTW89_FW_ELEMENT_ID_RADIO_B) | \
BIT(RTW89_FW_ELEMENT_ID_RF_NCTL) | \
BIT(RTW89_FW_ELEMENT_ID_TXPWR_TRK) | \
BITS_OF_RTW89_TXPWR_FW_ELEMENTS)
struct __rtw89_fw_txpwr_element {
......@@ -3457,6 +3459,59 @@ struct __rtw89_fw_txpwr_element {
u8 content[];
} __packed;
enum rtw89_fw_txpwr_trk_type {
__RTW89_FW_TXPWR_TRK_TYPE_6GHZ_START = 0,
RTW89_FW_TXPWR_TRK_TYPE_6GB_N = 0,
RTW89_FW_TXPWR_TRK_TYPE_6GB_P = 1,
RTW89_FW_TXPWR_TRK_TYPE_6GA_N = 2,
RTW89_FW_TXPWR_TRK_TYPE_6GA_P = 3,
__RTW89_FW_TXPWR_TRK_TYPE_6GHZ_MAX = 3,
__RTW89_FW_TXPWR_TRK_TYPE_5GHZ_START = 4,
RTW89_FW_TXPWR_TRK_TYPE_5GB_N = 4,
RTW89_FW_TXPWR_TRK_TYPE_5GB_P = 5,
RTW89_FW_TXPWR_TRK_TYPE_5GA_N = 6,
RTW89_FW_TXPWR_TRK_TYPE_5GA_P = 7,
__RTW89_FW_TXPWR_TRK_TYPE_5GHZ_MAX = 7,
__RTW89_FW_TXPWR_TRK_TYPE_2GHZ_START = 8,
RTW89_FW_TXPWR_TRK_TYPE_2GB_N = 8,
RTW89_FW_TXPWR_TRK_TYPE_2GB_P = 9,
RTW89_FW_TXPWR_TRK_TYPE_2GA_N = 10,
RTW89_FW_TXPWR_TRK_TYPE_2GA_P = 11,
RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_N = 12,
RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_P = 13,
RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_N = 14,
RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_P = 15,
__RTW89_FW_TXPWR_TRK_TYPE_2GHZ_MAX = 15,
RTW89_FW_TXPWR_TRK_TYPE_NR,
};
struct rtw89_fw_txpwr_track_cfg {
const s8 (*delta[RTW89_FW_TXPWR_TRK_TYPE_NR])[DELTA_SWINGIDX_SIZE];
};
#define RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_6GHZ \
(BIT(RTW89_FW_TXPWR_TRK_TYPE_6GB_N) | \
BIT(RTW89_FW_TXPWR_TRK_TYPE_6GB_P) | \
BIT(RTW89_FW_TXPWR_TRK_TYPE_6GA_N) | \
BIT(RTW89_FW_TXPWR_TRK_TYPE_6GA_P))
#define RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_5GHZ \
(BIT(RTW89_FW_TXPWR_TRK_TYPE_5GB_N) | \
BIT(RTW89_FW_TXPWR_TRK_TYPE_5GB_P) | \
BIT(RTW89_FW_TXPWR_TRK_TYPE_5GA_N) | \
BIT(RTW89_FW_TXPWR_TRK_TYPE_5GA_P))
#define RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_2GHZ \
(BIT(RTW89_FW_TXPWR_TRK_TYPE_2GB_N) | \
BIT(RTW89_FW_TXPWR_TRK_TYPE_2GB_P) | \
BIT(RTW89_FW_TXPWR_TRK_TYPE_2GA_N) | \
BIT(RTW89_FW_TXPWR_TRK_TYPE_2GA_P) | \
BIT(RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_N) | \
BIT(RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_P) | \
BIT(RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_N) | \
BIT(RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_P))
struct rtw89_fw_element_hdr {
__le32 id; /* enum rtw89_fw_element_id */
__le32 size; /* exclude header size */
......@@ -3477,6 +3532,11 @@ struct rtw89_fw_element_hdr {
__le32 data;
} __packed regs[];
} __packed reg2;
struct {
__le32 bitmap; /* bitmap of enum rtw89_fw_txpwr_trk_type */
__le32 rsvd;
s8 contents[][DELTA_SWINGIDX_SIZE];
} __packed txpwr_trk;
struct __rtw89_fw_txpwr_element txpwr;
} __packed u;
} __packed;
......
......@@ -291,8 +291,6 @@ struct rtw89_txpwr_byrate_cfg {
u32 data;
};
#define DELTA_SWINGIDX_SIZE 30
struct rtw89_txpwr_track_cfg {
const s8 (*delta_swingidx_6gb_n)[DELTA_SWINGIDX_SIZE];
const s8 (*delta_swingidx_6gb_p)[DELTA_SWINGIDX_SIZE];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment