summaryrefslogtreecommitdiff
path: root/Kernel/Net/RTL8168NetworkAdapter.cpp
diff options
context:
space:
mode:
authorLuke <luke.wilde@live.co.uk>2021-06-04 01:31:00 +0300
committerAndreas Kling <kling@serenityos.org>2021-06-10 21:54:51 +0200
commitd2f14764284d9dfc7a7d377021cd1a6c9c1fafa5 (patch)
treedee92ce13db032840c8c11f87ea0dab3ad116d89 /Kernel/Net/RTL8168NetworkAdapter.cpp
parenta898e01d4dc93e281196971000b110d264351919 (diff)
downloadserenity-d2f14764284d9dfc7a7d377021cd1a6c9c1fafa5.zip
Kernel: Add support for the RTL8168E-VL variant to the RTL8168 driver
Specifically chip version 17.
Diffstat (limited to 'Kernel/Net/RTL8168NetworkAdapter.cpp')
-rw-r--r--Kernel/Net/RTL8168NetworkAdapter.cpp166
1 files changed, 162 insertions, 4 deletions
diff --git a/Kernel/Net/RTL8168NetworkAdapter.cpp b/Kernel/Net/RTL8168NetworkAdapter.cpp
index ee1b13e9fe..3432ad7403 100644
--- a/Kernel/Net/RTL8168NetworkAdapter.cpp
+++ b/Kernel/Net/RTL8168NetworkAdapter.cpp
@@ -107,6 +107,7 @@ namespace Kernel {
#define CFG3_READY_TO_L23 0x2
#define CFG5_ASPM_ENABLE 0x1
+#define CFG5_SPI_ENABLE 0x8
#define PHY_LINK_STATUS 0x2
@@ -167,6 +168,7 @@ namespace Kernel {
#define MTPS_JUMBO 0x3F
#define MISC_RXDV_GATE_ENABLE 0x80000
+#define MISC_PWM_ENABLE 0x400000
#define MISC2_PFM_D3COLD_ENABLE 0x40
@@ -197,7 +199,7 @@ UNMAP_AFTER_INIT RTL8168NetworkAdapter::RTL8168NetworkAdapter(PCI::Address addre
identify_chip_version();
dmesgln("RTL8168: Version detected - {} ({}{})", possible_device_name(), (u8)m_version, m_version_uncertain ? "?" : "");
- if (m_version == ChipVersion::Unknown || m_version >= ChipVersion::Version4) {
+ if (m_version == ChipVersion::Unknown || (m_version >= ChipVersion::Version4 && m_version <= ChipVersion::Version16) || m_version >= ChipVersion::Version18) {
dmesgln("RTL8168: Aborting initialization! Support for your chip version ({}) is not implemented yet, please open a GH issue and include this message.", (u8)m_version);
return; // Each ChipVersion requires a specific implementation of configure_phy and hardware_quirks
}
@@ -384,8 +386,10 @@ void RTL8168NetworkAdapter::configure_phy()
TODO();
case ChipVersion::Version16:
TODO();
- case ChipVersion::Version17:
- TODO();
+ case ChipVersion::Version17: {
+ configure_phy_e_2();
+ return;
+ }
case ChipVersion::Version18:
TODO();
case ChipVersion::Version19:
@@ -445,6 +449,93 @@ void RTL8168NetworkAdapter::configure_phy_b_2()
phy_out_batch(phy_registers, 3);
}
+void RTL8168NetworkAdapter::configure_phy_e_2()
+{
+ // FIXME: linux's driver writes a firmware blob to the device at this point, is this needed?
+
+ constexpr PhyRegister phy_registers[] = {
+ // Enable delay cap
+ { 0x1f, 0x4 },
+ { 0x1f, 0x7 },
+ { 0x1e, 0xac },
+ { 0x18, 0x6 },
+ { 0x1f, 0x2 },
+ { 0x1f, 0 },
+ { 0x1f, 0 },
+
+ // Channel estimation fine tune
+ { 0x1f, 0x3 },
+ { 0x9, 0xa20f },
+ { 0x1f, 0 },
+ { 0x1f, 0 },
+
+ // Green Setting
+ { 0x1f, 0x5 },
+ { 0x5, 0x8b5b },
+ { 0x6, 0x9222 },
+ { 0x5, 0x8b6d },
+ { 0x6, 0x8000 },
+ { 0x5, 0x8b76 },
+ { 0x6, 0x8000 },
+ { 0x1f, 0 },
+ };
+
+ phy_out_batch(phy_registers, 19);
+
+ // 4 corner performance improvement
+ phy_out(0x1f, 0x5);
+ phy_out(0x5, 0x8b80);
+ phy_update(0x17, 0x6, 0);
+ phy_out(0x1f, 0);
+
+ // PHY auto speed down
+ phy_out(0x1f, 0x4);
+ phy_out(0x1f, 0x7);
+ phy_out(0x1e, 0x2d);
+ phy_update(0x18, 0x10, 0);
+ phy_out(0x1f, 0x2);
+ phy_out(0x1f, 0);
+ phy_update(0x14, 0x8000, 0);
+
+ // Improve 10M EEE waveform
+ phy_out(0x1f, 0x5);
+ phy_out(0x5, 0x8b86);
+ phy_update(0x6, 0x1, 0);
+ phy_out(0x1f, 0);
+
+ // Improve 2-pair detection performance
+ phy_out(0x1f, 0x5);
+ phy_out(0x5, 0x8b85);
+ phy_update(0x6, 0x4000, 0);
+ phy_out(0x1f, 0);
+
+ // EEE Setting
+ eri_update(0x1b0, ERI_MASK_1111, 0, 0x3, ERI_EXGMAC);
+ phy_out(0x1f, 0x5);
+ phy_out(0x5, 0x8b85);
+ phy_update(0x6, 0, 0x2000);
+ phy_out(0x1f, 0x4);
+ phy_out(0x1f, 0x7);
+ phy_out(0x1e, 0x20);
+ phy_update(0x15, 0, 0x100);
+ phy_out(0x1f, 0x2);
+ phy_out(0x1f, 0);
+ phy_out(0xd, 0x7);
+ phy_out(0xe, 0x3c);
+ phy_out(0xd, 0x4007);
+ phy_out(0xe, 0);
+ phy_out(0xd, 0);
+
+ // Green feature
+ phy_out(0x1f, 0x3);
+ phy_update(0x19, 0, 0x1);
+ phy_update(0x10, 0, 0x400);
+ phy_out(0x1f, 0);
+
+ // Broken BIOS workaround: feed GigaMAC registers with MAC address.
+ rar_exgmac_set();
+}
+
void RTL8168NetworkAdapter::configure_phy_h_1()
{
// FIXME: linux's driver writes a firmware blob to the device at this point, is this needed?
@@ -620,6 +711,25 @@ void RTL8168NetworkAdapter::configure_phy_h_2()
phy_out(0x1f, 0);
}
+void RTL8168NetworkAdapter::rar_exgmac_set()
+{
+ auto mac = mac_address();
+ const u16 w[] = {
+ (u16)(mac[0] | (mac[1] << 8)),
+ (u16)(mac[2] | (mac[3] << 8)),
+ (u16)(mac[4] | (mac[5] << 8)),
+ };
+
+ const ExgMacRegister exg_mac_registers[] = {
+ { 0xe0, ERI_MASK_1111, (u32)(w[0] | (w[1] << 16)) },
+ { 0xe4, ERI_MASK_1111, (u32)w[2] },
+ { 0xf0, ERI_MASK_1111, (u32)(w[0] << 16) },
+ { 0xf4, ERI_MASK_1111, (u32)(w[1] | (w[2] << 16)) },
+ };
+
+ exgmac_out_batch(exg_mac_registers, 4);
+}
+
void RTL8168NetworkAdapter::start_hardware()
{
@@ -709,7 +819,8 @@ void RTL8168NetworkAdapter::hardware_quirks()
case ChipVersion::Version16:
TODO();
case ChipVersion::Version17:
- TODO();
+ hardware_quirks_e_2();
+ return;
case ChipVersion::Version18:
TODO();
case ChipVersion::Version19:
@@ -760,6 +871,46 @@ void RTL8168NetworkAdapter::hardware_quirks_b_2()
out8(REG_CONFIG4, in8(REG_CONFIG4) & ~1);
}
+void RTL8168NetworkAdapter::hardware_quirks_e_2()
+{
+ constexpr EPhyUpdate ephy_info[] = {
+ { 0x9, 0, 0x80 },
+ { 0x19, 0, 0x224 },
+ };
+
+ csi_enable(CSI_ACCESS_1);
+
+ extended_phy_initialize(ephy_info, 2);
+
+ // FIXME: MTU performance tweak
+
+ eri_out(0xc0, ERI_MASK_0011, 0, ERI_EXGMAC);
+ eri_out(0xb8, ERI_MASK_0011, 0, ERI_EXGMAC);
+ eri_out(0xc8, ERI_MASK_1111, 0x100002, ERI_EXGMAC);
+ eri_out(0xe8, ERI_MASK_1111, 0x100006, ERI_EXGMAC);
+ eri_out(0xcc, ERI_MASK_1111, 0x50, ERI_EXGMAC);
+ eri_out(0xd0, ERI_MASK_1111, 0x7ff0060, ERI_EXGMAC);
+ eri_update(0x1b0, ERI_MASK_0001, 0x10, 0, ERI_EXGMAC);
+ eri_update(0xd4, ERI_MASK_0011, 0xc00, 0xff00, ERI_EXGMAC);
+
+ // Set early TX
+ out8(REG_MTPS, 0x27);
+
+ // FIXME: Disable PCIe clock request
+
+ // enable tx auto fifo
+ out32(REG_TXCFG, in32(REG_TXCFG) | TXCFG_AUTO_FIFO);
+
+ out8(REG_MCU, in8(REG_MCU) & ~MCU_NOW_IS_OOB);
+
+ // Set EEE LED frequency
+ out8(REG_EEE_LED, in8(REG_EEE_LED) & ~0x7);
+
+ out8(REG_DLLPR, in8(REG_DLLPR) | DLLPR_PFM_ENABLE);
+ out32(REG_MISC, in32(REG_MISC) | MISC_PWM_ENABLE);
+ out8(REG_CONFIG5, in8(REG_CONFIG5) & ~CFG5_SPI_ENABLE);
+}
+
void RTL8168NetworkAdapter::hardware_quirks_h()
{
// disable aspm and clock request before accessing extended phy
@@ -1189,6 +1340,13 @@ void RTL8168NetworkAdapter::eri_update(u32 address, u32 mask, u32 set, u32 clear
eri_out(address, mask, (value & ~clear) | set, type);
}
+void RTL8168NetworkAdapter::exgmac_out_batch(const ExgMacRegister exgmac_registers[], size_t length)
+{
+ for (size_t i = 0; i < length; i++) {
+ eri_out(exgmac_registers[i].address, exgmac_registers[i].mask, exgmac_registers[i].value, ERI_EXGMAC);
+ }
+}
+
void RTL8168NetworkAdapter::csi_out(u32 address, u32 data)
{
VERIFY(m_version >= ChipVersion::Version4);