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 |= BIT(31) | BIT(30);
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 	}
37 
38 	ieee->hwsec_active = 1;
39 	if ((ieee->ht_info->iot_action & HT_IOT_ACT_PURE_N_MODE) || !hwwep) {
40 		ieee->hwsec_active = 0;
41 		SECR_value &= ~SCR_RxDecEnable;
42 	}
43 	rtl92e_writeb(dev, SECR, SECR_value);
44 }
45 
46 void rtl92e_set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
47 		      u16 KeyType, const u8 *MacAddr, u32 *KeyContent)
48 {
49 	struct r8192_priv *priv = rtllib_priv(dev);
50 	struct rtllib_device *ieee = priv->rtllib;
51 
52 	if (EntryNo >= TOTAL_CAM_ENTRY)
53 		return;
54 
55 	ieee->swcamtable[EntryNo].bused = true;
56 	ieee->swcamtable[EntryNo].key_index = KeyIndex;
57 	ieee->swcamtable[EntryNo].key_type = KeyType;
58 	memcpy(ieee->swcamtable[EntryNo].macaddr, MacAddr, 6);
59 	ieee->swcamtable[EntryNo].useDK = 0;
60 	memcpy(ieee->swcamtable[EntryNo].key_buf, (u8 *)KeyContent, 16);
61 }
62 
63 void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
64 		    u16 KeyType, const u8 *MacAddr, u8 DefaultKey,
65 		    u32 *KeyContent)
66 {
67 	u32 TargetCommand = 0;
68 	u32 TargetContent = 0;
69 	u16 usConfig = 0;
70 	u8 i;
71 	struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
72 	enum rt_rf_power_state rt_state;
73 
74 	rt_state = priv->rtllib->rf_power_state;
75 	if (rt_state == rf_off) {
76 		if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) {
77 			netdev_warn(dev, "%s(): RF is OFF.\n",
78 				    __func__);
79 			return;
80 		}
81 		mutex_lock(&priv->rtllib->ips_mutex);
82 		rtl92e_ips_leave(dev);
83 		mutex_unlock(&priv->rtllib->ips_mutex);
84 	}
85 	priv->rtllib->is_set_key = true;
86 	if (EntryNo >= TOTAL_CAM_ENTRY) {
87 		netdev_info(dev, "%s(): Invalid CAM entry\n", __func__);
88 		return;
89 	}
90 
91 	if (DefaultKey)
92 		usConfig |= BIT(15) | (KeyType << 2);
93 	else
94 		usConfig |= BIT(15) | (KeyType << 2) | KeyIndex;
95 
96 	for (i = 0; i < CAM_CONTENT_COUNT; i++) {
97 		TargetCommand  = i + CAM_CONTENT_COUNT * EntryNo;
98 		TargetCommand |= BIT(31) | BIT(16);
99 
100 		if (i == 0) {
101 			TargetContent = (u32)(*(MacAddr + 0)) << 16 |
102 				(u32)(*(MacAddr + 1)) << 24 |
103 				(u32)usConfig;
104 
105 			rtl92e_writel(dev, WCAMI, TargetContent);
106 			rtl92e_writel(dev, RWCAM, TargetCommand);
107 		} else if (i == 1) {
108 			TargetContent = (u32)(*(MacAddr + 2)) |
109 				(u32)(*(MacAddr + 3)) <<  8 |
110 				(u32)(*(MacAddr + 4)) << 16 |
111 				(u32)(*(MacAddr + 5)) << 24;
112 			rtl92e_writel(dev, WCAMI, TargetContent);
113 			rtl92e_writel(dev, RWCAM, TargetCommand);
114 		} else {
115 			if (KeyContent) {
116 				rtl92e_writel(dev, WCAMI,
117 					      (u32)(*(KeyContent + i - 2)));
118 				rtl92e_writel(dev, RWCAM, TargetCommand);
119 				udelay(100);
120 			}
121 		}
122 	}
123 }
124