mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-18 18:23:53 +08:00
e3037485c6
This is a new mac80211 driver for Realtek 802.11ac wireless network chips. rtw88 now supports RTL8822BE/RTL8822CE now, with basic station mode functionalities. The firmware for both can be found at linux-firmware. https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git For RTL8822BE: rtw88/rtw8822b_fw.bin For RTL8822CE: rtw88/rtw8822c_fw.bin And for now, only PCI buses (RTL8xxxE) are supported. We will add support for USB and SDIO in the future. The bus interface abstraction can be seen in this driver such as hci.h. Most of the hardware setting are the same except for some TRX path or probing setup should be separated. Supported: * Basic STA/AP/ADHOC mode, and TDLS (STA is well tested) Missing feature: * WOW/PNO * USB & SDIO bus (such as RTL8xxxU/RTL8xxxS) * BT coexistence (8822B/8822C are combo ICs) * Multiple interfaces (for now single STA is better supported) * Dynamic hardware calibrations (to improve/stabilize performance) Potential problems: * static calibration spends too much time, and it is painful for driver to leave IDLE state. And slows down associate process. But reload function are under development, will be added soon! * TRX statictics misleading, as we are not reporting status correctly, or say, not reporting for "every" packet. The next patch set should have BT coexistence code since RTL8822B/C are combo ICs, and the driver for BT can be found after Linux Kernel v4.20. So it is better to add it first to make WiFi + BT work concurrently. Although now rtw88 is simple but we are developing more features for it. Even we want to add support for more chips such as RTL8821C/RTL8814B. Finally, rtw88 has many authors, listed alphabetically: Ping-Ke Shih <pkshih@realtek.com> Tzu-En Huang <tehuang@realtek.com> Yan-Hsuan Chuang <yhchuang@realtek.com> Reviewed-by: Stanislaw Gruszka <sgruszka@redhat.com> Reviewed-by: Brian Norris <briannorris@chromium.org> Tested-by: Brian Norris <briannorris@chromium.org> Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
121 lines
3.1 KiB
C
121 lines
3.1 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 = 5; 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;
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|