Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
0002 /* Copyright(c) 2018-2019  Realtek Corporation
0003  */
0004 
0005 #include "main.h"
0006 #include "sec.h"
0007 #include "reg.h"
0008 
0009 int rtw_sec_get_free_cam(struct rtw_sec_desc *sec)
0010 {
0011     /* if default key search is enabled, the first 4 cam entries
0012      * are used to direct map to group key with its key->key_idx, so
0013      * driver should use cam entries after 4 to install pairwise key
0014      */
0015     if (sec->default_key_search)
0016         return find_next_zero_bit(sec->cam_map, RTW_MAX_SEC_CAM_NUM,
0017                       RTW_SEC_DEFAULT_KEY_NUM);
0018 
0019     return find_first_zero_bit(sec->cam_map, RTW_MAX_SEC_CAM_NUM);
0020 }
0021 
0022 void rtw_sec_write_cam(struct rtw_dev *rtwdev,
0023                struct rtw_sec_desc *sec,
0024                struct ieee80211_sta *sta,
0025                struct ieee80211_key_conf *key,
0026                u8 hw_key_type, u8 hw_key_idx)
0027 {
0028     struct rtw_cam_entry *cam = &sec->cam_table[hw_key_idx];
0029     u32 write_cmd;
0030     u32 command;
0031     u32 content;
0032     u32 addr;
0033     int i, j;
0034 
0035     set_bit(hw_key_idx, sec->cam_map);
0036     cam->valid = true;
0037     cam->group = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE);
0038     cam->hw_key_type = hw_key_type;
0039     cam->key = key;
0040     if (sta)
0041         ether_addr_copy(cam->addr, sta->addr);
0042     else
0043         eth_broadcast_addr(cam->addr);
0044 
0045     write_cmd = RTW_SEC_CMD_WRITE_ENABLE | RTW_SEC_CMD_POLLING;
0046     addr = hw_key_idx << RTW_SEC_CAM_ENTRY_SHIFT;
0047     for (i = 7; i >= 0; i--) {
0048         switch (i) {
0049         case 0:
0050             content = ((key->keyidx & 0x3))     |
0051                   ((hw_key_type & 0x7)  << 2)   |
0052                   (cam->group       << 6)   |
0053                   (cam->valid       << 15)  |
0054                   (cam->addr[0]     << 16)  |
0055                   (cam->addr[1]     << 24);
0056             break;
0057         case 1:
0058             content = (cam->addr[2])        |
0059                   (cam->addr[3]     << 8)   |
0060                   (cam->addr[4]     << 16)  |
0061                   (cam->addr[5]     << 24);
0062             break;
0063         case 6:
0064         case 7:
0065             content = 0;
0066             break;
0067         default:
0068             j = (i - 2) << 2;
0069             content = (key->key[j])         |
0070                   (key->key[j + 1]  << 8)   |
0071                   (key->key[j + 2]  << 16)  |
0072                   (key->key[j + 3]  << 24);
0073             break;
0074         }
0075 
0076         command = write_cmd | (addr + i);
0077         rtw_write32(rtwdev, RTW_SEC_WRITE_REG, content);
0078         rtw_write32(rtwdev, RTW_SEC_CMD_REG, command);
0079     }
0080 }
0081 
0082 void rtw_sec_clear_cam(struct rtw_dev *rtwdev,
0083                struct rtw_sec_desc *sec,
0084                u8 hw_key_idx)
0085 {
0086     struct rtw_cam_entry *cam = &sec->cam_table[hw_key_idx];
0087     u32 write_cmd;
0088     u32 command;
0089     u32 addr;
0090 
0091     clear_bit(hw_key_idx, sec->cam_map);
0092     cam->valid = false;
0093     cam->key = NULL;
0094     eth_zero_addr(cam->addr);
0095 
0096     write_cmd = RTW_SEC_CMD_WRITE_ENABLE | RTW_SEC_CMD_POLLING;
0097     addr = hw_key_idx << RTW_SEC_CAM_ENTRY_SHIFT;
0098     command = write_cmd | addr;
0099     rtw_write32(rtwdev, RTW_SEC_WRITE_REG, 0);
0100     rtw_write32(rtwdev, RTW_SEC_CMD_REG, command);
0101 }
0102 
0103 u8 rtw_sec_cam_pg_backup(struct rtw_dev *rtwdev, u8 *used_cam)
0104 {
0105     struct rtw_sec_desc *sec = &rtwdev->sec;
0106     u8 offset = 0;
0107     u8 count, n;
0108 
0109     if (!used_cam)
0110         return 0;
0111 
0112     for (count = 0; count < MAX_PG_CAM_BACKUP_NUM; count++) {
0113         n = find_next_bit(sec->cam_map, RTW_MAX_SEC_CAM_NUM, offset);
0114         if (n == RTW_MAX_SEC_CAM_NUM)
0115             break;
0116 
0117         used_cam[count] = n;
0118         offset = n + 1;
0119     }
0120 
0121     return count;
0122 }
0123 
0124 void rtw_sec_enable_sec_engine(struct rtw_dev *rtwdev)
0125 {
0126     struct rtw_sec_desc *sec = &rtwdev->sec;
0127     u16 ctrl_reg;
0128     u16 sec_config;
0129 
0130     /* default use default key search for now */
0131     sec->default_key_search = true;
0132 
0133     ctrl_reg = rtw_read16(rtwdev, REG_CR);
0134     ctrl_reg |= RTW_SEC_ENGINE_EN;
0135     rtw_write16(rtwdev, REG_CR, ctrl_reg);
0136 
0137     sec_config = rtw_read16(rtwdev, RTW_SEC_CONFIG);
0138 
0139     sec_config |= RTW_SEC_TX_DEC_EN | RTW_SEC_RX_DEC_EN;
0140     if (sec->default_key_search)
0141         sec_config |= RTW_SEC_TX_UNI_USE_DK | RTW_SEC_RX_UNI_USE_DK |
0142                   RTW_SEC_TX_BC_USE_DK | RTW_SEC_RX_BC_USE_DK;
0143 
0144     rtw_write16(rtwdev, RTW_SEC_CONFIG, sec_config);
0145 }