The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/rtw88/sec.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 = 7; 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                 case 6:
   64                 case 7:
   65                         content = 0;
   66                         break;
   67                 default:
   68                         j = (i - 2) << 2;
   69                         content = (key->key[j])                 |
   70                                   (key->key[j + 1]      << 8)   |
   71                                   (key->key[j + 2]      << 16)  |
   72                                   (key->key[j + 3]      << 24);
   73                         break;
   74                 }
   75 
   76                 command = write_cmd | (addr + i);
   77                 rtw_write32(rtwdev, RTW_SEC_WRITE_REG, content);
   78                 rtw_write32(rtwdev, RTW_SEC_CMD_REG, command);
   79         }
   80 }
   81 
   82 void rtw_sec_clear_cam(struct rtw_dev *rtwdev,
   83                        struct rtw_sec_desc *sec,
   84                        u8 hw_key_idx)
   85 {
   86         struct rtw_cam_entry *cam = &sec->cam_table[hw_key_idx];
   87         u32 write_cmd;
   88         u32 command;
   89         u32 addr;
   90 
   91         clear_bit(hw_key_idx, sec->cam_map);
   92         cam->valid = false;
   93         cam->key = NULL;
   94         eth_zero_addr(cam->addr);
   95 
   96         write_cmd = RTW_SEC_CMD_WRITE_ENABLE | RTW_SEC_CMD_POLLING;
   97         addr = hw_key_idx << RTW_SEC_CAM_ENTRY_SHIFT;
   98         command = write_cmd | addr;
   99         rtw_write32(rtwdev, RTW_SEC_WRITE_REG, 0);
  100         rtw_write32(rtwdev, RTW_SEC_CMD_REG, command);
  101 }
  102 
  103 u8 rtw_sec_cam_pg_backup(struct rtw_dev *rtwdev, u8 *used_cam)
  104 {
  105         struct rtw_sec_desc *sec = &rtwdev->sec;
  106         u8 offset = 0;
  107         u8 count, n;
  108 
  109         if (!used_cam)
  110                 return 0;
  111 
  112         for (count = 0; count < MAX_PG_CAM_BACKUP_NUM; count++) {
  113                 n = find_next_bit(sec->cam_map, RTW_MAX_SEC_CAM_NUM, offset);
  114                 if (n == RTW_MAX_SEC_CAM_NUM)
  115                         break;
  116 
  117                 used_cam[count] = n;
  118                 offset = n + 1;
  119         }
  120 
  121         return count;
  122 }
  123 
  124 void rtw_sec_enable_sec_engine(struct rtw_dev *rtwdev)
  125 {
  126         struct rtw_sec_desc *sec = &rtwdev->sec;
  127         u16 ctrl_reg;
  128         u16 sec_config;
  129 
  130         /* default use default key search for now */
  131         sec->default_key_search = true;
  132 
  133         ctrl_reg = rtw_read16(rtwdev, REG_CR);
  134         ctrl_reg |= RTW_SEC_ENGINE_EN;
  135         rtw_write16(rtwdev, REG_CR, ctrl_reg);
  136 
  137         sec_config = rtw_read16(rtwdev, RTW_SEC_CONFIG);
  138 
  139         sec_config |= RTW_SEC_TX_DEC_EN | RTW_SEC_RX_DEC_EN;
  140         if (sec->default_key_search)
  141                 sec_config |= RTW_SEC_TX_UNI_USE_DK | RTW_SEC_RX_UNI_USE_DK |
  142                               RTW_SEC_TX_BC_USE_DK | RTW_SEC_RX_BC_USE_DK;
  143 
  144         rtw_write16(rtwdev, RTW_SEC_CONFIG, sec_config);
  145 }

Cache object: 23cdae20f2c8791bd197650a7054d8c8


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.