mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-02 08:39:08 -04:00
wifi: rtw89: check if atomic before queuing c2h
Before queuing C2H work, we check atomicity of the C2H's handler first now. If atomic or lock-free, handle it directly; otherwise, handle it with mutex in work as previous. This prepares for MAC MCC C2Hs which require to be processed directly. And, their handlers will be functions which can be considered atomic. Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://lore.kernel.org/r/20221129083130.45708-3-pkshih@realtek.com
This commit is contained in:
committed by
Kalle Valo
parent
38f25dec52
commit
860e8263ae
@@ -11,6 +11,9 @@
|
||||
#include "phy.h"
|
||||
#include "reg.h"
|
||||
|
||||
static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
|
||||
struct sk_buff *skb);
|
||||
|
||||
static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len,
|
||||
bool header)
|
||||
{
|
||||
@@ -2382,8 +2385,43 @@ void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev)
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
|
||||
static void rtw89_fw_c2h_parse_attr(struct sk_buff *c2h)
|
||||
{
|
||||
struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h);
|
||||
|
||||
attr->category = RTW89_GET_C2H_CATEGORY(c2h->data);
|
||||
attr->class = RTW89_GET_C2H_CLASS(c2h->data);
|
||||
attr->func = RTW89_GET_C2H_FUNC(c2h->data);
|
||||
attr->len = RTW89_GET_C2H_LEN(c2h->data);
|
||||
}
|
||||
|
||||
static bool rtw89_fw_c2h_chk_atomic(struct rtw89_dev *rtwdev,
|
||||
struct sk_buff *c2h)
|
||||
{
|
||||
struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h);
|
||||
u8 category = attr->category;
|
||||
u8 class = attr->class;
|
||||
u8 func = attr->func;
|
||||
|
||||
switch (category) {
|
||||
default:
|
||||
return false;
|
||||
case RTW89_C2H_CAT_MAC:
|
||||
return rtw89_mac_c2h_chk_atomic(rtwdev, class, func);
|
||||
}
|
||||
}
|
||||
|
||||
void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h)
|
||||
{
|
||||
rtw89_fw_c2h_parse_attr(c2h);
|
||||
if (!rtw89_fw_c2h_chk_atomic(rtwdev, c2h))
|
||||
goto enqueue;
|
||||
|
||||
rtw89_fw_c2h_cmd_handle(rtwdev, c2h);
|
||||
dev_kfree_skb_any(c2h);
|
||||
return;
|
||||
|
||||
enqueue:
|
||||
skb_queue_tail(&rtwdev->c2h_queue, c2h);
|
||||
ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work);
|
||||
}
|
||||
@@ -2391,10 +2429,11 @@ void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h)
|
||||
static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
u8 category = RTW89_GET_C2H_CATEGORY(skb->data);
|
||||
u8 class = RTW89_GET_C2H_CLASS(skb->data);
|
||||
u8 func = RTW89_GET_C2H_FUNC(skb->data);
|
||||
u16 len = RTW89_GET_C2H_LEN(skb->data);
|
||||
struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb);
|
||||
u8 category = attr->category;
|
||||
u8 class = attr->class;
|
||||
u8 func = attr->func;
|
||||
u16 len = attr->len;
|
||||
bool dump = true;
|
||||
|
||||
if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags))
|
||||
|
||||
@@ -2778,6 +2778,20 @@ static inline void RTW89_SET_FWCMD_TSF32_TOGL_EARLY(void *cmd, u32 val)
|
||||
#define RTW89_GET_C2H_LEN(c2h) \
|
||||
le32_get_bits(*((const __le32 *)(c2h) + 1), GENMASK(13, 0))
|
||||
|
||||
struct rtw89_fw_c2h_attr {
|
||||
u8 category;
|
||||
u8 class;
|
||||
u8 func;
|
||||
u16 len;
|
||||
};
|
||||
|
||||
static inline struct rtw89_fw_c2h_attr *RTW89_SKB_C2H_CB(struct sk_buff *skb)
|
||||
{
|
||||
static_assert(sizeof(skb->cb) >= sizeof(struct rtw89_fw_c2h_attr));
|
||||
|
||||
return (struct rtw89_fw_c2h_attr *)skb->cb;
|
||||
}
|
||||
|
||||
#define RTW89_GET_C2H_LOG_SRT_PRT(c2h) (char *)((__le32 *)(c2h) + 2)
|
||||
#define RTW89_GET_C2H_LOG_LEN(len) ((len) - RTW89_C2H_HEADER_LEN)
|
||||
|
||||
|
||||
@@ -4208,6 +4208,16 @@ void (* const rtw89_mac_c2h_info_handler[])(struct rtw89_dev *rtwdev,
|
||||
[RTW89_MAC_C2H_FUNC_BCN_CNT] = rtw89_mac_c2h_bcn_cnt,
|
||||
};
|
||||
|
||||
bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func)
|
||||
{
|
||||
switch (class) {
|
||||
default:
|
||||
return false;
|
||||
case RTW89_MAC_C2H_CLASS_MCC:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
|
||||
u32 len, u8 class, u8 func)
|
||||
{
|
||||
|
||||
@@ -894,6 +894,7 @@ static inline int rtw89_chip_disable_bb_rf(struct rtw89_dev *rtwdev)
|
||||
|
||||
u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev);
|
||||
int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err);
|
||||
bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func);
|
||||
void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
|
||||
u32 len, u8 class, u8 func);
|
||||
int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev);
|
||||
|
||||
Reference in New Issue
Block a user