]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/commitdiff
rtw88: allow c2h operation in irq context
authorYan-Hsuan Chuang <yhchuang@realtek.com>
Wed, 31 Jul 2019 12:22:45 +0000 (20:22 +0800)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Wed, 4 Sep 2019 09:38:39 +0000 (11:38 +0200)
BugLink: https://bugs.launchpad.net/bugs/1838133
Some of the c2h operations are small and can be done
under interrupt context. For the rest that requires
more operations or can go sleep, enqueue onto c2h queue.

Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
(cherry picked from commit 0d762f031d702272a17910fbeb45ab15b9673617 linux-next)
Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Acked-by: Seth Forshee <seth.forshee@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
drivers/net/wireless/realtek/rtw88/fw.c
drivers/net/wireless/realtek/rtw88/fw.h
drivers/net/wireless/realtek/rtw88/pci.c

index 6284779712131f41f6ef19b8e4f42157f81fbc1e..3c4dcb7cf69e5970a6ee60b9e5ade28d924f1f9a 100644 (file)
@@ -36,9 +36,6 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
        c2h = (struct rtw_c2h_cmd *)(skb->data + pkt_offset);
        len = skb->len - pkt_offset - 2;
 
-       rtw_dbg(rtwdev, RTW_DBG_FW, "recv C2H, id=0x%02x, seq=0x%02x, len=%d\n",
-               c2h->id, c2h->seq, len);
-
        switch (c2h->id) {
        case C2H_HALMAC:
                rtw_fw_c2h_cmd_handle_ext(rtwdev, skb);
@@ -48,6 +45,30 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
        }
 }
 
+void rtw_fw_c2h_cmd_rx_irqsafe(struct rtw_dev *rtwdev, u32 pkt_offset,
+                              struct sk_buff *skb)
+{
+       struct rtw_c2h_cmd *c2h;
+       u8 len;
+
+       c2h = (struct rtw_c2h_cmd *)(skb->data + pkt_offset);
+       len = skb->len - pkt_offset - 2;
+       *((u32 *)skb->cb) = pkt_offset;
+
+       rtw_dbg(rtwdev, RTW_DBG_FW, "recv C2H, id=0x%02x, seq=0x%02x, len=%d\n",
+               c2h->id, c2h->seq, len);
+
+       switch (c2h->id) {
+       default:
+               /* pass offset for further operation */
+               *((u32 *)skb->cb) = pkt_offset;
+               skb_queue_tail(&rtwdev->c2h_queue, skb);
+               ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work);
+               break;
+       }
+}
+EXPORT_SYMBOL(rtw_fw_c2h_cmd_rx_irqsafe);
+
 static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev,
                                    u8 *h2c)
 {
index 703466393ecb6fb9989d43dc3c1731fde0a50e50..67f6cf770cedfe31ec8c9664f4efefd261f18df3 100644 (file)
@@ -200,6 +200,8 @@ static inline struct rtw_c2h_cmd *get_c2h_from_skb(struct sk_buff *skb)
        return (struct rtw_c2h_cmd *)(skb->data + pkt_offset);
 }
 
+void rtw_fw_c2h_cmd_rx_irqsafe(struct rtw_dev *rtwdev, u32 pkt_offset,
+                              struct sk_buff *skb);
 void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb);
 void rtw_fw_send_general_info(struct rtw_dev *rtwdev);
 void rtw_fw_send_phydm_info(struct rtw_dev *rtwdev);
index c56251539874e75a27313ebbd3d7163a79c15dee..00ef229552d5ec1df89fe149398b11e01bf52683 100644 (file)
@@ -8,6 +8,7 @@
 #include "pci.h"
 #include "tx.h"
 #include "rx.h"
+#include "fw.h"
 #include "debug.h"
 
 static u32 rtw_pci_tx_queue_idx_addr[] = {
@@ -822,10 +823,7 @@ static void rtw_pci_rx_isr(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci,
                skb_put_data(new, skb->data, new_len);
 
                if (pkt_stat.is_c2h) {
-                        /* pass rx_desc & offset for further operation */
-                       *((u32 *)new->cb) = pkt_offset;
-                       skb_queue_tail(&rtwdev->c2h_queue, new);
-                       ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work);
+                       rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, new);
                } else {
                        /* remove rx_desc */
                        skb_pull(new, pkt_offset);