root/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rtl92e_cam_reset
  2. rtl92e_enable_hw_security_config
  3. rtl92e_set_swcam
  4. rtl92e_set_key
  5. rtl92e_cam_restore

   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 
  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 
  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 
  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 rtl92e_set_key(), dev:%p, EntryNo:%d, KeyIndex:%d,KeyType:%d, MacAddr %pM\n",
 112                  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 
 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, "rtl92e_cam_restore:\n");
 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                                        (u8 *)dev->dev_addr, 0,
 188                                        (u32 *)(&priv->rtllib->swcamtable[4].
 189                                        key_buf[0]));
 190                 } else {
 191                         rtl92e_set_key(dev, 4, 0,
 192                                        priv->rtllib->pairwise_key_type,
 193                                        MacAddr, 0,
 194                                        (u32 *)(&priv->rtllib->swcamtable[4].
 195                                        key_buf[0]));
 196                 }
 197 
 198         } else if (priv->rtllib->pairwise_key_type == KEY_TYPE_CCMP) {
 199                 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
 200                         rtl92e_set_key(dev, 4, 0,
 201                                        priv->rtllib->pairwise_key_type,
 202                                        (u8 *)dev->dev_addr, 0,
 203                                        (u32 *)(&priv->rtllib->swcamtable[4].
 204                                        key_buf[0]));
 205                 } else {
 206                         rtl92e_set_key(dev, 4, 0,
 207                                        priv->rtllib->pairwise_key_type, MacAddr,
 208                                        0, (u32 *)(&priv->rtllib->swcamtable[4].
 209                                        key_buf[0]));
 210                         }
 211         }
 212 
 213         if (priv->rtllib->group_key_type == KEY_TYPE_TKIP) {
 214                 MacAddr = CAM_CONST_BROAD;
 215                 for (EntryId = 1; EntryId < 4; EntryId++) {
 216                         if (priv->rtllib->swcamtable[EntryId].bused) {
 217                                 rtl92e_set_key(dev, EntryId, EntryId,
 218                                                priv->rtllib->group_key_type,
 219                                                MacAddr, 0,
 220                                                (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
 221                         }
 222                 }
 223                 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
 224                         if (priv->rtllib->swcamtable[0].bused) {
 225                                 rtl92e_set_key(dev, 0, 0,
 226                                                priv->rtllib->group_key_type,
 227                                                CAM_CONST_ADDR[0], 0,
 228                                                (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0]));
 229                         } else {
 230                                 netdev_warn(dev,
 231                                             "%s(): ADHOC TKIP: missing key entry.\n",
 232                                             __func__);
 233                                 return;
 234                         }
 235                 }
 236         } else if (priv->rtllib->group_key_type == KEY_TYPE_CCMP) {
 237                 MacAddr = CAM_CONST_BROAD;
 238                 for (EntryId = 1; EntryId < 4; EntryId++) {
 239                         if (priv->rtllib->swcamtable[EntryId].bused) {
 240                                 rtl92e_set_key(dev, EntryId, EntryId,
 241                                                priv->rtllib->group_key_type,
 242                                                MacAddr, 0,
 243                                                (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
 244                         }
 245                 }
 246 
 247                 if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
 248                         if (priv->rtllib->swcamtable[0].bused) {
 249                                 rtl92e_set_key(dev, 0, 0,
 250                                                priv->rtllib->group_key_type,
 251                                                CAM_CONST_ADDR[0], 0,
 252                                                (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0]));
 253                         } else {
 254                                 netdev_warn(dev,
 255                                             "%s(): ADHOC CCMP: missing key entry.\n",
 256                                             __func__);
 257                                 return;
 258                         }
 259                 }
 260         }
 261 }

/* [<][>][^][v][top][bottom][index][help] */