mirror of
https://github.com/opnsense/src.git
synced 2026-06-04 06:15:33 -04:00
Import rtw88 based on wireless-testing at 5d5d68bcff1f7ff27ba0b938a4df5849849b47e3 with adjustments for FreeBSD. While our version of the driver has knowledge about the incapablity of DMA above 4GB we do see errors if people have more than that often already showing when laoding firmware. The problem for that is currently believed to be outside this driver so importing it anyway for now. Given the lack of full license texts on non-local files this is imported under the draft policy for handling SPDX files (D29226). [1] Approved by: core (imp) [1] MFC after: 2 weeks
145 lines
3.5 KiB
C
145 lines
3.5 KiB
C
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
|
/* Copyright(c) 2018-2019 Realtek Corporation
|
|
*/
|
|
|
|
#include "main.h"
|
|
#include "sec.h"
|
|
#include "reg.h"
|
|
|
|
int rtw_sec_get_free_cam(struct rtw_sec_desc *sec)
|
|
{
|
|
/* if default key search is enabled, the first 4 cam entries
|
|
* are used to direct map to group key with its key->key_idx, so
|
|
* driver should use cam entries after 4 to install pairwise key
|
|
*/
|
|
if (sec->default_key_search)
|
|
return find_next_zero_bit(sec->cam_map, RTW_MAX_SEC_CAM_NUM,
|
|
RTW_SEC_DEFAULT_KEY_NUM);
|
|
|
|
return find_first_zero_bit(sec->cam_map, RTW_MAX_SEC_CAM_NUM);
|
|
}
|
|
|
|
void rtw_sec_write_cam(struct rtw_dev *rtwdev,
|
|
struct rtw_sec_desc *sec,
|
|
struct ieee80211_sta *sta,
|
|
struct ieee80211_key_conf *key,
|
|
u8 hw_key_type, u8 hw_key_idx)
|
|
{
|
|
struct rtw_cam_entry *cam = &sec->cam_table[hw_key_idx];
|
|
u32 write_cmd;
|
|
u32 command;
|
|
u32 content;
|
|
u32 addr;
|
|
int i, j;
|
|
|
|
set_bit(hw_key_idx, sec->cam_map);
|
|
cam->valid = true;
|
|
cam->group = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE);
|
|
cam->hw_key_type = hw_key_type;
|
|
cam->key = key;
|
|
if (sta)
|
|
ether_addr_copy(cam->addr, sta->addr);
|
|
else
|
|
eth_broadcast_addr(cam->addr);
|
|
|
|
write_cmd = RTW_SEC_CMD_WRITE_ENABLE | RTW_SEC_CMD_POLLING;
|
|
addr = hw_key_idx << RTW_SEC_CAM_ENTRY_SHIFT;
|
|
for (i = 7; i >= 0; i--) {
|
|
switch (i) {
|
|
case 0:
|
|
content = ((key->keyidx & 0x3)) |
|
|
((hw_key_type & 0x7) << 2) |
|
|
(cam->group << 6) |
|
|
(cam->valid << 15) |
|
|
(cam->addr[0] << 16) |
|
|
(cam->addr[1] << 24);
|
|
break;
|
|
case 1:
|
|
content = (cam->addr[2]) |
|
|
(cam->addr[3] << 8) |
|
|
(cam->addr[4] << 16) |
|
|
(cam->addr[5] << 24);
|
|
break;
|
|
case 6:
|
|
case 7:
|
|
content = 0;
|
|
break;
|
|
default:
|
|
j = (i - 2) << 2;
|
|
content = (key->key[j]) |
|
|
(key->key[j + 1] << 8) |
|
|
(key->key[j + 2] << 16) |
|
|
(key->key[j + 3] << 24);
|
|
break;
|
|
}
|
|
|
|
command = write_cmd | (addr + i);
|
|
rtw_write32(rtwdev, RTW_SEC_WRITE_REG, content);
|
|
rtw_write32(rtwdev, RTW_SEC_CMD_REG, command);
|
|
}
|
|
}
|
|
|
|
void rtw_sec_clear_cam(struct rtw_dev *rtwdev,
|
|
struct rtw_sec_desc *sec,
|
|
u8 hw_key_idx)
|
|
{
|
|
struct rtw_cam_entry *cam = &sec->cam_table[hw_key_idx];
|
|
u32 write_cmd;
|
|
u32 command;
|
|
u32 addr;
|
|
|
|
clear_bit(hw_key_idx, sec->cam_map);
|
|
cam->valid = false;
|
|
cam->key = NULL;
|
|
eth_zero_addr(cam->addr);
|
|
|
|
write_cmd = RTW_SEC_CMD_WRITE_ENABLE | RTW_SEC_CMD_POLLING;
|
|
addr = hw_key_idx << RTW_SEC_CAM_ENTRY_SHIFT;
|
|
command = write_cmd | addr;
|
|
rtw_write32(rtwdev, RTW_SEC_WRITE_REG, 0);
|
|
rtw_write32(rtwdev, RTW_SEC_CMD_REG, command);
|
|
}
|
|
|
|
u8 rtw_sec_cam_pg_backup(struct rtw_dev *rtwdev, u8 *used_cam)
|
|
{
|
|
struct rtw_sec_desc *sec = &rtwdev->sec;
|
|
u8 offset = 0;
|
|
u8 count, n;
|
|
|
|
if (!used_cam)
|
|
return 0;
|
|
|
|
for (count = 0; count < MAX_PG_CAM_BACKUP_NUM; count++) {
|
|
n = find_next_bit(sec->cam_map, RTW_MAX_SEC_CAM_NUM, offset);
|
|
if (n == RTW_MAX_SEC_CAM_NUM)
|
|
break;
|
|
|
|
used_cam[count] = n;
|
|
offset = n + 1;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
void rtw_sec_enable_sec_engine(struct rtw_dev *rtwdev)
|
|
{
|
|
struct rtw_sec_desc *sec = &rtwdev->sec;
|
|
u16 ctrl_reg;
|
|
u16 sec_config;
|
|
|
|
/* default use default key search for now */
|
|
sec->default_key_search = true;
|
|
|
|
ctrl_reg = rtw_read16(rtwdev, REG_CR);
|
|
ctrl_reg |= RTW_SEC_ENGINE_EN;
|
|
rtw_write16(rtwdev, REG_CR, ctrl_reg);
|
|
|
|
sec_config = rtw_read16(rtwdev, RTW_SEC_CONFIG);
|
|
|
|
sec_config |= RTW_SEC_TX_DEC_EN | RTW_SEC_RX_DEC_EN;
|
|
if (sec->default_key_search)
|
|
sec_config |= RTW_SEC_TX_UNI_USE_DK | RTW_SEC_RX_UNI_USE_DK |
|
|
RTW_SEC_TX_BC_USE_DK | RTW_SEC_RX_BC_USE_DK;
|
|
|
|
rtw_write16(rtwdev, RTW_SEC_CONFIG, sec_config);
|
|
}
|