mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-21 11:22:50 +00:00
374 lines
10 KiB
Diff
374 lines
10 KiB
Diff
From 31ba379043c3bde8f69d1e898dcd0d54b669e3c5 Mon Sep 17 00:00:00 2001
|
|
From: Bhagavathi Perumal S <quic_bperumal@quicinc.com>
|
|
Date: Tue, 14 Sep 2021 13:06:02 +0530
|
|
Subject: [PATCH 2/4] ath12k: Add mlo wmi setup apis
|
|
|
|
Added WMI helper function for the MLO setup/teardown command and event.
|
|
Add appropriate WMI tag, command id and event id to parse the event and
|
|
send request.
|
|
|
|
Signed-off-by: Bhagavathi Perumal S <quic_bperumal@quicinc.com>
|
|
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
|
---
|
|
drivers/net/wireless/ath/ath12k/core.c | 8 --
|
|
drivers/net/wireless/ath/ath12k/core.h | 3 +-
|
|
drivers/net/wireless/ath/ath12k/wmi.c | 170 ++++++++++++++++++++++++-
|
|
drivers/net/wireless/ath/ath12k/wmi.h | 66 +++++++++-
|
|
4 files changed, 229 insertions(+), 18 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath12k/core.h
|
|
+++ b/drivers/net/wireless/ath/ath12k/core.h
|
|
@@ -853,7 +853,8 @@ struct mlo_timestamp {
|
|
|
|
struct ath12k_pdev {
|
|
struct ath12k *ar;
|
|
- u32 pdev_id;
|
|
+ u16 pdev_id;
|
|
+ u16 hw_link_id;
|
|
struct ath12k_pdev_cap cap;
|
|
u8 mac_addr[ETH_ALEN];
|
|
struct mlo_timestamp timestamp;
|
|
--- a/drivers/net/wireless/ath/ath12k/wmi.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
|
|
@@ -485,6 +485,8 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(st
|
|
mac_phy_caps = wmi_mac_phy_caps + phy_idx;
|
|
|
|
pdev->pdev_id = mac_phy_caps->pdev_id;
|
|
+ pdev->hw_link_id = mac_phy_caps->hw_link_id;
|
|
+
|
|
pdev_cap->supported_bands |= mac_phy_caps->supported_bands;
|
|
pdev_cap->ampdu_density = mac_phy_caps->ampdu_density;
|
|
|
|
@@ -9026,6 +9028,66 @@ exit:
|
|
kfree(tb);
|
|
}
|
|
|
|
+static void ath12k_wmi_event_mlo_setup_complete(struct ath12k_base *ab,
|
|
+ struct sk_buff *skb)
|
|
+{
|
|
+ const void **tb;
|
|
+ const struct wmi_mlo_setup_complete_event_fixed_param *ev;
|
|
+ int ret;
|
|
+
|
|
+ tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
|
+ if (IS_ERR(tb)) {
|
|
+ ret = PTR_ERR(tb);
|
|
+ ath12k_warn(ab,
|
|
+ "failed to parse mlo setup complete event tlv %d\n",
|
|
+ ret);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ ev = tb[WMI_TAG_MLO_SETUP_COMPLETE_EVENT];
|
|
+ if (!ev) {
|
|
+ ath12k_warn(ab, "failed to fetch mlo setup complete event\n");
|
|
+ kfree(tb);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (ev->status)
|
|
+ ath12k_warn(ab, "mlo setup, pdev id %u, err %u\n",
|
|
+ ev->pdev_id, ev->status);
|
|
+
|
|
+ kfree(tb);
|
|
+}
|
|
+
|
|
+static void ath12k_wmi_event_teardown_complete(struct ath12k_base *ab,
|
|
+ struct sk_buff *skb)
|
|
+{
|
|
+ const void **tb;
|
|
+ const struct wmi_mlo_teardown_complete_fixed_param *ev;
|
|
+ int ret;
|
|
+
|
|
+ tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
|
+ if (IS_ERR(tb)) {
|
|
+ ret = PTR_ERR(tb);
|
|
+ ath12k_warn(ab,
|
|
+ "failed to parse teardown complete event tlv %d\n",
|
|
+ ret);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ ev = tb[WMI_TAG_MLO_TEARDOWN_COMPLETE];
|
|
+ if (!ev) {
|
|
+ ath12k_warn(ab, "failed to fetch teardown complete event\n");
|
|
+ kfree(tb);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (ev->status)
|
|
+ ath12k_warn(ab, "mlo teardown, pdev id %u, err %u\n",
|
|
+ ev->pdev_id, ev->status);
|
|
+
|
|
+ kfree(tb);
|
|
+}
|
|
+
|
|
static void ath12k_wmi_tlv_op_rx(struct ath12k_base *ab, struct sk_buff *skb)
|
|
{
|
|
struct wmi_cmd_hdr *cmd_hdr;
|
|
@@ -9160,6 +9222,12 @@ static void ath12k_wmi_tlv_op_rx(struct
|
|
case WMI_STATS_CTRL_PATH_EVENTID:
|
|
ath12k_process_tpc_stats(ab, skb);
|
|
break;
|
|
+ case WMI_MLO_SETUP_COMPLETE_EVENTID:
|
|
+ ath12k_wmi_event_mlo_setup_complete(ab, skb);
|
|
+ break;
|
|
+ case WMI_MLO_TEARDOWN_COMPLETE_EVENTID:
|
|
+ ath12k_wmi_event_teardown_complete(ab, skb);
|
|
+ break;
|
|
/* TODO: Add remaining events */
|
|
default:
|
|
ath12k_dbg(ab, ATH12K_DBG_WMI, "Unknown eventid: 0x%x\n", id);
|
|
@@ -9516,3 +9584,100 @@ int ath12k_wmi_pdev_ap_ps_cmd_send(struc
|
|
|
|
return ret;
|
|
}
|
|
+
|
|
+int ath12k_wmi_mlo_setup(struct ath12k *ar,
|
|
+ struct wmi_mlo_setup_params *mlo_params)
|
|
+{
|
|
+ struct ath12k_pdev_wmi *wmi = ar->wmi;
|
|
+ struct wmi_mlo_setup_cmd_fixed_param *cmd;
|
|
+ struct sk_buff *skb;
|
|
+ struct wmi_tlv *tlv;
|
|
+ u32 *plinks;
|
|
+ u32 num_links;
|
|
+ int i, ret, len;
|
|
+
|
|
+ num_links = mlo_params->num_partner_links;
|
|
+
|
|
+ len = sizeof(*cmd) + TLV_HDR_SIZE + (num_links * sizeof(u32));
|
|
+ skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, len);
|
|
+ if (!skb)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ cmd = (struct wmi_mlo_setup_cmd_fixed_param *)skb->data;
|
|
+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_MLO_SETUP_CMD) |
|
|
+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
|
+ cmd->mld_group_id = mlo_params->group_id;
|
|
+ cmd->pdev_id = ar->pdev->pdev_id;
|
|
+
|
|
+ tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd));
|
|
+ tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_UINT32) |
|
|
+ FIELD_PREP(WMI_TLV_LEN, num_links);
|
|
+
|
|
+ plinks = (u32 *)tlv->value;
|
|
+ for (i = 0; i < num_links; i++)
|
|
+ plinks[i] = mlo_params->partner_link_id[i];
|
|
+
|
|
+ ret = ath12k_wmi_cmd_send(wmi, skb, WMI_MLO_SETUP_CMDID);
|
|
+ if (ret) {
|
|
+ ath12k_warn(ar->ab,
|
|
+ "failed to submit WMI_MLO_SETUP_CMDID cmd\n");
|
|
+ dev_kfree_skb(skb);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int ath12k_wmi_mlo_ready(struct ath12k *ar)
|
|
+{
|
|
+ struct ath12k_pdev_wmi *wmi = ar->wmi;
|
|
+ struct wmi_mlo_ready_cmd_fixed_param *cmd;
|
|
+ struct sk_buff *skb;
|
|
+ int ret, len;
|
|
+
|
|
+ len = sizeof(*cmd);
|
|
+ skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, len);
|
|
+ if (!skb)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ cmd = (struct wmi_mlo_ready_cmd_fixed_param *)skb->data;
|
|
+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_MLO_READY_CMD) |
|
|
+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
|
+ cmd->pdev_id = ar->pdev->pdev_id;
|
|
+
|
|
+ ret = ath12k_wmi_cmd_send(wmi, skb, WMI_MLO_READY_CMDID);
|
|
+ if (ret) {
|
|
+ ath12k_warn(ar->ab,
|
|
+ "failed to submit WMI_MLO_READY_CMDID cmd\n");
|
|
+ dev_kfree_skb(skb);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int ath12k_wmi_mlo_teardown(struct ath12k *ar)
|
|
+{
|
|
+ struct ath12k_pdev_wmi *wmi = ar->wmi;
|
|
+ struct wmi_mlo_teardown_fixed_param *cmd;
|
|
+ struct sk_buff *skb;
|
|
+ int ret, len;
|
|
+
|
|
+ len = sizeof(*cmd);
|
|
+ skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, len);
|
|
+ if (!skb)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ cmd = (struct wmi_mlo_teardown_fixed_param *)skb->data;
|
|
+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_MLO_TEARDOWN_CMD) |
|
|
+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
|
+ cmd->pdev_id = ar->pdev->pdev_id;
|
|
+ cmd->reason_code = WMI_MLO_TEARDOWN_SSR_REASON;
|
|
+
|
|
+ ret = ath12k_wmi_cmd_send(wmi, skb, WMI_MLO_TEARDOWN_CMDID);
|
|
+ if (ret) {
|
|
+ ath12k_warn(ar->ab,
|
|
+ "failed to submit WMI MLO teardown cmd\n");
|
|
+ dev_kfree_skb(skb);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
--- a/drivers/net/wireless/ath/ath12k/wmi.h
|
|
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
|
|
@@ -202,6 +202,7 @@ enum wmi_cmd_group {
|
|
WMI_GRP_TWT = 0x3e,
|
|
WMI_GRP_MOTION_DET = 0x3f,
|
|
WMI_GRP_SPATIAL_REUSE = 0x40,
|
|
+ WMI_GRP_MLO = 0x48,
|
|
};
|
|
|
|
#define WMI_CMD_GRP(grp_id) (((grp_id) << 12) | 0x1)
|
|
@@ -626,6 +627,11 @@ enum wmi_tlv_cmd_id {
|
|
WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID =
|
|
WMI_TLV_CMD(WMI_GRP_SPATIAL_REUSE),
|
|
WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID,
|
|
+ WMI_MLO_LINK_SET_ACTIVE_CMDID = WMI_TLV_CMD(WMI_GRP_MLO),
|
|
+ WMI_MLO_SETUP_CMDID,
|
|
+ WMI_MLO_READY_CMDID,
|
|
+ WMI_MLO_TEARDOWN_CMDID,
|
|
+ WMI_MLO_PEER_TID_TO_LINK_MAP_CMDID,
|
|
};
|
|
|
|
enum wmi_tlv_event_id {
|
|
@@ -849,6 +855,9 @@ enum wmi_tlv_event_id {
|
|
WMI_TWT_DEL_DIALOG_EVENTID,
|
|
WMI_TWT_PAUSE_DIALOG_EVENTID,
|
|
WMI_TWT_RESUME_DIALOG_EVENTID,
|
|
+ WMI_MLO_LINK_SET_ACTIVE_RESP_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_MLO),
|
|
+ WMI_MLO_SETUP_COMPLETE_EVENTID,
|
|
+ WMI_MLO_TEARDOWN_COMPLETE_EVENTID,
|
|
};
|
|
|
|
enum wmi_tlv_pdev_param {
|
|
@@ -1923,6 +1932,14 @@ enum wmi_tlv_tag {
|
|
WMI_TAG_VDEV_CH_POWER_INFO,
|
|
WMI_TAG_EHT_RATE_SET = 0x3C4,
|
|
WMI_TAG_DCS_AWGN_INT_TYPE = 0x3C5,
|
|
+ WMI_TAG_MLO_TX_SEND_PARAMS,
|
|
+ WMI_TAG_MLO_PARTNER_LINK_PARAMS,
|
|
+ WMI_TAG_MLO_PARTNER_LINK_PARAMS_PEER_ASSOC,
|
|
+ WMI_TAG_MLO_SETUP_CMD,
|
|
+ WMI_TAG_MLO_SETUP_COMPLETE_EVENT,
|
|
+ WMI_TAG_MLO_READY_CMD,
|
|
+ WMI_TAG_MLO_TEARDOWN_CMD,
|
|
+ WMI_TAG_MLO_TEARDOWN_COMPLETE,
|
|
WMI_TAG_PDEV_PKTLOG_DECODE_INFO = 0x414,
|
|
WMI_TAG_TPC_STATS_GET_CMD = 0x38B,
|
|
WMI_TAG_TPC_STATS_EVENT_FIXED_PARAM,
|
|
@@ -2278,6 +2295,7 @@ struct ath12k_ppe_threshold {
|
|
u32 ru_bit_mask;
|
|
u32 ppet16_ppet8_ru3_ru0[PSOC_HOST_MAX_NUM_SS];
|
|
};
|
|
+
|
|
struct ath12k_service_ext_param {
|
|
u32 default_conc_scan_config_bits;
|
|
u32 default_fw_config_bits;
|
|
@@ -2699,6 +2717,25 @@ enum wmi_eht_mcs_support {
|
|
WMI_EHT_MCS_NOT_SUPPORTED = 3,
|
|
};
|
|
|
|
+#define EML_INFO_EMLSR_SUPPORT BIT(0)
|
|
+#define EML_INFO_EMLSR_PADDING_DELAY GENMASK(3, 1)
|
|
+#define EML_INFO_EMLSR_TRANSITION_DELAY GENMASK(6, 4)
|
|
+#define EML_INFO_EMLMR_SUPPORT BIT(7)
|
|
+#define EML_INFO_EMLMR_PADDING_DELAY GENMASK(10, 8)
|
|
+#define EML_INFO_TRANSITION_TIMEOUT GENMASK(14, 11)
|
|
+
|
|
+enum wmi_mld_cap_tid_to_link_map {
|
|
+ WMI_MLD_MAP_TID_TO_LINK_NONE,
|
|
+ WMI_MLD_MAP_EACH_TID_TO_SAME_OR_DIFF_LINK_SET,
|
|
+ WMI_MLD_MAP_ALL_TID_TO_SAME_LINK_SET,
|
|
+};
|
|
+
|
|
+#define MLD_INFO_MAX_SIMULTANEOUS_LINK GENMASK(3, 0)
|
|
+#define MLD_INFO_SRS_SUPPORT BIT(4)
|
|
+#define MLD_INFO_TID_TO_LINK_MAP_SUPPORT GENMASK(6, 5)
|
|
+#define MLD_INFO_FREQ_SEPARATION_STR GENMASK(11, 7)
|
|
+#define MLD_INFO_AAR_SUPPORT BIT(12)
|
|
+
|
|
struct wmi_mac_phy_caps_ext {
|
|
u32 hw_mode_id;
|
|
union {
|
|
@@ -2720,6 +2757,8 @@ struct wmi_mac_phy_caps_ext {
|
|
u32 eht_cap_info_internal;
|
|
u32 eht_supp_mcs_ext_2G[WMI_MAX_EHT_SUPP_MCS_2G_SIZE];
|
|
u32 eht_supp_mcs_ext_5G[WMI_MAX_EHT_SUPP_MCS_5G_SIZE];
|
|
+ u32 eml_info;
|
|
+ u32 mld_info;
|
|
} __packed;
|
|
|
|
/* 2 word representation of MAC addr */
|
|
@@ -5975,6 +6014,7 @@ struct wmi_dbglog_config_cmd_fixed_param
|
|
|
|
#define MAX_RADIOS 3
|
|
|
|
+#define WMI_MLO_CMD_TIMEOUT_HZ (5 * HZ)
|
|
#define WMI_SERVICE_READY_TIMEOUT_HZ (5 * HZ)
|
|
#define WMI_SEND_TIMEOUT_HZ (3 * HZ)
|
|
|
|
@@ -6162,6 +6202,43 @@ struct wmi_wow_ev_arg {
|
|
u32 data_len;
|
|
};
|
|
|
|
+struct wmi_mlo_setup_cmd_fixed_param {
|
|
+ u32 tlv_header;
|
|
+ u32 mld_group_id;
|
|
+ u32 pdev_id;
|
|
+} __packed;
|
|
+
|
|
+struct wmi_mlo_setup_params {
|
|
+ u32 group_id;
|
|
+ u8 num_partner_links;
|
|
+ u8 *partner_link_id;
|
|
+};
|
|
+
|
|
+struct wmi_mlo_ready_cmd_fixed_param {
|
|
+ u32 tlv_header;
|
|
+ u32 pdev_id;
|
|
+} __packed;
|
|
+
|
|
+enum wmi_mlo_tear_down_reason_code_type {
|
|
+ WMI_MLO_TEARDOWN_SSR_REASON,
|
|
+};
|
|
+
|
|
+struct wmi_mlo_teardown_fixed_param {
|
|
+ u32 tlv_header;
|
|
+ u32 pdev_id;
|
|
+ u32 reason_code;
|
|
+} __packed;
|
|
+
|
|
+struct wmi_mlo_setup_complete_event_fixed_param {
|
|
+ u32 pdev_id;
|
|
+ u32 status;
|
|
+} __packed;
|
|
+
|
|
+struct wmi_mlo_teardown_complete_fixed_param {
|
|
+ u32 pdev_id;
|
|
+ u32 status;
|
|
+} __packed;
|
|
+
|
|
#define ATH12K_FW_STATS_BUF_SIZE (1024 * 1024)
|
|
|
|
void ath12k_wmi_init_qcn9274(struct ath12k_base *ab,
|
|
@@ -6326,4 +6403,8 @@ int ath12k_wmi_send_vdev_set_tpc_power(s
|
|
int ath12k_wmi_pdev_m3_dump_enable(struct ath12k *ar, u32 enable);
|
|
int ath12k_wmi_pdev_get_tpc_table_cmdid(struct ath12k *ar);
|
|
void ath12k_wmi_free_tpc_stats_mem(struct ath12k *ar);
|
|
+int ath12k_wmi_mlo_setup(struct ath12k *ar,
|
|
+ struct wmi_mlo_setup_params *mlo_params);
|
|
+int ath12k_wmi_mlo_ready(struct ath12k *ar);
|
|
+int ath12k_wmi_mlo_teardown(struct ath12k *ar);
|
|
#endif
|