diff --git sys/contrib/dev/rtw88/tx.c sys/contrib/dev/rtw88/tx.c index 5a02553b3b63..63d437fecd5a 100644 --- sys/contrib/dev/rtw88/tx.c +++ sys/contrib/dev/rtw88/tx.c @@ -158,6 +158,7 @@ void rtw_tx_report_purge_timer(struct timer_list *t) struct rtw_dev *rtwdev = from_timer(rtwdev, t, tx_report.purge_timer); struct rtw_tx_report *tx_report = &rtwdev->tx_report; unsigned long flags; +#if defined(__linux__) if (skb_queue_len(&tx_report->queue) == 0) return; @@ -167,6 +168,37 @@ void rtw_tx_report_purge_timer(struct timer_list *t) spin_lock_irqsave(&tx_report->q_lock, flags); skb_queue_purge(&tx_report->queue); spin_unlock_irqrestore(&tx_report->q_lock, flags); +#elif defined(__FreeBSD__) + struct sk_buff *cur, *tmp; + uint32_t qlen, purged; + int *j; + + spin_lock_irqsave(&tx_report->q_lock, flags); + qlen = skb_queue_len(&tx_report->queue); + if (qlen == 0) { + spin_unlock_irqrestore(&tx_report->q_lock, flags); + return; + } + purged = 0; + skb_queue_walk_safe(&tx_report->queue, cur, tmp) { + j = (int *)IEEE80211_SKB_CB(cur)->status.status_driver_data[1]; + if (time_is_after_jiffies(*j + RTW_TX_PROBE_TIMEOUT)) { + __skb_unlink(cur, &tx_report->queue); + kfree_skb(cur); + purged++; + } + } + spin_unlock_irqrestore(&tx_report->q_lock, flags); + + /* + * XXX can't there always be a new enqueue in the queue + * simply not yet processed given the timer is updated without + * locks after enqueue in rtw_tx_report_enqueue(). + * Linux git 584dce175f0461d5d9d63952a1e7955678c91086 . + */ + rtw_warn(rtwdev, "failed to get tx report from firmware: " + "txreport qlen %u, purged %u\n", qlen, purged); +#endif } void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn) @@ -178,6 +210,10 @@ void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn) /* pass sn to tx report handler through driver data */ drv_data = (u8 *)IEEE80211_SKB_CB(skb)->status.status_driver_data; *drv_data = sn; +#if defined(__FreeBSD__) + int *j = (int *)IEEE80211_SKB_CB(skb)->status.status_driver_data[1]; + *j = jiffies; +#endif spin_lock_irqsave(&tx_report->q_lock, flags); __skb_queue_tail(&tx_report->queue, skb); @@ -515,7 +515,11 @@ void rtw_tx(struct rtw_dev *rtwdev, rtw_tx_pkt_info_update(rtwdev, &pkt_info, control->sta, skb); ret = rtw_hci_tx_write(rtwdev, &pkt_info, skb); if (ret) { +#if defined(__linux__) rtw_err(rtwdev, "failed to write TX skb to HCI\n"); +#elif defined(__FreeBSD__) + rtw_err(rtwdev, "%s: failed to write TX skb to HCI: %d\n", __func__, ret); +#endif goto out; } @@ -572,7 +576,11 @@ static int rtw_txq_push_skb(struct rtw_dev *rtwdev, rtw_tx_pkt_info_update(rtwdev, &pkt_info, txq->sta, skb); ret = rtw_hci_tx_write(rtwdev, &pkt_info, skb); if (ret) { +#if defined(__linux__) rtw_err(rtwdev, "failed to write TX skb to HCI\n"); +#elif defined(__FreeBSD__) + rtw_err(rtwdev, "%s: failed to write TX skb to HCI: %d\n", __func__, ret); +#endif return ret; } rtwtxq->last_push = jiffies;