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
******************************************************************************/
28
void CamResetAllEntry(struct net_device *dev)
32
ulcommand |= BIT31|BIT30;
33
write_nic_dword(dev, RWCAM, ulcommand);
36
#ifdef _RTL8192_EXT_PATCH_
37
void CamDeleteOneEntry(struct net_device *dev, u8 EntryNo)
39
u32 ulCommand = EntryNo * CAM_CONTENT_COUNT;
42
ulCommand = ulCommand | BIT31 | BIT16;
44
write_nic_dword(dev,WCAMI,ulContent);
45
write_nic_dword(dev,RWCAM,ulCommand);
48
void CamRestoreEachIFEntry(struct net_device* dev,u8 is_mesh)
51
struct r8192_priv *priv = rtllib_priv(dev);
52
struct rtllib_device *ieee = priv->rtllib;
53
for( i = 0 ; i< TOTAL_CAM_ENTRY; i++) {
56
if(ieee->swmeshcamtable[i].bused )
60
ieee->swmeshcamtable[i].key_index,
61
ieee->swmeshcamtable[i].key_type,
62
ieee->swmeshcamtable[i].macaddr,
63
ieee->swmeshcamtable[i].useDK,
64
(u32*)(&ieee->swmeshcamtable[i].key_buf[0])
68
if(ieee->swcamtable[i].bused )
72
ieee->swcamtable[i].key_index,
73
ieee->swcamtable[i].key_type,
74
ieee->swcamtable[i].macaddr,
75
ieee->swcamtable[i].useDK,
76
(u32*)(&ieee->swcamtable[i].key_buf[0]));
83
void write_cam(struct net_device *dev, u8 addr, u32 data)
85
write_nic_dword(dev, WCAMI, data);
86
write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
89
u32 read_cam(struct net_device *dev, u8 addr)
91
write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
92
return read_nic_dword(dev, 0xa8);
95
void EnableHWSecurityConfig8192(struct net_device *dev)
98
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
99
struct rtllib_device* ieee = priv->rtllib;
100
SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
101
#ifdef _RTL8192_EXT_PATCH_
102
if ((((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->rtllib->auth_mode != 2))
103
&&(ieee->iw_mode != IW_MODE_MESH))
105
if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->rtllib->auth_mode != 2))
108
SECR_value |= SCR_RxUseDK;
109
SECR_value |= SCR_TxUseDK;
111
else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
113
SECR_value |= SCR_RxUseDK;
114
SECR_value |= SCR_TxUseDK;
118
ieee->hwsec_active = 1;
119
#ifdef _RTL8192_EXT_PATCH_
120
if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep )
122
ieee->hwsec_active = 0;
123
SECR_value &= ~SCR_RxDecEnable;
124
SECR_value &= ~SCR_TxUseDK;
125
SECR_value &= ~SCR_RxUseDK;
126
SECR_value &= ~SCR_TxEncEnable;
129
if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep)
131
ieee->hwsec_active = 0;
132
SECR_value &= ~SCR_RxDecEnable;
137
if(IS_NORMAL_CHIP(priv->card_8192_version))
138
SECR_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
140
write_nic_byte(dev, REG_CR+1,0x02);
142
RT_TRACE(COMP_SEC,"The SECR-value %x \n",SECR_value)
143
priv->rtllib->SetHwRegHandler(dev, HW_VAR_WPA_CONFIG, &SECR_value);
145
RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
146
ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
148
write_nic_byte(dev, SECR, SECR_value);
153
void set_swcam(struct net_device *dev,
162
struct r8192_priv *priv = rtllib_priv(dev);
163
struct rtllib_device *ieee = priv->rtllib;
164
printk("===========>%s():EntryNo is %d,KeyIndex is %d,KeyType is %d,is_mesh is %d\n",__FUNCTION__,EntryNo,KeyIndex,KeyType,is_mesh);
166
#ifdef _RTL8192_EXT_PATCH_
167
ieee->swmeshcamtable[EntryNo].bused=true;
168
ieee->swmeshcamtable[EntryNo].key_index=KeyIndex;
169
ieee->swmeshcamtable[EntryNo].key_type=KeyType;
170
memcpy(ieee->swmeshcamtable[EntryNo].macaddr,MacAddr,6);
171
ieee->swmeshcamtable[EntryNo].useDK=DefaultKey;
172
memcpy(ieee->swmeshcamtable[EntryNo].key_buf,(u8*)KeyContent,16);
177
ieee->swcamtable[EntryNo].bused=true;
178
ieee->swcamtable[EntryNo].key_index=KeyIndex;
179
ieee->swcamtable[EntryNo].key_type=KeyType;
180
memcpy(ieee->swcamtable[EntryNo].macaddr,MacAddr,6);
181
ieee->swcamtable[EntryNo].useDK=DefaultKey;
182
memcpy(ieee->swcamtable[EntryNo].key_buf,(u8*)KeyContent,16);
185
#ifdef _RTL8192_EXT_PATCH_
186
void reset_IFswcam(struct net_device *dev, u8 is_mesh)
188
struct r8192_priv *priv = rtllib_priv(dev);
189
struct rtllib_device *ieee = priv->rtllib;
191
memset(ieee->swmeshcamtable,0,sizeof(SW_CAM_TABLE)*32);
194
memset(ieee->swcamtable,0,sizeof(SW_CAM_TABLE)*32);
198
void setKey(struct net_device *dev,
206
u32 TargetCommand = 0;
207
u32 TargetContent = 0;
211
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
212
RT_RF_POWER_STATE rtState;
213
rtState = priv->rtllib->eRFPowerState;
214
if(priv->rtllib->PowerSaveControl.bInactivePs){
215
if(rtState == eRfOff){
216
if(priv->rtllib->RfOffReason > RF_CHANGE_BY_IPS)
218
RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
222
down(&priv->rtllib->ips_sem);
224
up(&priv->rtllib->ips_sem); }
227
priv->rtllib->is_set_key = true;
229
if (EntryNo >= TOTAL_CAM_ENTRY)
230
RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
232
RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr));
235
usConfig |= BIT15 | (KeyType<<2);
237
usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
240
for(i=0 ; i<CAM_CONTENT_COUNT; i++){
241
TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
242
TargetCommand |= BIT31|BIT16;
245
TargetContent = (u32)(*(MacAddr+0)) << 16|
246
(u32)(*(MacAddr+1)) << 24|
249
write_nic_dword(dev, WCAMI, TargetContent);
250
write_nic_dword(dev, RWCAM, TargetCommand);
253
TargetContent = (u32)(*(MacAddr+2)) |
254
(u32)(*(MacAddr+3)) << 8|
255
(u32)(*(MacAddr+4)) << 16|
256
(u32)(*(MacAddr+5)) << 24;
257
write_nic_dword(dev, WCAMI, TargetContent);
258
write_nic_dword(dev, RWCAM, TargetCommand);
261
if(KeyContent != NULL)
263
write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
264
write_nic_dword(dev, RWCAM, TargetCommand);
265
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31))
271
RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig);
274
void CamPrintDbgReg(struct net_device* dev)
276
unsigned long rvalue;
277
unsigned char ucValue;
278
write_nic_dword(dev, DCAM, 0x80000000);
280
rvalue = read_nic_dword(dev, DCAM);
281
RT_TRACE(COMP_SEC, " TX CAM=%8lX ",rvalue);
282
if((rvalue & 0x40000000) != 0x4000000)
283
RT_TRACE(COMP_SEC, "-->TX Key Not Found ");
285
write_nic_dword(dev, DCAM, 0x00000000);
286
rvalue = read_nic_dword(dev, DCAM);
287
RT_TRACE(COMP_SEC, "RX CAM=%8lX ",rvalue);
288
if((rvalue & 0x40000000) != 0x4000000)
289
RT_TRACE(COMP_SEC, "-->CAM Key Not Found ");
290
ucValue = read_nic_byte(dev, SECR);
291
RT_TRACE(COMP_SEC, "WPA_Config=%x \n",ucValue);
294
void CAM_read_entry(struct net_device *dev, u32 iIndex)
296
u32 target_command=0;
297
u32 target_content=0;
301
for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
303
target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
304
target_command= target_command | BIT31;
309
ulStatus = read_nic_dword(dev, RWCAM);
310
if(ulStatus & BIT31){
318
write_nic_dword(dev, RWCAM, target_command);
319
RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
320
target_content = read_nic_dword(dev, RCAMO);
321
RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
326
void CamRestoreAllEntry( struct net_device *dev)
329
struct r8192_priv *priv = rtllib_priv(dev);
330
u8* MacAddr = priv->rtllib->current_network.bssid;
332
static u8 CAM_CONST_ADDR[4][6] = {
333
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
334
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
335
{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
336
{0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
337
static u8 CAM_CONST_BROAD[] =
338
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
340
RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
343
if ((priv->rtllib->pairwise_key_type == KEY_TYPE_WEP40)||
344
(priv->rtllib->pairwise_key_type == KEY_TYPE_WEP104))
347
for(EntryId=0; EntryId<4; EntryId++)
350
MacAddr = CAM_CONST_ADDR[EntryId];
351
if(priv->rtllib->swcamtable[EntryId].bused )
356
priv->rtllib->pairwise_key_type,
359
(u32*)(&priv->rtllib->swcamtable[EntryId].key_buf[0])
366
else if(priv->rtllib->pairwise_key_type == KEY_TYPE_TKIP)
370
if(priv->rtllib->iw_mode == IW_MODE_ADHOC)
375
priv->rtllib->pairwise_key_type,
378
(u32*)(&priv->rtllib->swcamtable[4].key_buf[0])
386
priv->rtllib->pairwise_key_type,
389
(u32*)(&priv->rtllib->swcamtable[4].key_buf[0])
395
else if(priv->rtllib->pairwise_key_type == KEY_TYPE_CCMP)
399
if(priv->rtllib->iw_mode == IW_MODE_ADHOC)
404
priv->rtllib->pairwise_key_type,
407
(u32*)(&priv->rtllib->swcamtable[4].key_buf[0])
415
priv->rtllib->pairwise_key_type,
418
(u32*)(&priv->rtllib->swcamtable[4].key_buf[0])
426
if(priv->rtllib->group_key_type == KEY_TYPE_TKIP)
428
MacAddr = CAM_CONST_BROAD;
429
for(EntryId=1 ; EntryId<4 ; EntryId++)
431
if(priv->rtllib->swcamtable[EntryId].bused )
436
priv->rtllib->group_key_type,
439
(u32*)(&priv->rtllib->swcamtable[EntryId].key_buf[0])
443
if(priv->rtllib->iw_mode == IW_MODE_ADHOC)
445
if(priv->rtllib->swcamtable[0].bused ){
449
priv->rtllib->group_key_type,
452
(u32*)(&priv->rtllib->swcamtable[0].key_buf[0])
457
RT_TRACE(COMP_ERR,"===>%s():ERR!! ADHOC TKIP ,but 0 entry is have no data\n",__FUNCTION__);
461
} else if(priv->rtllib->group_key_type == KEY_TYPE_CCMP) {
462
MacAddr = CAM_CONST_BROAD;
463
for(EntryId=1; EntryId<4 ; EntryId++)
465
if(priv->rtllib->swcamtable[EntryId].bused )
470
priv->rtllib->group_key_type,
473
(u32*)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
477
if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
478
if (priv->rtllib->swcamtable[0].bused) {
482
priv->rtllib->group_key_type,
485
(u32*)(&priv->rtllib->swcamtable[0].key_buf[0]));
487
RT_TRACE(COMP_ERR,"===>%s():ERR!! ADHOC CCMP ,but 0 entry is have no data\n",
496
#ifdef _RTL8192_EXT_PATCH_
497
u8 rtl8192_get_free_hwsec_cam_entry(struct rtllib_device *ieee, u8 *sta_addr)
499
u32 bitmap = (ieee->HwSecCamBitMap)>>4;
503
if ((NULL == ieee) || (NULL == sta_addr)) {
504
printk("%s: ieee or sta_addr is NULL.\n", __FUNCTION__);
505
return TOTAL_CAM_ENTRY;
508
/* Does STA already exist? */
509
/* CAM Index 31 is for AP */
510
for (i = 4; i < TOTAL_CAM_ENTRY-1; i++) {
511
addr = ieee->HwSecCamStaAddr[i];
512
if(memcmp(addr, sta_addr, ETH_ALEN) == 0)
516
/* Get a free CAM entry. */
517
for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY - 1; entry_idx++) {
518
if ((bitmap & BIT0) == 0) {
519
ieee->HwSecCamBitMap |= BIT0<<entry_idx;
520
memcpy(ieee->HwSecCamStaAddr[entry_idx], sta_addr, ETH_ALEN);
526
return TOTAL_CAM_ENTRY;
529
void rtl8192_del_hwsec_cam_entry(struct rtllib_device *ieee, u8 *sta_addr)
534
if ((NULL == ieee) || (NULL == sta_addr)) {
535
printk("%s: ieee or sta_addr is NULL.\n", __FUNCTION__);
539
if ((sta_addr[0]|sta_addr[1]|sta_addr[2]|sta_addr[3]|\
540
sta_addr[4]|sta_addr[5]) == 0) {
541
printk("%s: sta_addr is 00:00:00:00:00:00.\n", __FUNCTION__);
545
/* Does STA already exist? */
546
for (i = 4; i < TOTAL_CAM_ENTRY; i++) {
547
addr = ieee->HwSecCamStaAddr[i];
548
bitmap = (ieee->HwSecCamBitMap)>>i;
549
if (((bitmap & BIT0) == BIT0) && (memcmp(addr, sta_addr, ETH_ALEN) == 0)) {
550
/* Remove from HW Security CAM */
551
CamDeleteOneEntry(ieee->dev, i);
552
memset(ieee->HwSecCamStaAddr[i], 0, ETH_ALEN);
553
ieee->HwSecCamBitMap &= ~(BIT0<<i);
554
memset(&(ieee->swmeshcamtable[i]), 0, sizeof(SW_CAM_TABLE));
555
RT_TRACE(COMP_SEC, "====>del sw entry, EntryNo:%d, MacAddr:"MAC_FMT"\n",
556
i, MAC_ARG(sta_addr));