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
16void rtl92e_cam_reset(struct net_device *dev)
17{
18 u32 ulcommand = 0;
19
20 ulcommand |= BIT(31) | BIT(30);
21 rtl92e_writel(dev, x: RWCAM, y: ulcommand);
22}
23
24void 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, x: SECR, y: SECR_value);
44}
45
46void 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
63void 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, format: "%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(lock: &priv->rtllib->ips_mutex);
84 }
85 priv->rtllib->is_set_key = true;
86 if (EntryNo >= TOTAL_CAM_ENTRY) {
87 netdev_info(dev, format: "%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, x: WCAMI, y: TargetContent);
106 rtl92e_writel(dev, x: RWCAM, y: 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, x: WCAMI, y: TargetContent);
113 rtl92e_writel(dev, x: RWCAM, y: TargetCommand);
114 } else {
115 if (KeyContent) {
116 rtl92e_writel(dev, x: WCAMI,
117 y: (u32)(*(KeyContent + i - 2)));
118 rtl92e_writel(dev, x: RWCAM, y: TargetCommand);
119 udelay(100);
120 }
121 }
122 }
123}
124

source code of linux/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c