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