1/* Realtek RTL8169 Family Driver 2 * Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved. 3 * 4 * Permission to use, copy, modify and distribute this software and its 5 * documentation for any purpose and without fee is hereby granted, provided 6 * that the above copyright notice appear in all copies, and that both the 7 * copyright notice and this permission notice appear in supporting documentation. 8 * 9 * Marcus Overhagen makes no representations about the suitability of this software 10 * for any purpose. It is provided "as is" without express or implied warranty. 11 * 12 * MARCUS OVERHAGEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 13 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL MARCUS 14 * OVERHAGEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 15 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20#include <KernelExport.h> 21#include <Errors.h> 22#include <stdlib.h> 23#include <stdio.h> 24#include <fcntl.h> 25#include <string.h> 26#include <driver_settings.h> 27#ifdef HAIKU_TARGET_PLATFORM_HAIKU 28 #include <net/if_media.h> 29#endif 30 31 32#include "debug.h" 33#include "device.h" 34#include "driver.h" 35#include "hardware.h" 36#include "util.h" 37 38static int32 gOpenMask = 0; 39 40 41static void 42read_settings(rtl8169_device *device) 43{ 44 void *handle; 45 const char *param; 46 int mtu, count; 47 48 handle = load_driver_settings("rtl8169"); 49 if (!handle) 50 return; 51 52 param = get_driver_parameter(handle, "mtu", "-1", "-1"); 53 mtu = atoi(param); 54 if (mtu >= 50 && mtu <= 1500) 55 device->maxframesize = mtu + 14; 56 else if (mtu != -1) 57 dprintf("rtl8169: unsupported mtu setting '%s' ignored\n", param); 58 59 param = get_driver_parameter(handle, "rx_buffer_count", "-1", "-1"); 60 count = atoi(param); 61 if (count >= 2 && count <= 1024) 62 device->rxBufferCount = count; 63 else if (count != -1) 64 dprintf("rtl8169: unsupported rx_buffer_count setting '%s' ignored\n", param); 65 66 param = get_driver_parameter(handle, "tx_buffer_count", "-1", "-1"); 67 count = atoi(param); 68 if (count >= 2 && count <= 1024) 69 device->txBufferCount = count; 70 else if (count != -1) 71 dprintf("rtl8169: unsupported tx_buffer_count setting '%s' ignored\n", param); 72 73 unload_driver_settings(handle); 74} 75 76 77static void 78write_phy_reg(rtl8169_device *device, int reg, uint16 value) 79{ 80 int i; 81 write32(REG_PHYAR, 0x80000000 | (reg & 0x1f) << 16 | value); 82 snooze(1000); 83 for (i = 0; i < 2000; i++) { 84 if ((read32(REG_PHYAR) & 0x80000000) == 0) 85 break; 86 snooze(100); 87 } 88} 89 90 91static uint16 92read_phy_reg(rtl8169_device *device, int reg) 93{ 94 uint32 v; 95 int i; 96 write32(REG_PHYAR, (reg & 0x1f) << 16); 97 snooze(1000); 98 for (i = 0; i < 2000; i++) { 99 v = read32(REG_PHYAR); 100 if (v & 0x80000000) 101 return v & 0xffff; 102 snooze(100); 103 } 104 return 0xffff; 105} 106 107 108static inline void 109write_phy_reg_bit(rtl8169_device *device, int reg, int bitnum, int bitval) 110{ 111 uint16 val = read_phy_reg(device, reg); 112 if (bitval == 1) 113 val |= (1 << bitnum); 114 else 115 val &= ~(1 << bitnum); 116 write_phy_reg(device, reg, val); 117} 118 119 120static void 121phy_config(rtl8169_device *device) 122{ 123 TRACE("phy_config()\n"); 124 125 if (device->phy_version == 0 || device->phy_version == 1) { 126 uint16 val; 127 TRACE("performing phy init\n"); 128 // XXX this should probably not be done if the phy wasn't 129 // identified, but BSD does it too for mac_version == 0 (=> phy_version also 0) 130 // doing the same as the BSD and Linux driver here 131 // see IEE 802.3-2002 (is also uses decimal numbers when refering 132 // to the registers, as do we). Added a little documentation 133 write_phy_reg(device, 31, 0x0001); // vendor specific (enter programming mode?) 134 write_phy_reg(device, 21, 0x1000); // vendor specific 135 write_phy_reg(device, 24, 0x65c7); // vendor specific 136 write_phy_reg_bit(device, 4, 11, 0); // reset T (T=toggle) bit in reg 4 (ability) 137 val = read_phy_reg(device, 4) & 0x0fff; // get only the message code fields 138 write_phy_reg(device, 4, val); // and write them back. this clears the page and makes it unformatted (see 37.2.4.3.1) 139 write_phy_reg(device, 3, 0x00a1); // assign 32 bit phy identifier high word 140 write_phy_reg(device, 2, 0x0008); // assign 32 bit phy identifier low word 141 write_phy_reg(device, 1, 0x1020); // set status: 10 MBit full duplex and auto negotiation completed 142 write_phy_reg(device, 0, 0x1000); // reset the phy! 143 write_phy_reg_bit(device, 4, 11, 1); // set toggle bit high 144 write_phy_reg_bit(device, 4, 11, 0); // set toggle bit low => this is a toggle 145 val = (read_phy_reg(device, 4) & 0x0fff) | 0x7000; // set ack1, ack2, indicate formatted page 146 write_phy_reg(device, 4, val); // write the value from above 147 write_phy_reg(device, 3, 0xff41); // assign another 148 write_phy_reg(device, 2, 0xde60); // 32 bit phy identifier 149 write_phy_reg(device, 1, 0x0140); // phy will accept management frames with preamble suppressed, extended capability in reg 15 150 write_phy_reg(device, 0, 0x0077); // 151 write_phy_reg_bit(device, 4, 11, 1); // set toggle bit high 152 write_phy_reg_bit(device, 4, 11, 0); // set toggle bit low => this is a toggle 153 val = ( read_phy_reg(device, 4) & 0x0fff) | 0xa000; 154 write_phy_reg(device, 4, val); // 155 write_phy_reg(device, 3, 0xdf01); // assign another 156 write_phy_reg(device, 2, 0xdf20); // 32 bit phy identifier 157 write_phy_reg(device, 1, 0xff95); // phy will do 100Mbit and 10Mbit in full and half duplex, something reserved and 158 // remote fault detected, link is up and extended capability in reg 15 159 write_phy_reg(device, 0, 0xfa00); // select 10 MBit, disable auto neg., half duplex normal operation 160 write_phy_reg_bit(device, 4, 11, 1); // set toggle bit high 161 write_phy_reg_bit(device, 4, 11, 0); // set toggle bit low => this is a toggle 162 val = ( read_phy_reg(device, 4) & 0x0fff) | 0xb000; 163 write_phy_reg(device, 4, val); // write capabilites 164 write_phy_reg(device, 3, 0xff41); // assign another 165 write_phy_reg(device, 2, 0xde20); // 32 bit phy identifier 166 write_phy_reg(device, 1, 0x0140); // phy will accept management frames with preamble suppressed, extended capability in reg 15 167 write_phy_reg(device, 0, 0x00bb); // write status 168 write_phy_reg_bit(device, 4, 11, 1); // set toggle bit high 169 write_phy_reg_bit(device, 4, 11, 0); // set toggle bit low => this is a toggle 170 val = ( read_phy_reg(device, 4) & 0x0fff) | 0xf000; 171 write_phy_reg(device, 4, val); //w 4 15 12 f 172 write_phy_reg(device, 3, 0xdf01); // assign another 173 write_phy_reg(device, 2, 0xdf20); // 32 bit phy identifier 174 write_phy_reg(device, 1, 0xff95); // write capabilites 175 write_phy_reg(device, 0, 0xbf00); // write status 176 write_phy_reg_bit(device, 4, 11, 1); // set toggle bit high 177 write_phy_reg_bit(device, 4, 11, 0); // set toggle bit low => this is a toggle 178 write_phy_reg(device, 31, 0x0000); // vendor specific (leave programming mode?) 179 } 180 181 write_phy_reg(device, 4, 0x01e1); // 10/100 capability 182 write_phy_reg(device, 9, 0x0200); // 1000 capability 183 write_phy_reg(device, 0, 0x1200); // enable auto negotiation and restart it 184} 185 186 187static void 188dump_phy_stat(rtl8169_device *device) 189{ 190 uint32 v = read8(REG_PHY_STAT); 191 if (v & PHY_STAT_EnTBI) { 192 uint32 tbi = read32(REG_TBICSR); 193 TRACE("TBI mode active\n"); 194 if (tbi & TBICSR_ResetTBI) 195 TRACE("TBICSR_ResetTBI\n"); 196 if (tbi & TBICSR_TBILoopBack) 197 TRACE("TBICSR_TBILoopBack\n"); 198 if (tbi & TBICSR_TBINWEn) 199 TRACE("TBICSR_TBINWEn\n"); 200 if (tbi & TBICSR_TBIReNW) 201 TRACE("TBICSR_TBIReNW\n"); 202 if (tbi & TBICSR_TBILinkOk) 203 TRACE("TBICSR_TBILinkOk\n"); 204 if (tbi & TBICSR_NWComplete) 205 TRACE("TBICSR_NWComplete\n"); 206 } else { 207 TRACE("TBI mode NOT active\n"); 208 if (v & PHY_STAT_1000MF) 209 TRACE("PHY_STAT_1000MF\n"); 210 if (v & PHY_STAT_100M) 211 TRACE("PHY_STAT_100M\n"); 212 if (v & PHY_STAT_10M) 213 TRACE("PHY_STAT_10M\n"); 214 } 215 if (v & PHY_STAT_TxFlow) 216 TRACE("PHY_STAT_TxFlow\n"); 217 if (v & PHY_STAT_RxFlow) 218 TRACE("PHY_STAT_RxFlow\n"); 219 if (v & PHY_STAT_LinkSts) 220 TRACE("PHY_STAT_LinkSts\n"); 221 if (v & PHY_STAT_FullDup) 222 TRACE("PHY_STAT_FullDup\n"); 223} 224 225 226static void 227print_link_status(rtl8169_device *device) 228{ 229 uint32 phy = read8(REG_PHY_STAT); 230 if (phy & PHY_STAT_EnTBI) { 231 if (read32(REG_TBICSR) & TBICSR_TBILinkOk) 232 PRINT("Link active, 1000 Mbit Full Duplex (TBI mode)\n"); 233 else 234 PRINT("Link not active (TBI mode)\n"); 235 } else { 236 if (phy & PHY_STAT_LinkSts) { 237 if (phy & PHY_STAT_1000MF) 238 PRINT("Link active, 1000 Mbit Full Duplex (GMII mode)\n"); 239 else 240 PRINT("Link active, %s Mbit %s Duplex (MII mode)\n", 241 (phy & PHY_STAT_100M) ? "100" : (phy & PHY_STAT_10M) ? "10" : "unknown", 242 (phy & PHY_STAT_FullDup) ? "Full" : "Half"); 243 } else { 244 PRINT("Link not active (MII mode)\n"); 245 } 246 } 247} 248 249 250#ifdef PROFILING 251static void 252print_debug_info(void *cookie) 253{ 254 rtl8169_device *device = (rtl8169_device *)cookie; 255 256 // only print if interrupt count changed 257 if (device->intTotalCount == device->intTotalCountOld) 258 return; 259 260 PRINT("Int %10d, %6d/s Rx: %10d, %6d/s Tx: %10d, %6d/s Tmr %10d, %6d/s\n", 261 device->intTotalCount, 262 device->intCurrentCount, 263 device->intRxTotalCount, 264 device->intRxCurrentCount, 265 device->intTxTotalCount, 266 device->intTxCurrentCount, 267 device->intTimerTotalCount, 268 device->intTimerCurrentCount); 269 270 device->intTotalCountOld = device->intTotalCount; 271 device->intCurrentCount = 0; 272 device->intRxCurrentCount = 0; 273 device->intTxCurrentCount = 0; 274 device->intTimerCurrentCount = 0; 275} 276#endif // PROFILING 277 278 279static status_t 280init_buf_desc(rtl8169_device *device) 281{ 282 void *rx_buf_desc_virt, *rx_buf_desc_phy; 283 void *tx_buf_desc_virt, *tx_buf_desc_phy; 284 void *tx_buf_virt, *tx_buf_phy; 285 void *rx_buf_virt, *rx_buf_phy; 286 int i; 287 288 device->txBufArea = alloc_contiguous(&tx_buf_virt, &tx_buf_phy, 289 device->txBufferCount * FRAME_SIZE, 0, "rtl8169 tx buf"); 290 device->rxBufArea = alloc_contiguous(&rx_buf_virt, &rx_buf_phy, 291 device->rxBufferCount * FRAME_SIZE, 0, "rtl8169 rx buf"); 292 device->txDescArea = alloc_contiguous(&tx_buf_desc_virt, &tx_buf_desc_phy, 293 device->txBufferCount * sizeof(buf_desc), 0, "rtl8169 tx desc"); 294 device->rxDescArea = alloc_contiguous(&rx_buf_desc_virt, &rx_buf_desc_phy, 295 device->rxBufferCount * sizeof(buf_desc), 0, "rtl8169 rx desc"); 296 if (device->txBufArea < B_OK || device->rxBufArea < B_OK 297 || device->txDescArea < B_OK || device->rxDescArea < B_OK) 298 return B_NO_MEMORY; 299 300 device->txDesc = (buf_desc *)tx_buf_desc_virt; 301 device->rxDesc = (buf_desc *)rx_buf_desc_virt; 302 303 // setup transmit descriptors 304 for (i = 0; i < device->txBufferCount; i++) { 305 device->txBuf[i] = (char *)tx_buf_virt + (i * FRAME_SIZE); 306 device->txDesc[i].stat_len = TX_DESC_FS | TX_DESC_LS; 307 device->txDesc[i].buf_low 308 = (uint32)((char *)tx_buf_phy + (i * FRAME_SIZE)); 309 device->txDesc[i].buf_high = 0; 310 } 311 device->txDesc[i - 1].stat_len |= TX_DESC_EOR; 312 313 // setup receive descriptors 314 for (i = 0; i < device->rxBufferCount; i++) { 315 device->rxBuf[i] = (char *)rx_buf_virt + (i * FRAME_SIZE); 316 device->rxDesc[i].stat_len = RX_DESC_OWN | FRAME_SIZE; 317 device->rxDesc[i].buf_low 318 = (uint32)((char *)rx_buf_phy + (i * FRAME_SIZE)); 319 device->rxDesc[i].buf_high = 0; 320 } 321 device->rxDesc[i - 1].stat_len |= RX_DESC_EOR; 322 323 write32(REG_RDSAR_LOW, (uint32)rx_buf_desc_phy); 324 write32(REG_RDSAR_HIGH, 0); 325 write32(REG_TNPDS_LOW, (uint32)tx_buf_desc_phy); 326 write32(REG_TNPDS_HIGH, 0); 327 write32(REG_THPDS_LOW, 0); // high priority tx is unused 328 write32(REG_THPDS_HIGH, 0); 329 330 return B_OK; 331} 332 333 334static inline void 335rtl8169_tx_int(rtl8169_device *device) 336{ 337 int32 limit; 338 int32 count; 339 340 acquire_spinlock(&device->txSpinlock); 341 342 for (count = 0, limit = device->txUsed; limit > 0; limit--) { 343 if (device->txDesc[device->txIntIndex].stat_len & TX_DESC_OWN) 344 break; 345 device->txIntIndex = (device->txIntIndex + 1) % device->txBufferCount; 346 count++; 347 } 348 349// dprintf("tx int, txUsed %d, count %d\n", device->txUsed, count); 350 351 device->txUsed -= count; 352 353 release_spinlock(&device->txSpinlock); 354 355 if (count) 356 release_sem_etc(device->txFreeSem, count, B_DO_NOT_RESCHEDULE); 357} 358 359 360static inline void 361rtl8169_rx_int(rtl8169_device *device) 362{ 363 int32 limit; 364 int32 count; 365 366 acquire_spinlock(&device->rxSpinlock); 367 368 for (count = 0, limit = device->rxFree; limit > 0; limit--) { 369 if (device->rxDesc[device->rxIntIndex].stat_len & RX_DESC_OWN) 370 break; 371 device->rxIntIndex = (device->rxIntIndex + 1) % device->rxBufferCount; 372 count++; 373 } 374 375// dprintf("rx int, rxFree %d, count %d\n", device->rxFree, count); 376 377 device->rxFree -= count; 378 379 release_spinlock(&device->rxSpinlock); 380 381 if (count) 382 release_sem_etc(device->rxReadySem, count, B_DO_NOT_RESCHEDULE); 383} 384 385 386static status_t 387rtl8169_get_link_state(rtl8169_device *device) 388{ 389 bool link_ok = false; 390 bool full_duplex = false; 391 uint32 speed = 0; 392 bool linkStateChange = false; 393 uint32 phy; 394 395 dump_phy_stat(device); 396 print_link_status(device); 397 398 phy = read8(REG_PHY_STAT); 399 if (phy & PHY_STAT_EnTBI) { 400 link_ok = (read32(REG_TBICSR) & TBICSR_TBILinkOk); 401 if (link_ok) { 402 speed = 1000000; 403 full_duplex = true; 404 } 405 } else { 406 if (phy & PHY_STAT_LinkSts) { 407 link_ok = true; 408 if (phy & PHY_STAT_1000MF) { 409 speed = 1000000; 410 full_duplex = true; 411 } else { 412 speed = (phy & PHY_STAT_100M) ? 100000 : 10000; 413 full_duplex = (phy & PHY_STAT_FullDup); 414 } 415 } 416 } 417 418 linkStateChange = (link_ok != device->link_ok 419 || full_duplex != device->full_duplex 420 || speed != device->speed); 421 422 device->link_ok = link_ok; 423 device->full_duplex = full_duplex; 424 device->speed = speed; 425 426#ifdef HAIKU_TARGET_PLATFORM_HAIKU 427 if (linkStateChange && device->linkChangeSem >= B_OK) 428 release_sem_etc(device->linkChangeSem, 1, B_DO_NOT_RESCHEDULE); 429#endif 430 431 return B_OK; 432} 433 434 435static int32 436rtl8169_int(void *data) 437{ 438 rtl8169_device *device = (rtl8169_device *)data; 439 uint16 stat; 440 int32 ret; 441 442 stat = read16(REG_INT_STAT); 443 if (stat == 0 || stat == 0xffff) 444 return B_UNHANDLED_INTERRUPT; 445 446 write16(REG_INT_STAT, stat); 447 ret = B_HANDLED_INTERRUPT; 448 449 PROFILING_ONLY(device->intTotalCount++); 450 PROFILING_ONLY(device->intCurrentCount++); 451 452 453 if (stat & INT_TimeOut) { 454 PROFILING_ONLY(device->intTimerTotalCount++); 455 PROFILING_ONLY(device->intTimerCurrentCount++); 456 } 457 458 if (stat & INT_PUN) { 459 rtl8169_get_link_state(device); 460 } 461 462 if (stat & (INT_TOK | INT_TER)) { 463 rtl8169_tx_int(device); 464 PROFILING_ONLY(device->intTxTotalCount++); 465 PROFILING_ONLY(device->intTxCurrentCount++); 466 ret = B_INVOKE_SCHEDULER; 467 } 468 469 if (stat & (INT_ROK | INT_RER | INT_FOVW)) { 470 rtl8169_rx_int(device); 471 PROFILING_ONLY(device->intRxTotalCount++); 472 PROFILING_ONLY(device->intRxCurrentCount++); 473 ret = B_INVOKE_SCHEDULER; 474 } 475 476 return ret; 477} 478 479 480status_t 481rtl8169_open(const char *name, uint32 flags, void** cookie) 482{ 483 rtl8169_device *device; 484 char *deviceName; 485 int mmioIndex; 486 uint32 val; 487 int dev_id; 488 int mask; 489 int i; 490 491 TRACE("rtl8169_open()\n"); 492 493 for (dev_id = 0; (deviceName = gDevNameList[dev_id]) != NULL; dev_id++) { 494 if (!strcmp(name, deviceName)) 495 break; 496 } 497 if (deviceName == NULL) { 498 ERROR("invalid device name\n"); 499 return B_ERROR; 500 } 501 502 // allow only one concurrent access 503 mask = 1 << dev_id; 504 if (atomic_or(&gOpenMask, mask) & mask) 505 return B_BUSY; 506 507 *cookie = device = (rtl8169_device *)malloc(sizeof(rtl8169_device)); 508 if (!device) { 509 atomic_and(&gOpenMask, ~(1 << dev_id)); 510 return B_NO_MEMORY; 511 } 512 513 memset(device, 0, sizeof(*device)); 514 515 device->devId = dev_id; 516 device->pciInfo = gDevList[dev_id]; 517 device->nonblocking = (flags & O_NONBLOCK) ? true : false; 518 device->closed = false; 519 520 // setup defaults 521 device->maxframesize = 1514; // not FRAME_SIZE 522 device->txBufferCount = DEFAULT_TX_BUF_COUNT; 523 device->rxBufferCount = DEFAULT_RX_BUF_COUNT; 524 // get modifications from settings file 525 read_settings(device); 526 527 device->rxBuf = (void **)malloc(sizeof(void *) * device->rxBufferCount); 528 B_INITIALIZE_SPINLOCK(&device->rxSpinlock); 529 device->rxNextIndex = 0; 530 device->rxIntIndex = 0; 531 device->rxFree = device->rxBufferCount; 532 device->rxReadySem = create_sem(0, "rtl8169 rx ready"); 533 534 device->txBuf = (void **)malloc(sizeof(void *) * device->txBufferCount); 535 B_INITIALIZE_SPINLOCK(&device->txSpinlock); 536 device->txNextIndex = 0; 537 device->txIntIndex = 0; 538 device->txUsed = 0; 539 device->txFreeSem = create_sem(device->txBufferCount, "rtl8169 tx free"); 540 541 // enable busmaster and memory mapped access, disable io port access 542 val = gPci->read_pci_config(device->pciInfo->bus, device->pciInfo->device, 543 device->pciInfo->function, PCI_command, 2); 544 val = PCI_PCICMD_BME | PCI_PCICMD_MSE | (val & ~PCI_PCICMD_IOS); 545 gPci->write_pci_config(device->pciInfo->bus, device->pciInfo->device, 546 device->pciInfo->function, PCI_command, 2, val); 547 548 // adjust PCI latency timer 549 TRACE("changing PCI latency to 0x40\n"); 550 gPci->write_pci_config(device->pciInfo->bus, device->pciInfo->device, 551 device->pciInfo->function, PCI_latency, 1, 0x40); 552 553 // get IRQ 554 device->irq = device->pciInfo->u.h0.interrupt_line; 555 if (device->irq == 0 || device->irq == 0xff) { 556 ERROR("no IRQ assigned\n"); 557 goto err; 558 } 559 560 TRACE("IRQ %d\n", device->irq); 561 562 // map registers into memory 563 564 if (device->pciInfo->device_id == 0x8168) 565 mmioIndex = 2; 566 else 567 mmioIndex = 1; 568 569 TRACE("hardware register address [%i] %p\n", mmioIndex, 570 (void *)device->pciInfo->u.h0.base_registers[mmioIndex]); 571 572 device->regArea = map_mem(&device->regAddr, 573 (void *)device->pciInfo->u.h0.base_registers[mmioIndex], 256, 0, 574 "rtl8169 register"); 575 if (device->regArea < B_OK) { 576 ERROR("can't map hardware registers\n"); 577 goto err; 578 } 579 580 TRACE("mapped registers to %p\n", device->regAddr); 581 582 // disable receiver & transmitter XXX might be removed 583 write8(REG_CR, read8(REG_CR) & ~(CR_RE | CR_TE)); 584 585 // do a soft reset 586 write8(REG_CR, read8(REG_CR) | CR_RST); 587 for (i = 0; (read8(REG_CR) & CR_RST) && i < 1000; i++) 588 snooze(10); 589 if (i == 1000) { 590 ERROR("hardware reset failed\n"); 591 goto err; 592 } 593 594 TRACE("reset done\n"); 595 596 // get MAC hardware version 597 device->mac_version = ((read32(REG_TX_CONFIG) & 0x7c000000) >> 25) 598 | ((read32(REG_TX_CONFIG) & 0x00800000) >> 23); 599 TRACE("8169 Mac Version %d\n", device->mac_version); 600 if (device->mac_version > 0) { // this is a RTL8169s single chip 601 // get PHY hardware version 602 device->phy_version = read_phy_reg(device, 0x03) & 0x000f; 603 TRACE("8169 Phy Version %d\n", device->phy_version); 604 } else { 605 // we should probably detect what kind of phy is used 606 device->phy_version = 0; 607 TRACE("8169 Phy Version unknown\n"); 608 } 609 610 if (device->mac_version == 1) { 611 // as it's done by the BSD driver... 612 TRACE("Setting MAC Reg C+CR 0x82h = 0x01h\n"); 613 write8(0x82, 0x01); // don't know what this does 614 TRACE("Setting PHY Reg 0x0bh = 0x00h\n"); 615 write_phy_reg(device, 0x0b, 0x0000); 616 // 0xb is a reserved (vendor specific register), don't know what 617 // this does 618 } 619 620 // configure PHY 621 phy_config(device); 622 623#ifdef HAIKU_TARGET_PLATFORM_HAIKU 624 device->linkChangeSem = -1; 625#endif 626 627 rtl8169_get_link_state(device); 628 629 // initialize MAC address 630 for (i = 0; i < 6; i++) 631 device->macaddr[i] = read8(i); 632 633 TRACE("MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 634 device->macaddr[0], device->macaddr[1], device->macaddr[2], 635 device->macaddr[3], device->macaddr[4], device->macaddr[5]); 636 637 // setup interrupt handler 638 if (install_io_interrupt_handler(device->irq, rtl8169_int, device, 0) 639 < B_OK) { 640 ERROR("can't install interrupt handler\n"); 641 goto err; 642 } 643 644 #ifdef PROFILING 645 device->intTotalCount = 0; 646 device->intTotalCountOld = 0; 647 device->intRxTotalCount = 0; 648 device->intTxTotalCount = 0; 649 device->intTimerTotalCount = 0; 650 device->intCurrentCount = 0; 651 device->intRxCurrentCount = 0; 652 device->intTxCurrentCount = 0; 653 device->intTimerCurrentCount = 0; 654 device->timer = create_timer(print_debug_info, device, 1000000, 655 B_PERIODIC_TIMER); 656 #endif // PROFILING 657 658 write16(0xe0, read16(0xe0)); // write CR+ command 659 660 write16(0xe0, read16(0xe0) | 0x0003); 661 // don't know what this does, BSD says "enable C+ Tx/Rx" 662 663 if (device->mac_version == 1) { 664 TRACE("Setting Reg C+CR bit 3 and bit 14 to 1\n"); 665 // bit 3 is PCI multiple read/write enable (max Tx/Rx DMA burst size 666 // setting is no longer valid then) 667 // bit 14 ??? (need more docs) 668 write16(0xe0, read16(0xe0) | 0x4008); 669 } 670 671 // setup buffer descriptors and buffers 672 if (init_buf_desc(device) != B_OK) { 673 ERROR("setting up buffer descriptors failed\n"); 674 goto err; 675 } 676 677 // enable receiver & transmitter 678 write8(REG_CR, read8(REG_CR) | CR_RE | CR_TE); 679 680 write8(REG_9346CR, 0xc0); // enable config access 681 write8(REG_CONFIG1, read8(REG_CONFIG1) & ~1); // disable power management 682 write8(REG_9346CR, 0x00); // disable config access 683 684 write8(0xec, 0x3f); // disable early transmit treshold 685 write16(0xda, FRAME_SIZE); // receive packet maximum size 686 687 write16(0x5c, read16(0x5c) & 0xf000); // disable early receive interrupts 688 689 write32(0x4c, 0); // RxMissed ??? 690 691 // setup receive config, can only be done when receiver is enabled! 692 // 1024 byte FIFO treshold, 1024 DMA burst 693 write32(REG_RX_CONFIG, (read32(REG_RX_CONFIG) & RX_CONFIG_MASK) 694 | (0x6 << RC_CONFIG_RXFTH_Shift) | (0x6 << RC_CONFIG_MAXDMA_Shift) 695 | RX_CONFIG_AcceptBroad | RX_CONFIG_AcceptMulti 696 | RX_CONFIG_AcceptMyPhys); 697 698 write32(0x8, 0); // multicast filter 699 write32(0xc, 0); // multicast filter 700 701 // setup transmit config, can only be done when transmitter is enabled! 702 // append CRC, 1024 DMA burst 703 write32(REG_TX_CONFIG, (read32(REG_TX_CONFIG) & ~(0x10000 | (1 << 8))) 704 | (0x6 << 8)); 705 706 // clear pending interrupt status 707 write16(REG_INT_STAT, 0xffff); 708 709 // enable used interrupts 710 write16(REG_INT_MASK, INT_FOVW | INT_PUN | INT_TER | INT_TOK | INT_RER 711 | INT_ROK); 712 713 return B_OK; 714 715err: 716 delete_sem(device->rxReadySem); 717 delete_sem(device->txFreeSem); 718 delete_area(device->regArea); 719 delete_area(device->txBufArea); 720 delete_area(device->rxBufArea); 721 delete_area(device->txDescArea); 722 delete_area(device->rxDescArea); 723 free(device->txBuf); 724 free(device->rxBuf); 725 free(device); 726 atomic_and(&gOpenMask, ~(1 << dev_id)); 727 return B_ERROR; 728} 729 730 731status_t 732rtl8169_close(void* cookie) 733{ 734 rtl8169_device *device = (rtl8169_device *)cookie; 735 TRACE("rtl8169_close()\n"); 736 737 device->closed = true; 738 release_sem(device->rxReadySem); 739 release_sem(device->txFreeSem); 740 741 return B_OK; 742} 743 744 745status_t 746rtl8169_free(void* cookie) 747{ 748 rtl8169_device *device = (rtl8169_device *)cookie; 749 TRACE("rtl8169_free()\n"); 750 751 // disable receiver & transmitter 752 write8(REG_CR, read8(REG_CR) & ~(CR_RE | CR_TE)); 753 754 // disable interrupts 755 write16(REG_INT_MASK, 0); 756 757 PROFILING_ONLY(delete_timer(device->timer)); 758 759 // well... 760 remove_io_interrupt_handler (device->irq, rtl8169_int, device); 761 762 delete_sem(device->rxReadySem); 763 delete_sem(device->txFreeSem); 764 delete_area(device->regArea); 765 delete_area(device->txBufArea); 766 delete_area(device->rxBufArea); 767 delete_area(device->txDescArea); 768 delete_area(device->rxDescArea); 769 free(device->txBuf); 770 free(device->rxBuf); 771 free(device); 772 atomic_and(&gOpenMask, ~(1 << device->devId)); 773 return B_OK; 774} 775 776 777status_t 778rtl8169_read(void* cookie, off_t position, void *buf, size_t* numBytes) 779{ 780 rtl8169_device *device = (rtl8169_device *)cookie; 781 cpu_status cpu; 782 status_t stat; 783 int len; 784 TRACE("rtl8169_read() enter\n"); 785 786 if (device->closed) { 787 TRACE("rtl8169_read() interrupted 1\n"); 788 return B_INTERRUPTED; 789 } 790retry: 791 stat = acquire_sem_etc(device->rxReadySem, 1, 792 B_CAN_INTERRUPT | (device->nonblocking ? B_TIMEOUT : 0), 0); 793 if (device->closed) { 794 // TRACE("rtl8169_read() interrupted 2\n"); 795 // net_server will crash if we print this 796 // (race condition in net_server?) 797 return B_INTERRUPTED; 798 } 799 if (stat == B_WOULD_BLOCK) { 800 TRACE("rtl8169_read() would block (OK 0 bytes)\n"); 801 *numBytes = 0; 802 return B_OK; 803 } 804 if (stat != B_OK) { 805 TRACE("rtl8169_read() error\n"); 806 return B_ERROR; 807 } 808 809 if (device->rxDesc[device->rxNextIndex].stat_len & RX_DESC_OWN) { 810 ERROR("rtl8169_read() buffer still in use\n"); 811 goto retry; 812 } 813 814 len = (device->rxDesc[device->rxNextIndex].stat_len & RX_DESC_LEN_MASK); 815 len -= 4; // remove CRC that Realtek always appends 816 if (len < 0) 817 len = 0; 818 if (len > (int)*numBytes) 819 len = *numBytes; 820 821 memcpy(buf, device->rxBuf[device->rxNextIndex], len); 822 *numBytes = len; 823 824 cpu = disable_interrupts(); 825 acquire_spinlock(&device->rxSpinlock); 826 827 device->rxDesc[device->rxNextIndex].stat_len = RX_DESC_OWN | FRAME_SIZE 828 | (device->rxDesc[device->rxNextIndex].stat_len & RX_DESC_EOR); 829 device->rxFree++; 830 831 release_spinlock(&device->rxSpinlock); 832 restore_interrupts(cpu); 833 834 device->rxNextIndex = (device->rxNextIndex + 1) % device->rxBufferCount; 835 836 TRACE("rtl8169_read() leave\n"); 837 return B_OK; 838} 839 840 841status_t 842rtl8169_write(void* cookie, off_t position, const void* buffer, 843 size_t* numBytes) 844{ 845 rtl8169_device *device = (rtl8169_device *)cookie; 846 cpu_status cpu; 847 status_t stat; 848 int len; 849 850 TRACE("rtl8169_write() enter\n"); 851 852 len = *numBytes; 853 if (len > FRAME_SIZE) { 854 TRACE("rtl8169_write() buffer too large\n"); 855 return B_ERROR; 856 } 857 858 if (device->closed) { 859 TRACE("rtl8169_write() interrupted 1\n"); 860 return B_INTERRUPTED; 861 } 862retry: 863 stat = acquire_sem_etc(device->txFreeSem, 1, B_CAN_INTERRUPT | B_TIMEOUT, 864 device->nonblocking ? 0 : TX_TIMEOUT); 865 if (device->closed) { 866 TRACE("rtl8169_write() interrupted 2\n"); 867 return B_INTERRUPTED; 868 } 869 if (stat == B_WOULD_BLOCK) { 870 TRACE("rtl8169_write() would block (OK 0 bytes)\n"); 871 *numBytes = 0; 872 return B_OK; 873 } 874 if (stat == B_TIMED_OUT) { 875 TRACE("rtl8169_write() timeout\n"); 876 return B_BUSY; 877 } 878 if (stat != B_OK) { 879 TRACE("rtl8169_write() error\n"); 880 return B_ERROR; 881 } 882 883 if (device->txDesc[device->txNextIndex].stat_len & TX_DESC_OWN) { 884 ERROR("rtl8169_write() buffer still in use\n"); 885 goto retry; 886 } 887 888 memcpy(device->txBuf[device->txNextIndex], buffer, len); 889 890 cpu = disable_interrupts(); 891 acquire_spinlock(&device->txSpinlock); 892 893 device->txUsed++; 894 device->txDesc[device->txNextIndex].stat_len 895 = (device->txDesc[device->txNextIndex].stat_len & RX_DESC_EOR) 896 | TX_DESC_OWN | TX_DESC_FS | TX_DESC_LS | len; 897 898 release_spinlock(&device->txSpinlock); 899 restore_interrupts(cpu); 900 901 device->txNextIndex = (device->txNextIndex + 1) % device->txBufferCount; 902 903 write8(REG_TPPOLL, read8(REG_TPPOLL) | TPPOLL_NPQ); // set queue polling bit 904 905 TRACE("rtl8169_write() leave\n"); 906 return B_OK; 907} 908 909 910status_t 911rtl8169_control(void *cookie, uint32 op, void *arg, size_t len) 912{ 913 rtl8169_device *device = (rtl8169_device *)cookie; 914 915 switch (op) { 916 case ETHER_INIT: 917 TRACE("rtl8169_control() ETHER_INIT\n"); 918 return B_OK; 919 920 case ETHER_GETADDR: 921 TRACE("rtl8169_control() ETHER_GETADDR\n"); 922 memcpy(arg, &device->macaddr, sizeof(device->macaddr)); 923 return B_OK; 924 925 case ETHER_NONBLOCK: 926 if (*(int32 *)arg) { 927 TRACE("non blocking mode on\n"); 928 device->nonblocking = true; 929 /* could be used to unblock pending read and write calls, 930 * but this doesn't seem to be required 931 release_sem_etc(device->txFreeSem, 1, B_DO_NOT_RESCHEDULE); 932 release_sem_etc(device->rxReadySem, 1, B_DO_NOT_RESCHEDULE); 933 */ 934 } else { 935 TRACE("non blocking mode off\n"); 936 device->nonblocking = false; 937 } 938 return B_OK; 939 940 case ETHER_ADDMULTI: 941 TRACE("rtl8169_control() ETHER_ADDMULTI\n"); 942 break; 943 944 case ETHER_REMMULTI: 945 TRACE("rtl8169_control() ETHER_REMMULTI\n"); 946 return B_OK; 947 948 case ETHER_SETPROMISC: 949 if (*(int32 *)arg) { 950 TRACE("promiscuous mode on\n"); 951 write32(REG_RX_CONFIG, read32(REG_RX_CONFIG) 952 | RX_CONFIG_AcceptAllPhys); 953 write32(0x8, 0xffffffff); // multicast filter 954 write32(0xc, 0xffffffff); // multicast filter 955 } else { 956 TRACE("promiscuous mode off\n"); 957 write32(REG_RX_CONFIG, read32(REG_RX_CONFIG) 958 & ~RX_CONFIG_AcceptAllPhys); 959 write32(0x8, 0); // multicast filter 960 write32(0xc, 0); // multicast filter 961 } 962 return B_OK; 963 964 case ETHER_GETFRAMESIZE: 965 TRACE("rtl8169_control() ETHER_GETFRAMESIZE, framesize = %d (MTU = %d)\n", device->maxframesize, device->maxframesize - 14); 966 *(uint32*)arg = device->maxframesize; 967 return B_OK; 968 969#ifdef HAIKU_TARGET_PLATFORM_HAIKU 970 case ETHER_GET_LINK_STATE: 971 { 972 ether_link_state_t state; 973 974 state.media = IFM_ETHER; 975 state.media |= (device->link_ok ? IFM_ACTIVE : 0); 976 state.media |= (device->full_duplex ? IFM_FULL_DUPLEX : IFM_HALF_DUPLEX); 977 if (device->speed == 1000000000) 978 state.media |= IFM_1000_T; 979 else if (device->speed == 100000000) 980 state.media |= IFM_100_TX; 981 else if (device->speed == 10000000) 982 state.media |= IFM_10_T; 983 984 state.speed = device->speed; 985 state.quality = 1000; 986 987 return user_memcpy(arg, &state, sizeof(ether_link_state_t)); 988 } 989 990 case ETHER_SET_LINK_STATE_SEM: 991 { 992 if (user_memcpy(&device->linkChangeSem, arg, sizeof(sem_id)) < B_OK) { 993 device->linkChangeSem = -1; 994 return B_BAD_ADDRESS; 995 } 996 return B_OK; 997 } 998#endif 999 1000 default: 1001 TRACE("rtl8169_control() Invalid command\n"); 1002 break; 1003 } 1004 1005 return B_ERROR; 1006} 1007 1008