1
2
3
4
5
6
7
8
9
10#include "rtl_core.h"
11#include "r8192E_phy.h"
12#include "r8192E_phyreg.h"
13#include "r8190P_rtl8256.h"
14#include "r8192E_cmdpkt.h"
15
16void 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
24void 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->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep) {
46 ieee->hwsec_active = 0;
47 SECR_value &= ~SCR_RxDecEnable;
48 }
49
50 RT_TRACE(COMP_SEC, "%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n",
51 __func__, ieee->hwsec_active, ieee->pairwise_key_type,
52 SECR_value);
53 rtl92e_writeb(dev, SECR, SECR_value);
54}
55
56void rtl92e_set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
57 u16 KeyType, const u8 *MacAddr, u8 DefaultKey,
58 u32 *KeyContent, u8 is_mesh)
59{
60 struct r8192_priv *priv = rtllib_priv(dev);
61 struct rtllib_device *ieee = priv->rtllib;
62
63 RT_TRACE(COMP_DBG,
64 "===========>%s():EntryNo is %d,KeyIndex is %d,KeyType is %d,is_mesh is %d\n",
65 __func__, EntryNo, KeyIndex, KeyType, is_mesh);
66
67 if (EntryNo >= TOTAL_CAM_ENTRY)
68 return;
69
70 if (!is_mesh) {
71 ieee->swcamtable[EntryNo].bused = true;
72 ieee->swcamtable[EntryNo].key_index = KeyIndex;
73 ieee->swcamtable[EntryNo].key_type = KeyType;
74 memcpy(ieee->swcamtable[EntryNo].macaddr, MacAddr, 6);
75 ieee->swcamtable[EntryNo].useDK = DefaultKey;
76 memcpy(ieee->swcamtable[EntryNo].key_buf, (u8 *)KeyContent, 16);
77 }
78}
79
80void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
81 u16 KeyType, const u8 *MacAddr, u8 DefaultKey,
82 u32 *KeyContent)
83{
84 u32 TargetCommand = 0;
85 u32 TargetContent = 0;
86 u16 usConfig = 0;
87 u8 i;
88 struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
89 enum rt_rf_power_state rtState;
90
91 rtState = priv->rtllib->eRFPowerState;
92 if (priv->rtllib->PowerSaveControl.bInactivePs) {
93 if (rtState == eRfOff) {
94 if (priv->rtllib->RfOffReason > RF_CHANGE_BY_IPS) {
95 netdev_warn(dev, "%s(): RF is OFF.\n",
96 __func__);
97 return;
98 }
99 mutex_lock(&priv->rtllib->ips_mutex);
100 rtl92e_ips_leave(dev);
101 mutex_unlock(&priv->rtllib->ips_mutex);
102 }
103 }
104 priv->rtllib->is_set_key = true;
105 if (EntryNo >= TOTAL_CAM_ENTRY) {
106 netdev_info(dev, "%s(): Invalid CAM entry\n", __func__);
107 return;
108 }
109
110 RT_TRACE(COMP_SEC,
111 "====>to rtl92e_set_key(), dev:%p, EntryNo:%d, KeyIndex:%d,KeyType:%d, MacAddr %pM\n",
112 dev, EntryNo, KeyIndex, KeyType, MacAddr);
113
114 if (DefaultKey)
115 usConfig |= BIT15 | (KeyType<<2);
116 else
117 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
118
119
120 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
121 TargetCommand = i + CAM_CONTENT_COUNT * EntryNo;
122 TargetCommand |= BIT31|BIT16;
123
124 if (i == 0) {
125 TargetContent = (u32)(*(MacAddr+0)) << 16 |
126 (u32)(*(MacAddr+1)) << 24 |
127 (u32)usConfig;
128
129 rtl92e_writel(dev, WCAMI, TargetContent);
130 rtl92e_writel(dev, RWCAM, TargetCommand);
131 } else if (i == 1) {
132 TargetContent = (u32)(*(MacAddr+2)) |
133 (u32)(*(MacAddr+3)) << 8 |
134 (u32)(*(MacAddr+4)) << 16 |
135 (u32)(*(MacAddr+5)) << 24;
136 rtl92e_writel(dev, WCAMI, TargetContent);
137 rtl92e_writel(dev, RWCAM, TargetCommand);
138 } else {
139 if (KeyContent != NULL) {
140 rtl92e_writel(dev, WCAMI,
141 (u32)(*(KeyContent+i-2)));
142 rtl92e_writel(dev, RWCAM, TargetCommand);
143 udelay(100);
144 }
145 }
146 }
147 RT_TRACE(COMP_SEC, "=========>after set key, usconfig:%x\n", usConfig);
148}
149
150void rtl92e_cam_restore(struct net_device *dev)
151{
152 u8 EntryId = 0;
153 struct r8192_priv *priv = rtllib_priv(dev);
154 u8 *MacAddr = priv->rtllib->current_network.bssid;
155
156 static u8 CAM_CONST_ADDR[4][6] = {
157 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
158 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
159 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
160 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
161 };
162 static u8 CAM_CONST_BROAD[] = {
163 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
164 };
165
166 RT_TRACE(COMP_SEC, "rtl92e_cam_restore:\n");
167
168
169 if ((priv->rtllib->pairwise_key_type == KEY_TYPE_WEP40) ||
170 (priv->rtllib->pairwise_key_type == KEY_TYPE_WEP104)) {
171
172 for (EntryId = 0; EntryId < 4; EntryId++) {
173 MacAddr = CAM_CONST_ADDR[EntryId];
174 if (priv->rtllib->swcamtable[EntryId].bused) {
175 rtl92e_set_key(dev, EntryId, EntryId,
176 priv->rtllib->pairwise_key_type,
177 MacAddr, 0,
178 (u32 *)(&priv->rtllib->swcamtable
179 [EntryId].key_buf[0]));
180 }
181 }
182
183 } else if (priv->rtllib->pairwise_key_type == KEY_TYPE_TKIP) {
184 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
185 rtl92e_set_key(dev, 4, 0,
186 priv->rtllib->pairwise_key_type,
187 (u8 *)dev->dev_addr, 0,
188 (u32 *)(&priv->rtllib->swcamtable[4].
189 key_buf[0]));
190 } else {
191 rtl92e_set_key(dev, 4, 0,
192 priv->rtllib->pairwise_key_type,
193 MacAddr, 0,
194 (u32 *)(&priv->rtllib->swcamtable[4].
195 key_buf[0]));
196 }
197
198 } else if (priv->rtllib->pairwise_key_type == KEY_TYPE_CCMP) {
199 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
200 rtl92e_set_key(dev, 4, 0,
201 priv->rtllib->pairwise_key_type,
202 (u8 *)dev->dev_addr, 0,
203 (u32 *)(&priv->rtllib->swcamtable[4].
204 key_buf[0]));
205 } else {
206 rtl92e_set_key(dev, 4, 0,
207 priv->rtllib->pairwise_key_type, MacAddr,
208 0, (u32 *)(&priv->rtllib->swcamtable[4].
209 key_buf[0]));
210 }
211 }
212
213 if (priv->rtllib->group_key_type == KEY_TYPE_TKIP) {
214 MacAddr = CAM_CONST_BROAD;
215 for (EntryId = 1; EntryId < 4; EntryId++) {
216 if (priv->rtllib->swcamtable[EntryId].bused) {
217 rtl92e_set_key(dev, EntryId, EntryId,
218 priv->rtllib->group_key_type,
219 MacAddr, 0,
220 (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
221 }
222 }
223 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
224 if (priv->rtllib->swcamtable[0].bused) {
225 rtl92e_set_key(dev, 0, 0,
226 priv->rtllib->group_key_type,
227 CAM_CONST_ADDR[0], 0,
228 (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0]));
229 } else {
230 netdev_warn(dev,
231 "%s(): ADHOC TKIP: missing key entry.\n",
232 __func__);
233 return;
234 }
235 }
236 } else if (priv->rtllib->group_key_type == KEY_TYPE_CCMP) {
237 MacAddr = CAM_CONST_BROAD;
238 for (EntryId = 1; EntryId < 4; EntryId++) {
239 if (priv->rtllib->swcamtable[EntryId].bused) {
240 rtl92e_set_key(dev, EntryId, EntryId,
241 priv->rtllib->group_key_type,
242 MacAddr, 0,
243 (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
244 }
245 }
246
247 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
248 if (priv->rtllib->swcamtable[0].bused) {
249 rtl92e_set_key(dev, 0, 0,
250 priv->rtllib->group_key_type,
251 CAM_CONST_ADDR[0], 0,
252 (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0]));
253 } else {
254 netdev_warn(dev,
255 "%s(): ADHOC CCMP: missing key entry.\n",
256 __func__);
257 return;
258 }
259 }
260 }
261}
262