root/drivers/net/wireless/realtek/rtw88/sec.c

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

DEFINITIONS

This source file includes following definitions.
  1. rtw_sec_get_free_cam
  2. rtw_sec_write_cam
  3. rtw_sec_clear_cam
  4. rtw_sec_enable_sec_engine

   1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
   2 /* Copyright(c) 2018-2019  Realtek Corporation
   3  */
   4 
   5 #include "main.h"
   6 #include "sec.h"
   7 #include "reg.h"
   8 
   9 int rtw_sec_get_free_cam(struct rtw_sec_desc *sec)
  10 {
  11         /* if default key search is enabled, the first 4 cam entries
  12          * are used to direct map to group key with its key->key_idx, so
  13          * driver should use cam entries after 4 to install pairwise key
  14          */
  15         if (sec->default_key_search)
  16                 return find_next_zero_bit(sec->cam_map, RTW_MAX_SEC_CAM_NUM,
  17                                           RTW_SEC_DEFAULT_KEY_NUM);
  18 
  19         return find_first_zero_bit(sec->cam_map, RTW_MAX_SEC_CAM_NUM);
  20 }
  21 
  22 void rtw_sec_write_cam(struct rtw_dev *rtwdev,
  23                        struct rtw_sec_desc *sec,
  24                        struct ieee80211_sta *sta,
  25                        struct ieee80211_key_conf *key,
  26                        u8 hw_key_type, u8 hw_key_idx)
  27 {
  28         struct rtw_cam_entry *cam = &sec->cam_table[hw_key_idx];
  29         u32 write_cmd;
  30         u32 command;
  31         u32 content;
  32         u32 addr;
  33         int i, j;
  34 
  35         set_bit(hw_key_idx, sec->cam_map);
  36         cam->valid = true;
  37         cam->group = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE);
  38         cam->hw_key_type = hw_key_type;
  39         cam->key = key;
  40         if (sta)
  41                 ether_addr_copy(cam->addr, sta->addr);
  42         else
  43                 eth_broadcast_addr(cam->addr);
  44 
  45         write_cmd = RTW_SEC_CMD_WRITE_ENABLE | RTW_SEC_CMD_POLLING;
  46         addr = hw_key_idx << RTW_SEC_CAM_ENTRY_SHIFT;
  47         for (i = 5; i >= 0; i--) {
  48                 switch (i) {
  49                 case 0:
  50                         content = ((key->keyidx & 0x3))         |
  51                                   ((hw_key_type & 0x7)  << 2)   |
  52                                   (cam->group           << 6)   |
  53                                   (cam->valid           << 15)  |
  54                                   (cam->addr[0]         << 16)  |
  55                                   (cam->addr[1]         << 24);
  56                         break;
  57                 case 1:
  58                         content = (cam->addr[2])                |
  59                                   (cam->addr[3]         << 8)   |
  60                                   (cam->addr[4]         << 16)  |
  61                                   (cam->addr[5]         << 24);
  62                         break;
  63                 default:
  64                         j = (i - 2) << 2;
  65                         content = (key->key[j])                 |
  66                                   (key->key[j + 1]      << 8)   |
  67                                   (key->key[j + 2]      << 16)  |
  68                                   (key->key[j + 3]      << 24);
  69                         break;
  70                 }
  71 
  72                 command = write_cmd | (addr + i);
  73                 rtw_write32(rtwdev, RTW_SEC_WRITE_REG, content);
  74                 rtw_write32(rtwdev, RTW_SEC_CMD_REG, command);
  75         }
  76 }
  77 
  78 void rtw_sec_clear_cam(struct rtw_dev *rtwdev,
  79                        struct rtw_sec_desc *sec,
  80                        u8 hw_key_idx)
  81 {
  82         struct rtw_cam_entry *cam = &sec->cam_table[hw_key_idx];
  83         u32 write_cmd;
  84         u32 command;
  85         u32 addr;
  86 
  87         clear_bit(hw_key_idx, sec->cam_map);
  88         cam->valid = false;
  89         cam->key = NULL;
  90         eth_zero_addr(cam->addr);
  91 
  92         write_cmd = RTW_SEC_CMD_WRITE_ENABLE | RTW_SEC_CMD_POLLING;
  93         addr = hw_key_idx << RTW_SEC_CAM_ENTRY_SHIFT;
  94         command = write_cmd | addr;
  95         rtw_write32(rtwdev, RTW_SEC_WRITE_REG, 0);
  96         rtw_write32(rtwdev, RTW_SEC_CMD_REG, command);
  97 }
  98 
  99 void rtw_sec_enable_sec_engine(struct rtw_dev *rtwdev)
 100 {
 101         struct rtw_sec_desc *sec = &rtwdev->sec;
 102         u16 ctrl_reg;
 103         u16 sec_config;
 104 
 105         /* default use default key search for now */
 106         sec->default_key_search = true;
 107 
 108         ctrl_reg = rtw_read16(rtwdev, REG_CR);
 109         ctrl_reg |= RTW_SEC_ENGINE_EN;
 110         rtw_write16(rtwdev, REG_CR, ctrl_reg);
 111 
 112         sec_config = rtw_read16(rtwdev, RTW_SEC_CONFIG);
 113 
 114         sec_config |= RTW_SEC_TX_DEC_EN | RTW_SEC_RX_DEC_EN;
 115         if (sec->default_key_search)
 116                 sec_config |= RTW_SEC_TX_UNI_USE_DK | RTW_SEC_RX_UNI_USE_DK |
 117                               RTW_SEC_TX_BC_USE_DK | RTW_SEC_RX_BC_USE_DK;
 118 
 119         rtw_write16(rtwdev, RTW_SEC_CONFIG, sec_config);
 120 }

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