rtw88: handle C2H_CCX_TX_RPT to know if packet TX'ed successfully
authorPing-Ke Shih <pkshih@realtek.com>
Mon, 4 May 2020 10:50:06 +0000 (18:50 +0800)
committerKalle Valo <kvalo@codeaurora.org>
Wed, 6 May 2020 08:34:31 +0000 (11:34 +0300)
TX status report of 8723D differs from 8822B/8822C, it uses
C2H_CCX_TX_RPT (0x03) with different format. With sequence number
and TX status, driver can know if certain packet was transmitted
successfully.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20200504105010.10780-5-yhchuang@realtek.com
drivers/net/wireless/realtek/rtw88/fw.c
drivers/net/wireless/realtek/rtw88/fw.h
drivers/net/wireless/realtek/rtw88/tx.c
drivers/net/wireless/realtek/rtw88/tx.h

index 5e981fd..2c28afe 100644 (file)
@@ -25,7 +25,7 @@ static void rtw_fw_c2h_cmd_handle_ext(struct rtw_dev *rtwdev,
 
        switch (sub_cmd_id) {
        case C2H_CCX_RPT:
-               rtw_tx_report_handle(rtwdev, skb);
+               rtw_tx_report_handle(rtwdev, skb, C2H_CCX_RPT);
                break;
        default:
                break;
@@ -142,6 +142,9 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
                goto unlock;
 
        switch (c2h->id) {
+       case C2H_CCX_TX_RPT:
+               rtw_tx_report_handle(rtwdev, skb, C2H_CCX_TX_RPT);
+               break;
        case C2H_BT_INFO:
                rtw_coex_bt_info_notify(rtwdev, c2h->payload, len);
                break;
@@ -155,6 +158,7 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
                rtw_fw_ra_report_handle(rtwdev, c2h->payload, len);
                break;
        default:
+               rtw_dbg(rtwdev, RTW_DBG_FW, "C2H 0x%x isn't handled\n", c2h->id);
                break;
        }
 
index 2933ef7..470e180 100644 (file)
@@ -26,6 +26,7 @@
 #define FW_START_ADDR_LEGACY           0x1000
 
 enum rtw_c2h_cmd_id {
+       C2H_CCX_TX_RPT = 0x03,
        C2H_BT_INFO = 0x09,
        C2H_BT_MP_INFO = 0x0b,
        C2H_RA_RPT = 0x0c,
@@ -218,8 +219,10 @@ struct rtw_fw_hdr_legacy {
 } __packed;
 
 /* C2H */
-#define GET_CCX_REPORT_SEQNUM(c2h_payload)     (c2h_payload[8] & 0xfc)
-#define GET_CCX_REPORT_STATUS(c2h_payload)     (c2h_payload[9] & 0xc0)
+#define GET_CCX_REPORT_SEQNUM_V0(c2h_payload)  (c2h_payload[6] & 0xfc)
+#define GET_CCX_REPORT_STATUS_V0(c2h_payload)  (c2h_payload[0] & 0xc0)
+#define GET_CCX_REPORT_SEQNUM_V1(c2h_payload)  (c2h_payload[8] & 0xfc)
+#define GET_CCX_REPORT_STATUS_V1(c2h_payload)  (c2h_payload[9] & 0xc0)
 
 #define GET_RA_REPORT_RATE(c2h_payload)                (c2h_payload[0] & 0x7f)
 #define GET_RA_REPORT_SGI(c2h_payload)         ((c2h_payload[0] & 0x80) >> 7)
index 6098998..79c4211 100644 (file)
@@ -196,7 +196,7 @@ static void rtw_tx_report_tx_status(struct rtw_dev *rtwdev,
        ieee80211_tx_status_irqsafe(rtwdev->hw, skb);
 }
 
-void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
+void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src)
 {
        struct rtw_tx_report *tx_report = &rtwdev->tx_report;
        struct rtw_c2h_cmd *c2h;
@@ -207,8 +207,13 @@ void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
 
        c2h = get_c2h_from_skb(skb);
 
-       sn = GET_CCX_REPORT_SEQNUM(c2h->payload);
-       st = GET_CCX_REPORT_STATUS(c2h->payload);
+       if (src == C2H_CCX_TX_RPT) {
+               sn = GET_CCX_REPORT_SEQNUM_V0(c2h->payload);
+               st = GET_CCX_REPORT_STATUS_V0(c2h->payload);
+       } else {
+               sn = GET_CCX_REPORT_SEQNUM_V1(c2h->payload);
+               st = GET_CCX_REPORT_STATUS_V1(c2h->payload);
+       }
 
        spin_lock_irqsave(&tx_report->q_lock, flags);
        skb_queue_walk_safe(&tx_report->queue, cur, tmp) {
index b973de0..72dfd40 100644 (file)
@@ -95,7 +95,7 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
                            struct sk_buff *skb);
 void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb);
 void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn);
-void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb);
+void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src);
 void rtw_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev,
                                   struct rtw_tx_pkt_info *pkt_info,
                                   struct sk_buff *skb);