0001
0002
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
0012
0013
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
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 }