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
rtw89_wow_get_sec_hdr_len(struct rtw89_dev * rtwdev)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
rtw89_wow_mgd_linked(struct rtw89_dev * rtwdev)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
rtw89_wow_no_link(struct rtw89_dev * rtwdev)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
rtw_wow_has_mgd_features(struct rtw89_dev * rtwdev)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
rtw89_wow_parse_akm(struct rtw89_dev * rtwdev,struct sk_buff * skb)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
rtw89_wow_parse_akm(struct rtw89_dev * rtwdev,struct sk_buff * skb)143 void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb)
144 {
145 }
146 #endif
147
148 #endif
149