ath11k: vdev and peer delete synchronization with firmware
v2 cover ath11k: vdev and peer delete synchronization with firmware
When add an interface immediately after removing the interface, vdev deletion in firmware might not have been completed. add vdev_delete_resp_event and wait_event_timeout to synchronize with firmware.
Peer creation in firmware fails if last peer deletion is still in progress, add wait for the event after deleting every peer from host driver to synchronize with firmware.
1) add vdev delete resp event and wait event to get ack from firmware
2) add wait event timeout for peer delete to get ack from firmware
3) code clean up and replace the api 'ath11k_mac_get_ar_vdev_stop_status' with 'ath11k_mac_get_ar_by_vdev_id'
V2: Rebased on latest ath.git TOT - Addressed Kalle's comment.
Ritesh Singh (3):
ath11k: vdev delete synchronization with firmware
ath11k: peer delete synchronization with firmware
ath11k: remove "ath11k_mac_get_ar_vdev_stop_status" references
drivers/net/wireless/ath/ath11k/core.c | 2 + drivers/net/wireless/ath/ath11k/core.h | 9 ++-- drivers/net/wireless/ath/ath11k/mac.c | 82 ++++++++++++++++------------------ drivers/net/wireless/ath/ath11k/mac.h | 2 - drivers/net/wireless/ath/ath11k/peer.c | 44 ++++++++++++++++-- drivers/net/wireless/ath/ath11k/peer.h | 2 + drivers/net/wireless/ath/ath11k/wmi.c | 81 ++++++++++++++++++++++++++++++--- drivers/net/wireless/ath/ath11k/wmi.h | 4 ++ 8 files changed, 166 insertions(+), 60 deletions(-)
Signature · 1 line
2.7.4
PATCH v2 1/3 ath11k: vdev delete synchronization with firmware
From: Ritesh Singh <[email protected]>
When the interface is added immediately after removing the interface, vdev deletion in firmware might not have been completed.
Hence, add vdev_delete_resp_event and wait_event_timeout to synchronize with firmware.
---
V2: Rebased on latest ath.git TOT(Addressed Kalle's comment).
drivers/net/wireless/ath/ath11k/core.c | 1 + drivers/net/wireless/ath/ath11k/core.h | 2 ++ drivers/net/wireless/ath/ath11k/mac.c | 29 ++++++++++++---- drivers/net/wireless/ath/ath11k/wmi.c | 62 +++++++++++++++++++++++++++++++++- drivers/net/wireless/ath/ath11k/wmi.h | 4 +++ 5 files changed, 90 insertions(+), 8 deletions(-)
drivers/net/wireless/ath/ath11k/core.c +1 -0
@@ -810,6 +810,7 @@ static void ath11k_core_restart(struct work_struct *work)complete (&ar->peer_assoc_done);complete (&ar->install_key_done);complete (&ar->vdev_setup_done); +complete (&ar->vdev_delete_done);complete (&ar->bss_survey_done);complete (&ar->thermal.wmi_sync);
drivers/net/wireless/ath/ath11k/core.h +2 -0
@@ -430,6 +430,7 @@ struct ath11k_per_peer_tx_stats { };#define ATH11K_FLUSH_TIMEOUT (5 * HZ) +#define ATH11K_VDEV_DELETE_TIMEOUT_HZ (5 * HZ)struct ath11k_vdev_stop_status {bool stop_in_progress;
@@ -512,6 +513,7 @@ struct ath11k {int last_wmi_vdev_start_status;struct ath11k_vdev_stop_status vdev_stop_status;struct completion vdev_setup_done; +struct completion vdev_delete_done;int num_peers;int max_num_peers;
drivers/net/wireless/ath/ath11k/mac.c +22 -7
@@ -4664,6 +4664,7 @@ static void ath11k_mac_op_remove_interface(struct ieee80211_hw *hw,struct ath11k *ar = hw->priv;struct ath11k_vif *arvif =ath11k_vif_to_arvif (vif);struct ath11k_base *ab = ar->ab; +unsigned long time_left;int ret;int i;
@@ -4672,10 +4673,6 @@ static void ath11k_mac_op_remove_interface(struct ieee80211_hw *hw,ath11k_dbg (ab,ATH11K_DBG_MAC ,"mac remove interface (vdev %d)\n" , arvif->vdev_id); -spin_lock_bh (&ar->data_lock); -list_del (&arvif->list); -spin_unlock_bh (&ar->data_lock); -if (arvif->vdev_type ==WMI_VDEV_TYPE_AP ) { ret =ath11k_peer_delete (ar, arvif->vdev_id, vif->addr);if (ret)
@@ -4683,16 +4680,33 @@ static void ath11k_mac_op_remove_interface(struct ieee80211_hw *hw, arvif->vdev_id, ret); } +reinit_completion (&ar->vdev_delete_done); + ret =ath11k_wmi_vdev_delete (ar, arvif->vdev_id); -if (ret) +if (ret) {ath11k_warn (ab,"failed to delete WMI vdev %d: %d\n" , arvif->vdev_id, ret); + goto err_vdev_del; + } + + time_left =wait_for_completion_timeout (&ar->vdev_delete_done, +ATH11K_VDEV_DELETE_TIMEOUT_HZ ); +if (time_left ==0 ) { +ath11k_warn (ab,"Timeout in receiving vdev delete response\n" ); + goto err_vdev_del; + } + ab->free_vdev_map |=1LL << (arvif->vdev_id); + ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id); ar->num_created_vdevs--; +ath11k_dbg (ab,ATH11K_DBG_MAC ,"vdev %pM deleted, vdev_id %d\n" , vif->addr, arvif->vdev_id); - ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id); - ab->free_vdev_map |=1LL << (arvif->vdev_id); + +err_vdev_del: +spin_lock_bh (&ar->data_lock); +list_del (&arvif->list); +spin_unlock_bh (&ar->data_lock);ath11k_peer_cleanup (ar, arvif->vdev_id);
@@ -6458,6 +6472,7 @@ int ath11k_mac_allocate(struct ath11k_base *ab)INIT_LIST_HEAD (&ar->ppdu_stats_info);mutex_init (&ar->conf_mutex);init_completion (&ar->vdev_setup_done); +init_completion (&ar->vdev_delete_done);init_completion (&ar->peer_assoc_done);init_completion (&ar->install_key_done);init_completion (&ar->bss_survey_done);
drivers/net/wireless/ath/ath11k/wmi.c +61 -1
92 lines not on this page · raw message
drivers/net/wireless/ath/ath11k/wmi.h +4 -0
@@ -4018,6 +4018,10 @@ struct wmi_regulatory_rule_struct {u32 flag_info; }; +struct wmi_vdev_delete_resp_event { +u32 vdev_id; +} __packed; +struct wmi_peer_delete_resp_event {u32 vdev_id;struct wmi_mac_addr peer_macaddr;
Signature · 7 lines
2.7.4 -- ath11k mailing list [email protected] http://lists.infradead.org/mailman/listinfo/ath11k
PATCH v2 2/3 ath11k: peer delete synchronization with firmware
In reply to Maharaja KennadyrajanFrom: Ritesh Singh <[email protected]>
Peer creation in firmware fails, if last peer deletion is still in progress.
Hence, add wait for the event after deleting every peer from host driver to synchronize with firmware.
---
V2: Rebased on latest ath.git TOT(Addressed Kalle's comment).
drivers/net/wireless/ath/ath11k/core.c | 1 + drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/mac.c | 17 ++++++++++++- drivers/net/wireless/ath/ath11k/peer.c | 44 +++++++++++++++++++++++++++++++--- drivers/net/wireless/ath/ath11k/peer.h | 2 ++ drivers/net/wireless/ath/ath11k/wmi.c | 17 ++++++++++--- 6 files changed, 75 insertions(+), 7 deletions(-)
drivers/net/wireless/ath/ath11k/core.c +1 -0
@@ -808,6 +808,7 @@ static void ath11k_core_restart(struct work_struct *work)complete (&ar->scan.started);complete (&ar->scan.completed);complete (&ar->peer_assoc_done); +complete (&ar->peer_delete_done);complete (&ar->install_key_done);complete (&ar->vdev_setup_done);complete (&ar->vdev_delete_done);
drivers/net/wireless/ath/ath11k/core.h +1 -0
@@ -506,6 +506,7 @@ struct ath11k {u8 lmac_id;struct completion peer_assoc_done; +struct completion peer_delete_done;int install_key_status;struct completion install_key_done;
drivers/net/wireless/ath/ath11k/mac.c +16 -1
@@ -4628,8 +4628,22 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, err_peer_del:if (arvif->vdev_type ==WMI_VDEV_TYPE_AP ) { +reinit_completion (&ar->peer_delete_done); + + ret =ath11k_wmi_send_peer_delete_cmd (ar, vif->addr, + arvif->vdev_id); +if (ret) { +ath11k_warn (ar->ab,"failed to delete peer vdev_id %d addr %pM\n" , + arvif->vdev_id, vif->addr); +return ret; + } + + ret =ath11k_wait_for_peer_delete_done (ar, arvif->vdev_id, + vif->addr); +if (ret) +return ret; + ar->num_peers--; -ath11k_wmi_send_peer_delete_cmd (ar, vif->addr, arvif->vdev_id); } err_vdev_del:
@@ -6474,6 +6488,7 @@ int ath11k_mac_allocate(struct ath11k_base *ab)init_completion (&ar->vdev_setup_done);init_completion (&ar->vdev_delete_done);init_completion (&ar->peer_assoc_done); +init_completion (&ar->peer_delete_done);init_completion (&ar->install_key_done);init_completion (&ar->bss_survey_done);init_completion (&ar->scan.started);
drivers/net/wireless/ath/ath11k/peer.c +41 -3
68 lines not on this page · raw message
drivers/net/wireless/ath/ath11k/peer.h +2 -0
@@ -41,5 +41,7 @@ void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id);int ath11k_peer_delete (struct ath11k *ar,u32 vdev_id,u8 *addr);int ath11k_peer_create (struct ath11k *ar,struct ath11k_vif *arvif,struct ieee80211_sta *sta,struct peer_create_params *param); +int ath11k_wait_for_peer_delete_done (struct ath11k *ar,u32 vdev_id, +const u8 *addr);#endif /* _PEER_H_ */
drivers/net/wireless/ath/ath11k/wmi.c +14 -3
@@ -5730,15 +5730,26 @@ static int ath11k_ready_event(struct ath11k_base *ab, struct sk_buff *skb)static void ath11k_peer_delete_resp_event (struct ath11k_base *ab,struct sk_buff *skb) {struct wmi_peer_delete_resp_event peer_del_resp; +struct ath11k *ar;if (ath11k_pull_peer_del_resp_ev (ab, skb, &peer_del_resp) !=0 ) {ath11k_warn (ab,"failed to extract peer delete resp" );return ; } -/* TODO: Do we need to validate whether ath11k_peer_find() return NULL -* Why this is needed when there is HTT event for peer delete -*/ +rcu_read_lock (); + ar =ath11k_mac_get_ar_by_vdev_id (ab, peer_del_resp.vdev_id); +if (!ar) { +ath11k_warn (ab,"invalid vdev id in peer delete resp ev %d" , + peer_del_resp.vdev_id); +rcu_read_unlock (); +return ; + } + +complete (&ar->peer_delete_done); +rcu_read_unlock (); +ath11k_dbg (ab,ATH11K_DBG_WMI ,"peer delete resp for vdev id %d addr %pM\n" , + peer_del_resp.vdev_id, peer_del_resp.peer_macaddr.addr); } static void ath11k_vdev_delete_resp_event(struct ath11k_base *ab,
Signature · 7 lines
2.7.4 -- ath11k mailing list [email protected] http://lists.infradead.org/mailman/listinfo/ath11k
PATCH v2 3/3 ath11k: remove "ath11k_mac_get_ar_vdev_stop_status" references
In reply to Maharaja KennadyrajanFrom: Ritesh Singh <[email protected]>
Unused structure ath11k_vdev_stop_status is removed. 'ath11k_mac_get_ar_vdev_stop_status' api has been replaced with 'ath11k_mac_get_ar_by_vdev_id' inside vdev_stopped_event.
---
V2: Rebased on latest ath.git TOT(Addressed Kalle's comment).
drivers/net/wireless/ath/ath11k/core.h | 6 ------ drivers/net/wireless/ath/ath11k/mac.c | 36 ---------------------------------- drivers/net/wireless/ath/ath11k/mac.h | 2 -- drivers/net/wireless/ath/ath11k/wmi.c | 2 +- 4 files changed, 1 insertion(+), 45 deletions(-)
drivers/net/wireless/ath/ath11k/core.h +0 -6
@@ -432,11 +432,6 @@ struct ath11k_per_peer_tx_stats {#define ATH11K_FLUSH_TIMEOUT (5 * HZ)#define ATH11K_VDEV_DELETE_TIMEOUT_HZ (5 * HZ) -struct ath11k_vdev_stop_status { -bool stop_in_progress; -u32 vdev_id; -}; -struct ath11k {struct ath11k_base *ab;struct ath11k_pdev *pdev;
@@ -512,7 +507,6 @@ struct ath11k {struct completion install_key_done;int last_wmi_vdev_start_status; -struct ath11k_vdev_stop_status vdev_stop_status;struct completion vdev_setup_done;struct completion vdev_delete_done;
drivers/net/wireless/ath/ath11k/mac.c +0 -36
@@ -537,31 +537,6 @@ struct ath11k *ath11k_mac_get_ar_by_pdev_id(struct ath11k_base *ab, u32 pdev_id)return NULL ; } -struct ath11k *ath11k_mac_get_ar_vdev_stop_status (struct ath11k_base *ab, -u32 vdev_id) -{ -int i; -struct ath11k_pdev *pdev; -struct ath11k *ar; - -for (i =0 ; i < ab->num_radios; i++) { - pdev =rcu_dereference (ab->pdevs_active[i]); -if (pdev && pdev->ar) { - ar = pdev->ar; - -spin_lock_bh (&ar->data_lock); -if (ar->vdev_stop_status.stop_in_progress && - ar->vdev_stop_status.vdev_id == vdev_id) { - ar->vdev_stop_status.stop_in_progress = false; -spin_unlock_bh (&ar->data_lock); -return ar; - } -spin_unlock_bh (&ar->data_lock); - } - } -return NULL ; -} -static void ath11k_pdev_caps_update (struct ath11k *ar) {struct ath11k_base *ab = ar->ab;
@@ -5024,13 +4999,6 @@ static int ath11k_mac_vdev_stop(struct ath11k_vif *arvif)reinit_completion (&ar->vdev_setup_done); -spin_lock_bh (&ar->data_lock); - - ar->vdev_stop_status.stop_in_progress = true; - ar->vdev_stop_status.vdev_id = arvif->vdev_id; - -spin_unlock_bh (&ar->data_lock); - ret =ath11k_wmi_vdev_stop (ar, arvif->vdev_id);if (ret) { ath11k_warn(ar->ab, "failed to stop WMI vdev %i: %d\n",
@@ -5059,10 +5027,6 @@ static int ath11k_mac_vdev_stop(struct ath11k_vif *arvif)return 0 ; err: -spin_lock_bh (&ar->data_lock); - ar->vdev_stop_status.stop_in_progress = false; -spin_unlock_bh (&ar->data_lock); -return ret; }
drivers/net/wireless/ath/ath11k/mac.h +0 -2
@@ -137,8 +137,6 @@ struct ath11k_vif *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab, u32 vdev_id);struct ath11k *ath11k_mac_get_ar_by_vdev_id (struct ath11k_base *ab,u32 vdev_id);struct ath11k *ath11k_mac_get_ar_by_pdev_id (struct ath11k_base *ab,u32 pdev_id); -struct ath11k *ath11k_mac_get_ar_vdev_stop_status (struct ath11k_base *ab, -u32 vdev_id);void ath11k_mac_drain_tx (struct ath11k *ar);void ath11k_mac_peer_cleanup_all (struct ath11k *ar);
drivers/net/wireless/ath/ath11k/wmi.c +1 -1
@@ -5856,7 +5856,7 @@ static void ath11k_vdev_stopped_event(struct ath11k_base *ab, struct sk_buff *sk }rcu_read_lock (); - ar =ath11k_mac_get_ar_vdev_stop_status (ab, vdev_id); + ar =ath11k_mac_get_ar_by_vdev_id (ab, vdev_id);if (!ar) {ath11k_warn (ab,"invalid vdev id in vdev stopped ev %d" , vdev_id);
Signature · 7 lines
2.7.4 -- ath11k mailing list [email protected] http://lists.infradead.org/mailman/listinfo/ath11k
On 2020-11-12 13:12, Maharaja Kennadyrajan wrote:
Hi Kalle,
Kindly ignore this patchset as I didn't mention the version number in the subject name of the patches in the patchlist.
I will correct this and send v3 patchset.
Regret for the inconvenience caused.
Regards,
Maha
Quoted 32 lines
When add an interface immediately after removing the interface, vdev deletion in firmware might not have been completed. add
vdev_delete_resp_eventandwait_event_timeoutto synchronize with firmware.Peer creation in firmware fails if last peer deletion is still in progress, add wait for the event after deleting every peer from host driver to synchronize with firmware.
1) add vdev delete resp event and wait event to get ack from firmware
2) add wait event timeout for peer delete to get ack from firmware
3) code clean up and replace the api 'ath11k_mac_get_ar_vdev_stop_status' with 'ath11k_mac_get_ar_by_vdev_id'V2: Rebased on latest ath.git TOT - Addressed Kalle's comment.
Ritesh Singh (3):
ath11k: vdev delete synchronization with firmware
ath11k: peer delete synchronization with firmware
ath11k: remove "ath11k_mac_get_ar_vdev_stop_status" referencesdrivers/net/wireless/ath/ath11k/core.c | 2 + drivers/net/wireless/ath/ath11k/core.h | 9 ++-- drivers/net/wireless/ath/ath11k/mac.c | 82 ++++++++++++++++------------------ drivers/net/wireless/ath/ath11k/mac.h | 2 - drivers/net/wireless/ath/ath11k/peer.c | 44 ++++++++++++++++-- drivers/net/wireless/ath/ath11k/peer.h | 2 + drivers/net/wireless/ath/ath11k/wmi.c | 81 ++++++++++++++++++++++++++++++--- drivers/net/wireless/ath/ath11k/wmi.h | 4 ++ 8 files changed, 166 insertions(+), 60 deletions(-)
Signature · 3 lines
ath11k mailing list [email protected] http://lists.infradead.org/mailman/listinfo/ath11k