Serenity Operating System
at master 1713 lines 54 kB view raw
1/* 2 * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/MACAddress.h> 8#include <Kernel/Bus/PCI/API.h> 9#include <Kernel/Bus/PCI/IDs.h> 10#include <Kernel/Debug.h> 11#include <Kernel/Net/NetworkingManagement.h> 12#include <Kernel/Net/Realtek/RTL8168NetworkAdapter.h> 13#include <Kernel/Sections.h> 14 15namespace Kernel { 16 17#define REG_MAC 0x00 18#define REG_MAR4 0x0B 19#define REG_MAR0 0x0F 20#define REG_EEE_LED 0x1B 21#define REG_TXADDR 0x20 22#define REG_COMMAND 0x37 23#define REG_TXSTART 0x38 24#define REG_IMR 0x3C 25#define REG_ISR 0x3E 26#define REG_TXCFG 0x40 27#define REG_RXCFG 0x44 28#define REG_MPC 0x4C 29#define REG_CFG9346 0x50 30#define REG_CONFIG1 0x52 31#define REG_CONFIG2 0x53 32#define REG_CONFIG3 0x54 33#define REG_CONFIG4 0x55 34#define REG_CONFIG5 0x56 35#define REG_MULTIINTR 0x5C 36#define REG_PHYACCESS 0x60 37#define REG_CSI_DATA 0x64 38#define REG_CSI_ADDR 0x68 39#define REG_PHYSTATUS 0x6C 40#define REG_PMCH 0x6F 41#define REG_ERI_DATA 0x70 42#define REG_ERI_ADDR 0x74 43#define REG_EPHYACCESS 0x80 44#define REG_OCP_DATA 0xB0 45#define REG_OCP_ADDR 0xB4 46#define REG_GPHY_OCP 0xB8 47#define REG_DLLPR 0xD0 48#define REG_MCU 0xD3 49#define REG_RMS 0xDA 50#define REG_CPLUS_COMMAND 0xE0 51#define REG_INT_MOD 0xE2 52#define REG_RXADDR 0xE4 53#define REG_MTPS 0xEC 54#define REG_MISC 0xF0 55#define REG_MISC2 0xF2 56#define REG_IBCR0 0xF8 57#define REG_IBCR2 0xF9 58#define REG_IBISR0 0xFB 59 60#define COMMAND_TX_ENABLE 0x4 61#define COMMAND_RX_ENABLE 0x8 62#define COMMAND_RESET 0x10 63 64#define CPLUS_COMMAND_VERIFY_CHECKSUM 0x20 65#define CPLUS_COMMAND_VLAN_STRIP 0x40 66#define CPLUS_COMMAND_MAC_DBGO_SEL 0x1C 67#define CPLUS_COMMAND_PACKET_CONTROL_DISABLE 0x80 68#define CPLUS_COMMAND_ASF 0x100 69#define CPLUS_COMMAND_CXPL_DBG_SEL 0x200 70#define CPLUS_COMMAND_FORCE_TXFLOW_ENABLE 0x400 71#define CPLUS_COMMAND_FORCE_RXFLOW_ENABLE 0x800 72#define CPLUS_COMMAND_FORCE_HALF_DUP 0x1000 73#define CPLUS_COMMAND_MAC_DBGO_OE 0x4000 74#define CPLUS_COMMAND_ENABLE_BIST 0x8000 75 76#define INT_RXOK 0x1 77#define INT_RXERR 0x2 78#define INT_TXOK 0x4 79#define INT_TXERR 0x8 80#define INT_RX_OVERFLOW 0x10 81#define INT_LINK_CHANGE 0x20 82#define INT_RX_FIFO_OVERFLOW 0x40 83#define INT_SYS_ERR 0x8000 84 85#define CFG9346_NONE 0x00 86#define CFG9346_EEM0 0x40 87#define CFG9346_EEM1 0x80 88#define CFG9346_UNLOCK (CFG9346_EEM0 | CFG9346_EEM1) 89 90#define TXCFG_AUTO_FIFO 0x80 91#define TXCFG_MAX_DMA_UNLIMITED 0x700 92#define TXCFG_EMPTY 0x800 93#define TXCFG_IFG011 0x3000000 94 95#define RXCFG_READ_MASK 0x3F 96 97#define RXCFG_APM 0x2 98#define RXCFG_AM 0x4 99#define RXCFG_AB 0x8 100#define RXCFG_MAX_DMA_UNLIMITED 0x700 101#define RXCFG_EARLY_OFF_V2 0x800 102#define RXCFG_FTH_NONE 0xE000 103#define RXCFG_MULTI_ENABLE 0x4000 104#define RXCFG_128INT_ENABLE 0x8000 105 106#define CFG2_CLOCK_REQUEST_ENABLE 0x80 107 108#define CFG3_BEACON_ENABLE 0x1 109#define CFG3_READY_TO_L23 0x2 110 111#define CFG5_ASPM_ENABLE 0x1 112#define CFG5_SPI_ENABLE 0x8 113 114#define PHY_LINK_STATUS 0x2 115 116#define PHY_FLAG 0x80000000 117#define PHY_REG_BMCR 0x00 118#define PHY_REG_ANAR 0x4 119#define PHY_REG_GBCR 0x9 120 121#define CSI_FLAG 0x80000000 122#define CSI_BYTE_ENABLE 0xF000 123#define CSI_FUNC_NIC 0x20000 124#define CSI_FUNC_NIC2 0x10000 125 126#define CSI_ACCESS_1 0x17000000 127#define CSI_ACCESS_2 0x27000000 128 129#define EPHY_FLAG 0x80000000 130 131#define ERI_FLAG 0x80000000 132#define ERI_MASK_0001 0x1000 133#define ERI_MASK_0011 0x3000 134#define ERI_MASK_0100 0x4000 135#define ERI_MASK_0101 0x5000 136#define ERI_MASK_1111 0xF000 137 138#define ERI_EXGMAC 0x0 139 140#define OCP_FLAG 0x80000000 141#define OCP_STANDARD_PHY_BASE 0xa400 142 143#define TXSTART_START 0x40 144 145#define BMCR_RESET 0x8000 146#define BMCR_SPEED_0 0x2000 147#define BMCR_AUTO_NEGOTIATE 0x1000 148#define BMCR_RESTART_AUTO_NEGOTIATE 0x200 149#define BMCR_DUPLEX 0x100 150#define BMCR_SPEED_1 0x40 151 152#define ADVERTISE_10_HALF 0x20 153#define ADVERTISE_10_FULL 0x40 154#define ADVERTISE_100_HALF 0x80 155#define ADVERTISE_100_FULL 0x100 156#define ADVERTISE_PAUSE_CAP 0x400 157#define ADVERTISE_PAUSE_ASYM 0x800 158 159#define ADVERTISE_1000_HALF 0x100 160#define ADVERTISE_1000_FULL 0x200 161 162#define DLLPR_PFM_ENABLE 0x40 163#define DLLPR_TX_10M_PS_ENABLE 0x80 164 165#define MCU_LINK_LIST_READY 0x2 166#define MCU_RX_EMPTY 0x10 167#define MCU_TX_EMPTY 0x20 168#define MCU_NOW_IS_OOB 0x80 169 170#define MTPS_JUMBO 0x3F 171 172#define MISC_RXDV_GATE_ENABLE 0x80000 173#define MISC_PWM_ENABLE 0x400000 174 175#define MISC2_PFM_D3COLD_ENABLE 0x40 176 177#define PHYSTATUS_FULLDUP 0x01 178#define PHYSTATUS_1000MF 0x10 179#define PHYSTATUS_100M 0x08 180#define PHYSTATUS_10M 0x04 181 182#define TX_BUFFER_SIZE 0x1FF8 183#define RX_BUFFER_SIZE 0x1FF8 // FIXME: this should be increased (0x3FFF) 184 185UNMAP_AFTER_INIT ErrorOr<bool> RTL8168NetworkAdapter::probe(PCI::DeviceIdentifier const& pci_device_identifier) 186{ 187 if (pci_device_identifier.hardware_id().vendor_id != PCI::VendorID::Realtek) 188 return false; 189 if (pci_device_identifier.hardware_id().device_id != 0x8168) 190 return false; 191 return true; 192} 193 194UNMAP_AFTER_INIT ErrorOr<NonnullLockRefPtr<NetworkAdapter>> RTL8168NetworkAdapter::create(PCI::DeviceIdentifier const& pci_device_identifier) 195{ 196 u8 irq = pci_device_identifier.interrupt_line().value(); 197 auto interface_name = TRY(NetworkingManagement::generate_interface_name_from_pci_address(pci_device_identifier)); 198 auto registers_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_device_identifier, PCI::HeaderType0BaseRegister::BAR0)); 199 return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) RTL8168NetworkAdapter(pci_device_identifier, irq, move(registers_io_window), move(interface_name)))); 200} 201 202bool RTL8168NetworkAdapter::determine_supported_version() const 203{ 204 switch (m_version) { 205 case ChipVersion::Version1: 206 case ChipVersion::Version2: 207 case ChipVersion::Version3: 208 return true; 209 case ChipVersion::Version4: 210 case ChipVersion::Version5: 211 case ChipVersion::Version6: 212 case ChipVersion::Version7: 213 case ChipVersion::Version8: 214 case ChipVersion::Version9: 215 case ChipVersion::Version10: 216 case ChipVersion::Version11: 217 case ChipVersion::Version12: 218 case ChipVersion::Version13: 219 case ChipVersion::Version14: 220 return false; 221 case ChipVersion::Version15: 222 return true; 223 case ChipVersion::Version16: 224 return false; 225 case ChipVersion::Version17: 226 return true; 227 case ChipVersion::Version18: 228 case ChipVersion::Version19: 229 case ChipVersion::Version20: 230 case ChipVersion::Version21: 231 case ChipVersion::Version22: 232 case ChipVersion::Version23: 233 case ChipVersion::Version24: 234 case ChipVersion::Version25: 235 case ChipVersion::Version26: 236 case ChipVersion::Version27: 237 case ChipVersion::Version28: 238 case ChipVersion::Version29: 239 return false; 240 case ChipVersion::Version30: 241 return true; 242 default: 243 return false; 244 } 245} 246 247UNMAP_AFTER_INIT RTL8168NetworkAdapter::RTL8168NetworkAdapter(PCI::DeviceIdentifier const& device_identifier, u8 irq, NonnullOwnPtr<IOWindow> registers_io_window, NonnullOwnPtr<KString> interface_name) 248 : NetworkAdapter(move(interface_name)) 249 , PCI::Device(device_identifier) 250 , IRQHandler(irq) 251 , m_registers_io_window(move(registers_io_window)) 252 , m_rx_descriptors_region(MM.allocate_contiguous_kernel_region(Memory::page_round_up(sizeof(TXDescriptor) * (number_of_rx_descriptors + 1)).release_value_but_fixme_should_propagate_errors(), "RTL8168 RX"sv, Memory::Region::Access::ReadWrite).release_value()) 253 , m_tx_descriptors_region(MM.allocate_contiguous_kernel_region(Memory::page_round_up(sizeof(RXDescriptor) * (number_of_tx_descriptors + 1)).release_value_but_fixme_should_propagate_errors(), "RTL8168 TX"sv, Memory::Region::Access::ReadWrite).release_value()) 254{ 255 dmesgln_pci(*this, "Found @ {}", device_identifier.address()); 256 dmesgln_pci(*this, "I/O port base: {}", m_registers_io_window); 257} 258 259UNMAP_AFTER_INIT ErrorOr<void> RTL8168NetworkAdapter::initialize(Badge<NetworkingManagement>) 260{ 261 identify_chip_version(); 262 dmesgln_pci(*this, "Version detected - {} ({}{})", possible_device_name(), (u8)m_version, m_version_uncertain ? "?" : ""); 263 264 if (!determine_supported_version()) { 265 dmesgln_pci(*this, "Aborting initialization! Support for your chip version ({}) is not implemented yet, please open a GH issue and include this message.", (u8)m_version); 266 return Error::from_errno(ENODEV); // Each ChipVersion requires a specific implementation of configure_phy and hardware_quirks 267 } 268 // set initial REG_RXCFG 269 auto rx_config = RXCFG_MAX_DMA_UNLIMITED; 270 if (m_version <= ChipVersion::Version3) { 271 rx_config |= RXCFG_FTH_NONE; 272 } else if (m_version <= ChipVersion::Version8 || (m_version >= ChipVersion::Version16 && m_version <= ChipVersion::Version19)) { 273 rx_config |= RXCFG_128INT_ENABLE | RXCFG_MULTI_ENABLE; 274 } else if (m_version >= ChipVersion::Version21) { 275 rx_config |= RXCFG_128INT_ENABLE | RXCFG_MULTI_ENABLE | RXCFG_EARLY_OFF_V2; 276 } else { 277 rx_config |= RXCFG_128INT_ENABLE; 278 } 279 out32(REG_RXCFG, rx_config); 280 281 // disable interrupts 282 out16(REG_IMR, 0); 283 284 // initialize hardware 285 if (m_version == ChipVersion::Version23 || m_version == ChipVersion::Version27 || m_version == ChipVersion::Version28) { 286 // disable CMAC 287 out8(REG_IBCR2, in8(REG_IBCR2) & ~1); 288 289 while ((in32(REG_IBISR0) & 0x2) != 0) 290 ; 291 292 out8(REG_IBISR0, in8(REG_IBISR0) | 0x20); 293 out8(REG_IBCR0, in8(REG_IBCR0) & ~1); 294 } 295 if (m_version >= ChipVersion::Version21) { 296 m_ocp_base_address = OCP_STANDARD_PHY_BASE; 297 298 // enable RXDV gate 299 out32(REG_MISC, in32(REG_MISC) | MISC_RXDV_GATE_ENABLE); 300 301 while ((in32(REG_TXCFG) & TXCFG_EMPTY) == 0) 302 ; 303 304 while ((in32(REG_MCU) & (MCU_RX_EMPTY | MCU_TX_EMPTY)) == 0) 305 ; 306 307 out8(REG_COMMAND, in8(REG_COMMAND) & ~(COMMAND_RX_ENABLE | COMMAND_TX_ENABLE)); 308 out8(REG_MCU, in8(REG_MCU) & ~MCU_NOW_IS_OOB); 309 310 // vendor magic values ??? 311 auto data = ocp_in(0xe8de); 312 data &= ~(1 << 14); 313 ocp_out(0xe8de, data); 314 315 while ((in32(REG_MCU) & MCU_LINK_LIST_READY) == 0) 316 ; 317 318 // vendor magic values ??? 319 data = ocp_in(0xe8de); 320 data |= (1 << 15); 321 ocp_out(0xe8de, data); 322 323 while ((in32(REG_MCU) & MCU_LINK_LIST_READY) == 0) 324 ; 325 } 326 327 // software reset 328 reset(); 329 330 // clear interrupts 331 out16(REG_ISR, 0xffff); 332 333 enable_bus_mastering(device_identifier()); 334 335 read_mac_address(); 336 dmesgln_pci(*this, "MAC address: {}", mac_address().to_string()); 337 338 // notify about driver start 339 if (m_version >= ChipVersion::Version11 && m_version <= ChipVersion::Version13) { 340 // if check_dash 341 // notify 342 TODO(); 343 } else if (m_version == ChipVersion::Version23 || m_version == ChipVersion::Version27 || m_version == ChipVersion::Version28) { 344 // if check_dash 345 // notify 346 TODO(); 347 } 348 349 startup(); 350 return {}; 351} 352 353void RTL8168NetworkAdapter::startup() 354{ 355 // initialize descriptors 356 initialize_rx_descriptors(); 357 initialize_tx_descriptors(); 358 359 // register irq 360 enable_irq(); 361 362 // version specific phy configuration 363 configure_phy(); 364 365 // software reset phy 366 phy_out(PHY_REG_BMCR, phy_in(PHY_REG_BMCR) | BMCR_RESET); 367 while ((phy_in(PHY_REG_BMCR) & BMCR_RESET) != 0) 368 ; 369 370 set_phy_speed(); 371 372 // set C+ command 373 auto cplus_command = in16(REG_CPLUS_COMMAND) | CPLUS_COMMAND_VERIFY_CHECKSUM | CPLUS_COMMAND_VLAN_STRIP; 374 out16(REG_CPLUS_COMMAND, cplus_command); 375 in16(REG_CPLUS_COMMAND); // C+ Command barrier 376 377 // power up phy 378 if (m_version >= ChipVersion::Version9 && m_version <= ChipVersion::Version15) { 379 out8(REG_PMCH, in8(REG_PMCH) | 0x80); 380 } else if (m_version >= ChipVersion::Version26) { 381 out8(REG_PMCH, in8(REG_PMCH) | 0xC0); 382 } else if (m_version >= ChipVersion::Version21 && m_version <= ChipVersion::Version23) { 383 out8(REG_PMCH, in8(REG_PMCH) | 0xC0); 384 // vendor magic values ??? 385 eri_update(0x1a8, ERI_MASK_1111, 0xfc000000, 0, ERI_EXGMAC); 386 } 387 388 // wakeup phy (more vendor magic values) 389 phy_out(0x1F, 0); 390 if (m_version <= ChipVersion::Version13) { 391 phy_out(0x0E, 0); 392 } 393 phy_out(PHY_REG_BMCR, BMCR_AUTO_NEGOTIATE); // send known good phy write (acts as a phy barrier) 394 start_hardware(); 395 396 // re-enable interrupts 397 auto enabled_interrupts = INT_RXOK | INT_RXERR | INT_TXOK | INT_TXERR | INT_RX_OVERFLOW | INT_LINK_CHANGE | INT_SYS_ERR; 398 if (m_version == ChipVersion::Version1) { 399 enabled_interrupts |= INT_RX_FIFO_OVERFLOW; 400 enabled_interrupts &= ~INT_RX_OVERFLOW; 401 } 402 out16(REG_IMR, enabled_interrupts); 403 404 // update link status 405 m_link_up = (in8(REG_PHYSTATUS) & PHY_LINK_STATUS) != 0; 406} 407 408void RTL8168NetworkAdapter::configure_phy() 409{ 410 // this method sets a bunch of magic vendor values to the phy configuration registers based on the hardware version 411 switch (m_version) { 412 case ChipVersion::Version1: { 413 configure_phy_b_1(); 414 return; 415 } 416 case ChipVersion::Version2: 417 case ChipVersion::Version3: { 418 configure_phy_b_2(); 419 return; 420 } 421 case ChipVersion::Version4: 422 TODO(); 423 case ChipVersion::Version5: 424 TODO(); 425 case ChipVersion::Version6: 426 TODO(); 427 case ChipVersion::Version7: 428 TODO(); 429 case ChipVersion::Version8: 430 TODO(); 431 case ChipVersion::Version9: 432 TODO(); 433 case ChipVersion::Version10: 434 TODO(); 435 case ChipVersion::Version11: 436 TODO(); 437 case ChipVersion::Version12: 438 TODO(); 439 case ChipVersion::Version13: 440 TODO(); 441 case ChipVersion::Version14: 442 TODO(); 443 case ChipVersion::Version15: { 444 configure_phy_e_2(); 445 return; 446 } 447 case ChipVersion::Version16: 448 TODO(); 449 case ChipVersion::Version17: { 450 configure_phy_e_2(); 451 return; 452 } 453 case ChipVersion::Version18: 454 TODO(); 455 case ChipVersion::Version19: 456 TODO(); 457 case ChipVersion::Version20: 458 TODO(); 459 case ChipVersion::Version21: 460 TODO(); 461 case ChipVersion::Version22: 462 TODO(); 463 case ChipVersion::Version23: 464 TODO(); 465 case ChipVersion::Version24: 466 TODO(); 467 case ChipVersion::Version25: 468 TODO(); 469 case ChipVersion::Version26: 470 TODO(); 471 case ChipVersion::Version27: 472 TODO(); 473 case ChipVersion::Version28: 474 TODO(); 475 case ChipVersion::Version29: { 476 configure_phy_h_1(); 477 return; 478 } 479 case ChipVersion::Version30: { 480 configure_phy_h_2(); 481 return; 482 } 483 default: 484 VERIFY_NOT_REACHED(); 485 } 486} 487 488void RTL8168NetworkAdapter::configure_phy_b_1() 489{ 490 constexpr PhyRegister phy_registers[] = { 491 { 0x10, 0xf41b }, 492 { 0x1f, 0 } 493 }; 494 495 phy_out(0x1f, 0x1); 496 phy_out(0x16, 1 << 0); 497 498 phy_out_batch(phy_registers, 2); 499} 500 501void RTL8168NetworkAdapter::configure_phy_b_2() 502{ 503 constexpr PhyRegister phy_registers[] = { 504 { 0x1f, 0x1 }, 505 { 0x10, 0xf41b }, 506 { 0x1f, 0 } 507 }; 508 509 phy_out_batch(phy_registers, 3); 510} 511 512void RTL8168NetworkAdapter::configure_phy_e_2() 513{ 514 // FIXME: linux's driver writes a firmware blob to the device at this point, is this needed? 515 516 constexpr PhyRegister phy_registers[] = { 517 // Enable delay cap 518 { 0x1f, 0x4 }, 519 { 0x1f, 0x7 }, 520 { 0x1e, 0xac }, 521 { 0x18, 0x6 }, 522 { 0x1f, 0x2 }, 523 { 0x1f, 0 }, 524 { 0x1f, 0 }, 525 526 // Channel estimation fine tune 527 { 0x1f, 0x3 }, 528 { 0x9, 0xa20f }, 529 { 0x1f, 0 }, 530 { 0x1f, 0 }, 531 532 // Green Setting 533 { 0x1f, 0x5 }, 534 { 0x5, 0x8b5b }, 535 { 0x6, 0x9222 }, 536 { 0x5, 0x8b6d }, 537 { 0x6, 0x8000 }, 538 { 0x5, 0x8b76 }, 539 { 0x6, 0x8000 }, 540 { 0x1f, 0 }, 541 }; 542 543 phy_out_batch(phy_registers, 19); 544 545 // 4 corner performance improvement 546 phy_out(0x1f, 0x5); 547 phy_out(0x5, 0x8b80); 548 phy_update(0x17, 0x6, 0); 549 phy_out(0x1f, 0); 550 551 // PHY auto speed down 552 phy_out(0x1f, 0x4); 553 phy_out(0x1f, 0x7); 554 phy_out(0x1e, 0x2d); 555 phy_update(0x18, 0x10, 0); 556 phy_out(0x1f, 0x2); 557 phy_out(0x1f, 0); 558 phy_update(0x14, 0x8000, 0); 559 560 // Improve 10M EEE waveform 561 phy_out(0x1f, 0x5); 562 phy_out(0x5, 0x8b86); 563 phy_update(0x6, 0x1, 0); 564 phy_out(0x1f, 0); 565 566 // Improve 2-pair detection performance 567 phy_out(0x1f, 0x5); 568 phy_out(0x5, 0x8b85); 569 phy_update(0x6, 0x4000, 0); 570 phy_out(0x1f, 0); 571 572 // EEE Setting 573 eri_update(0x1b0, ERI_MASK_1111, 0, 0x3, ERI_EXGMAC); 574 phy_out(0x1f, 0x5); 575 phy_out(0x5, 0x8b85); 576 phy_update(0x6, 0, 0x2000); 577 phy_out(0x1f, 0x4); 578 phy_out(0x1f, 0x7); 579 phy_out(0x1e, 0x20); 580 phy_update(0x15, 0, 0x100); 581 phy_out(0x1f, 0x2); 582 phy_out(0x1f, 0); 583 phy_out(0xd, 0x7); 584 phy_out(0xe, 0x3c); 585 phy_out(0xd, 0x4007); 586 phy_out(0xe, 0); 587 phy_out(0xd, 0); 588 589 // Green feature 590 phy_out(0x1f, 0x3); 591 phy_update(0x19, 0, 0x1); 592 phy_update(0x10, 0, 0x400); 593 phy_out(0x1f, 0); 594 595 // Broken BIOS workaround: feed GigaMAC registers with MAC address. 596 rar_exgmac_set(); 597} 598 599void RTL8168NetworkAdapter::configure_phy_h_1() 600{ 601 // FIXME: linux's driver writes a firmware blob to the device at this point, is this needed? 602 603 // CHN EST parameters adjust - giga master 604 phy_out(0x1f, 0x0a43); 605 phy_out(0x13, 0x809b); 606 phy_update(0x14, 0x8000, 0xf800); 607 phy_out(0x13, 0x80a2); 608 phy_update(0x14, 0x8000, 0xff00); 609 phy_out(0x13, 0x80a4); 610 phy_update(0x14, 0x8500, 0xff00); 611 phy_out(0x13, 0x809c); 612 phy_update(0x14, 0xbd00, 0xff00); 613 phy_out(0x1f, 0); 614 615 // CHN EST parameters adjust - giga slave 616 phy_out(0x1f, 0x0a43); 617 phy_out(0x13, 0x80ad); 618 phy_update(0x14, 0x7000, 0xf800); 619 phy_out(0x13, 0x80b4); 620 phy_update(0x14, 0x5000, 0xff00); 621 phy_out(0x13, 0x80ac); 622 phy_update(0x14, 0x4000, 0xff00); 623 phy_out(0x1f, 0); 624 625 // CHN EST parameters adjust - fnet 626 phy_out(0x1f, 0x0a43); 627 phy_out(0x13, 0x808e); 628 phy_update(0x14, 0x1200, 0xff00); 629 phy_out(0x13, 0x8090); 630 phy_update(0x14, 0xe500, 0xff00); 631 phy_out(0x13, 0x8092); 632 phy_update(0x14, 0x9f00, 0xff00); 633 phy_out(0x1f, 0); 634 635 // enable R-tune & PGA-retune function 636 u16 dout_tapbin = 0; 637 phy_out(0x1f, 0x0a46); 638 auto data = phy_in(0x13); 639 data &= 3; 640 data <<= 2; 641 dout_tapbin |= data; 642 data = phy_in(0x12); 643 data &= 0xc000; 644 data >>= 14; 645 dout_tapbin |= data; 646 dout_tapbin = ~(dout_tapbin ^ 0x8); 647 dout_tapbin <<= 12; 648 dout_tapbin &= 0xf000; 649 phy_out(0x1f, 0x0a43); 650 phy_out(0x13, 0x827a); 651 phy_update(0x14, dout_tapbin, 0xf000); 652 phy_out(0x13, 0x827b); 653 phy_update(0x14, dout_tapbin, 0xf000); 654 phy_out(0x13, 0x827c); 655 phy_update(0x14, dout_tapbin, 0xf000); 656 phy_out(0x13, 0x827d); 657 phy_update(0x14, dout_tapbin, 0xf000); 658 659 phy_out(0x1f, 0x0a43); 660 phy_out(0x13, 0x811); 661 phy_update(0x14, 0x800, 0); 662 phy_out(0x1f, 0x0a42); 663 phy_update(0x16, 0x2, 0); 664 phy_out(0x1f, 0); 665 666 // enable GPHY 10M 667 phy_out(0x1f, 0x0a44); 668 phy_update(0x11, 0x800, 0); 669 phy_out(0x1f, 0); 670 671 // SAR ADC performance 672 phy_out(0x1f, 0x0bca); 673 phy_update(0x17, 0x4000, 0x3000); 674 phy_out(0x1f, 0); 675 676 phy_out(0x1f, 0x0a43); 677 phy_out(0x13, 0x803f); 678 phy_update(0x14, 0, 0x3000); 679 phy_out(0x13, 0x8047); 680 phy_update(0x14, 0, 0x3000); 681 phy_out(0x13, 0x804f); 682 phy_update(0x14, 0, 0x3000); 683 phy_out(0x13, 0x8057); 684 phy_update(0x14, 0, 0x3000); 685 phy_out(0x13, 0x805f); 686 phy_update(0x14, 0, 0x3000); 687 phy_out(0x13, 0x8067); 688 phy_update(0x14, 0, 0x3000); 689 phy_out(0x13, 0x806f); 690 phy_update(0x14, 0, 0x3000); 691 phy_out(0x1f, 0); 692 693 // disable phy pfm mode 694 phy_out(0x1f, 0x0a44); 695 phy_update(0x11, 0, 0x80); 696 phy_out(0x1f, 0); 697 698 // Check ALDPS bit, disable it if enabled 699 phy_out(0x1f, 0x0a43); 700 if (phy_in(0x10) & 0x4) 701 phy_update(0x10, 0, 0x4); 702 703 phy_out(0x1f, 0); 704} 705 706void RTL8168NetworkAdapter::configure_phy_h_2() 707{ 708 // FIXME: linux's driver writes a firmware blob to the device at this point, is this needed? 709 710 // CHIN EST parameter update 711 phy_out(0x1f, 0x0a43); 712 phy_out(0x13, 0x808a); 713 phy_update(0x14, 0x000a, 0x3f); 714 phy_out(0x1f, 0); 715 716 // enable R-tune & PGA-retune function 717 phy_out(0x1f, 0x0a43); 718 phy_out(0x13, 0x811); 719 phy_update(0x14, 0x800, 0); 720 phy_out(0x1f, 0x0a42); 721 phy_update(0x16, 0x2, 0); 722 phy_out(0x1f, 0); 723 724 // enable GPHY 10M 725 phy_out(0x1f, 0x0a44); 726 phy_update(0x11, 0x800, 0); 727 phy_out(0x1f, 0); 728 729 ocp_out(0xdd02, 0x807d); 730 auto data = ocp_in(0xdd02); 731 u16 ioffset_p3 = ((data & 0x80) >> 7); 732 ioffset_p3 <<= 3; 733 734 data = ocp_in(0xdd00); 735 ioffset_p3 |= ((data & (0xe000)) >> 13); 736 u16 ioffset_p2 = ((data & (0x1e00)) >> 9); 737 u16 ioffset_p1 = ((data & (0x1e0)) >> 5); 738 u16 ioffset_p0 = ((data & 0x10) >> 4); 739 ioffset_p0 <<= 3; 740 ioffset_p0 |= (data & (0x7)); 741 data = (ioffset_p3 << 12) | (ioffset_p2 << 8) | (ioffset_p1 << 4) | (ioffset_p0); 742 743 if ((ioffset_p3 != 0x0f) || (ioffset_p2 != 0x0f) || (ioffset_p1 != 0x0f) || (ioffset_p0 != 0x0f)) { 744 phy_out(0x1f, 0x0bcf); 745 phy_out(0x16, data); 746 phy_out(0x1f, 0); 747 } 748 749 // Modify rlen (TX LPF corner frequency) level 750 phy_out(0x1f, 0x0bcd); 751 data = phy_in(0x16); 752 data &= 0x000f; 753 u16 rlen = 0; 754 if (data > 3) 755 rlen = data - 3; 756 data = rlen | (rlen << 4) | (rlen << 8) | (rlen << 12); 757 phy_out(0x17, data); 758 phy_out(0x1f, 0x0bcd); 759 phy_out(0x1f, 0); 760 761 // disable phy pfm mode 762 phy_out(0x1f, 0x0a44); 763 phy_update(0x11, 0, 0x80); 764 phy_out(0x1f, 0); 765 766 // Check ALDPS bit, disable it if enabled 767 phy_out(0x1f, 0x0a43); 768 if (phy_in(0x10) & 0x4) 769 phy_update(0x10, 0, 0x4); 770 771 phy_out(0x1f, 0); 772} 773 774void RTL8168NetworkAdapter::rar_exgmac_set() 775{ 776 auto mac = mac_address(); 777 const u16 w[] = { 778 (u16)(mac[0] | (mac[1] << 8)), 779 (u16)(mac[2] | (mac[3] << 8)), 780 (u16)(mac[4] | (mac[5] << 8)), 781 }; 782 783 const ExgMacRegister exg_mac_registers[] = { 784 { 0xe0, ERI_MASK_1111, (u32)(w[0] | (w[1] << 16)) }, 785 { 0xe4, ERI_MASK_1111, (u32)w[2] }, 786 { 0xf0, ERI_MASK_1111, (u32)(w[0] << 16) }, 787 { 0xf4, ERI_MASK_1111, (u32)(w[1] | (w[2] << 16)) }, 788 }; 789 790 exgmac_out_batch(exg_mac_registers, 4); 791} 792 793void RTL8168NetworkAdapter::start_hardware() 794{ 795 796 // unlock config registers 797 out8(REG_CFG9346, CFG9346_UNLOCK); 798 799 // configure the maximum transmit packet size 800 out16(REG_MTPS, MTPS_JUMBO); 801 802 // configure the maximum receive packet size 803 out16(REG_RMS, RX_BUFFER_SIZE); 804 805 auto cplus_command = in16(REG_CPLUS_COMMAND); 806 cplus_command |= CPLUS_COMMAND_PACKET_CONTROL_DISABLE; 807 // undocumented magic value??? 808 cplus_command |= 0x1; 809 out16(REG_CPLUS_COMMAND, cplus_command); 810 811 // setup interrupt moderation, magic from vendor (Linux Driver uses 0x5151, *BSD Driver uses 0x5100, RTL Driver use 0x5f51???) 812 out16(REG_INT_MOD, 0x5151); 813 814 // point to tx descriptors 815 out64(REG_TXADDR, m_tx_descriptors_region->physical_page(0)->paddr().get()); 816 817 // point to rx descriptors 818 out64(REG_RXADDR, m_rx_descriptors_region->physical_page(0)->paddr().get()); 819 820 // configure tx: use the maximum dma transfer size, default interframe gap time. 821 out32(REG_TXCFG, TXCFG_IFG011 | TXCFG_MAX_DMA_UNLIMITED); 822 823 // version specific quirks and tweaks 824 hardware_quirks(); 825 826 in8(REG_IMR); // known good read (acts as a barrier) 827 828 // relock config registers 829 out8(REG_CFG9346, CFG9346_NONE); 830 831 // enable rx/tx 832 out8(REG_COMMAND, COMMAND_RX_ENABLE | COMMAND_TX_ENABLE); 833 834 // turn on all multicast 835 out32(REG_MAR0, 0xFFFFFFFF); 836 out32(REG_MAR4, 0xFFFFFFFF); 837 838 // configure rx mode: accept physical (MAC) match, multicast, and broadcast 839 out32(REG_RXCFG, (in32(REG_RXCFG) & ~RXCFG_READ_MASK) | RXCFG_APM | RXCFG_AM | RXCFG_AB); 840 841 // disable early-rx interrupts 842 out16(REG_MULTIINTR, in16(REG_MULTIINTR) & 0xF000); 843} 844 845void RTL8168NetworkAdapter::hardware_quirks() 846{ 847 switch (m_version) { 848 case ChipVersion::Version1: 849 hardware_quirks_b_1(); 850 return; 851 case ChipVersion::Version2: 852 case ChipVersion::Version3: 853 hardware_quirks_b_2(); 854 return; 855 case ChipVersion::Version4: 856 TODO(); 857 case ChipVersion::Version5: 858 TODO(); 859 case ChipVersion::Version6: 860 TODO(); 861 case ChipVersion::Version7: 862 TODO(); 863 case ChipVersion::Version8: 864 TODO(); 865 case ChipVersion::Version9: 866 TODO(); 867 case ChipVersion::Version10: 868 TODO(); 869 case ChipVersion::Version11: 870 TODO(); 871 case ChipVersion::Version12: 872 TODO(); 873 case ChipVersion::Version13: 874 TODO(); 875 case ChipVersion::Version14: 876 TODO(); 877 case ChipVersion::Version15: 878 return; 879 case ChipVersion::Version16: 880 TODO(); 881 case ChipVersion::Version17: 882 hardware_quirks_e_2(); 883 return; 884 case ChipVersion::Version18: 885 TODO(); 886 case ChipVersion::Version19: 887 TODO(); 888 case ChipVersion::Version20: 889 TODO(); 890 case ChipVersion::Version21: 891 TODO(); 892 case ChipVersion::Version22: 893 TODO(); 894 case ChipVersion::Version23: 895 TODO(); 896 case ChipVersion::Version24: 897 TODO(); 898 case ChipVersion::Version25: 899 TODO(); 900 case ChipVersion::Version26: 901 TODO(); 902 case ChipVersion::Version27: 903 TODO(); 904 case ChipVersion::Version28: 905 TODO(); 906 case ChipVersion::Version29: 907 case ChipVersion::Version30: 908 hardware_quirks_h(); 909 return; 910 default: 911 VERIFY_NOT_REACHED(); 912 } 913} 914 915void RTL8168NetworkAdapter::hardware_quirks_b_1() 916{ 917 // disable checked reserved bits 918 out8(REG_CONFIG3, in8(REG_CONFIG3) & ~CFG3_BEACON_ENABLE); 919 constexpr u16 version1_cplus_quirks = CPLUS_COMMAND_ENABLE_BIST | CPLUS_COMMAND_MAC_DBGO_OE | CPLUS_COMMAND_FORCE_HALF_DUP | CPLUS_COMMAND_FORCE_RXFLOW_ENABLE | CPLUS_COMMAND_FORCE_TXFLOW_ENABLE | CPLUS_COMMAND_CXPL_DBG_SEL | CPLUS_COMMAND_ASF | CPLUS_COMMAND_PACKET_CONTROL_DISABLE | CPLUS_COMMAND_MAC_DBGO_SEL; 920 out16(REG_CPLUS_COMMAND, in16(REG_CPLUS_COMMAND) & ~version1_cplus_quirks); 921} 922 923void RTL8168NetworkAdapter::hardware_quirks_b_2() 924{ 925 hardware_quirks_b_1(); 926 927 // configure the maximum transmit packet size (again) 928 out16(REG_MTPS, MTPS_JUMBO); 929 930 // disable checked reserved bits 931 out8(REG_CONFIG4, in8(REG_CONFIG4) & ~1); 932} 933 934void RTL8168NetworkAdapter::hardware_quirks_e_2() 935{ 936 constexpr EPhyUpdate ephy_info[] = { 937 { 0x9, 0, 0x80 }, 938 { 0x19, 0, 0x224 }, 939 }; 940 941 csi_enable(CSI_ACCESS_1); 942 943 extended_phy_initialize(ephy_info, 2); 944 945 // FIXME: MTU performance tweak 946 947 eri_out(0xc0, ERI_MASK_0011, 0, ERI_EXGMAC); 948 eri_out(0xb8, ERI_MASK_0011, 0, ERI_EXGMAC); 949 eri_out(0xc8, ERI_MASK_1111, 0x100002, ERI_EXGMAC); 950 eri_out(0xe8, ERI_MASK_1111, 0x100006, ERI_EXGMAC); 951 eri_out(0xcc, ERI_MASK_1111, 0x50, ERI_EXGMAC); 952 eri_out(0xd0, ERI_MASK_1111, 0x7ff0060, ERI_EXGMAC); 953 eri_update(0x1b0, ERI_MASK_0001, 0x10, 0, ERI_EXGMAC); 954 eri_update(0xd4, ERI_MASK_0011, 0xc00, 0xff00, ERI_EXGMAC); 955 956 // Set early TX 957 out8(REG_MTPS, 0x27); 958 959 // FIXME: Disable PCIe clock request 960 961 // enable tx auto fifo 962 out32(REG_TXCFG, in32(REG_TXCFG) | TXCFG_AUTO_FIFO); 963 964 out8(REG_MCU, in8(REG_MCU) & ~MCU_NOW_IS_OOB); 965 966 // Set EEE LED frequency 967 out8(REG_EEE_LED, in8(REG_EEE_LED) & ~0x7); 968 969 out8(REG_DLLPR, in8(REG_DLLPR) | DLLPR_PFM_ENABLE); 970 out32(REG_MISC, in32(REG_MISC) | MISC_PWM_ENABLE); 971 out8(REG_CONFIG5, in8(REG_CONFIG5) & ~CFG5_SPI_ENABLE); 972} 973 974void RTL8168NetworkAdapter::hardware_quirks_h() 975{ 976 // disable aspm and clock request before accessing extended phy 977 out8(REG_CONFIG2, in8(REG_CONFIG2) & ~CFG2_CLOCK_REQUEST_ENABLE); 978 out8(REG_CONFIG5, in8(REG_CONFIG5) & ~CFG5_ASPM_ENABLE); 979 980 // initialize extended phy 981 constexpr EPhyUpdate ephy_info[] = { 982 { 0x1e, 0x800, 0x1 }, 983 { 0x1d, 0, 0x800 }, 984 { 0x5, 0xffff, 0x2089 }, 985 { 0x6, 0xffff, 0x5881 }, 986 { 0x4, 0xffff, 0x154a }, 987 { 0x1, 0xffff, 0x68b } 988 }; 989 extended_phy_initialize(ephy_info, 6); 990 991 // enable tx auto fifo 992 out32(REG_TXCFG, in32(REG_TXCFG) | TXCFG_AUTO_FIFO); 993 994 // vendor magic values ??? 995 eri_out(0xC8, ERI_MASK_0101, 0x80002, ERI_EXGMAC); 996 eri_out(0xCC, ERI_MASK_0001, 0x38, ERI_EXGMAC); 997 eri_out(0xD0, ERI_MASK_0001, 0x48, ERI_EXGMAC); 998 eri_out(0xE8, ERI_MASK_1111, 0x100006, ERI_EXGMAC); 999 1000 csi_enable(CSI_ACCESS_1); 1001 1002 // vendor magic values ??? 1003 eri_update(0xDC, ERI_MASK_0001, 0x0, 0x1, ERI_EXGMAC); 1004 eri_update(0xDC, ERI_MASK_0001, 0x1, 0x0, ERI_EXGMAC); 1005 eri_update(0xDC, ERI_MASK_1111, 0x10, 0x0, ERI_EXGMAC); 1006 eri_update(0xD4, ERI_MASK_1111, 0x1F00, 0x0, ERI_EXGMAC); 1007 eri_out(0x5F0, ERI_MASK_0011, 0x4F87, ERI_EXGMAC); 1008 1009 // disable rxdv gate 1010 out32(REG_MISC, in32(REG_MISC) & ~MISC_RXDV_GATE_ENABLE); 1011 1012 // set early TX 1013 out8(REG_MTPS, 0x27); 1014 1015 // vendor magic values ??? 1016 eri_out(0xC0, ERI_MASK_0011, 0, ERI_EXGMAC); 1017 eri_out(0xB8, ERI_MASK_0011, 0, ERI_EXGMAC); 1018 1019 // Set EEE LED frequency 1020 out8(REG_EEE_LED, in8(REG_EEE_LED) & ~0x7); 1021 1022 out8(REG_DLLPR, in8(REG_DLLPR) & ~DLLPR_PFM_ENABLE); 1023 out8(REG_MISC2, in8(REG_MISC2) & ~MISC2_PFM_D3COLD_ENABLE); 1024 out8(REG_DLLPR, in8(REG_DLLPR) & ~DLLPR_TX_10M_PS_ENABLE); 1025 1026 // vendor magic values ??? 1027 eri_update(0x1B0, ERI_MASK_0011, 0, 0x1000, ERI_EXGMAC); 1028 1029 // disable l2l3 state 1030 out8(REG_CONFIG3, in8(REG_CONFIG3) & ~CFG3_READY_TO_L23); 1031 1032 // blackmagic code taken from linux's r8169 1033 phy_out(0x1F, 0x0C42); 1034 auto rg_saw_count = (phy_in(0x13) & 0x3FFF); 1035 phy_out(0x1F, 0); 1036 if (rg_saw_count > 0) { 1037 u16 sw_count_1ms_ini = 16000000 / rg_saw_count; 1038 sw_count_1ms_ini &= 0x0fff; 1039 u32 data = ocp_in(0xd412); 1040 data &= ~0x0fff; 1041 data |= sw_count_1ms_ini; 1042 ocp_out(0xd412, data); 1043 } 1044 1045 u32 data = ocp_in(0xe056); 1046 data &= ~0xf0; 1047 data |= 0x70; 1048 ocp_out(0xe056, data); 1049 1050 data = ocp_in(0xe052); 1051 data &= ~0x6000; 1052 data |= 0x8008; 1053 ocp_out(0xe052, data); 1054 1055 data = ocp_in(0xe0d6); 1056 data &= ~0x1ff; 1057 data |= 0x17f; 1058 ocp_out(0xe0d6, data); 1059 1060 data = ocp_in(0xd420); 1061 data &= ~0x0fff; 1062 data |= 0x47f; 1063 ocp_out(0xd420, data); 1064 1065 ocp_out(0xe63e, 0x1); 1066 ocp_out(0xe63e, 0); 1067 ocp_out(0xc094, 0); 1068 ocp_out(0xc09e, 0); 1069} 1070 1071void RTL8168NetworkAdapter::set_phy_speed() 1072{ 1073 // wakeup phy 1074 phy_out(0x1F, 0); 1075 1076 // advertise all available features to get best connection possible 1077 auto auto_negotiation_advertisement = phy_in(PHY_REG_ANAR); 1078 auto_negotiation_advertisement |= ADVERTISE_10_HALF; // 10 mbit half duplex 1079 auto_negotiation_advertisement |= ADVERTISE_10_FULL; // 10 mbit full duplex 1080 auto_negotiation_advertisement |= ADVERTISE_100_HALF; // 100 mbit half duplex 1081 auto_negotiation_advertisement |= ADVERTISE_100_FULL; // 100 mbit full duplex 1082 auto_negotiation_advertisement |= ADVERTISE_PAUSE_CAP; // capable of pause flow control 1083 auto_negotiation_advertisement |= ADVERTISE_PAUSE_ASYM; // capable of asymmetric pause flow control 1084 phy_out(PHY_REG_ANAR, auto_negotiation_advertisement); 1085 1086 auto gigabyte_control = phy_in(PHY_REG_GBCR); 1087 gigabyte_control |= ADVERTISE_1000_HALF; // 1000 mbit half dulpex 1088 gigabyte_control |= ADVERTISE_1000_FULL; // 1000 mbit full duplex 1089 phy_out(PHY_REG_GBCR, gigabyte_control); 1090 1091 // restart auto-negotiation with set advertisements 1092 phy_out(PHY_REG_BMCR, BMCR_AUTO_NEGOTIATE | BMCR_RESTART_AUTO_NEGOTIATE); 1093} 1094 1095UNMAP_AFTER_INIT void RTL8168NetworkAdapter::initialize_rx_descriptors() 1096{ 1097 auto* rx_descriptors = (RXDescriptor*)m_rx_descriptors_region->vaddr().as_ptr(); 1098 for (size_t i = 0; i < number_of_rx_descriptors; ++i) { 1099 auto& descriptor = rx_descriptors[i]; 1100 auto region = MM.allocate_contiguous_kernel_region(Memory::page_round_up(RX_BUFFER_SIZE).release_value_but_fixme_should_propagate_errors(), "RTL8168 RX buffer"sv, Memory::Region::Access::ReadWrite).release_value(); 1101 memset(region->vaddr().as_ptr(), 0, region->size()); // MM already zeros out newly allocated pages, but we do it again in case that ever changes 1102 m_rx_buffers_regions.append(move(region)); 1103 1104 descriptor.buffer_size = RX_BUFFER_SIZE; 1105 descriptor.flags = RXDescriptor::Ownership; // let the NIC know it can use this descriptor 1106 auto physical_address = m_rx_buffers_regions[i]->physical_page(0)->paddr().get(); 1107 descriptor.buffer_address_low = physical_address & 0xFFFFFFFF; 1108 descriptor.buffer_address_high = (u64)physical_address >> 32; // cast to prevent shift count >= with of type warnings in 32 bit systems 1109 } 1110 rx_descriptors[number_of_rx_descriptors - 1].flags = rx_descriptors[number_of_rx_descriptors - 1].flags | RXDescriptor::EndOfRing; 1111} 1112 1113UNMAP_AFTER_INIT void RTL8168NetworkAdapter::initialize_tx_descriptors() 1114{ 1115 auto* tx_descriptors = (TXDescriptor*)m_tx_descriptors_region->vaddr().as_ptr(); 1116 for (size_t i = 0; i < number_of_tx_descriptors; ++i) { 1117 auto& descriptor = tx_descriptors[i]; 1118 auto region = MM.allocate_contiguous_kernel_region(Memory::page_round_up(TX_BUFFER_SIZE).release_value_but_fixme_should_propagate_errors(), "RTL8168 TX buffer"sv, Memory::Region::Access::ReadWrite).release_value(); 1119 memset(region->vaddr().as_ptr(), 0, region->size()); // MM already zeros out newly allocated pages, but we do it again in case that ever changes 1120 m_tx_buffers_regions.append(move(region)); 1121 1122 descriptor.flags = TXDescriptor::FirstSegment | TXDescriptor::LastSegment; 1123 auto physical_address = m_tx_buffers_regions[i]->physical_page(0)->paddr().get(); 1124 descriptor.buffer_address_low = physical_address & 0xFFFFFFFF; 1125 descriptor.buffer_address_high = (u64)physical_address >> 32; 1126 } 1127 tx_descriptors[number_of_tx_descriptors - 1].flags = tx_descriptors[number_of_tx_descriptors - 1].flags | TXDescriptor::EndOfRing; 1128} 1129 1130UNMAP_AFTER_INIT RTL8168NetworkAdapter::~RTL8168NetworkAdapter() = default; 1131 1132bool RTL8168NetworkAdapter::handle_irq(RegisterState const&) 1133{ 1134 bool was_handled = false; 1135 for (;;) { 1136 int status = in16(REG_ISR); 1137 out16(REG_ISR, status); 1138 1139 m_entropy_source.add_random_event(status); 1140 1141 dbgln_if(RTL8168_DEBUG, "RTL8168: handle_irq status={:#04x}", status); 1142 1143 if ((status & (INT_RXOK | INT_RXERR | INT_TXOK | INT_TXERR | INT_RX_OVERFLOW | INT_LINK_CHANGE | INT_RX_FIFO_OVERFLOW | INT_SYS_ERR)) == 0) 1144 break; 1145 1146 was_handled = true; 1147 if (status & INT_RXOK) { 1148 dbgln_if(RTL8168_DEBUG, "RTL8168: RX ready"); 1149 receive(); 1150 } 1151 if (status & INT_RXERR) { 1152 dbgln_if(RTL8168_DEBUG, "RTL8168: RX error - invalid packet"); 1153 } 1154 if (status & INT_TXOK) { 1155 dbgln_if(RTL8168_DEBUG, "RTL8168: TX complete"); 1156 m_wait_queue.wake_one(); 1157 } 1158 if (status & INT_TXERR) { 1159 dbgln_if(RTL8168_DEBUG, "RTL8168: TX error - invalid packet"); 1160 } 1161 if (status & INT_RX_OVERFLOW) { 1162 dmesgln_pci(*this, "RX descriptor unavailable (packet lost)"); 1163 receive(); 1164 } 1165 if (status & INT_LINK_CHANGE) { 1166 m_link_up = (in8(REG_PHYSTATUS) & PHY_LINK_STATUS) != 0; 1167 dmesgln_pci(*this, "Link status changed up={}", m_link_up); 1168 } 1169 if (status & INT_RX_FIFO_OVERFLOW) { 1170 dmesgln_pci(*this, "RX FIFO overflow"); 1171 receive(); 1172 } 1173 if (status & INT_SYS_ERR) { 1174 dmesgln_pci(*this, "Fatal system error"); 1175 } 1176 } 1177 return was_handled; 1178} 1179 1180void RTL8168NetworkAdapter::reset() 1181{ 1182 out8(REG_COMMAND, COMMAND_RESET); 1183 while ((in8(REG_COMMAND) & COMMAND_RESET) != 0) 1184 ; 1185} 1186 1187UNMAP_AFTER_INIT void RTL8168NetworkAdapter::read_mac_address() 1188{ 1189 MACAddress mac {}; 1190 for (int i = 0; i < 6; i++) 1191 mac[i] = in8(REG_MAC + i); 1192 set_mac_address(mac); 1193} 1194 1195void RTL8168NetworkAdapter::send_raw(ReadonlyBytes payload) 1196{ 1197 dbgln_if(RTL8168_DEBUG, "RTL8168: send_raw length={}", payload.size()); 1198 1199 if (payload.size() > TX_BUFFER_SIZE) { 1200 dmesgln_pci(*this, "Packet was too big; discarding"); 1201 return; 1202 } 1203 1204 auto* tx_descriptors = (TXDescriptor*)m_tx_descriptors_region->vaddr().as_ptr(); 1205 auto& free_descriptor = tx_descriptors[m_tx_free_index]; 1206 1207 if ((free_descriptor.flags & TXDescriptor::Ownership) != 0) { 1208 dbgln_if(RTL8168_DEBUG, "RTL8168: No free TX buffers, sleeping until one is available"); 1209 m_wait_queue.wait_forever("RTL8168NetworkAdapter"sv); 1210 return send_raw(payload); 1211 // if we woke up a TX descriptor is guaranteed to be available, so this should never recurse more than once 1212 // but this can probably be done more cleanly 1213 } 1214 1215 dbgln_if(RTL8168_DEBUG, "RTL8168: Chose descriptor {}", m_tx_free_index); 1216 memcpy(m_tx_buffers_regions[m_tx_free_index]->vaddr().as_ptr(), payload.data(), payload.size()); 1217 1218 m_tx_free_index = (m_tx_free_index + 1) % number_of_tx_descriptors; 1219 1220 free_descriptor.frame_length = payload.size() & 0x3FFF; 1221 free_descriptor.flags = free_descriptor.flags | TXDescriptor::Ownership; 1222 1223 out8(REG_TXSTART, TXSTART_START); // FIXME: this shouldn't be done so often, we should look into doing this using the watchdog timer 1224} 1225 1226void RTL8168NetworkAdapter::receive() 1227{ 1228 auto* rx_descriptors = (RXDescriptor*)m_rx_descriptors_region->vaddr().as_ptr(); 1229 for (u16 i = 0; i < number_of_rx_descriptors; ++i) { 1230 auto descriptor_index = (m_rx_free_index + i) % number_of_rx_descriptors; 1231 auto& descriptor = rx_descriptors[descriptor_index]; 1232 1233 if ((descriptor.flags & RXDescriptor::Ownership) != 0) { 1234 m_rx_free_index = descriptor_index; 1235 break; 1236 } 1237 1238 u16 flags = descriptor.flags; 1239 u16 length = descriptor.buffer_size & 0x3FFF; 1240 1241 dbgln_if(RTL8168_DEBUG, "RTL8168: receive, flags={:#04x}, length={}, descriptor={}", flags, length, descriptor_index); 1242 1243 if (length > RX_BUFFER_SIZE || (flags & RXDescriptor::ErrorSummary) != 0) { 1244 dmesgln_pci(*this, "receive got bad packet, flags={:#04x}, length={}", flags, length); 1245 } else if ((flags & RXDescriptor::FirstSegment) != 0 && (flags & RXDescriptor::LastSegment) == 0) { 1246 VERIFY_NOT_REACHED(); 1247 // Our maximum received packet size is smaller than the descriptor buffer size, so packets should never be segmented 1248 // if this happens on a real NIC it might not respect that, and we will have to support packet segmentation 1249 } else { 1250 did_receive({ m_rx_buffers_regions[descriptor_index]->vaddr().as_ptr(), length }); 1251 } 1252 1253 descriptor.buffer_size = RX_BUFFER_SIZE; 1254 flags = RXDescriptor::Ownership; 1255 if (descriptor_index == number_of_rx_descriptors - 1) 1256 flags |= RXDescriptor::EndOfRing; 1257 descriptor.flags = flags; // let the NIC know it can use this descriptor again 1258 } 1259} 1260 1261void RTL8168NetworkAdapter::out8(u16 address, u8 data) 1262{ 1263 m_registers_io_window->write8(address, data); 1264} 1265 1266void RTL8168NetworkAdapter::out16(u16 address, u16 data) 1267{ 1268 m_registers_io_window->write16(address, data); 1269} 1270 1271void RTL8168NetworkAdapter::out32(u16 address, u32 data) 1272{ 1273 m_registers_io_window->write32(address, data); 1274} 1275 1276void RTL8168NetworkAdapter::out64(u16 address, u64 data) 1277{ 1278 // ORDER MATTERS: Some NICs require the high part of the address to be written first 1279 m_registers_io_window->write32(address + 4, (u32)(data >> 32)); 1280 m_registers_io_window->write32(address, (u32)(data & 0xFFFFFFFF)); 1281} 1282 1283u8 RTL8168NetworkAdapter::in8(u16 address) 1284{ 1285 return m_registers_io_window->read8(address); 1286} 1287 1288u16 RTL8168NetworkAdapter::in16(u16 address) 1289{ 1290 return m_registers_io_window->read16(address); 1291} 1292 1293u32 RTL8168NetworkAdapter::in32(u16 address) 1294{ 1295 return m_registers_io_window->read32(address); 1296} 1297 1298void RTL8168NetworkAdapter::phy_out(u8 address, u16 data) 1299{ 1300 if (m_version == ChipVersion::Version11) { 1301 TODO(); 1302 } else if (m_version == ChipVersion::Version12 || m_version == ChipVersion::Version13) { 1303 TODO(); 1304 } else if (m_version >= ChipVersion::Version21) { 1305 if (address == 0x1F) { 1306 m_ocp_base_address = data ? data << 4 : OCP_STANDARD_PHY_BASE; 1307 return; 1308 } 1309 1310 if (m_ocp_base_address != OCP_STANDARD_PHY_BASE) 1311 address -= 0x10; 1312 1313 ocp_phy_out(m_ocp_base_address + address * 2, data); 1314 } else { 1315 VERIFY((address & 0xE0) == 0); // register address is only 5 bit 1316 out32(REG_PHYACCESS, PHY_FLAG | (address & 0x1F) << 16 | (data & 0xFFFF)); 1317 while ((in32(REG_PHYACCESS) & PHY_FLAG) != 0) 1318 ; 1319 } 1320} 1321 1322u16 RTL8168NetworkAdapter::phy_in(u8 address) 1323{ 1324 if (m_version == ChipVersion::Version11) { 1325 TODO(); 1326 } else if (m_version == ChipVersion::Version12 || m_version == ChipVersion::Version13) { 1327 TODO(); 1328 } else if (m_version >= ChipVersion::Version21) { 1329 if (m_ocp_base_address != OCP_STANDARD_PHY_BASE) 1330 address -= 0x10; 1331 1332 return ocp_phy_in(m_ocp_base_address + address * 2); 1333 } else { 1334 VERIFY((address & 0xE0) == 0); // register address is only 5 bit 1335 out32(REG_PHYACCESS, (address & 0x1F) << 16); 1336 while ((in32(REG_PHYACCESS) & PHY_FLAG) == 0) 1337 ; 1338 return in32(REG_PHYACCESS) & 0xFFFF; 1339 } 1340} 1341 1342void RTL8168NetworkAdapter::phy_update(u32 address, u32 set, u32 clear) 1343{ 1344 auto value = phy_in(address); 1345 phy_out(address, (value & ~clear) | set); 1346} 1347 1348void RTL8168NetworkAdapter::phy_out_batch(const PhyRegister phy_registers[], size_t length) 1349{ 1350 for (size_t i = 0; i < length; i++) { 1351 phy_out(phy_registers[i].address, phy_registers[i].data); 1352 } 1353} 1354 1355void RTL8168NetworkAdapter::extended_phy_out(u8 address, u16 data) 1356{ 1357 VERIFY((address & 0xE0) == 0); // register address is only 5 bit 1358 out32(REG_EPHYACCESS, EPHY_FLAG | (address & 0x1F) << 16 | (data & 0xFFFF)); 1359 while ((in32(REG_EPHYACCESS) & EPHY_FLAG) != 0) 1360 ; 1361} 1362 1363u16 RTL8168NetworkAdapter::extended_phy_in(u8 address) 1364{ 1365 VERIFY((address & 0xE0) == 0); // register address is only 5 bit 1366 out32(REG_EPHYACCESS, (address & 0x1F) << 16); 1367 while ((in32(REG_EPHYACCESS) & EPHY_FLAG) == 0) 1368 ; 1369 return in32(REG_EPHYACCESS) & 0xFFFF; 1370} 1371 1372void RTL8168NetworkAdapter::extended_phy_initialize(const EPhyUpdate ephy_info[], size_t length) 1373{ 1374 for (size_t i = 0; i < length; i++) { 1375 auto updated_value = (extended_phy_in(ephy_info[i].offset) & ~ephy_info[i].clear) | ephy_info[i].set; 1376 extended_phy_out(ephy_info[i].offset, updated_value); 1377 } 1378} 1379 1380void RTL8168NetworkAdapter::eri_out(u32 address, u32 mask, u32 data, u32 type) 1381{ 1382 out32(REG_ERI_DATA, data); 1383 out32(REG_ERI_ADDR, ERI_FLAG | type | mask | address); 1384 while ((in32(REG_ERI_ADDR) & ERI_FLAG) != 0) 1385 ; 1386} 1387 1388u32 RTL8168NetworkAdapter::eri_in(u32 address, u32 type) 1389{ 1390 out32(REG_ERI_ADDR, type | ERI_MASK_1111 | address); 1391 while ((in32(REG_ERI_ADDR) & ERI_FLAG) == 0) 1392 ; 1393 return in32(REG_ERI_DATA); 1394} 1395 1396void RTL8168NetworkAdapter::eri_update(u32 address, u32 mask, u32 set, u32 clear, u32 type) 1397{ 1398 auto value = eri_in(address, type); 1399 eri_out(address, mask, (value & ~clear) | set, type); 1400} 1401 1402void RTL8168NetworkAdapter::exgmac_out_batch(const ExgMacRegister exgmac_registers[], size_t length) 1403{ 1404 for (size_t i = 0; i < length; i++) { 1405 eri_out(exgmac_registers[i].address, exgmac_registers[i].mask, exgmac_registers[i].value, ERI_EXGMAC); 1406 } 1407} 1408 1409void RTL8168NetworkAdapter::csi_out(u32 address, u32 data) 1410{ 1411 VERIFY(m_version >= ChipVersion::Version4); 1412 out32(REG_CSI_DATA, data); 1413 auto modifier = CSI_BYTE_ENABLE; 1414 if (m_version == ChipVersion::Version20) { 1415 modifier |= CSI_FUNC_NIC; 1416 } else if (m_version == ChipVersion::Version26) { 1417 modifier |= CSI_FUNC_NIC2; 1418 } 1419 out32(REG_CSI_ADDR, CSI_FLAG | (address & 0xFFF) | modifier); 1420 while ((in32(REG_CSI_ADDR) & CSI_FLAG) != 0) 1421 ; 1422} 1423 1424u32 RTL8168NetworkAdapter::csi_in(u32 address) 1425{ 1426 VERIFY(m_version >= ChipVersion::Version4); 1427 auto modifier = CSI_BYTE_ENABLE; 1428 if (m_version == ChipVersion::Version20) { 1429 modifier |= CSI_FUNC_NIC; 1430 } else if (m_version == ChipVersion::Version26) { 1431 modifier |= CSI_FUNC_NIC2; 1432 } 1433 out32(REG_CSI_ADDR, (address & 0xFFF) | modifier); 1434 while ((in32(REG_CSI_ADDR) & CSI_FLAG) == 0) 1435 ; 1436 return in32(REG_CSI_DATA) & 0xFFFF; 1437} 1438 1439void RTL8168NetworkAdapter::csi_enable(u32 bits) 1440{ 1441 auto csi = csi_in(0x70c) & 0x00ffffff; 1442 csi_out(0x70c, csi | bits); 1443} 1444 1445void RTL8168NetworkAdapter::ocp_out(u32 address, u32 data) 1446{ 1447 VERIFY((address & 0xFFFF0001) == 0); 1448 out32(REG_OCP_DATA, OCP_FLAG | address << 15 | data); 1449} 1450 1451u32 RTL8168NetworkAdapter::ocp_in(u32 address) 1452{ 1453 VERIFY((address & 0xFFFF0001) == 0); 1454 out32(REG_OCP_DATA, address << 15); 1455 return in32(REG_OCP_DATA); 1456} 1457 1458void RTL8168NetworkAdapter::ocp_phy_out(u32 address, u32 data) 1459{ 1460 VERIFY((address & 0xFFFF0001) == 0); 1461 out32(REG_GPHY_OCP, OCP_FLAG | (address << 15) | data); 1462 while ((in32(REG_GPHY_OCP) & OCP_FLAG) != 0) 1463 ; 1464} 1465 1466u16 RTL8168NetworkAdapter::ocp_phy_in(u32 address) 1467{ 1468 VERIFY((address & 0xFFFF0001) == 0); 1469 out32(REG_GPHY_OCP, address << 15); 1470 while ((in32(REG_GPHY_OCP) & OCP_FLAG) == 0) 1471 ; 1472 return in32(REG_GPHY_OCP) & 0xFFFF; 1473} 1474 1475void RTL8168NetworkAdapter::identify_chip_version() 1476{ 1477 auto transmit_config = in32(REG_TXCFG); 1478 auto registers = transmit_config & 0x7c800000; 1479 auto hw_version_id = transmit_config & 0x700000; 1480 1481 m_version_uncertain = false; 1482 1483 switch (registers) { 1484 case 0x30000000: 1485 m_version = ChipVersion::Version1; 1486 break; 1487 case 0x38000000: 1488 if (hw_version_id == 00000) { 1489 m_version = ChipVersion::Version2; 1490 } else if (hw_version_id == 0x500000) { 1491 m_version = ChipVersion::Version3; 1492 } else { 1493 m_version = ChipVersion::Version3; 1494 m_version_uncertain = true; 1495 } 1496 break; 1497 case 0x3C000000: 1498 if (hw_version_id == 00000) { 1499 m_version = ChipVersion::Version4; 1500 } else if (hw_version_id == 0x200000) { 1501 m_version = ChipVersion::Version5; 1502 } else if (hw_version_id == 0x400000) { 1503 m_version = ChipVersion::Version6; 1504 } else { 1505 m_version = ChipVersion::Version6; 1506 m_version_uncertain = true; 1507 } 1508 break; 1509 case 0x3C800000: 1510 if (hw_version_id == 0x100000) { 1511 m_version = ChipVersion::Version7; 1512 } else if (hw_version_id == 0x300000) { 1513 m_version = ChipVersion::Version8; 1514 } else { 1515 m_version = ChipVersion::Version8; 1516 m_version_uncertain = true; 1517 } 1518 break; 1519 case 0x28000000: 1520 if (hw_version_id == 0x100000) { 1521 m_version = ChipVersion::Version9; 1522 } else if (hw_version_id == 0x300000) { 1523 m_version = ChipVersion::Version10; 1524 } else { 1525 m_version = ChipVersion::Version10; 1526 m_version_uncertain = true; 1527 } 1528 break; 1529 case 0x28800000: 1530 if (hw_version_id == 00000) { 1531 m_version = ChipVersion::Version11; 1532 } else if (hw_version_id == 0x200000) { 1533 m_version = ChipVersion::Version12; 1534 } else if (hw_version_id == 0x300000) { 1535 m_version = ChipVersion::Version13; 1536 } else { 1537 m_version = ChipVersion::Version13; 1538 m_version_uncertain = true; 1539 } 1540 break; 1541 case 0x2C000000: 1542 if (hw_version_id == 0x100000) { 1543 m_version = ChipVersion::Version14; 1544 } else if (hw_version_id == 0x200000) { 1545 m_version = ChipVersion::Version15; 1546 } else { 1547 m_version = ChipVersion::Version15; 1548 m_version_uncertain = true; 1549 } 1550 break; 1551 case 0x2C800000: 1552 if (hw_version_id == 00000) { 1553 m_version = ChipVersion::Version16; 1554 } else if (hw_version_id == 0x100000) { 1555 m_version = ChipVersion::Version17; 1556 } else { 1557 m_version = ChipVersion::Version17; 1558 m_version_uncertain = true; 1559 } 1560 break; 1561 case 0x48000000: 1562 if (hw_version_id == 00000) { 1563 m_version = ChipVersion::Version18; 1564 } else if (hw_version_id == 0x100000) { 1565 m_version = ChipVersion::Version19; 1566 } else { 1567 m_version = ChipVersion::Version19; 1568 m_version_uncertain = true; 1569 } 1570 break; 1571 case 0x48800000: 1572 if (hw_version_id == 00000) { 1573 m_version = ChipVersion::Version20; 1574 } else { 1575 m_version = ChipVersion::Version20; 1576 m_version_uncertain = true; 1577 } 1578 1579 break; 1580 case 0x4C000000: 1581 if (hw_version_id == 00000) { 1582 m_version = ChipVersion::Version21; 1583 } else if (hw_version_id == 0x100000) { 1584 m_version = ChipVersion::Version22; 1585 } else { 1586 m_version = ChipVersion::Version22; 1587 m_version_uncertain = true; 1588 } 1589 break; 1590 case 0x50000000: 1591 if (hw_version_id == 00000) { 1592 m_version = ChipVersion::Version23; 1593 } else if (hw_version_id == 0x100000) { 1594 m_version = ChipVersion::Version27; 1595 } else if (hw_version_id == 0x200000) { 1596 m_version = ChipVersion::Version28; 1597 } else { 1598 m_version = ChipVersion::Version28; 1599 m_version_uncertain = true; 1600 } 1601 break; 1602 case 0x50800000: 1603 if (hw_version_id == 00000) { 1604 m_version = ChipVersion::Version24; 1605 } else if (hw_version_id == 0x100000) { 1606 m_version = ChipVersion::Version25; 1607 } else { 1608 m_version = ChipVersion::Version25; 1609 m_version_uncertain = true; 1610 } 1611 break; 1612 case 0x5C800000: 1613 if (hw_version_id == 00000) { 1614 m_version = ChipVersion::Version26; 1615 } else { 1616 m_version = ChipVersion::Version26; 1617 m_version_uncertain = true; 1618 } 1619 break; 1620 case 0x54000000: 1621 if (hw_version_id == 00000) { 1622 m_version = ChipVersion::Version29; 1623 } else if (hw_version_id == 0x100000) { 1624 m_version = ChipVersion::Version30; 1625 } else { 1626 m_version = ChipVersion::Version30; 1627 m_version_uncertain = true; 1628 } 1629 break; 1630 default: 1631 dbgln_if(RTL8168_DEBUG, "Unable to determine device version: {:#04x}", registers); 1632 m_version = ChipVersion::Unknown; 1633 m_version_uncertain = true; 1634 break; 1635 } 1636} 1637 1638StringView RTL8168NetworkAdapter::possible_device_name() 1639{ 1640 switch (m_version) { // We are following *BSD's versioning scheme, the comments note linux's versioning scheme, but they dont match up exactly 1641 case ChipVersion::Version1: 1642 case ChipVersion::Version2: 1643 case ChipVersion::Version3: 1644 return "RTL8168B/8111B"sv; // 11, 12, 17 1645 case ChipVersion::Version4: 1646 case ChipVersion::Version5: 1647 case ChipVersion::Version6: 1648 return "RTL8168C/8111C"sv; // 19, 20, 21, 22 1649 case ChipVersion::Version7: 1650 case ChipVersion::Version8: 1651 return "RTL8168CP/8111CP"sv; // 18, 23, 24 1652 case ChipVersion::Version9: 1653 case ChipVersion::Version10: 1654 return "RTL8168D/8111D"sv; // 25, 26 1655 case ChipVersion::Version11: 1656 case ChipVersion::Version12: 1657 case ChipVersion::Version13: 1658 return "RTL8168DP/8111DP"sv; // 27, 28, 31 1659 case ChipVersion::Version14: 1660 case ChipVersion::Version15: 1661 return "RTL8168E/8111E"sv; // 32, 33 1662 case ChipVersion::Version16: 1663 case ChipVersion::Version17: 1664 return "RTL8168E-VL/8111E-VL"sv; // 34 1665 case ChipVersion::Version18: 1666 case ChipVersion::Version19: 1667 return "RTL8168F/8111F"sv; // 35, 36 1668 case ChipVersion::Version20: 1669 return "RTL8411"sv; // 38 1670 case ChipVersion::Version21: 1671 case ChipVersion::Version22: 1672 return "RTL8168G/8111G"sv; // 40, 41, 42 1673 case ChipVersion::Version23: 1674 case ChipVersion::Version27: 1675 case ChipVersion::Version28: 1676 return "RTL8168EP/8111EP"sv; // 49, 50, 51 1677 case ChipVersion::Version24: 1678 case ChipVersion::Version25: 1679 return "RTL8168GU/8111GU"sv; // ??? 1680 case ChipVersion::Version26: 1681 return "RTL8411B"sv; // 44 1682 case ChipVersion::Version29: 1683 case ChipVersion::Version30: 1684 return "RTL8168H/8111H"sv; // 45, 46 1685 case ChipVersion::Unknown: 1686 return "Unknown"sv; 1687 } 1688 VERIFY_NOT_REACHED(); 1689} 1690 1691bool RTL8168NetworkAdapter::link_full_duplex() 1692{ 1693 u8 phystatus = in8(REG_PHYSTATUS); 1694 return !!(phystatus & (PHYSTATUS_FULLDUP | PHYSTATUS_1000MF)); 1695} 1696 1697i32 RTL8168NetworkAdapter::link_speed() 1698{ 1699 if (!link_up()) 1700 return NetworkAdapter::LINKSPEED_INVALID; 1701 1702 u8 phystatus = in8(REG_PHYSTATUS); 1703 if (phystatus & PHYSTATUS_1000MF) 1704 return 1000; 1705 if (phystatus & PHYSTATUS_100M) 1706 return 100; 1707 if (phystatus & PHYSTATUS_10M) 1708 return 10; 1709 1710 return NetworkAdapter::LINKSPEED_INVALID; 1711} 1712 1713}