[PATCH v4 4/4] wifi: ath12k: add set band edge channel power for WCN7850
Lingbo Kong
quic_lingbok at quicinc.com
Sun Sep 10 01:28:02 PDT 2023
Currently, ath12k does not have the ability to set band edge channel power
for WCN7850. In order to support this, ath12k gets band edge channel power
table in ath12k_acpi_dsm_get_data() function and sets pdev_id and
param_type_id, then finally sends these data and
WMI_PDEV_SET_BIOS_INTERFACE_CMDID to firmware to set band edge channel
power.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
Signed-off-by: Lingbo Kong <quic_lingbok at quicinc.com>
---
v4:
1.revise commit log using imperative voice
v3:
1.remove unnecessary cpu_to_le32()
2.adjust the order of the macros
v2:
no change
drivers/net/wireless/ath/ath12k/acpi.c | 29 +++++++++++++++++++
drivers/net/wireless/ath/ath12k/acpi.h | 5 ++++
drivers/net/wireless/ath/ath12k/core.h | 1 +
drivers/net/wireless/ath/ath12k/wmi.c | 40 ++++++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/wmi.h | 3 ++
5 files changed, 78 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/acpi.c b/drivers/net/wireless/ath/ath12k/acpi.c
index a9931e17bd17..389b900df170 100644
--- a/drivers/net/wireless/ath/ath12k/acpi.c
+++ b/drivers/net/wireless/ath/ath12k/acpi.c
@@ -82,6 +82,16 @@ static int ath12k_acpi_dsm_get_data(struct ath12k_base *ab, int func)
memcpy(&ab->acdata->cca_data, obj->buffer.pointer,
obj->buffer.length);
break;
+ case ATH12K_ACPI_DSM_FUNC_INDEX_BAND_EDGE:
+ if (obj->buffer.length != ATH12K_ACPI_DSM_BAND_EDGE_DATA_SIZE) {
+ ath12k_err(ab, "Invalid BAND EDGE data size %d\n",
+ obj->buffer.length);
+ ret = -EINVAL;
+ goto out;
+ }
+ memcpy(&ab->acdata->band_edge_power, obj->buffer.pointer,
+ obj->buffer.length);
+ break;
}
} else {
ath12k_err(ab,
@@ -311,6 +321,25 @@ int ath12k_get_acpi_all_data(struct ath12k_base *ab)
}
}
+ if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acdata, ATH12K_ACPI_FUNC_BIT_BAND_EDGE_CHAN_POWER)) {
+ ret = ath12k_acpi_dsm_get_data(ab,
+ ATH12K_ACPI_DSM_FUNC_INDEX_BAND_EDGE);
+ if (ret) {
+ ath12k_err(ab, "failed to get band edge channel power %d\n", ret);
+ goto err_free_acdata;
+ }
+
+ if (ab->acdata->band_edge_power[0] == ATH12K_ACPI_BAND_EDGE_VERSION &&
+ ab->acdata->band_edge_power[1] == ATH12K_ACPI_BAND_EDGE_ENABLE_FLAG) {
+ ret = ath12k_wmi_pdev_set_band_edge_power(ab,
+ ab->acdata->band_edge_power);
+ if (ret) {
+ ath12k_err(ab, "set band edge channel power failed %d\n", ret);
+ goto err_free_acdata;
+ }
+ }
+ }
+
status = acpi_install_notify_handler(ACPI_HANDLE(ab->dev),
ACPI_DEVICE_NOTIFY,
acpi_dsm_notify, ab);
diff --git a/drivers/net/wireless/ath/ath12k/acpi.h b/drivers/net/wireless/ath/ath12k/acpi.h
index 1f05a68e490b..27f28fc13600 100644
--- a/drivers/net/wireless/ath/ath12k/acpi.h
+++ b/drivers/net/wireless/ath/ath12k/acpi.h
@@ -14,12 +14,14 @@
#define ATH12K_ACPI_DSM_FUNC_INDEX_CCA 6
#define ATH12K_ACPI_DSM_FUNC_INDEX_TAS_CFG 8
#define ATH12K_ACPI_DSM_FUNC_INDEX_TAS_DATA 9
+#define ATH12K_ACPI_DSM_FUNC_INDEX_BAND_EDGE 10
#define ATH12K_ACPI_FUNC_BIT_BIOS_SAR BIT(3)
#define ATH12K_ACPI_FUNC_BIT_GEO_OFFSET BIT(4)
#define ATH12K_ACPI_FUNC_BIT_CCA BIT(5)
#define ATH12K_ACPI_FUNC_BIT_TAS_CFG BIT(7)
#define ATH12K_ACPI_FUNC_BIT_TAS_DATA BIT(8)
+#define ATH12K_ACPI_FUNC_BIT_BAND_EDGE_CHAN_POWER BIT(9)
#define ATH12K_ACPI_NOTIFY_EVENT 0x86
#define ATH12K_ACPI_FUNC_BIT_VALID(_acdata, _func) ((((_acdata)->func_bit) & (_func)) != 0)
@@ -30,6 +32,8 @@
#define ATH12K_ACPI_POWER_LIMIT_ENABLE_FLAG 0x1
#define ATH12K_ACPI_CCA_THR_VERSION 0x1
#define ATH12K_ACPI_CCA_THR_ENABLE_FLAG 0x1
+#define ATH12K_ACPI_BAND_EDGE_VERSION 0x1
+#define ATH12K_ACPI_BAND_EDGE_ENABLE_FLAG 0x1
#define ATH12K_ACPI_GEO_OFFSET_DATA_OFFSET 1
#define ATH12K_ACPI_DBS_BACKOFF_DATA_OFFSET 2
@@ -41,6 +45,7 @@
#define ATH12K_ACPI_CCA_THR_OFFSET_LEN 36
#define ATH12K_ACPI_DSM_TAS_DATA_SIZE 69
+#define ATH12K_ACPI_DSM_BAND_EDGE_DATA_SIZE 100
#define ATH12K_ACPI_DSM_TAS_CFG_SIZE 108
#define ATH12K_ACPI_DSM_GEO_OFFSET_DATA_SIZE (ATH12K_ACPI_GEO_OFFSET_DATA_OFFSET + \
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index d57e2013b0fe..d06c3984aef9 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -781,6 +781,7 @@ struct ath12k_base {
u8 bios_sar_data[ATH12K_ACPI_DSM_BIOS_SAR_DATA_SIZE];
u8 geo_offset_data[ATH12K_ACPI_DSM_GEO_OFFSET_DATA_SIZE];
u8 cca_data[ATH12K_ACPI_DSM_CCA_DATA_SIZE];
+ u8 band_edge_power[ATH12K_ACPI_DSM_BAND_EDGE_DATA_SIZE];
} *acdata;
/* must be last */
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 727ce28abd7d..102228229932 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -7130,3 +7130,43 @@ int ath12k_wmi_pdev_set_cca_thr_table_param(struct ath12k_base *ab,
}
return ret;
}
+
+int ath12k_wmi_pdev_set_band_edge_power(struct ath12k_base *ab,
+ const u8 *pchan_table)
+{
+ struct ath12k_wmi_base *wmi_ab = &ab->wmi_ab;
+ struct wmi_pdev_set_bios_interface_cmd *cmd;
+ struct wmi_tlv *tlv;
+ struct sk_buff *skb;
+ int ret;
+ u8 *buf_ptr;
+ u32 len, len_aligned;
+
+ len_aligned = roundup(ATH12K_ACPI_DSM_BAND_EDGE_DATA_SIZE, sizeof(u32));
+ len = sizeof(*cmd) + TLV_HDR_SIZE + len_aligned;
+
+ skb = ath12k_wmi_alloc_skb(wmi_ab, len);
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_pdev_set_bios_interface_cmd *)skb->data;
+ cmd->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_PDEV_SET_BIOS_INTERFACE_CMD_PARAMS,
+ sizeof(*cmd));
+ cmd->pdev_id = cpu_to_le32(WMI_PDEV_ID_SOC);
+ cmd->param_type_id = cpu_to_le32(WMI_BIOS_PARAM_TYPE_BANDEDGE_CTL_POWER);
+ cmd->length = cpu_to_le32(ATH12K_ACPI_DSM_BAND_EDGE_DATA_SIZE);
+
+ buf_ptr = skb->data + sizeof(*cmd);
+ tlv = (struct wmi_tlv *)buf_ptr;
+ tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_BYTE, len_aligned);
+ buf_ptr += TLV_HDR_SIZE;
+ memcpy(buf_ptr, pchan_table, ATH12K_ACPI_DSM_BAND_EDGE_DATA_SIZE);
+
+ ret = ath12k_wmi_cmd_send(&wmi_ab->wmi[0], skb, WMI_PDEV_SET_BIOS_INTERFACE_CMDID);
+ if (ret) {
+ ath12k_warn(ab, "failed to send WMI_PDEV_SET_BIOS_INTERFACE_CMDID %d\n", ret);
+ dev_kfree_skb(skb);
+ }
+
+ return ret;
+}
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index 7607cd7ab699..73d790d405cd 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -4808,6 +4808,7 @@ enum bios_param_type {
WMI_BIOS_PARAM_CCA_THRESHOLD_TYPE = 0,
WMI_BIOS_PARAM_TAS_CONFIG_TYPE = 1,
WMI_BIOS_PARAM_TAS_DATA_TYPE = 2,
+ WMI_BIOS_PARAM_TYPE_BANDEDGE_CTL_POWER = 3,
WMI_BIOS_PARAM_TYPE_MAX,
};
@@ -4955,4 +4956,6 @@ int ath12k_wmi_pdev_set_bios_geo_table_param(struct ath12k_base *ab,
u8 *pgeo_table);
int ath12k_wmi_pdev_set_cca_thr_table_param(struct ath12k_base *ab,
u8 *pcca_table);
+int ath12k_wmi_pdev_set_band_edge_power(struct ath12k_base *ab,
+ const u8 *pchan_table);
#endif
--
2.34.1
More information about the ath12k
mailing list