Message ID | 20241023133004.2253830-7-kvalo@kernel.org |
---|---|
State | New |
Headers | show |
Series | wifi: ath12k: MLO support part 2 | expand |
Kalle Valo <kvalo@kernel.org> wrote: > @@ -7016,7 +7017,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) > struct ath12k_vif *ahvif = arvif->ahvif; > struct ieee80211_vif *vif = ath12k_ahvif_to_vif(ahvif); > struct ath12k_wmi_vdev_create_arg vdev_arg = {0}; > - struct ath12k_wmi_peer_create_arg peer_param; > + struct ath12k_wmi_peer_create_arg peer_param = {0}; Using '= {}' as initializer would be better, no matter first field of struct will be changed in the future.
Jeff Johnson <quic_jjohnson@quicinc.com> writes: >> @@ -1244,9 +1249,23 @@ int ath12k_wmi_send_peer_create_cmd(struct ath12k *ar, >> cmd->peer_type = cpu_to_le32(arg->peer_type); >> cmd->vdev_id = cpu_to_le32(arg->vdev_id); >> >> + ptr = skb->data + sizeof(*cmd); >> + tlv = ptr; >> + tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_STRUCT, >> + sizeof(*ml_param)); > > using the same TLV size both here and for the TLV that follows doesn't seem > logical. is this missing + TLV_HDR_SIZE to account for its own TLV header? I have forgotten the details of WMI voodoo so I can't really comment right now :) >> + ptr += TLV_HDR_SIZE; >> + ml_param = ptr; >> + ml_param->tlv_header = >> + ath12k_wmi_tlv_cmd_hdr(WMI_TAG_MLO_PEER_CREATE_PARAMS, >> + sizeof(*ml_param)); But did you notice that here is used ath12k_wmi_tlv_cmd_hdr() and it reduces the header size: static __le32 ath12k_wmi_tlv_cmd_hdr(u32 cmd, u32 len) { return ath12k_wmi_tlv_hdr(cmd, len - TLV_HDR_SIZE); }
On 10/29/2024 8:54 AM, Kalle Valo wrote: > Jeff Johnson <quic_jjohnson@quicinc.com> writes: > >>> @@ -1244,9 +1249,23 @@ int ath12k_wmi_send_peer_create_cmd(struct ath12k *ar, >>> cmd->peer_type = cpu_to_le32(arg->peer_type); >>> cmd->vdev_id = cpu_to_le32(arg->vdev_id); >>> >>> + ptr = skb->data + sizeof(*cmd); >>> + tlv = ptr; >>> + tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_STRUCT, >>> + sizeof(*ml_param)); >> >> using the same TLV size both here and for the TLV that follows doesn't seem >> logical. is this missing + TLV_HDR_SIZE to account for its own TLV header? > > I have forgotten the details of WMI voodoo so I can't really comment > right now :) > >>> + ptr += TLV_HDR_SIZE; >>> + ml_param = ptr; >>> + ml_param->tlv_header = >>> + ath12k_wmi_tlv_cmd_hdr(WMI_TAG_MLO_PEER_CREATE_PARAMS, >>> + sizeof(*ml_param)); > > But did you notice that here is used ath12k_wmi_tlv_cmd_hdr() and it > reduces the header size: > > static __le32 ath12k_wmi_tlv_cmd_hdr(u32 cmd, u32 len) > { > return ath12k_wmi_tlv_hdr(cmd, len - TLV_HDR_SIZE); > } > Yes, I missed that since that is evil to use the _cmd_ TLV function on something that isn't the command TLV. Please fix to use the standard function and subtract the thv header size from the length param
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 019a1a6c6777..b628bc2fd0f5 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -4981,8 +4981,9 @@ static int ath12k_mac_station_add(struct ath12k *ar, } peer_param.vdev_id = arvif->vdev_id; - peer_param.peer_addr = sta->addr; + peer_param.peer_addr = arsta->addr; peer_param.peer_type = WMI_PEER_TYPE_DEFAULT; + peer_param.ml_enabled = sta->mlo; ret = ath12k_peer_create(ar, arvif, sta, &peer_param); if (ret) { @@ -7016,7 +7017,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) struct ath12k_vif *ahvif = arvif->ahvif; struct ieee80211_vif *vif = ath12k_ahvif_to_vif(ahvif); struct ath12k_wmi_vdev_create_arg vdev_arg = {0}; - struct ath12k_wmi_peer_create_arg peer_param; + struct ath12k_wmi_peer_create_arg peer_param = {0}; struct ieee80211_bss_conf *link_conf; u32 param_id, param_value; u16 nss; diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index e089b58bbea1..0583d832fac7 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -1230,9 +1230,14 @@ int ath12k_wmi_send_peer_create_cmd(struct ath12k *ar, struct ath12k_wmi_pdev *wmi = ar->wmi; struct wmi_peer_create_cmd *cmd; struct sk_buff *skb; - int ret; + int ret, len; + struct wmi_peer_create_mlo_params *ml_param; + void *ptr; + struct wmi_tlv *tlv; - skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); + len = sizeof(*cmd) + TLV_HDR_SIZE + sizeof(*ml_param); + + skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, len); if (!skb) return -ENOMEM; @@ -1244,9 +1249,23 @@ int ath12k_wmi_send_peer_create_cmd(struct ath12k *ar, cmd->peer_type = cpu_to_le32(arg->peer_type); cmd->vdev_id = cpu_to_le32(arg->vdev_id); + ptr = skb->data + sizeof(*cmd); + tlv = ptr; + tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_STRUCT, + sizeof(*ml_param)); + ptr += TLV_HDR_SIZE; + ml_param = ptr; + ml_param->tlv_header = + ath12k_wmi_tlv_cmd_hdr(WMI_TAG_MLO_PEER_CREATE_PARAMS, + sizeof(*ml_param)); + if (arg->ml_enabled) + ml_param->flags = cpu_to_le32(ATH12K_WMI_FLAG_MLO_ENABLED); + + ptr += sizeof(*ml_param); + ath12k_dbg(ar->ab, ATH12K_DBG_WMI, - "WMI peer create vdev_id %d peer_addr %pM\n", - arg->vdev_id, arg->peer_addr); + "WMI peer create vdev_id %d peer_addr %pM ml_flags 0x%x\n", + arg->vdev_id, arg->peer_addr, ml_param->flags); ret = ath12k_wmi_cmd_send(wmi, skb, WMI_PEER_CREATE_CMDID); if (ret) { diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index 33b9643644c6..07bd275608bf 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -3026,6 +3026,12 @@ struct ath12k_wmi_peer_create_arg { const u8 *peer_addr; u32 peer_type; u32 vdev_id; + bool ml_enabled; +}; + +struct wmi_peer_create_mlo_params { + __le32 tlv_header; + __le32 flags; }; struct ath12k_wmi_pdev_set_regdomain_arg {