Skip to content

Commit c36f2cd

Browse files
Baochen Qiangjeff-t-johnson
authored andcommitted
wifi: ath12k: support WMI_MLO_LINK_SET_ACTIVE_CMDID command
Add WMI_MLO_LINK_SET_ACTIVE_CMDID command. This command allows host to send required link information to firmware such that firmware can make decision on activating/deactivating links in various scenarios. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00284-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1 Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Signed-off-by: Baochen Qiang <[email protected]> Reviewed-by: Vasanthakumar Thiagarajan <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jeff Johnson <[email protected]>
1 parent e47b11e commit c36f2cd

File tree

2 files changed

+336
-1
lines changed

2 files changed

+336
-1
lines changed

drivers/net/wireless/ath/ath12k/wmi.c

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10498,3 +10498,224 @@ int ath12k_wmi_send_vdev_set_tpc_power(struct ath12k *ar,
1049810498

1049910499
return 0;
1050010500
}
10501+
10502+
static int
10503+
ath12k_wmi_fill_disallowed_bmap(struct ath12k_base *ab,
10504+
struct wmi_disallowed_mlo_mode_bitmap_params *dislw_bmap,
10505+
struct wmi_mlo_link_set_active_arg *arg)
10506+
{
10507+
struct wmi_ml_disallow_mode_bmap_arg *dislw_bmap_arg;
10508+
u8 i;
10509+
10510+
if (arg->num_disallow_mode_comb >
10511+
ARRAY_SIZE(arg->disallow_bmap)) {
10512+
ath12k_warn(ab, "invalid num_disallow_mode_comb: %d",
10513+
arg->num_disallow_mode_comb);
10514+
return -EINVAL;
10515+
}
10516+
10517+
dislw_bmap_arg = &arg->disallow_bmap[0];
10518+
for (i = 0; i < arg->num_disallow_mode_comb; i++) {
10519+
dislw_bmap->tlv_header =
10520+
ath12k_wmi_tlv_cmd_hdr(0, sizeof(*dislw_bmap));
10521+
dislw_bmap->disallowed_mode_bitmap =
10522+
cpu_to_le32(dislw_bmap_arg->disallowed_mode);
10523+
dislw_bmap->ieee_link_id_comb =
10524+
le32_encode_bits(dislw_bmap_arg->ieee_link_id[0],
10525+
WMI_DISALW_MLO_MODE_BMAP_IEEE_LINK_ID_COMB_1) |
10526+
le32_encode_bits(dislw_bmap_arg->ieee_link_id[1],
10527+
WMI_DISALW_MLO_MODE_BMAP_IEEE_LINK_ID_COMB_2) |
10528+
le32_encode_bits(dislw_bmap_arg->ieee_link_id[2],
10529+
WMI_DISALW_MLO_MODE_BMAP_IEEE_LINK_ID_COMB_3) |
10530+
le32_encode_bits(dislw_bmap_arg->ieee_link_id[3],
10531+
WMI_DISALW_MLO_MODE_BMAP_IEEE_LINK_ID_COMB_4);
10532+
10533+
ath12k_dbg(ab, ATH12K_DBG_WMI,
10534+
"entry %d disallowed_mode %d ieee_link_id_comb 0x%x",
10535+
i, dislw_bmap_arg->disallowed_mode,
10536+
dislw_bmap_arg->ieee_link_id_comb);
10537+
dislw_bmap++;
10538+
dislw_bmap_arg++;
10539+
}
10540+
10541+
return 0;
10542+
}
10543+
10544+
int ath12k_wmi_send_mlo_link_set_active_cmd(struct ath12k_base *ab,
10545+
struct wmi_mlo_link_set_active_arg *arg)
10546+
{
10547+
struct wmi_disallowed_mlo_mode_bitmap_params *disallowed_mode_bmap;
10548+
struct wmi_mlo_set_active_link_number_params *link_num_param;
10549+
u32 num_link_num_param = 0, num_vdev_bitmap = 0;
10550+
struct ath12k_wmi_base *wmi_ab = &ab->wmi_ab;
10551+
struct wmi_mlo_link_set_active_cmd *cmd;
10552+
u32 num_inactive_vdev_bitmap = 0;
10553+
u32 num_disallow_mode_comb = 0;
10554+
struct wmi_tlv *tlv;
10555+
struct sk_buff *skb;
10556+
__le32 *vdev_bitmap;
10557+
void *buf_ptr;
10558+
int i, ret;
10559+
u32 len;
10560+
10561+
if (!arg->num_vdev_bitmap && !arg->num_link_entry) {
10562+
ath12k_warn(ab, "Invalid num_vdev_bitmap and num_link_entry");
10563+
return -EINVAL;
10564+
}
10565+
10566+
switch (arg->force_mode) {
10567+
case WMI_MLO_LINK_FORCE_MODE_ACTIVE_LINK_NUM:
10568+
case WMI_MLO_LINK_FORCE_MODE_INACTIVE_LINK_NUM:
10569+
num_link_num_param = arg->num_link_entry;
10570+
fallthrough;
10571+
case WMI_MLO_LINK_FORCE_MODE_ACTIVE:
10572+
case WMI_MLO_LINK_FORCE_MODE_INACTIVE:
10573+
case WMI_MLO_LINK_FORCE_MODE_NO_FORCE:
10574+
num_vdev_bitmap = arg->num_vdev_bitmap;
10575+
break;
10576+
case WMI_MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE:
10577+
num_vdev_bitmap = arg->num_vdev_bitmap;
10578+
num_inactive_vdev_bitmap = arg->num_inactive_vdev_bitmap;
10579+
break;
10580+
default:
10581+
ath12k_warn(ab, "Invalid force mode: %u", arg->force_mode);
10582+
return -EINVAL;
10583+
}
10584+
10585+
num_disallow_mode_comb = arg->num_disallow_mode_comb;
10586+
len = sizeof(*cmd) +
10587+
TLV_HDR_SIZE + sizeof(*link_num_param) * num_link_num_param +
10588+
TLV_HDR_SIZE + sizeof(*vdev_bitmap) * num_vdev_bitmap +
10589+
TLV_HDR_SIZE + TLV_HDR_SIZE + TLV_HDR_SIZE +
10590+
TLV_HDR_SIZE + sizeof(*disallowed_mode_bmap) * num_disallow_mode_comb;
10591+
if (arg->force_mode == WMI_MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE)
10592+
len += sizeof(*vdev_bitmap) * num_inactive_vdev_bitmap;
10593+
10594+
skb = ath12k_wmi_alloc_skb(wmi_ab, len);
10595+
if (!skb)
10596+
return -ENOMEM;
10597+
10598+
cmd = (struct wmi_mlo_link_set_active_cmd *)skb->data;
10599+
cmd->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_MLO_LINK_SET_ACTIVE_CMD,
10600+
sizeof(*cmd));
10601+
cmd->force_mode = cpu_to_le32(arg->force_mode);
10602+
cmd->reason = cpu_to_le32(arg->reason);
10603+
ath12k_dbg(ab, ATH12K_DBG_WMI,
10604+
"mode %d reason %d num_link_num_param %d num_vdev_bitmap %d inactive %d num_disallow_mode_comb %d",
10605+
arg->force_mode, arg->reason, num_link_num_param,
10606+
num_vdev_bitmap, num_inactive_vdev_bitmap,
10607+
num_disallow_mode_comb);
10608+
10609+
buf_ptr = skb->data + sizeof(*cmd);
10610+
tlv = buf_ptr;
10611+
tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_STRUCT,
10612+
sizeof(*link_num_param) * num_link_num_param);
10613+
buf_ptr += TLV_HDR_SIZE;
10614+
10615+
if (num_link_num_param) {
10616+
cmd->ctrl_flags =
10617+
le32_encode_bits(arg->ctrl_flags.dync_force_link_num ? 1 : 0,
10618+
CRTL_F_DYNC_FORCE_LINK_NUM);
10619+
10620+
link_num_param = buf_ptr;
10621+
for (i = 0; i < num_link_num_param; i++) {
10622+
link_num_param->tlv_header =
10623+
ath12k_wmi_tlv_cmd_hdr(0, sizeof(*link_num_param));
10624+
link_num_param->num_of_link =
10625+
cpu_to_le32(arg->link_num[i].num_of_link);
10626+
link_num_param->vdev_type =
10627+
cpu_to_le32(arg->link_num[i].vdev_type);
10628+
link_num_param->vdev_subtype =
10629+
cpu_to_le32(arg->link_num[i].vdev_subtype);
10630+
link_num_param->home_freq =
10631+
cpu_to_le32(arg->link_num[i].home_freq);
10632+
ath12k_dbg(ab, ATH12K_DBG_WMI,
10633+
"entry %d num_of_link %d vdev type %d subtype %d freq %d control_flags %d",
10634+
i, arg->link_num[i].num_of_link,
10635+
arg->link_num[i].vdev_type,
10636+
arg->link_num[i].vdev_subtype,
10637+
arg->link_num[i].home_freq,
10638+
__le32_to_cpu(cmd->ctrl_flags));
10639+
link_num_param++;
10640+
}
10641+
10642+
buf_ptr += sizeof(*link_num_param) * num_link_num_param;
10643+
}
10644+
10645+
tlv = buf_ptr;
10646+
tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_UINT32,
10647+
sizeof(*vdev_bitmap) * num_vdev_bitmap);
10648+
buf_ptr += TLV_HDR_SIZE;
10649+
10650+
if (num_vdev_bitmap) {
10651+
vdev_bitmap = buf_ptr;
10652+
for (i = 0; i < num_vdev_bitmap; i++) {
10653+
vdev_bitmap[i] = cpu_to_le32(arg->vdev_bitmap[i]);
10654+
ath12k_dbg(ab, ATH12K_DBG_WMI, "entry %d vdev_id_bitmap 0x%x",
10655+
i, arg->vdev_bitmap[i]);
10656+
}
10657+
10658+
buf_ptr += sizeof(*vdev_bitmap) * num_vdev_bitmap;
10659+
}
10660+
10661+
if (arg->force_mode == WMI_MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE) {
10662+
tlv = buf_ptr;
10663+
tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_UINT32,
10664+
sizeof(*vdev_bitmap) *
10665+
num_inactive_vdev_bitmap);
10666+
buf_ptr += TLV_HDR_SIZE;
10667+
10668+
if (num_inactive_vdev_bitmap) {
10669+
vdev_bitmap = buf_ptr;
10670+
for (i = 0; i < num_inactive_vdev_bitmap; i++) {
10671+
vdev_bitmap[i] =
10672+
cpu_to_le32(arg->inactive_vdev_bitmap[i]);
10673+
ath12k_dbg(ab, ATH12K_DBG_WMI,
10674+
"entry %d inactive_vdev_id_bitmap 0x%x",
10675+
i, arg->inactive_vdev_bitmap[i]);
10676+
}
10677+
10678+
buf_ptr += sizeof(*vdev_bitmap) * num_inactive_vdev_bitmap;
10679+
}
10680+
} else {
10681+
/* add empty vdev bitmap2 tlv */
10682+
tlv = buf_ptr;
10683+
tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_UINT32, 0);
10684+
buf_ptr += TLV_HDR_SIZE;
10685+
}
10686+
10687+
/* add empty ieee_link_id_bitmap tlv */
10688+
tlv = buf_ptr;
10689+
tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_UINT32, 0);
10690+
buf_ptr += TLV_HDR_SIZE;
10691+
10692+
/* add empty ieee_link_id_bitmap2 tlv */
10693+
tlv = buf_ptr;
10694+
tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_UINT32, 0);
10695+
buf_ptr += TLV_HDR_SIZE;
10696+
10697+
tlv = buf_ptr;
10698+
tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_STRUCT,
10699+
sizeof(*disallowed_mode_bmap) *
10700+
arg->num_disallow_mode_comb);
10701+
buf_ptr += TLV_HDR_SIZE;
10702+
10703+
ret = ath12k_wmi_fill_disallowed_bmap(ab, buf_ptr, arg);
10704+
if (ret)
10705+
goto free_skb;
10706+
10707+
ret = ath12k_wmi_cmd_send(&wmi_ab->wmi[0], skb, WMI_MLO_LINK_SET_ACTIVE_CMDID);
10708+
if (ret) {
10709+
ath12k_warn(ab,
10710+
"failed to send WMI_MLO_LINK_SET_ACTIVE_CMDID: %d\n", ret);
10711+
goto free_skb;
10712+
}
10713+
10714+
ath12k_dbg(ab, ATH12K_DBG_WMI, "WMI mlo link set active cmd");
10715+
10716+
return ret;
10717+
10718+
free_skb:
10719+
dev_kfree_skb(skb);
10720+
return ret;
10721+
}

drivers/net/wireless/ath/ath12k/wmi.h

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1974,6 +1974,7 @@ enum wmi_tlv_tag {
19741974
WMI_TAG_TPC_STATS_CTL_PWR_TABLE_EVENT,
19751975
WMI_TAG_VDEV_SET_TPC_POWER_CMD = 0x3B5,
19761976
WMI_TAG_VDEV_CH_POWER_INFO,
1977+
WMI_TAG_MLO_LINK_SET_ACTIVE_CMD = 0x3BE,
19771978
WMI_TAG_EHT_RATE_SET = 0x3C4,
19781979
WMI_TAG_DCS_AWGN_INT_TYPE = 0x3C5,
19791980
WMI_TAG_MLO_TX_SEND_PARAMS,
@@ -6061,6 +6062,118 @@ struct wmi_vdev_set_tpc_power_cmd {
60616062
*/
60626063
} __packed;
60636064

6065+
#define CRTL_F_DYNC_FORCE_LINK_NUM GENMASK(3, 2)
6066+
6067+
struct wmi_mlo_link_set_active_cmd {
6068+
__le32 tlv_header;
6069+
__le32 force_mode;
6070+
__le32 reason;
6071+
__le32 use_ieee_link_id_bitmap;
6072+
struct ath12k_wmi_mac_addr_params ap_mld_mac_addr;
6073+
__le32 ctrl_flags;
6074+
} __packed;
6075+
6076+
struct wmi_mlo_set_active_link_number_params {
6077+
__le32 tlv_header;
6078+
__le32 num_of_link;
6079+
__le32 vdev_type;
6080+
__le32 vdev_subtype;
6081+
__le32 home_freq;
6082+
} __packed;
6083+
6084+
#define WMI_DISALW_MLO_MODE_BMAP_IEEE_LINK_ID_COMB_1 GENMASK(7, 0)
6085+
#define WMI_DISALW_MLO_MODE_BMAP_IEEE_LINK_ID_COMB_2 GENMASK(15, 8)
6086+
#define WMI_DISALW_MLO_MODE_BMAP_IEEE_LINK_ID_COMB_3 GENMASK(23, 16)
6087+
#define WMI_DISALW_MLO_MODE_BMAP_IEEE_LINK_ID_COMB_4 GENMASK(31, 24)
6088+
6089+
struct wmi_disallowed_mlo_mode_bitmap_params {
6090+
__le32 tlv_header;
6091+
__le32 disallowed_mode_bitmap;
6092+
__le32 ieee_link_id_comb;
6093+
} __packed;
6094+
6095+
enum wmi_mlo_link_force_mode {
6096+
WMI_MLO_LINK_FORCE_MODE_ACTIVE = 1,
6097+
WMI_MLO_LINK_FORCE_MODE_INACTIVE = 2,
6098+
WMI_MLO_LINK_FORCE_MODE_ACTIVE_LINK_NUM = 3,
6099+
WMI_MLO_LINK_FORCE_MODE_INACTIVE_LINK_NUM = 4,
6100+
WMI_MLO_LINK_FORCE_MODE_NO_FORCE = 5,
6101+
WMI_MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE = 6,
6102+
WMI_MLO_LINK_FORCE_MODE_NON_FORCE_UPDATE = 7,
6103+
};
6104+
6105+
enum wmi_mlo_link_force_reason {
6106+
WMI_MLO_LINK_FORCE_REASON_NEW_CONNECT = 1,
6107+
WMI_MLO_LINK_FORCE_REASON_NEW_DISCONNECT = 2,
6108+
WMI_MLO_LINK_FORCE_REASON_LINK_REMOVAL = 3,
6109+
WMI_MLO_LINK_FORCE_REASON_TDLS = 4,
6110+
WMI_MLO_LINK_FORCE_REASON_REVERT_FAILURE = 5,
6111+
WMI_MLO_LINK_FORCE_REASON_LINK_DELETE = 6,
6112+
WMI_MLO_LINK_FORCE_REASON_SINGLE_LINK_EMLSR_OP = 7,
6113+
};
6114+
6115+
struct wmi_mlo_link_num_arg {
6116+
u32 num_of_link;
6117+
u32 vdev_type;
6118+
u32 vdev_subtype;
6119+
u32 home_freq;
6120+
};
6121+
6122+
struct wmi_mlo_control_flags_arg {
6123+
bool overwrite_force_active_bitmap;
6124+
bool overwrite_force_inactive_bitmap;
6125+
bool dync_force_link_num;
6126+
bool post_re_evaluate;
6127+
u8 post_re_evaluate_loops;
6128+
bool dont_reschedule_workqueue;
6129+
};
6130+
6131+
struct wmi_ml_link_force_cmd_arg {
6132+
u8 ap_mld_mac_addr[ETH_ALEN];
6133+
u16 ieee_link_id_bitmap;
6134+
u16 ieee_link_id_bitmap2;
6135+
u8 link_num;
6136+
};
6137+
6138+
struct wmi_ml_disallow_mode_bmap_arg {
6139+
u32 disallowed_mode;
6140+
union {
6141+
u32 ieee_link_id_comb;
6142+
u8 ieee_link_id[4];
6143+
};
6144+
};
6145+
6146+
/* maximum size of link number param array
6147+
* for MLO link set active command
6148+
*/
6149+
#define WMI_MLO_LINK_NUM_SZ 2
6150+
6151+
/* maximum size of vdev bitmap array for
6152+
* MLO link set active command
6153+
*/
6154+
#define WMI_MLO_VDEV_BITMAP_SZ 2
6155+
6156+
/* Max number of disallowed bitmap combination
6157+
* sent to firmware
6158+
*/
6159+
#define WMI_ML_MAX_DISALLOW_BMAP_COMB 4
6160+
6161+
struct wmi_mlo_link_set_active_arg {
6162+
enum wmi_mlo_link_force_mode force_mode;
6163+
enum wmi_mlo_link_force_reason reason;
6164+
u32 num_link_entry;
6165+
u32 num_vdev_bitmap;
6166+
u32 num_inactive_vdev_bitmap;
6167+
struct wmi_mlo_link_num_arg link_num[WMI_MLO_LINK_NUM_SZ];
6168+
u32 vdev_bitmap[WMI_MLO_VDEV_BITMAP_SZ];
6169+
u32 inactive_vdev_bitmap[WMI_MLO_VDEV_BITMAP_SZ];
6170+
struct wmi_mlo_control_flags_arg ctrl_flags;
6171+
bool use_ieee_link_id;
6172+
struct wmi_ml_link_force_cmd_arg force_cmd;
6173+
u32 num_disallow_mode_comb;
6174+
struct wmi_ml_disallow_mode_bmap_arg disallow_bmap[WMI_ML_MAX_DISALLOW_BMAP_COMB];
6175+
};
6176+
60646177
void ath12k_wmi_init_qcn9274(struct ath12k_base *ab,
60656178
struct ath12k_wmi_resource_config_arg *config);
60666179
void ath12k_wmi_init_wcn7850(struct ath12k_base *ab,
@@ -6259,5 +6372,6 @@ bool ath12k_wmi_supports_6ghz_cc_ext(struct ath12k *ar);
62596372
int ath12k_wmi_send_vdev_set_tpc_power(struct ath12k *ar,
62606373
u32 vdev_id,
62616374
struct ath12k_reg_tpc_power_info *param);
6262-
6375+
int ath12k_wmi_send_mlo_link_set_active_cmd(struct ath12k_base *ab,
6376+
struct wmi_mlo_link_set_active_arg *param);
62636377
#endif

0 commit comments

Comments
 (0)