1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
4  *
5  * Based on the r8180 driver, which is:
6  * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
7  *
8  * Contact Information: wlanfae <wlanfae@realtek.com>
9  */
10 #include "rtl_core.h"
11 #include "r8192E_phy.h"
12 #include "r8192E_phyreg.h"
13 #include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */
14 #include "r8192E_cmdpkt.h"
15 
rtl92e_cam_reset(struct net_device * dev)16 void 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 
rtl92e_enable_hw_security_config(struct net_device * dev)24 void 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 
rtl92e_set_swcam(struct net_device * dev,u8 EntryNo,u8 KeyIndex,u16 KeyType,const u8 * MacAddr,u8 DefaultKey,u32 * KeyContent,u8 is_mesh)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)
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 
rtl92e_set_key(struct net_device * dev,u8 EntryNo,u8 KeyIndex,u16 KeyType,const u8 * MacAddr,u8 DefaultKey,u32 * KeyContent)80 void 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 %s, dev:%p, EntryNo:%d, KeyIndex:%d,KeyType:%d, MacAddr %pM\n",
112 		 __func__, 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 
rtl92e_cam_restore(struct net_device * dev)150 void 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, "%s:\n", __func__);
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 				       (const u8 *)dev->dev_addr, 0,
188 				       (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
189 		} else {
190 			rtl92e_set_key(dev, 4, 0,
191 				       priv->rtllib->pairwise_key_type,
192 				       MacAddr, 0,
193 				       (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
194 		}
195 
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]));
202 		} else {
203 			rtl92e_set_key(dev, 4, 0,
204 				       priv->rtllib->pairwise_key_type, MacAddr,
205 				       0, (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
206 			}
207 	}
208 
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,
215 					       MacAddr, 0,
216 					       (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
217 			}
218 		}
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]));
225 			} else {
226 				netdev_warn(dev,
227 					    "%s(): ADHOC TKIP: missing key entry.\n",
228 					    __func__);
229 				return;
230 			}
231 		}
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,
238 					       MacAddr, 0,
239 					       (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
240 			}
241 		}
242 
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]));
249 			} else {
250 				netdev_warn(dev,
251 					    "%s(): ADHOC CCMP: missing key entry.\n",
252 					    __func__);
253 				return;
254 			}
255 		}
256 	}
257 }
258