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) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->rtllib->auth_mode != 2))
60 SECR_value |= SCR_RxUseDK;
61 SECR_value |= SCR_TxUseDK;
63 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
65 SECR_value |= SCR_RxUseDK;
66 SECR_value |= SCR_TxUseDK;
70 ieee->hwsec_active = 1;
71 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", __func__, \
78 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
80 write_nic_byte(dev, SECR, SECR_value);
84 void set_swcam(struct net_device *dev,
93 struct r8192_priv *priv = rtllib_priv(dev);
94 struct rtllib_device *ieee = priv->rtllib;
95 RT_TRACE(COMP_DBG, "===========>%s():EntryNo is %d,KeyIndex is "
96 "%d,KeyType is %d,is_mesh is %d\n", __func__, EntryNo,
97 KeyIndex, KeyType, is_mesh);
100 ieee->swcamtable[EntryNo].bused=true;
101 ieee->swcamtable[EntryNo].key_index=KeyIndex;
102 ieee->swcamtable[EntryNo].key_type=KeyType;
103 memcpy(ieee->swcamtable[EntryNo].macaddr,MacAddr,6);
104 ieee->swcamtable[EntryNo].useDK=DefaultKey;
105 memcpy(ieee->swcamtable[EntryNo].key_buf,(u8*)KeyContent,16);
109 void setKey(struct net_device *dev,
117 u32 TargetCommand = 0;
118 u32 TargetContent = 0;
121 struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
122 enum rt_rf_power_state rtState;
123 rtState = priv->rtllib->eRFPowerState;
124 if (priv->rtllib->PowerSaveControl.bInactivePs){
125 if (rtState == eRfOff){
126 if (priv->rtllib->RfOffReason > RF_CHANGE_BY_IPS)
128 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__func__);
132 down(&priv->rtllib->ips_sem);
134 up(&priv->rtllib->ips_sem); }
137 priv->rtllib->is_set_key = true;
138 if (EntryNo >= TOTAL_CAM_ENTRY)
139 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
141 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d,"
142 "KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex,
143 KeyType, MAC_ARG(MacAddr));
146 usConfig |= BIT15 | (KeyType<<2);
148 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
151 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
152 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
153 TargetCommand |= BIT31|BIT16;
156 TargetContent = (u32)(*(MacAddr+0)) << 16|
157 (u32)(*(MacAddr+1)) << 24|
160 write_nic_dword(dev, WCAMI, TargetContent);
161 write_nic_dword(dev, RWCAM, TargetCommand);
163 TargetContent = (u32)(*(MacAddr+2)) |
164 (u32)(*(MacAddr+3)) << 8|
165 (u32)(*(MacAddr+4)) << 16|
166 (u32)(*(MacAddr+5)) << 24;
167 write_nic_dword(dev, WCAMI, TargetContent);
168 write_nic_dword(dev, RWCAM, TargetCommand);
170 if (KeyContent != NULL) {
171 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
172 write_nic_dword(dev, RWCAM, TargetCommand);
177 RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig);
180 void CAM_read_entry(struct net_device *dev, u32 iIndex)
182 u32 target_command=0;
183 u32 target_content=0;
187 for (entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
189 target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
190 target_command= target_command | BIT31;
194 ulStatus = read_nic_dword(dev, RWCAM);
195 if (ulStatus & BIT31){
202 write_nic_dword(dev, RWCAM, target_command);
203 RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
204 target_content = read_nic_dword(dev, RCAMO);
205 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
210 void CamRestoreAllEntry( struct net_device *dev)
213 struct r8192_priv *priv = rtllib_priv(dev);
214 u8* MacAddr = priv->rtllib->current_network.bssid;
216 static u8 CAM_CONST_ADDR[4][6] = {
217 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
218 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
219 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
220 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
221 static u8 CAM_CONST_BROAD[] =
222 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
224 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
227 if ((priv->rtllib->pairwise_key_type == KEY_TYPE_WEP40)||
228 (priv->rtllib->pairwise_key_type == KEY_TYPE_WEP104))
231 for (EntryId=0; EntryId<4; EntryId++)
234 MacAddr = CAM_CONST_ADDR[EntryId];
235 if (priv->rtllib->swcamtable[EntryId].bused )
240 priv->rtllib->pairwise_key_type,
243 (u32*)(&priv->rtllib->swcamtable[EntryId].key_buf[0])
250 else if (priv->rtllib->pairwise_key_type == KEY_TYPE_TKIP)
254 if (priv->rtllib->iw_mode == IW_MODE_ADHOC)
259 priv->rtllib->pairwise_key_type,
262 (u32*)(&priv->rtllib->swcamtable[4].key_buf[0])
270 priv->rtllib->pairwise_key_type,
273 (u32*)(&priv->rtllib->swcamtable[4].key_buf[0])
279 else if (priv->rtllib->pairwise_key_type == KEY_TYPE_CCMP)
283 if (priv->rtllib->iw_mode == IW_MODE_ADHOC)
288 priv->rtllib->pairwise_key_type,
291 (u32*)(&priv->rtllib->swcamtable[4].key_buf[0])
299 priv->rtllib->pairwise_key_type,
302 (u32*)(&priv->rtllib->swcamtable[4].key_buf[0])
310 if (priv->rtllib->group_key_type == KEY_TYPE_TKIP)
312 MacAddr = CAM_CONST_BROAD;
313 for (EntryId=1 ; EntryId<4 ; EntryId++)
315 if (priv->rtllib->swcamtable[EntryId].bused )
320 priv->rtllib->group_key_type,
323 (u32*)(&priv->rtllib->swcamtable[EntryId].key_buf[0])
327 if (priv->rtllib->iw_mode == IW_MODE_ADHOC)
329 if (priv->rtllib->swcamtable[0].bused ){
333 priv->rtllib->group_key_type,
336 (u32*)(&priv->rtllib->swcamtable[0].key_buf[0])
341 RT_TRACE(COMP_ERR,"===>%s():ERR!! ADHOC TKIP ,but 0 entry is have no data\n",__func__);
345 } else if (priv->rtllib->group_key_type == KEY_TYPE_CCMP) {
346 MacAddr = CAM_CONST_BROAD;
347 for (EntryId=1; EntryId<4 ; EntryId++)
349 if (priv->rtllib->swcamtable[EntryId].bused )
354 priv->rtllib->group_key_type,
357 (u32*)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
361 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
362 if (priv->rtllib->swcamtable[0].bused) {
366 priv->rtllib->group_key_type,
369 (u32*)(&priv->rtllib->swcamtable[0].key_buf[0]));
371 RT_TRACE(COMP_ERR,"===>%s():ERR!! ADHOC CCMP ,but 0 entry is have no data\n",