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