1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
4 *
5 * Based on the r8180 driver, which is:
6 * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
7 *
8 * Contact Information: wlanfae <wlanfae@realtek.com>
9 */
10 #include "rtl_core.h"
11 #include "r8192E_phy.h"
12 #include "r8192E_phyreg.h"
13 #include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */
14 #include "r8192E_cmdpkt.h"
15
rtl92e_cam_reset(struct net_device * dev)16 void rtl92e_cam_reset(struct net_device *dev)
17 {
18 u32 ulcommand = 0;
19
20 ulcommand |= BIT31|BIT30;
21 rtl92e_writel(dev, RWCAM, ulcommand);
22 }
23
rtl92e_enable_hw_security_config(struct net_device * dev)24 void rtl92e_enable_hw_security_config(struct net_device *dev)
25 {
26 u8 SECR_value = 0x0;
27 struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
28 struct rtllib_device *ieee = priv->rtllib;
29
30 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
31 if (((ieee->pairwise_key_type == KEY_TYPE_WEP40) ||
32 (ieee->pairwise_key_type == KEY_TYPE_WEP104)) &&
33 (priv->rtllib->auth_mode != 2)) {
34 SECR_value |= SCR_RxUseDK;
35 SECR_value |= SCR_TxUseDK;
36 } else if ((ieee->iw_mode == IW_MODE_ADHOC) &&
37 (ieee->pairwise_key_type & (KEY_TYPE_CCMP |
38 KEY_TYPE_TKIP))) {
39 SECR_value |= SCR_RxUseDK;
40 SECR_value |= SCR_TxUseDK;
41 }
42
43
44 ieee->hwsec_active = 1;
45 if ((ieee->pHTInfo->iot_action & HT_IOT_ACT_PURE_N_MODE) || !hwwep) {
46 ieee->hwsec_active = 0;
47 SECR_value &= ~SCR_RxDecEnable;
48 }
49 rtl92e_writeb(dev, SECR, SECR_value);
50 }
51
rtl92e_set_swcam(struct net_device * dev,u8 EntryNo,u8 KeyIndex,u16 KeyType,const u8 * MacAddr,u8 DefaultKey,u32 * KeyContent,u8 is_mesh)52 void rtl92e_set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
53 u16 KeyType, const u8 *MacAddr, u8 DefaultKey,
54 u32 *KeyContent, u8 is_mesh)
55 {
56 struct r8192_priv *priv = rtllib_priv(dev);
57 struct rtllib_device *ieee = priv->rtllib;
58
59 if (EntryNo >= TOTAL_CAM_ENTRY)
60 return;
61
62 if (!is_mesh) {
63 ieee->swcamtable[EntryNo].bused = true;
64 ieee->swcamtable[EntryNo].key_index = KeyIndex;
65 ieee->swcamtable[EntryNo].key_type = KeyType;
66 memcpy(ieee->swcamtable[EntryNo].macaddr, MacAddr, 6);
67 ieee->swcamtable[EntryNo].useDK = DefaultKey;
68 memcpy(ieee->swcamtable[EntryNo].key_buf, (u8 *)KeyContent, 16);
69 }
70 }
71
rtl92e_set_key(struct net_device * dev,u8 EntryNo,u8 KeyIndex,u16 KeyType,const u8 * MacAddr,u8 DefaultKey,u32 * KeyContent)72 void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
73 u16 KeyType, const u8 *MacAddr, u8 DefaultKey,
74 u32 *KeyContent)
75 {
76 u32 TargetCommand = 0;
77 u32 TargetContent = 0;
78 u16 usConfig = 0;
79 u8 i;
80 struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
81 enum rt_rf_power_state rt_state;
82
83 rt_state = priv->rtllib->rf_power_state;
84 if (priv->rtllib->PowerSaveControl.bInactivePs) {
85 if (rt_state == rf_off) {
86 if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) {
87 netdev_warn(dev, "%s(): RF is OFF.\n",
88 __func__);
89 return;
90 }
91 mutex_lock(&priv->rtllib->ips_mutex);
92 rtl92e_ips_leave(dev);
93 mutex_unlock(&priv->rtllib->ips_mutex);
94 }
95 }
96 priv->rtllib->is_set_key = true;
97 if (EntryNo >= TOTAL_CAM_ENTRY) {
98 netdev_info(dev, "%s(): Invalid CAM entry\n", __func__);
99 return;
100 }
101
102 if (DefaultKey)
103 usConfig |= BIT15 | (KeyType<<2);
104 else
105 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
106
107
108 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
109 TargetCommand = i + CAM_CONTENT_COUNT * EntryNo;
110 TargetCommand |= BIT31|BIT16;
111
112 if (i == 0) {
113 TargetContent = (u32)(*(MacAddr+0)) << 16 |
114 (u32)(*(MacAddr+1)) << 24 |
115 (u32)usConfig;
116
117 rtl92e_writel(dev, WCAMI, TargetContent);
118 rtl92e_writel(dev, RWCAM, TargetCommand);
119 } else if (i == 1) {
120 TargetContent = (u32)(*(MacAddr+2)) |
121 (u32)(*(MacAddr+3)) << 8 |
122 (u32)(*(MacAddr+4)) << 16 |
123 (u32)(*(MacAddr+5)) << 24;
124 rtl92e_writel(dev, WCAMI, TargetContent);
125 rtl92e_writel(dev, RWCAM, TargetCommand);
126 } else {
127 if (KeyContent != NULL) {
128 rtl92e_writel(dev, WCAMI,
129 (u32)(*(KeyContent+i-2)));
130 rtl92e_writel(dev, RWCAM, TargetCommand);
131 udelay(100);
132 }
133 }
134 }
135 }
136
rtl92e_cam_restore(struct net_device * dev)137 void rtl92e_cam_restore(struct net_device *dev)
138 {
139 u8 EntryId = 0;
140 struct r8192_priv *priv = rtllib_priv(dev);
141 u8 *MacAddr = priv->rtllib->current_network.bssid;
142
143 static u8 CAM_CONST_ADDR[4][6] = {
144 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
145 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
146 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
147 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
148 };
149 static u8 CAM_CONST_BROAD[] = {
150 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
151 };
152
153 if ((priv->rtllib->pairwise_key_type == KEY_TYPE_WEP40) ||
154 (priv->rtllib->pairwise_key_type == KEY_TYPE_WEP104)) {
155
156 for (EntryId = 0; EntryId < 4; EntryId++) {
157 MacAddr = CAM_CONST_ADDR[EntryId];
158 if (priv->rtllib->swcamtable[EntryId].bused) {
159 rtl92e_set_key(dev, EntryId, EntryId,
160 priv->rtllib->pairwise_key_type,
161 MacAddr, 0,
162 (u32 *)(&priv->rtllib->swcamtable
163 [EntryId].key_buf[0]));
164 }
165 }
166
167 } else if (priv->rtllib->pairwise_key_type == KEY_TYPE_TKIP) {
168 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
169 rtl92e_set_key(dev, 4, 0,
170 priv->rtllib->pairwise_key_type,
171 (const u8 *)dev->dev_addr, 0,
172 (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
173 } else {
174 rtl92e_set_key(dev, 4, 0,
175 priv->rtllib->pairwise_key_type,
176 MacAddr, 0,
177 (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
178 }
179
180 } else if (priv->rtllib->pairwise_key_type == KEY_TYPE_CCMP) {
181 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
182 rtl92e_set_key(dev, 4, 0,
183 priv->rtllib->pairwise_key_type,
184 (const u8 *)dev->dev_addr, 0,
185 (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
186 } else {
187 rtl92e_set_key(dev, 4, 0,
188 priv->rtllib->pairwise_key_type, MacAddr,
189 0, (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
190 }
191 }
192
193 if (priv->rtllib->group_key_type == KEY_TYPE_TKIP) {
194 MacAddr = CAM_CONST_BROAD;
195 for (EntryId = 1; EntryId < 4; EntryId++) {
196 if (priv->rtllib->swcamtable[EntryId].bused) {
197 rtl92e_set_key(dev, EntryId, EntryId,
198 priv->rtllib->group_key_type,
199 MacAddr, 0,
200 (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
201 }
202 }
203 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
204 if (priv->rtllib->swcamtable[0].bused) {
205 rtl92e_set_key(dev, 0, 0,
206 priv->rtllib->group_key_type,
207 CAM_CONST_ADDR[0], 0,
208 (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0]));
209 } else {
210 netdev_warn(dev,
211 "%s(): ADHOC TKIP: missing key entry.\n",
212 __func__);
213 return;
214 }
215 }
216 } else if (priv->rtllib->group_key_type == KEY_TYPE_CCMP) {
217 MacAddr = CAM_CONST_BROAD;
218 for (EntryId = 1; EntryId < 4; EntryId++) {
219 if (priv->rtllib->swcamtable[EntryId].bused) {
220 rtl92e_set_key(dev, EntryId, EntryId,
221 priv->rtllib->group_key_type,
222 MacAddr, 0,
223 (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
224 }
225 }
226
227 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
228 if (priv->rtllib->swcamtable[0].bused) {
229 rtl92e_set_key(dev, 0, 0,
230 priv->rtllib->group_key_type,
231 CAM_CONST_ADDR[0], 0,
232 (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0]));
233 } else {
234 netdev_warn(dev,
235 "%s(): ADHOC CCMP: missing key entry.\n",
236 __func__);
237 return;
238 }
239 }
240 }
241 }
242