1 /******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
4 * Based on the r8180 driver, which is:
5 * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 * The full GNU General Public License is included in this distribution in the
20 * file called LICENSE.
22 * Contact Information:
23 * wlanfae <wlanfae@realtek.com>
24 ******************************************************************************/
26 #include "r8192E_phy.h"
27 #include "r8192E_phyreg.h"
28 #include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */
29 #include "r8192E_cmdpkt.h"
32 void CamResetAllEntry(struct net_device
*dev
)
36 ulcommand
|= BIT31
|BIT30
;
37 write_nic_dword(dev
, RWCAM
, ulcommand
);
40 void write_cam(struct net_device
*dev
, u8 addr
, u32 data
)
42 write_nic_dword(dev
, WCAMI
, data
);
43 write_nic_dword(dev
, RWCAM
, BIT31
|BIT16
|(addr
&0xff));
46 u32
read_cam(struct net_device
*dev
, u8 addr
)
48 write_nic_dword(dev
, RWCAM
, 0x80000000|(addr
&0xff));
49 return read_nic_dword(dev
, 0xa8);
52 void EnableHWSecurityConfig8192(struct net_device
*dev
)
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
|
66 SECR_value
|= SCR_RxUseDK
;
67 SECR_value
|= SCR_TxUseDK
;
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
;
77 RT_TRACE(COMP_SEC
, "%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n",
78 __func__
, ieee
->hwsec_active
, ieee
->pairwise_key_type
,
80 write_nic_byte(dev
, SECR
, SECR_value
);
83 void set_swcam(struct net_device
*dev
, u8 EntryNo
, u8 KeyIndex
, u16 KeyType
,
84 u8
*MacAddr
, u8 DefaultKey
, u32
*KeyContent
, u8 is_mesh
)
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
);
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);
101 void setKey(struct net_device
*dev
, u8 EntryNo
, u8 KeyIndex
, u16 KeyType
,
102 u8
*MacAddr
, u8 DefaultKey
, u32
*KeyContent
)
104 u32 TargetCommand
= 0;
105 u32 TargetContent
= 0;
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",
118 down(&priv
->rtllib
->ips_sem
);
120 up(&priv
->rtllib
->ips_sem
);
124 priv
->rtllib
->is_set_key
= true;
125 if (EntryNo
>= TOTAL_CAM_ENTRY
)
126 RT_TRACE(COMP_ERR
, "cam entry exceeds in setKey()\n");
128 RT_TRACE(COMP_SEC
, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d,"
129 "KeyType:%d, MacAddr %pM\n", dev
, EntryNo
, KeyIndex
,
133 usConfig
|= BIT15
| (KeyType
<<2);
135 usConfig
|= BIT15
| (KeyType
<<2) | KeyIndex
;
138 for (i
= 0; i
< CAM_CONTENT_COUNT
; i
++) {
139 TargetCommand
= i
+ CAM_CONTENT_COUNT
* EntryNo
;
140 TargetCommand
|= BIT31
|BIT16
;
143 TargetContent
= (u32
)(*(MacAddr
+0)) << 16 |
144 (u32
)(*(MacAddr
+1)) << 24 |
147 write_nic_dword(dev
, WCAMI
, TargetContent
);
148 write_nic_dword(dev
, RWCAM
, TargetCommand
);
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
);
157 if (KeyContent
!= NULL
) {
158 write_nic_dword(dev
, WCAMI
,
159 (u32
)(*(KeyContent
+i
-2)));
160 write_nic_dword(dev
, RWCAM
, TargetCommand
);
165 RT_TRACE(COMP_SEC
, "=========>after set key, usconfig:%x\n", usConfig
);
168 void CAM_read_entry(struct net_device
*dev
, u32 iIndex
)
170 u32 target_command
= 0;
171 u32 target_content
= 0;
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
;
180 ulStatus
= read_nic_dword(dev
, RWCAM
);
181 if (ulStatus
& BIT31
)
186 write_nic_dword(dev
, RWCAM
, target_command
);
187 RT_TRACE(COMP_SEC
, "CAM_read_entry(): WRITE A0: %x\n",
189 target_content
= read_nic_dword(dev
, RCAMO
);
190 RT_TRACE(COMP_SEC
, "CAM_read_entry(): WRITE A8: %x\n",
193 printk(KERN_INFO
"\n");
196 void CamRestoreAllEntry(struct net_device
*dev
)
199 struct r8192_priv
*priv
= rtllib_priv(dev
);
200 u8
*MacAddr
= priv
->rtllib
->current_network
.bssid
;
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}
208 static u8 CAM_CONST_BROAD
[] = {
209 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
212 RT_TRACE(COMP_SEC
, "CamRestoreAllEntry:\n");
215 if ((priv
->rtllib
->pairwise_key_type
== KEY_TYPE_WEP40
) ||
216 (priv
->rtllib
->pairwise_key_type
== KEY_TYPE_WEP104
)) {
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]));
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]));
234 setKey(dev
, 4, 0, priv
->rtllib
->pairwise_key_type
,
236 (u32
*)(&priv
->rtllib
->swcamtable
[4].key_buf
[0]));
239 } else if (priv
->rtllib
->pairwise_key_type
== KEY_TYPE_CCMP
) {
240 if (priv
->rtllib
->iw_mode
== IW_MODE_ADHOC
) {
242 priv
->rtllib
->pairwise_key_type
,
243 (u8
*)dev
->dev_addr
, 0,
244 (u32
*)(&priv
->rtllib
->swcamtable
[4].
248 priv
->rtllib
->pairwise_key_type
, MacAddr
,
249 0, (u32
*)(&priv
->rtllib
->swcamtable
[4].
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
,
261 (u32
*)(&priv
->rtllib
->swcamtable
[EntryId
].key_buf
[0])
265 if (priv
->rtllib
->iw_mode
== IW_MODE_ADHOC
) {
266 if (priv
->rtllib
->swcamtable
[0].bused
) {
268 priv
->rtllib
->group_key_type
,
269 CAM_CONST_ADDR
[0], 0,
270 (u32
*)(&priv
->rtllib
->swcamtable
[0].key_buf
[0])
273 RT_TRACE(COMP_ERR
, "===>%s():ERR!! ADHOC TKIP "
274 ",but 0 entry is have no data\n",
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
,
286 (u32
*)(&priv
->rtllib
->swcamtable
[EntryId
].key_buf
[0]));
290 if (priv
->rtllib
->iw_mode
== IW_MODE_ADHOC
) {
291 if (priv
->rtllib
->swcamtable
[0].bused
) {
293 priv
->rtllib
->group_key_type
,
294 CAM_CONST_ADDR
[0], 0,
295 (u32
*)(&priv
->rtllib
->swcamtable
[0].key_buf
[0]));
297 RT_TRACE(COMP_ERR
, "===>%s():ERR!! ADHOC CCMP ,"
298 "but 0 entry is have no data\n",