1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "rtl_core.h"
26#include "r8192E_phy.h"
27#include "r8192E_phyreg.h"
28#include "r8190P_rtl8256.h"
29#include "r8192E_cmdpkt.h"
30
31extern int hwwep;
32void CamResetAllEntry(struct net_device *dev)
33{
34 u32 ulcommand = 0;
35
36 ulcommand |= BIT31|BIT30;
37 write_nic_dword(dev, RWCAM, ulcommand);
38}
39
40void write_cam(struct net_device *dev, u8 addr, u32 data)
41{
42 write_nic_dword(dev, WCAMI, data);
43 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff));
44}
45
46u32 read_cam(struct net_device *dev, u8 addr)
47{
48 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff));
49 return read_nic_dword(dev, 0xa8);
50}
51
52void EnableHWSecurityConfig8192(struct net_device *dev)
53{
54 u8 SECR_value = 0x0;
55 struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
56 struct rtllib_device *ieee = priv->rtllib;
57 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
58 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) ||
59 (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) &&
60 (priv->rtllib->auth_mode != 2)) {
61 SECR_value |= SCR_RxUseDK;
62 SECR_value |= SCR_TxUseDK;
63 } else if ((ieee->iw_mode == IW_MODE_ADHOC) &&
64 (ieee->pairwise_key_type & (KEY_TYPE_CCMP |
65 KEY_TYPE_TKIP))) {
66 SECR_value |= SCR_RxUseDK;
67 SECR_value |= SCR_TxUseDK;
68 }
69
70
71 ieee->hwsec_active = 1;
72 if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep) {
73 ieee->hwsec_active = 0;
74 SECR_value &= ~SCR_RxDecEnable;
75 }
76
77 RT_TRACE(COMP_SEC, "%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n",
78 __func__, ieee->hwsec_active, ieee->pairwise_key_type,
79 SECR_value);
80 write_nic_byte(dev, SECR, SECR_value);
81}
82
83void set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType,
84 u8 *MacAddr, u8 DefaultKey, u32 *KeyContent, u8 is_mesh)
85{
86 struct r8192_priv *priv = rtllib_priv(dev);
87 struct rtllib_device *ieee = priv->rtllib;
88 RT_TRACE(COMP_DBG, "===========>%s():EntryNo is %d,KeyIndex is "
89 "%d,KeyType is %d,is_mesh is %d\n", __func__, EntryNo,
90 KeyIndex, KeyType, is_mesh);
91 if (!is_mesh) {
92 ieee->swcamtable[EntryNo].bused = true;
93 ieee->swcamtable[EntryNo].key_index = KeyIndex;
94 ieee->swcamtable[EntryNo].key_type = KeyType;
95 memcpy(ieee->swcamtable[EntryNo].macaddr, MacAddr, 6);
96 ieee->swcamtable[EntryNo].useDK = DefaultKey;
97 memcpy(ieee->swcamtable[EntryNo].key_buf, (u8 *)KeyContent, 16);
98 }
99}
100
101void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType,
102 u8 *MacAddr, u8 DefaultKey, u32 *KeyContent)
103{
104 u32 TargetCommand = 0;
105 u32 TargetContent = 0;
106 u16 usConfig = 0;
107 u8 i;
108 struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
109 enum rt_rf_power_state rtState;
110 rtState = priv->rtllib->eRFPowerState;
111 if (priv->rtllib->PowerSaveControl.bInactivePs) {
112 if (rtState == eRfOff) {
113 if (priv->rtllib->RfOffReason > RF_CHANGE_BY_IPS) {
114 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",
115 __func__);
116 return ;
117 } else {
118 down(&priv->rtllib->ips_sem);
119 IPSLeave(dev);
120 up(&priv->rtllib->ips_sem);
121 }
122 }
123 }
124 priv->rtllib->is_set_key = true;
125 if (EntryNo >= TOTAL_CAM_ENTRY)
126 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
127
128 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d,"
129 "KeyType:%d, MacAddr %pM\n", dev, EntryNo, KeyIndex,
130 KeyType, MacAddr);
131
132 if (DefaultKey)
133 usConfig |= BIT15 | (KeyType<<2);
134 else
135 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
136
137
138 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
139 TargetCommand = i + CAM_CONTENT_COUNT * EntryNo;
140 TargetCommand |= BIT31|BIT16;
141
142 if (i == 0) {
143 TargetContent = (u32)(*(MacAddr+0)) << 16 |
144 (u32)(*(MacAddr+1)) << 24 |
145 (u32)usConfig;
146
147 write_nic_dword(dev, WCAMI, TargetContent);
148 write_nic_dword(dev, RWCAM, TargetCommand);
149 } else if (i == 1) {
150 TargetContent = (u32)(*(MacAddr+2)) |
151 (u32)(*(MacAddr+3)) << 8 |
152 (u32)(*(MacAddr+4)) << 16 |
153 (u32)(*(MacAddr+5)) << 24;
154 write_nic_dword(dev, WCAMI, TargetContent);
155 write_nic_dword(dev, RWCAM, TargetCommand);
156 } else {
157 if (KeyContent != NULL) {
158 write_nic_dword(dev, WCAMI,
159 (u32)(*(KeyContent+i-2)));
160 write_nic_dword(dev, RWCAM, TargetCommand);
161 udelay(100);
162 }
163 }
164 }
165 RT_TRACE(COMP_SEC, "=========>after set key, usconfig:%x\n", usConfig);
166}
167
168void CAM_read_entry(struct net_device *dev, u32 iIndex)
169{
170 u32 target_command = 0;
171 u32 target_content = 0;
172 u8 entry_i = 0;
173 u32 ulStatus;
174 s32 i = 100;
175 for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
176 target_command = entry_i+CAM_CONTENT_COUNT*iIndex;
177 target_command = target_command | BIT31;
178
179 while ((i--) >= 0) {
180 ulStatus = read_nic_dword(dev, RWCAM);
181 if (ulStatus & BIT31)
182 continue;
183 else
184 break;
185 }
186 write_nic_dword(dev, RWCAM, target_command);
187 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A0: %x\n",
188 target_command);
189 target_content = read_nic_dword(dev, RCAMO);
190 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x\n",
191 target_content);
192 }
193 printk(KERN_INFO "\n");
194}
195
196void CamRestoreAllEntry(struct net_device *dev)
197{
198 u8 EntryId = 0;
199 struct r8192_priv *priv = rtllib_priv(dev);
200 u8 *MacAddr = priv->rtllib->current_network.bssid;
201
202 static u8 CAM_CONST_ADDR[4][6] = {
203 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
204 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
205 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
206 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
207 };
208 static u8 CAM_CONST_BROAD[] = {
209 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
210 };
211
212 RT_TRACE(COMP_SEC, "CamRestoreAllEntry:\n");
213
214
215 if ((priv->rtllib->pairwise_key_type == KEY_TYPE_WEP40) ||
216 (priv->rtllib->pairwise_key_type == KEY_TYPE_WEP104)) {
217
218 for (EntryId = 0; EntryId < 4; EntryId++) {
219 MacAddr = CAM_CONST_ADDR[EntryId];
220 if (priv->rtllib->swcamtable[EntryId].bused) {
221 setKey(dev, EntryId , EntryId,
222 priv->rtllib->pairwise_key_type, MacAddr,
223 0, (u32 *)(&priv->rtllib->swcamtable
224 [EntryId].key_buf[0]));
225 }
226 }
227
228 } else if (priv->rtllib->pairwise_key_type == KEY_TYPE_TKIP) {
229 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
230 setKey(dev, 4, 0, priv->rtllib->pairwise_key_type,
231 (u8 *)dev->dev_addr, 0,
232 (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
233 } else {
234 setKey(dev, 4, 0, priv->rtllib->pairwise_key_type,
235 MacAddr, 0,
236 (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
237 }
238
239 } else if (priv->rtllib->pairwise_key_type == KEY_TYPE_CCMP) {
240 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
241 setKey(dev, 4, 0,
242 priv->rtllib->pairwise_key_type,
243 (u8 *)dev->dev_addr, 0,
244 (u32 *)(&priv->rtllib->swcamtable[4].
245 key_buf[0]));
246 } else {
247 setKey(dev, 4, 0,
248 priv->rtllib->pairwise_key_type, MacAddr,
249 0, (u32 *)(&priv->rtllib->swcamtable[4].
250 key_buf[0]));
251 }
252 }
253
254 if (priv->rtllib->group_key_type == KEY_TYPE_TKIP) {
255 MacAddr = CAM_CONST_BROAD;
256 for (EntryId = 1; EntryId < 4; EntryId++) {
257 if (priv->rtllib->swcamtable[EntryId].bused) {
258 setKey(dev, EntryId, EntryId,
259 priv->rtllib->group_key_type,
260 MacAddr, 0,
261 (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0])
262 );
263 }
264 }
265 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
266 if (priv->rtllib->swcamtable[0].bused) {
267 setKey(dev, 0, 0,
268 priv->rtllib->group_key_type,
269 CAM_CONST_ADDR[0], 0,
270 (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0])
271 );
272 } else {
273 RT_TRACE(COMP_ERR, "===>%s():ERR!! ADHOC TKIP "
274 ",but 0 entry is have no data\n",
275 __func__);
276 return;
277 }
278 }
279 } else if (priv->rtllib->group_key_type == KEY_TYPE_CCMP) {
280 MacAddr = CAM_CONST_BROAD;
281 for (EntryId = 1; EntryId < 4; EntryId++) {
282 if (priv->rtllib->swcamtable[EntryId].bused) {
283 setKey(dev, EntryId , EntryId,
284 priv->rtllib->group_key_type,
285 MacAddr, 0,
286 (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
287 }
288 }
289
290 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
291 if (priv->rtllib->swcamtable[0].bused) {
292 setKey(dev, 0 , 0,
293 priv->rtllib->group_key_type,
294 CAM_CONST_ADDR[0], 0,
295 (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0]));
296 } else {
297 RT_TRACE(COMP_ERR, "===>%s():ERR!! ADHOC CCMP ,"
298 "but 0 entry is have no data\n",
299 __func__);
300 return;
301 }
302 }
303 }
304}
305