Message ID | 20230405054646.7300-1-quic_rgnanase@quicinc.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Kalle Valo |
Headers | show |
Series | wifi: ath12k: add wait operation for tx management packets for flush from mac80211 | expand |
Ramya Gnanasekar <quic_rgnanase@quicinc.com> writes: > From: Karthik M <quic_karm@quicinc.com> > > Transmission of management packets are done in a work queue. Sometimes > the workqueue does not finish Tx immediately, then it lead after the next > step of vdev delete finished, it start to send the management packet to > firmware and lead firmware crash. > > ieee80211_set_disassoc() have logic of ieee80211_flush_queues() after > it send_deauth_disassoc() to ath12k, its purpose is make sure the > deauth was actually sent, so it need to change ath12k to match the > purpose of mac80211. > > To address these issues wait for Tx management as well as Tx data packets. > > Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 > > Signed-off-by: Karthik M <quic_karm@quicinc.com> > Signed-off-by: Ramya Gnanasekar <quic_rgnanase@quicinc.com> > > diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c > index a89e66653f04..499b81cd938e 100644 Ramya, how do you submit your patches? Your patches are missing the "---" line which breaks my scripts. I have asked this already before but no reply from you: https://lore.kernel.org/all/87edqot8m4.fsf@kernel.org/ Please do not ignore my questions. If you continue to do that I will just stop taking patches from you.
> -----Original Message----- > From: Kalle Valo <kvalo@kernel.org> > Sent: Monday, April 17, 2023 6:26 PM > To: Ramya Gnanasekar (Temp) (QUIC) <quic_rgnanase@quicinc.com> > Cc: ath12k@lists.infradead.org; linux-wireless@vger.kernel.org; Karthik M > (QUIC) <quic_karm@quicinc.com> > Subject: Re: [PATCH] wifi: ath12k: add wait operation for tx management > packets for flush from mac80211 > > WARNING: This email originated from outside of Qualcomm. Please be wary of > any links or attachments, and do not enable macros. > > Ramya Gnanasekar <quic_rgnanase@quicinc.com> writes: > > > From: Karthik M <quic_karm@quicinc.com> > > > > Transmission of management packets are done in a work queue. Sometimes > > the workqueue does not finish Tx immediately, then it lead after the > > next step of vdev delete finished, it start to send the management > > packet to firmware and lead firmware crash. > > > > ieee80211_set_disassoc() have logic of ieee80211_flush_queues() after > > it send_deauth_disassoc() to ath12k, its purpose is make sure the > > deauth was actually sent, so it need to change ath12k to match the > > purpose of mac80211. > > > > To address these issues wait for Tx management as well as Tx data packets. > > > > Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029- > QCAHKSWPL_SILICONZ-1 > > > > Signed-off-by: Karthik M <quic_karm@quicinc.com> > > Signed-off-by: Ramya Gnanasekar <quic_rgnanase@quicinc.com> > > > > diff --git a/drivers/net/wireless/ath/ath12k/core.c > > b/drivers/net/wireless/ath/ath12k/core.c > > index a89e66653f04..499b81cd938e 100644 > > Ramya, how do you submit your patches? Your patches are missing the "---" line > which breaks my scripts. I have asked this already before but no reply from you: > > https://lore.kernel.org/all/87edqot8m4.fsf@kernel.org/ > > Please do not ignore my questions. If you continue to do that I will just stop > taking patches from you. > > -- > https://patchwork.kernel.org/project/linux-wireless/list/ > > https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatch > es Hi Kalle, I use "git send-email" to send the patches and the patches are generated using "git format-patch" command. Thanks, Ramya
> -----Original Message----- > From: Ramya Gnanasekar <rgnanase@qti.qualcomm.com> > Sent: Monday, April 17, 2023 8:01 PM > To: Kalle Valo <kvalo@kernel.org>; Ramya Gnanasekar (Temp) (QUIC) > <quic_rgnanase@quicinc.com> > Cc: ath12k@lists.infradead.org; linux-wireless@vger.kernel.org; Karthik M > (QUIC) <quic_karm@quicinc.com> > Subject: RE: [PATCH] wifi: ath12k: add wait operation for tx management > packets for flush from mac80211 > > > -----Original Message----- > > From: Kalle Valo <kvalo@kernel.org> > > Sent: Monday, April 17, 2023 6:26 PM > > To: Ramya Gnanasekar (Temp) (QUIC) <quic_rgnanase@quicinc.com> > > Cc: ath12k@lists.infradead.org; linux-wireless@vger.kernel.org; > > Karthik M > > (QUIC) <quic_karm@quicinc.com> > > Subject: Re: [PATCH] wifi: ath12k: add wait operation for tx > > management packets for flush from mac80211 > > > > WARNING: This email originated from outside of Qualcomm. Please be > > wary of any links or attachments, and do not enable macros. > > > > Ramya Gnanasekar <quic_rgnanase@quicinc.com> writes: > > > > > From: Karthik M <quic_karm@quicinc.com> > > > > > > Transmission of management packets are done in a work queue. > > > Sometimes the workqueue does not finish Tx immediately, then it lead > > > after the next step of vdev delete finished, it start to send the > > > management packet to firmware and lead firmware crash. > > > > > > ieee80211_set_disassoc() have logic of ieee80211_flush_queues() > > > after it send_deauth_disassoc() to ath12k, its purpose is make sure > > > the deauth was actually sent, so it need to change ath12k to match > > > the purpose of mac80211. > > > > > > To address these issues wait for Tx management as well as Tx data packets. > > > > > > Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029- > > QCAHKSWPL_SILICONZ-1 > > > > > > Signed-off-by: Karthik M <quic_karm@quicinc.com> > > > Signed-off-by: Ramya Gnanasekar <quic_rgnanase@quicinc.com> > > > > > > diff --git a/drivers/net/wireless/ath/ath12k/core.c > > > b/drivers/net/wireless/ath/ath12k/core.c > > > index a89e66653f04..499b81cd938e 100644 > > > > Ramya, how do you submit your patches? Your patches are missing the > > "---" line which breaks my scripts. I have asked this already before but no reply > from you: > > > > https://lore.kernel.org/all/87edqot8m4.fsf@kernel.org/ > > > > Please do not ignore my questions. If you continue to do that I will > > just stop taking patches from you. > > > > -- > > https://patchwork.kernel.org/project/linux-wireless/list/ > > > > https://wireless.wiki.kernel.org/en/developers/documentation/submittin > > gpatch > > es > > Hi Kalle, > > I use "git send-email" to send the patches and the patches are generated using > "git format-patch" command. > > Thanks, > Ramya Hi Kalle, I used "git format-patch -p1" which removed "---" while generating patch. I will correct it by using "git format-patch -1" in future patches. Also I will resend this patch with right format. Thanks, Ramya
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index a89e66653f04..499b81cd938e 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -706,6 +706,7 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab) idr_for_each(&ar->txmgmt_idr, ath12k_mac_tx_mgmt_pending_free, ar); idr_destroy(&ar->txmgmt_idr); + wake_up(&ar->txmgmt_empty_waitq); } wake_up(&ab->wmi_ab.tx_credits_wq); diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index dffa687ee40e..509a9d4450b4 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -532,6 +532,7 @@ struct ath12k { /* protects txmgmt_idr data */ spinlock_t txmgmt_idr_lock; atomic_t num_pending_mgmt_tx; + wait_queue_head_t txmgmt_empty_waitq; /* cycle count is reported twice for each visited channel during scan. * access protected by data_lock diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index bf7e5b6977b2..0e5cc477ba56 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -4316,6 +4316,21 @@ static int __ath12k_set_antenna(struct ath12k *ar, u32 tx_ant, u32 rx_ant) return 0; } +static void ath12k_mgmt_over_wmi_tx_drop(struct ath12k *ar, struct sk_buff *skb) +{ + int num_mgmt; + + ieee80211_free_txskb(ar->hw, skb); + + num_mgmt = atomic_dec_if_positive(&ar->num_pending_mgmt_tx); + + if (num_mgmt < 0) + WARN_ON_ONCE(1); + + if (!num_mgmt) + wake_up(&ar->txmgmt_empty_waitq); +} + int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx) { struct sk_buff *msdu = skb; @@ -4332,7 +4347,7 @@ int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx) info = IEEE80211_SKB_CB(msdu); memset(&info->status, 0, sizeof(info->status)); - ieee80211_free_txskb(ar->hw, msdu); + ath12k_mgmt_over_wmi_tx_drop(ar, skb); return 0; } @@ -4416,7 +4431,7 @@ static void ath12k_mgmt_over_wmi_tx_purge(struct ath12k *ar) struct sk_buff *skb; while ((skb = skb_dequeue(&ar->wmi_mgmt_tx_queue)) != NULL) - ieee80211_free_txskb(ar->hw, skb); + ath12k_mgmt_over_wmi_tx_drop(ar, skb); } static void ath12k_mgmt_over_wmi_tx_work(struct work_struct *work) @@ -4431,7 +4446,7 @@ static void ath12k_mgmt_over_wmi_tx_work(struct work_struct *work) skb_cb = ATH12K_SKB_CB(skb); if (!skb_cb->vif) { ath12k_warn(ar->ab, "no vif found for mgmt frame\n"); - ieee80211_free_txskb(ar->hw, skb); + ath12k_mgmt_over_wmi_tx_drop(ar, skb); continue; } @@ -4442,16 +4457,14 @@ static void ath12k_mgmt_over_wmi_tx_work(struct work_struct *work) if (ret) { ath12k_warn(ar->ab, "failed to tx mgmt frame, vdev_id %d :%d\n", arvif->vdev_id, ret); - ieee80211_free_txskb(ar->hw, skb); - } else { - atomic_inc(&ar->num_pending_mgmt_tx); + ath12k_mgmt_over_wmi_tx_drop(ar, skb); } } else { ath12k_warn(ar->ab, "dropping mgmt frame for vdev %d, is_started %d\n", arvif->vdev_id, arvif->is_started); - ieee80211_free_txskb(ar->hw, skb); + ath12k_mgmt_over_wmi_tx_drop(ar, skb); } } } @@ -4482,6 +4495,7 @@ static int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb, } skb_queue_tail(q, skb); + atomic_inc(&ar->num_pending_mgmt_tx); ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work); return 0; @@ -5955,6 +5969,13 @@ static void ath12k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *v ATH12K_FLUSH_TIMEOUT); if (time_left == 0) ath12k_warn(ar->ab, "failed to flush transmit queue %ld\n", time_left); + + time_left = wait_event_timeout(ar->txmgmt_empty_waitq, + (atomic_read(&ar->num_pending_mgmt_tx) == 0), + ATH12K_FLUSH_TIMEOUT); + if (time_left == 0) + ath12k_warn(ar->ab, "failed to flush mgmt transmit queue %ld\n", + time_left); } static int @@ -6932,6 +6953,7 @@ int ath12k_mac_register(struct ath12k_base *ab) if (ret) goto err_cleanup; + init_waitqueue_head(&ar->txmgmt_empty_waitq); idr_init(&ar->txmgmt_idr); spin_lock_init(&ar->txmgmt_idr_lock); } diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 3e6991120e53..1d303b217758 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -4637,6 +4637,7 @@ static int wmi_process_mgmt_tx_comp(struct ath12k *ar, u32 desc_id, struct sk_buff *msdu; struct ieee80211_tx_info *info; struct ath12k_skb_cb *skb_cb; + int num_mgmt; spin_lock_bh(&ar->txmgmt_idr_lock); msdu = idr_find(&ar->txmgmt_idr, desc_id); @@ -4660,10 +4661,15 @@ static int wmi_process_mgmt_tx_comp(struct ath12k *ar, u32 desc_id, ieee80211_tx_status_irqsafe(ar->hw, msdu); + num_mgmt = atomic_dec_if_positive(&ar->num_pending_mgmt_tx); + /* WARN when we received this event without doing any mgmt tx */ - if (atomic_dec_if_positive(&ar->num_pending_mgmt_tx) < 0) + if (num_mgmt < 0) WARN_ON_ONCE(1); + if (!num_mgmt) + wake_up(&ar->txmgmt_empty_waitq); + return 0; }