xref: /linux/drivers/net/wireless/realtek/rtw89/wow.h (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2 /* Copyright(c) 2019-2022  Realtek Corporation
3  */
4 
5 #ifndef __RTW89_WOW_H__
6 #define __RTW89_WOW_H__
7 
8 #define RTW89_KEY_PN_0 GENMASK_ULL(7, 0)
9 #define RTW89_KEY_PN_1 GENMASK_ULL(15, 8)
10 #define RTW89_KEY_PN_2 GENMASK_ULL(23, 16)
11 #define RTW89_KEY_PN_3 GENMASK_ULL(31, 24)
12 #define RTW89_KEY_PN_4 GENMASK_ULL(39, 32)
13 #define RTW89_KEY_PN_5 GENMASK_ULL(47, 40)
14 
15 #define RTW89_IGTK_IPN_0 GENMASK_ULL(7, 0)
16 #define RTW89_IGTK_IPN_1 GENMASK_ULL(15, 8)
17 #define RTW89_IGTK_IPN_2 GENMASK_ULL(23, 16)
18 #define RTW89_IGTK_IPN_3 GENMASK_ULL(31, 24)
19 #define RTW89_IGTK_IPN_4 GENMASK_ULL(39, 32)
20 #define RTW89_IGTK_IPN_5 GENMASK_ULL(47, 40)
21 #define RTW89_IGTK_IPN_6 GENMASK_ULL(55, 48)
22 #define RTW89_IGTK_IPN_7 GENMASK_ULL(63, 56)
23 
24 #define RTW89_WOW_VALID_CHECK 0xDD
25 #define RTW89_WOW_SYMBOL_CHK_PTK BIT(0)
26 #define RTW89_WOW_SYMBOL_CHK_GTK BIT(1)
27 
28 enum rtw89_wake_reason {
29 	RTW89_WOW_RSN_RX_PTK_REKEY = 0x1,
30 	RTW89_WOW_RSN_RX_GTK_REKEY = 0x2,
31 	RTW89_WOW_RSN_RX_DEAUTH = 0x8,
32 	RTW89_WOW_RSN_DISCONNECT = 0x10,
33 	RTW89_WOW_RSN_RX_MAGIC_PKT = 0x21,
34 	RTW89_WOW_RSN_RX_PATTERN_MATCH = 0x23,
35 	RTW89_WOW_RSN_RX_NLO = 0x55,
36 };
37 
38 enum rtw89_fw_alg {
39 	RTW89_WOW_FW_ALG_WEP40 = 0x1,
40 	RTW89_WOW_FW_ALG_WEP104 = 0x2,
41 	RTW89_WOW_FW_ALG_TKIP = 0x3,
42 	RTW89_WOW_FW_ALG_CCMP = 0x6,
43 	RTW89_WOW_FW_ALG_CCMP_256 = 0x7,
44 	RTW89_WOW_FW_ALG_GCMP = 0x8,
45 	RTW89_WOW_FW_ALG_GCMP_256 = 0x9,
46 	RTW89_WOW_FW_ALG_AES_CMAC = 0xa,
47 };
48 
49 struct rtw89_cipher_suite {
50 	u8 oui[3];
51 	u8 type;
52 } __packed;
53 
54 struct rtw89_rsn_ie {
55 	u8 tag_number;
56 	u8 tag_length;
57 	__le16 rsn_version;
58 	struct rtw89_cipher_suite group_cipher_suite;
59 	__le16 pairwise_cipher_suite_cnt;
60 	struct rtw89_cipher_suite pairwise_cipher_suite;
61 	__le16 akm_cipher_suite_cnt;
62 	struct rtw89_cipher_suite akm_cipher_suite;
63 } __packed;
64 
65 struct rtw89_cipher_info {
66 	u32 cipher;
67 	u8 fw_alg;
68 	enum ieee80211_key_len len;
69 };
70 
71 struct rtw89_set_key_info_iter_data {
72 	u32 gtk_cipher;
73 	u32 igtk_cipher;
74 	bool rx_ready;
75 	bool error;
76 };
77 
78 static inline int rtw89_wow_get_sec_hdr_len(struct rtw89_dev *rtwdev)
79 {
80 	struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
81 
82 	if (!(rtwdev->chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)))
83 		return 0;
84 
85 	switch (rtw_wow->ptk_alg) {
86 	case RTW89_WOW_FW_ALG_WEP40:
87 		return 4;
88 	case RTW89_WOW_FW_ALG_TKIP:
89 	case RTW89_WOW_FW_ALG_CCMP:
90 	case RTW89_WOW_FW_ALG_GCMP_256:
91 		return 8;
92 	default:
93 		return 0;
94 	}
95 }
96 
97 #ifdef CONFIG_PM
98 static inline bool rtw89_wow_mgd_linked(struct rtw89_dev *rtwdev)
99 {
100 	struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
101 	struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
102 
103 	return rtwvif->net_type == RTW89_NET_TYPE_INFRA;
104 }
105 
106 static inline bool rtw89_wow_no_link(struct rtw89_dev *rtwdev)
107 {
108 	struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
109 	struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
110 
111 	return rtwvif->net_type == RTW89_NET_TYPE_NO_LINK;
112 }
113 
114 static inline bool rtw_wow_has_mgd_features(struct rtw89_dev *rtwdev)
115 {
116 	struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
117 
118 	return !bitmap_empty(rtw_wow->flags, RTW89_WOW_FLAG_NUM);
119 }
120 
121 int rtw89_wow_suspend(struct rtw89_dev *rtwdev, struct cfg80211_wowlan *wowlan);
122 int rtw89_wow_resume(struct rtw89_dev *rtwdev);
123 void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb);
124 #else
125 static inline
126 void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb)
127 {
128 }
129 #endif
130 
131 #endif
132