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