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 
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 
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 	ieee->hwsec_active = 1;
44 	if ((ieee->ht_info->iot_action & HT_IOT_ACT_PURE_N_MODE) || !hwwep) {
45 		ieee->hwsec_active = 0;
46 		SECR_value &= ~SCR_RxDecEnable;
47 	}
48 	rtl92e_writeb(dev, SECR, SECR_value);
49 }
50 
51 void rtl92e_set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
52 		      u16 KeyType, const u8 *MacAddr, u32 *KeyContent)
53 {
54 	struct r8192_priv *priv = rtllib_priv(dev);
55 	struct rtllib_device *ieee = priv->rtllib;
56 
57 	if (EntryNo >= TOTAL_CAM_ENTRY)
58 		return;
59 
60 	ieee->swcamtable[EntryNo].bused = true;
61 	ieee->swcamtable[EntryNo].key_index = KeyIndex;
62 	ieee->swcamtable[EntryNo].key_type = KeyType;
63 	memcpy(ieee->swcamtable[EntryNo].macaddr, MacAddr, 6);
64 	ieee->swcamtable[EntryNo].useDK = 0;
65 	memcpy(ieee->swcamtable[EntryNo].key_buf, (u8 *)KeyContent, 16);
66 }
67 
68 void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
69 		    u16 KeyType, const u8 *MacAddr, u8 DefaultKey,
70 		    u32 *KeyContent)
71 {
72 	u32 TargetCommand = 0;
73 	u32 TargetContent = 0;
74 	u16 usConfig = 0;
75 	u8 i;
76 	struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
77 	enum rt_rf_power_state rt_state;
78 
79 	rt_state = priv->rtllib->rf_power_state;
80 	if (rt_state == rf_off) {
81 		if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) {
82 			netdev_warn(dev, "%s(): RF is OFF.\n",
83 				    __func__);
84 			return;
85 		}
86 		mutex_lock(&priv->rtllib->ips_mutex);
87 		rtl92e_ips_leave(dev);
88 		mutex_unlock(&priv->rtllib->ips_mutex);
89 	}
90 	priv->rtllib->is_set_key = true;
91 	if (EntryNo >= TOTAL_CAM_ENTRY) {
92 		netdev_info(dev, "%s(): Invalid CAM entry\n", __func__);
93 		return;
94 	}
95 
96 	if (DefaultKey)
97 		usConfig |= BIT15 | (KeyType << 2);
98 	else
99 		usConfig |= BIT15 | (KeyType << 2) | KeyIndex;
100 
101 	for (i = 0; i < CAM_CONTENT_COUNT; i++) {
102 		TargetCommand  = i + CAM_CONTENT_COUNT * EntryNo;
103 		TargetCommand |= BIT31 | BIT16;
104 
105 		if (i == 0) {
106 			TargetContent = (u32)(*(MacAddr + 0)) << 16 |
107 				(u32)(*(MacAddr + 1)) << 24 |
108 				(u32)usConfig;
109 
110 			rtl92e_writel(dev, WCAMI, TargetContent);
111 			rtl92e_writel(dev, RWCAM, TargetCommand);
112 		} else if (i == 1) {
113 			TargetContent = (u32)(*(MacAddr + 2)) |
114 				(u32)(*(MacAddr + 3)) <<  8 |
115 				(u32)(*(MacAddr + 4)) << 16 |
116 				(u32)(*(MacAddr + 5)) << 24;
117 			rtl92e_writel(dev, WCAMI, TargetContent);
118 			rtl92e_writel(dev, RWCAM, TargetCommand);
119 		} else {
120 			if (KeyContent != NULL) {
121 				rtl92e_writel(dev, WCAMI,
122 					      (u32)(*(KeyContent + i - 2)));
123 				rtl92e_writel(dev, RWCAM, TargetCommand);
124 				udelay(100);
125 			}
126 		}
127 	}
128 }
129 
130 void rtl92e_cam_restore(struct net_device *dev)
131 {
132 	u8 EntryId = 0;
133 	struct r8192_priv *priv = rtllib_priv(dev);
134 	u8 *MacAddr = priv->rtllib->current_network.bssid;
135 
136 	static u8	CAM_CONST_ADDR[4][6] = {
137 		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
138 		{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
139 		{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
140 		{0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
141 	};
142 	static u8	CAM_CONST_BROAD[] = {
143 		0xff, 0xff, 0xff, 0xff, 0xff, 0xff
144 	};
145 
146 	if ((priv->rtllib->pairwise_key_type == KEY_TYPE_WEP40) ||
147 	    (priv->rtllib->pairwise_key_type == KEY_TYPE_WEP104)) {
148 		for (EntryId = 0; EntryId < 4; EntryId++) {
149 			MacAddr = CAM_CONST_ADDR[EntryId];
150 			if (priv->rtllib->swcamtable[EntryId].bused) {
151 				rtl92e_set_key(dev, EntryId, EntryId,
152 					       priv->rtllib->pairwise_key_type,
153 					       MacAddr, 0,
154 					       (u32 *)(&priv->rtllib->swcamtable
155 						       [EntryId].key_buf[0]));
156 			}
157 		}
158 
159 	} else if (priv->rtllib->pairwise_key_type == KEY_TYPE_TKIP) {
160 		if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
161 			rtl92e_set_key(dev, 4, 0,
162 				       priv->rtllib->pairwise_key_type,
163 				       (const u8 *)dev->dev_addr, 0,
164 				       (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
165 		} else {
166 			rtl92e_set_key(dev, 4, 0,
167 				       priv->rtllib->pairwise_key_type,
168 				       MacAddr, 0,
169 				       (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
170 		}
171 
172 	} else if (priv->rtllib->pairwise_key_type == KEY_TYPE_CCMP) {
173 		if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
174 			rtl92e_set_key(dev, 4, 0,
175 				       priv->rtllib->pairwise_key_type,
176 				       (const u8 *)dev->dev_addr, 0,
177 				       (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
178 		} else {
179 			rtl92e_set_key(dev, 4, 0,
180 				       priv->rtllib->pairwise_key_type, MacAddr,
181 				       0, (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
182 			}
183 	}
184 
185 	if (priv->rtllib->group_key_type == KEY_TYPE_TKIP) {
186 		MacAddr = CAM_CONST_BROAD;
187 		for (EntryId = 1; EntryId < 4; EntryId++) {
188 			if (priv->rtllib->swcamtable[EntryId].bused) {
189 				rtl92e_set_key(dev, EntryId, EntryId,
190 					       priv->rtllib->group_key_type,
191 					       MacAddr, 0,
192 					       (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
193 			}
194 		}
195 		if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
196 			if (priv->rtllib->swcamtable[0].bused) {
197 				rtl92e_set_key(dev, 0, 0,
198 					       priv->rtllib->group_key_type,
199 					       CAM_CONST_ADDR[0], 0,
200 					       (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0]));
201 			} else {
202 				netdev_warn(dev,
203 					    "%s(): ADHOC TKIP: missing key entry.\n",
204 					    __func__);
205 				return;
206 			}
207 		}
208 	} else if (priv->rtllib->group_key_type == KEY_TYPE_CCMP) {
209 		MacAddr = CAM_CONST_BROAD;
210 		for (EntryId = 1; EntryId < 4; EntryId++) {
211 			if (priv->rtllib->swcamtable[EntryId].bused) {
212 				rtl92e_set_key(dev, EntryId, EntryId,
213 					       priv->rtllib->group_key_type,
214 					       MacAddr, 0,
215 					       (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
216 			}
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 CCMP: missing key entry.\n",
228 					    __func__);
229 				return;
230 			}
231 		}
232 	}
233 }
234