GNU Linux-libre 6.8.7-gnu
[releases.git] / drivers / staging / rtl8192e / rtl8192e / rtl_cam.c
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 }