1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
5 * Based on the r8180 driver, which is:
6 * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
8 * Contact Information: wlanfae <wlanfae@realtek.com>
11 #include "r8192E_phy.h"
12 #include "r8192E_phyreg.h"
13 #include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */
14 #include "r8192E_cmdpkt.h"
16 void rtl92e_cam_reset(struct net_device *dev)
20 ulcommand |= BIT31|BIT30;
21 rtl92e_writel(dev, RWCAM, ulcommand);
24 void rtl92e_enable_hw_security_config(struct net_device *dev)
27 struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
28 struct rtllib_device *ieee = priv->rtllib;
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 |
39 SECR_value |= SCR_RxUseDK;
40 SECR_value |= SCR_TxUseDK;
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;
50 RT_TRACE(COMP_SEC, "%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n",
51 __func__, ieee->hwsec_active, ieee->pairwise_key_type,
53 rtl92e_writeb(dev, SECR, SECR_value);
56 void 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)
60 struct r8192_priv *priv = rtllib_priv(dev);
61 struct rtllib_device *ieee = priv->rtllib;
64 "===========>%s():EntryNo is %d,KeyIndex is %d,KeyType is %d,is_mesh is %d\n",
65 __func__, EntryNo, KeyIndex, KeyType, is_mesh);
67 if (EntryNo >= TOTAL_CAM_ENTRY)
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);
80 void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
81 u16 KeyType, const u8 *MacAddr, u8 DefaultKey,
84 u32 TargetCommand = 0;
85 u32 TargetContent = 0;
88 struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
89 enum rt_rf_power_state rtState;
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",
99 mutex_lock(&priv->rtllib->ips_mutex);
100 rtl92e_ips_leave(dev);
101 mutex_unlock(&priv->rtllib->ips_mutex);
104 priv->rtllib->is_set_key = true;
105 if (EntryNo >= TOTAL_CAM_ENTRY) {
106 netdev_info(dev, "%s(): Invalid CAM entry\n", __func__);
111 "====>to %s, dev:%p, EntryNo:%d, KeyIndex:%d,KeyType:%d, MacAddr %pM\n",
112 __func__, dev, EntryNo, KeyIndex, KeyType, MacAddr);
115 usConfig |= BIT15 | (KeyType<<2);
117 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
120 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
121 TargetCommand = i + CAM_CONTENT_COUNT * EntryNo;
122 TargetCommand |= BIT31|BIT16;
125 TargetContent = (u32)(*(MacAddr+0)) << 16 |
126 (u32)(*(MacAddr+1)) << 24 |
129 rtl92e_writel(dev, WCAMI, TargetContent);
130 rtl92e_writel(dev, RWCAM, TargetCommand);
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);
139 if (KeyContent != NULL) {
140 rtl92e_writel(dev, WCAMI,
141 (u32)(*(KeyContent+i-2)));
142 rtl92e_writel(dev, RWCAM, TargetCommand);
147 RT_TRACE(COMP_SEC, "=========>after set key, usconfig:%x\n", usConfig);
150 void rtl92e_cam_restore(struct net_device *dev)
153 struct r8192_priv *priv = rtllib_priv(dev);
154 u8 *MacAddr = priv->rtllib->current_network.bssid;
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}
162 static u8 CAM_CONST_BROAD[] = {
163 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
166 RT_TRACE(COMP_SEC, "%s:\n", __func__);
169 if ((priv->rtllib->pairwise_key_type == KEY_TYPE_WEP40) ||
170 (priv->rtllib->pairwise_key_type == KEY_TYPE_WEP104)) {
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,
178 (u32 *)(&priv->rtllib->swcamtable
179 [EntryId].key_buf[0]));
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 (const u8 *)dev->dev_addr, 0,
188 (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
190 rtl92e_set_key(dev, 4, 0,
191 priv->rtllib->pairwise_key_type,
193 (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
196 } else if (priv->rtllib->pairwise_key_type == KEY_TYPE_CCMP) {
197 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
198 rtl92e_set_key(dev, 4, 0,
199 priv->rtllib->pairwise_key_type,
200 (const u8 *)dev->dev_addr, 0,
201 (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
203 rtl92e_set_key(dev, 4, 0,
204 priv->rtllib->pairwise_key_type, MacAddr,
205 0, (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
209 if (priv->rtllib->group_key_type == KEY_TYPE_TKIP) {
210 MacAddr = CAM_CONST_BROAD;
211 for (EntryId = 1; EntryId < 4; EntryId++) {
212 if (priv->rtllib->swcamtable[EntryId].bused) {
213 rtl92e_set_key(dev, EntryId, EntryId,
214 priv->rtllib->group_key_type,
216 (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
219 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
220 if (priv->rtllib->swcamtable[0].bused) {
221 rtl92e_set_key(dev, 0, 0,
222 priv->rtllib->group_key_type,
223 CAM_CONST_ADDR[0], 0,
224 (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0]));
227 "%s(): ADHOC TKIP: missing key entry.\n",
232 } else if (priv->rtllib->group_key_type == KEY_TYPE_CCMP) {
233 MacAddr = CAM_CONST_BROAD;
234 for (EntryId = 1; EntryId < 4; EntryId++) {
235 if (priv->rtllib->swcamtable[EntryId].bused) {
236 rtl92e_set_key(dev, EntryId, EntryId,
237 priv->rtllib->group_key_type,
239 (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
243 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
244 if (priv->rtllib->swcamtable[0].bused) {
245 rtl92e_set_key(dev, 0, 0,
246 priv->rtllib->group_key_type,
247 CAM_CONST_ADDR[0], 0,
248 (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0]));
251 "%s(): ADHOC CCMP: missing key entry.\n",