[PATCH v7 3/4] wifi: ath12k: add adjust configuration of CCA threshold value for WCN7850
Lingbo Kong
quic_lingbok at quicinc.com
Fri Oct 13 04:44:33 PDT 2023
Currently, ath12k does not have the ability to adjust CCA threshold values
to meet the regulatory requirements. In order to support this, ath12k gets
CCA threshold configuration in ath12k_acpi_dsm_get_data() function, then
sets pdev_id and param_type_id and finally sends these data to firmware to
implement the adjustment of the CCA threshold value.
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>
---
v7:
1.adjust the length of line
2.add cpu_to_le32()
v6:
1.no change
v5:
1.rebase to the latest tag
v4:
1.revise commit log using imperative voice
v3:
1.remove unnecessary cpu_to_le32()
2.adjust the order of the macros
3.apply jeff's advice
v2:
no change
drivers/net/wireless/ath/ath12k/acpi.c | 31 ++++++++++++++++++
drivers/net/wireless/ath/ath12k/acpi.h | 8 +++++
drivers/net/wireless/ath/ath12k/core.h | 1 +
drivers/net/wireless/ath/ath12k/wmi.c | 44 ++++++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/wmi.h | 6 ++--
5 files changed, 88 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/acpi.c b/drivers/net/wireless/ath/ath12k/acpi.c
index 56073557b0f3..cb0850ae110a 100644
--- a/drivers/net/wireless/ath/ath12k/acpi.c
+++ b/drivers/net/wireless/ath/ath12k/acpi.c
@@ -72,6 +72,16 @@ static int ath12k_acpi_dsm_get_data(struct ath12k_base *ab, int func)
memcpy(&ab->acdata->geo_offset_data, obj->buffer.pointer,
obj->buffer.length);
break;
+ case ATH12K_ACPI_DSM_FUNC_INDEX_CCA:
+ if (obj->buffer.length != ATH12K_ACPI_DSM_CCA_DATA_SIZE) {
+ ath12k_err(ab, "Invalid CCA data size %d\n",
+ obj->buffer.length);
+ ret = -EINVAL;
+ goto out;
+ }
+ memcpy(&ab->acdata->cca_data, obj->buffer.pointer,
+ obj->buffer.length);
+ break;
}
} else {
ath12k_err(ab,
@@ -277,6 +287,27 @@ int ath12k_get_acpi_all_data(struct ath12k_base *ab)
goto err_free_acdata;
}
+ if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acdata, ATH12K_ACPI_FUNC_BIT_CCA)) {
+ ret = ath12k_acpi_dsm_get_data(ab,
+ ATH12K_ACPI_DSM_FUNC_INDEX_CCA);
+ if (ret) {
+ ath12k_err(ab,
+ "failed to get cca threshold configuration %d\n",
+ ret);
+ goto err_free_acdata;
+ }
+
+ if (ab->acdata->cca_data[0] == ATH12K_ACPI_CCA_THR_VERSION &&
+ ab->acdata->cca_data[ATH12K_ACPI_CCA_THR_OFFSET_DATA_OFFSET] ==
+ ATH12K_ACPI_CCA_THR_ENABLE_FLAG) {
+ ret = ath12k_wmi_pdev_set_cca_thr_table_param(ab);
+ if (ret) {
+ ath12k_err(ab, "set cca threshold 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 2146855dffae..f9ad4d573b78 100644
--- a/drivers/net/wireless/ath/ath12k/acpi.h
+++ b/drivers/net/wireless/ath/ath12k/acpi.h
@@ -11,11 +11,13 @@
#define ATH12K_ACPI_DSM_FUNC_SUPPORT_FUNCS 0
#define ATH12K_ACPI_DSM_FUNC_BIOS_SAR 4
#define ATH12K_ACPI_DSM_FUNC_GEO_OFFSET 5
+#define ATH12K_ACPI_DSM_FUNC_INDEX_CCA 6
#define ATH12K_ACPI_DSM_FUNC_TAS_CFG 8
#define ATH12K_ACPI_DSM_FUNC_TAS_DATA 9
#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)
@@ -26,13 +28,17 @@
#define ATH12K_ACPI_TAS_DATA_ENABLE 0x1
#define ATH12K_ACPI_POWER_LIMIT_VERSION 0x1
#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_GEO_OFFSET_DATA_OFFSET 1
#define ATH12K_ACPI_DBS_BACKOFF_DATA_OFFSET 2
+#define ATH12K_ACPI_CCA_THR_OFFSET_DATA_OFFSET 5
#define ATH12K_ACPI_BIOS_SAR_DBS_BACKOFF_LEN 10
#define ATH12K_ACPI_POWER_LIMIT_DATA_OFFSET 12
#define ATH12K_ACPI_BIOS_SAR_GEO_OFFSET_LEN 18
#define ATH12K_ACPI_BIOS_SAR_TABLE_LEN 22
+#define ATH12K_ACPI_CCA_THR_OFFSET_LEN 36
#define ATH12K_ACPI_DSM_TAS_DATA_SIZE 69
#define ATH12K_ACPI_DSM_TAS_CFG_SIZE 108
@@ -41,6 +47,8 @@
ATH12K_ACPI_BIOS_SAR_GEO_OFFSET_LEN)
#define ATH12K_ACPI_DSM_BIOS_SAR_DATA_SIZE (ATH12K_ACPI_POWER_LIMIT_DATA_OFFSET + \
ATH12K_ACPI_BIOS_SAR_TABLE_LEN)
+#define ATH12K_ACPI_DSM_CCA_DATA_SIZE (ATH12K_ACPI_CCA_THR_OFFSET_DATA_OFFSET + \
+ ATH12K_ACPI_CCA_THR_OFFSET_LEN)
int ath12k_get_acpi_all_data(struct ath12k_base *ab);
void acpi_dsm_notify(acpi_handle handle, u32 event, void *data);
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index e9823e063fb6..4b663577c2b9 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -802,6 +802,7 @@ struct ath12k_base {
u8 tas_sar_power_table[ATH12K_ACPI_DSM_TAS_DATA_SIZE];
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];
} *acdata;
/* must be last */
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 09e0a27612ab..0d9101f9643a 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -7161,3 +7161,47 @@ int ath12k_wmi_pdev_set_bios_geo_table_param(struct ath12k_base *ab,
return ret;
}
+
+int ath12k_wmi_pdev_set_cca_thr_table_param(struct ath12k_base *ab)
+{
+ 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 *pcca_table = ab->acdata->cca_data;
+ u8 *buf_ptr;
+ u32 len, cca_thr_len_aligned;
+ u8 *pcca_value = pcca_table + ATH12K_ACPI_CCA_THR_OFFSET_DATA_OFFSET;
+
+ cca_thr_len_aligned = roundup(ATH12K_ACPI_CCA_THR_OFFSET_LEN, sizeof(u32));
+ len = sizeof(*cmd) + TLV_HDR_SIZE + cca_thr_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,
+ sizeof(*cmd));
+ cmd->pdev_id = cpu_to_le32(WMI_PDEV_ID_SOC);
+ cmd->param_type_id = cpu_to_le32(WMI_BIOS_PARAM_CCA_THRESHOLD_TYPE);
+ cmd->length = cpu_to_le32(ATH12K_ACPI_CCA_THR_OFFSET_LEN);
+
+ buf_ptr = skb->data + sizeof(*cmd);
+ tlv = (struct wmi_tlv *)buf_ptr;
+ tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_BYTE, cca_thr_len_aligned);
+ buf_ptr += TLV_HDR_SIZE;
+ memcpy(buf_ptr, pcca_value, ATH12K_ACPI_CCA_THR_OFFSET_LEN);
+
+ 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 677cb2e615e9..8c6b16a572ee 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -4808,8 +4808,9 @@ struct wmi_pdev_set_bios_interface_cmd {
} __packed;
enum bios_param_type {
- WMI_BIOS_PARAM_TAS_CONFIG_TYPE = 1,
- WMI_BIOS_PARAM_TAS_DATA_TYPE = 2,
+ 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_MAX,
};
@@ -4980,4 +4981,5 @@ int ath12k_wmi_pdev_set_bios_sar_table_param(struct ath12k_base *ab,
u8 *psar_table);
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);
#endif
--
2.34.1
More information about the ath12k
mailing list