WMI and debugfs calls for TWT dialogs
v4 cover WMI and debugfs calls for TWT dialogs
This patchset adds support for TWT dialogs using debugfs.
John Crispin (2):
ath11k: add WMI calls to manually add/del/pause/resume TWT dialogs
ath11k: add debugfs for TWT debug calls
drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/debug.c | 199 +++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/debug.h | 8 + drivers/net/wireless/ath/ath11k/mac.c | 5 + drivers/net/wireless/ath/ath11k/wmi.c | 204 ++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.h | 114 +++++++++++++ 6 files changed, 531 insertions(+)
base-commit: be8cd9b8f5ed435c27530430aa1b1da30f9825d5
Signature · 1 line
2.25.0
PATCH v4 1/2 ath11k: add WMI calls to manually add/del/pause/resume TWT dialogs
From: John Crispin <[email protected]>
These calls are used for debugging and will be required for WFA certification tests.
---
Changes in V3
* Resolved compilation warnings
* Rebased to latest git tree.
Changes in V2
* avoid void * conversion
* add debug output for WMI calls
drivers/net/wireless/ath/ath11k/wmi.c | 204 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.h | 114 ++++++++++++++ 2 files changed, 318 insertions(+)
drivers/net/wireless/ath/ath11k/wmi.c +204 -0
@@ -128,6 +128,8 @@ static const struct wmi_tlv_policy wmi_tlv_policies[] = { .min_len = sizeof(struct wmi_probe_resp_tx_status_event) }, [WMI_TAG_VDEV_DELETE_RESP_EVENT] = { .min_len = sizeof(struct wmi_vdev_delete_resp_event) }, + [WMI_TAG_TWT_ADD_DIALOG_COMPLETE_EVENT ] + = { .min_len = sizeof(struct wmi_twt_add_dialog_event) }, };#define PRIMAP (_hw_mode_) \
@@ -2527,6 +2529,169 @@ int ath11k_wmi_delba_send(struct ath11k *ar, u32 vdev_id, const u8 *mac,return ret; } +int ath11k_wmi_send_twt_add_dialog_cmd (struct ath11k *ar, +struct wmi_twt_add_dialog_params *params) +{ +struct ath11k_pdev_wmi *wmi = ar->wmi; +struct ath11k_base *ab = wmi->wmi_ab->ab; +struct wmi_twt_add_dialog_params_cmd *cmd; +struct sk_buff *skb; +int ret, len; + + len =sizeof (*cmd); + + skb =ath11k_wmi_alloc_skb (wmi->wmi_ab, len); +if (!skb) +return -ENOMEM ; + + cmd = (struct wmi_twt_add_dialog_params_cmd *)skb->data; + cmd->tlv_header =FIELD_PREP (WMI_TLV_TAG ,WMI_TAG_TWT_ADD_DIALOG_CMD ) | +FIELD_PREP (WMI_TLV_LEN , len -TLV_HDR_SIZE ); + + cmd->vdev_id = params->vdev_id; +ether_addr_copy (cmd->peer_macaddr.addr, params->peer_macaddr); + cmd->dialog_id = params->dialog_id; + cmd->wake_intvl_us = params->wake_intvl_us; + cmd->wake_intvl_mantis = params->wake_intvl_mantis; + cmd->wake_dura_us = params->wake_dura_us; + cmd->sp_offset_us = params->sp_offset_us; + cmd->flags = params->twt_cmd; +if (params->flag_bcast) + cmd->flags |=WMI_TWT_ADD_DIALOG_FLAG_BCAST ; +if (params->flag_trigger) + cmd->flags |=WMI_TWT_ADD_DIALOG_FLAG_TRIGGER ; +if (params->flag_flow_type) + cmd->flags |=WMI_TWT_ADD_DIALOG_FLAG_FLOW_TYPE ; +if (params->flag_protection) + cmd->flags |=WMI_TWT_ADD_DIALOG_FLAG_PROTECTION ; + +ath11k_dbg (ar->ab,ATH11K_DBG_WMI , +"wmi_send_twt_add_dialog id %d dialog id %d wake_intvl_us %d" +" wake_intvl_mantis %d wake_dura_us %d sp_offset_us %d " +"flags %x\n" , + cmd->vdev_id, cmd->dialog_id, cmd->wake_intvl_us, + cmd->wake_intvl_mantis, cmd->wake_dura_us, cmd->sp_offset_us, + cmd->flags); + + ret =ath11k_wmi_cmd_send (wmi, skb,WMI_TWT_ADD_DIALOG_CMDID ); + +if (ret) { +ath11k_warn (ab,"Failed to send WMI_TWT_ADD_DIALOG_CMDID" ); +dev_kfree_skb (skb); + } +return ret; +} + +int ath11k_wmi_send_twt_del_dialog_cmd (struct ath11k *ar, +struct wmi_twt_del_dialog_params *params) +{ +struct ath11k_pdev_wmi *wmi = ar->wmi; +struct ath11k_base *ab = wmi->wmi_ab->ab; +struct wmi_twt_del_dialog_params_cmd *cmd; +struct sk_buff *skb; +int ret, len; + + len =sizeof (*cmd); + + skb =ath11k_wmi_alloc_skb (wmi->wmi_ab, len); +if (!skb) +return -ENOMEM ; + + cmd = (struct wmi_twt_del_dialog_params_cmd *)skb->data; + cmd->tlv_header =FIELD_PREP (WMI_TLV_TAG ,WMI_TAG_TWT_DEL_DIALOG_CMD ) | +FIELD_PREP (WMI_TLV_LEN , len -TLV_HDR_SIZE ); + + cmd->vdev_id = params->vdev_id; +ether_addr_copy (cmd->peer_macaddr.addr, params->peer_macaddr); + cmd->dialog_id = params->dialog_id; + +ath11k_dbg (ar->ab,ATH11K_DBG_WMI , +"wmi_send_twt_del_dialog id %d dialog id %d\n" , + cmd->vdev_id, cmd->dialog_id); + + ret =ath11k_wmi_cmd_send (wmi, skb,WMI_TWT_DEL_DIALOG_CMDID ); +if (ret) { +ath11k_warn (ab,"Failed to send WMI_TWT_DEL_DIALOG_CMDID" ); +dev_kfree_skb (skb); + } +return ret; +} + +int ath11k_wmi_send_twt_pause_dialog_cmd (struct ath11k *ar, +struct wmi_twt_pause_dialog_params *params) +{ +struct ath11k_pdev_wmi *wmi = ar->wmi; +struct ath11k_base *ab = wmi->wmi_ab->ab; +struct wmi_twt_pause_dialog_params_cmd *cmd; +struct sk_buff *skb; +int ret, len; + + len =sizeof (*cmd); + + skb =ath11k_wmi_alloc_skb (wmi->wmi_ab, len); +if (!skb) +return -ENOMEM ; + + cmd = (struct wmi_twt_pause_dialog_params_cmd *)skb->data; + cmd->tlv_header =FIELD_PREP (WMI_TLV_TAG , +WMI_TAG_TWT_PAUSE_DIALOG_CMD ) | +FIELD_PREP (WMI_TLV_LEN , len -TLV_HDR_SIZE ); + + cmd->vdev_id = params->vdev_id; +ether_addr_copy (cmd->peer_macaddr.addr, params->peer_macaddr); + cmd->dialog_id = params->dialog_id; + +ath11k_dbg (ar->ab,ATH11K_DBG_WMI , +"wmi_send_twt_pause_dialog id %d dialog id %d\n" , + cmd->vdev_id, cmd->dialog_id); + + ret =ath11k_wmi_cmd_send (wmi, skb,WMI_TWT_PAUSE_DIALOG_CMDID ); +if (ret) { +ath11k_warn (ab,"Failed to send WMI_TWT_PAUSE_DIALOG_CMDID" ); +dev_kfree_skb (skb); + } +return ret; +} + +int ath11k_wmi_send_twt_resume_dialog_cmd (struct ath11k *ar, +struct wmi_twt_resume_dialog_params *params) +{ +struct ath11k_pdev_wmi *wmi = ar->wmi; +struct ath11k_base *ab = wmi->wmi_ab->ab; +struct wmi_twt_resume_dialog_params_cmd *cmd; +struct sk_buff *skb; +int ret, len; + + len =sizeof (*cmd); + + skb =ath11k_wmi_alloc_skb (wmi->wmi_ab, len); +if (!skb) +return -ENOMEM ; + + cmd = (struct wmi_twt_resume_dialog_params_cmd *)skb->data; + cmd->tlv_header =FIELD_PREP (WMI_TLV_TAG , +WMI_TAG_TWT_RESUME_DIALOG_CMD ) | +FIELD_PREP (WMI_TLV_LEN , len -TLV_HDR_SIZE ); + + cmd->vdev_id = params->vdev_id; +ether_addr_copy (cmd->peer_macaddr.addr, params->peer_macaddr); + cmd->dialog_id = params->dialog_id; + cmd->sp_offset_us = params->sp_offset_us; + cmd->next_twt_size = params->next_twt_size; + +ath11k_dbg (ar->ab,ATH11K_DBG_WMI , +"wmi_send_twt_resume_dialog id %d dialog id %d sp_offset_us %d next_twt_size %d\n" , + cmd->vdev_id, cmd->dialog_id, cmd->sp_offset_us, + cmd->next_twt_size); + + ret =ath11k_wmi_cmd_send (wmi, skb,WMI_TWT_RESUME_DIALOG_CMDID ); +if (ret) { +ath11k_warn (ab,"Failed to send WMI_TWT_RESUME_DIALOG_CMDID" ); +dev_kfree_skb (skb); + } +return ret; +} +int ath11k_wmi_addba_set_resp (struct ath11k *ar,u32 vdev_id,const u8 *mac,u32 tid,u32 status) {
@@ -6756,6 +6921,39 @@ static void ath11k_wmi_event_wow_wakeup_host(struct ath11k_base *ab, struct sk_bcomplete (&ab->wow.wakeup_completed); } +static void ath11k_wmi_twt_add_dialog_event (struct ath11k_base *ab, +struct sk_buff *skb) +{ +const char *status[] = { +"OK" ,"TWT_NOT_ENABLED" ,"USED_DIALOG_ID" ,"INVALID_PARAM" , +"NOT_READY" ,"NO_RESOURCE" ,"NO_ACK" ,"NO_RESPONSE" , +"DENIED" ,"UNKNOWN_ERROR" + }; +const void **tb; +const struct wmi_twt_add_dialog_event *ev; +int ret; + + tb =ath11k_wmi_tlv_parse_alloc (ab, skb->data, skb->len,GFP_ATOMIC ); +if (IS_ERR (tb)) { + ret =PTR_ERR (tb); +ath11k_warn (ab,"failed to parse tlv: %d\n" , ret); +return ; + } + + ev = tb[WMI_TAG_TWT_ADD_DIALOG_COMPLETE_EVENT ]; +if (!ev) { +ath11k_warn (ab,"failed to fetch twt add dialog ev" ); + goto exit; + } + +ath11k_info (ab, +"TWT Add Dialog Event - Status: %s, DialogId: %d, VdevId: %d\n" , + status[ev->status], ev->vdev_id, ev->dialog_id); + +exit: +kfree (tb); +} +static void ath11k_wmi_tlv_op_rx (struct ath11k_base *ab,struct sk_buff *skb) {struct wmi_cmd_hdr *cmd_hdr;
@@ -6848,11 +7046,17 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)case WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID :ath11k_probe_resp_tx_status_event (ab, skb);break ; +case WMI_TWT_ADD_DIALOG_EVENTID : +ath11k_wmi_twt_add_dialog_event (ab, skb); +break ;/* add Unsupported events here */ case WMI_TBTTOFFSET_EXT_UPDATE_EVENTID :case WMI_PEER_OPER_MODE_CHANGE_EVENTID :case WMI_TWT_ENABLE_EVENTID :case WMI_TWT_DISABLE_EVENTID : +case WMI_TWT_DEL_DIALOG_EVENTID : +case WMI_TWT_PAUSE_DIALOG_EVENTID : +case WMI_TWT_RESUME_DIALOG_EVENTID :case WMI_PDEV_DMA_RING_CFG_RSP_EVENTID :ath11k_dbg (ab,ATH11K_DBG_WMI ,"ignoring unsupported event 0x%x\n" , id);
drivers/net/wireless/ath/ath11k/wmi.h +114 -0
126 lines not on this page · raw message
Signature · 1 line
2.25.0
PATCH v4 2/2 ath11k: add debugfs for TWT debug calls
In reply to Aloka DixitFrom: John Crispin <[email protected]>
These new debugfs files allow us to manually add/del/pause/resume TWT dialogs for test/debug purposes.
The debugfs files expect the following parametersadd_dialog - mac dialog_id wake_intvl_us wake_intvl_mantis
wake_dura_us sp_offset_us twt_cmd flag_bcast flag_trigger flag_flow_type flag_protectiondel_dialog - mac dialog_idpause_dialog - mac dialog_idresume_dialog - mac dialog_id sp_offset_us next_twt_size
---
Changes in V3
* Resolved compilation warnings
* Rebased to latest git tree.
Changes in V2
* add a better patch description
drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/debug.c | 199 ++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/debug.h | 8 + drivers/net/wireless/ath/ath11k/mac.c | 5 + 4 files changed, 213 insertions(+)
drivers/net/wireless/ath/ath11k/core.h +1 -0
@@ -239,6 +239,7 @@ struct ath11k_vif {bool rsnie_present;bool wpaie_present;struct ieee80211_chanctx_conf chanctx; +struct dentry *debugfs_twt; };struct ath11k_vif_iter {
drivers/net/wireless/ath/ath11k/debug.c +199 -0
202 lines not on this page · raw message
drivers/net/wireless/ath/ath11k/debug.h +8 -0
@@ -64,4 +64,12 @@ do { \ __ath11k_dbg(ar, dbg_mask, fmt, ##__VA_ARGS__); \ } while (0) +#ifdef CONFIG_MAC80211_DEBUGFS +void ath11k_debugfs_twt (struct ath11k_vif *arvif,bool enable); +#else +static inline void ath11k_debugfs_twt (struct ath11k_vif *arvif,bool enable) +{ +} +#endif +#endif /* _ATH11K_DEBUG_H_ */
drivers/net/wireless/ath/ath11k/mac.c +5 -0
@@ -2111,6 +2111,8 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,ath11k_wmi_send_twt_enable_cmd (ar, ar->pdev->pdev_id); else ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id); +if (vif->type ==NL80211_IFTYPE_AP ) +ath11k_debugfs_twt (arvif, info->twt_requester); }if (changed &BSS_CHANGED_HE_OBSS_PD )
@@ -4735,6 +4737,9 @@ static void ath11k_mac_op_remove_interface(struct ieee80211_hw *hw,/* TODO: recal traffic pause state based on the available vdevs */ +debugfs_remove_recursive (arvif->debugfs_twt); + arvif->debugfs_twt =NULL ; +mutex_unlock (&ar->conf_mutex); }
Signature · 1 line
2.25.0
Re: [PATCH V4 2/2] ath11k: add debugfs for TWT debug calls
+ ath11k
Quoted 15 lines · Aloka Dixit
From: John Crispin <[email protected]>
These new debugfs files allow us to manually add/del/pause/resume TWT dialogs for test/debug purposes.
The debugfs files expect the following parameters
add_dialog- macdialog_idwake_intvl_uswake_intvl_mantis
wake_dura_ussp_offset_ustwt_cmdflag_bcastflag_triggerflag_flow_typeflag_protectiondel_dialog- macdialog_idpause_dialog- macdialog_idresume_dialog- macdialog_idsp_offset_usnext_twt_sizeSigned-off-by John Crispin <[email protected]>Signed-off-by Aloka Dixit <[email protected]>
[...]
Quoted 20 lines
drivers/net/wireless/ath/ath11k/debug.h +8
-0@@ -64,4 +64,12 @@ do { \ __ath11k_dbg(ar, dbg_mask, fmt, ##__VA_ARGS__); \ } while (0) +#ifdef CONFIG_MAC80211_DEBUGFS +void ath11k_debugfs_twt (struct ath11k_vif *arvif,bool enable); +#else +static inline void ath11k_debugfs_twt (struct ath11k_vif *arvif,bool enable) +{ +} +#endif +#endif /* _ATH11K_DEBUG_H_ */ drivers/net/wireless/ath/ath11k/mac.c +0
-0
drivers/net/wireless/ath/ath11k/mac.c static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, · line 2116
Quoted 6 lines
drivers/net/wireless/ath/ath11k/mac.c +2
-0@@ -2111,6 +2111,8 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,ath11k_wmi_send_twt_enable_cmd (ar, ar->pdev->pdev_id); else ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id); +if (vif->type ==NL80211_IFTYPE_AP ) +ath11k_debugfs_twt (arvif, info->twt_requester); }
These hunks gave my deja vu and indeed I have provided comments before:
http://lists.infradead.org/pipermail/ath11k/2020-July/000039.html
I'll copy my comments here:
To make this more generic can you call this ath11k_debugs_add_interface() or something like that? Ah, but this is in ath11k_mac_op_bss_info_changed(). Shouldn't it be in ath11k_mac_op_add_interface()?
Hmm, I think I get now. You create the debugfs directory and files only when twt is actually enabled, not when the interface is added. I have concerns about files coming and going like that dynamically. Wouldn't it be cleaner to create the directory and the files when the interface is added? And just return a good error code if someone tries to use the debugfs files when twt is disabled?
Signature · 8 lines
https://patchwork.kernel.org/project/linux-wireless/list/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches -- ath11k mailing list [email protected] http://lists.infradead.org/mailman/listinfo/ath11k