aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/8139too.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/8139too.c')
-rw-r--r--drivers/net/8139too.c344
1 files changed, 169 insertions, 175 deletions
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 76d3048a1a63..7ba470ee2175 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -291,198 +291,197 @@ static struct {
291 291
292/* Symbolic offsets to registers. */ 292/* Symbolic offsets to registers. */
293enum RTL8139_registers { 293enum RTL8139_registers {
294 MAC0 = 0, /* Ethernet hardware address. */ 294 MAC0 = 0, /* Ethernet hardware address. */
295 MAR0 = 8, /* Multicast filter. */ 295 MAR0 = 8, /* Multicast filter. */
296 TxStatus0 = 0x10, /* Transmit status (Four 32bit registers). */ 296 TxStatus0 = 0x10, /* Transmit status (Four 32bit registers). */
297 TxAddr0 = 0x20, /* Tx descriptors (also four 32bit). */ 297 TxAddr0 = 0x20, /* Tx descriptors (also four 32bit). */
298 RxBuf = 0x30, 298 RxBuf = 0x30,
299 ChipCmd = 0x37, 299 ChipCmd = 0x37,
300 RxBufPtr = 0x38, 300 RxBufPtr = 0x38,
301 RxBufAddr = 0x3A, 301 RxBufAddr = 0x3A,
302 IntrMask = 0x3C, 302 IntrMask = 0x3C,
303 IntrStatus = 0x3E, 303 IntrStatus = 0x3E,
304 TxConfig = 0x40, 304 TxConfig = 0x40,
305 RxConfig = 0x44, 305 RxConfig = 0x44,
306 Timer = 0x48, /* A general-purpose counter. */ 306 Timer = 0x48, /* A general-purpose counter. */
307 RxMissed = 0x4C, /* 24 bits valid, write clears. */ 307 RxMissed = 0x4C, /* 24 bits valid, write clears. */
308 Cfg9346 = 0x50, 308 Cfg9346 = 0x50,
309 Config0 = 0x51, 309 Config0 = 0x51,
310 Config1 = 0x52, 310 Config1 = 0x52,
311 FlashReg = 0x54, 311 FlashReg = 0x54,
312 MediaStatus = 0x58, 312 MediaStatus = 0x58,
313 Config3 = 0x59, 313 Config3 = 0x59,
314 Config4 = 0x5A, /* absent on RTL-8139A */ 314 Config4 = 0x5A, /* absent on RTL-8139A */
315 HltClk = 0x5B, 315 HltClk = 0x5B,
316 MultiIntr = 0x5C, 316 MultiIntr = 0x5C,
317 TxSummary = 0x60, 317 TxSummary = 0x60,
318 BasicModeCtrl = 0x62, 318 BasicModeCtrl = 0x62,
319 BasicModeStatus = 0x64, 319 BasicModeStatus = 0x64,
320 NWayAdvert = 0x66, 320 NWayAdvert = 0x66,
321 NWayLPAR = 0x68, 321 NWayLPAR = 0x68,
322 NWayExpansion = 0x6A, 322 NWayExpansion = 0x6A,
323 /* Undocumented registers, but required for proper operation. */ 323 /* Undocumented registers, but required for proper operation. */
324 FIFOTMS = 0x70, /* FIFO Control and test. */ 324 FIFOTMS = 0x70, /* FIFO Control and test. */
325 CSCR = 0x74, /* Chip Status and Configuration Register. */ 325 CSCR = 0x74, /* Chip Status and Configuration Register. */
326 PARA78 = 0x78, 326 PARA78 = 0x78,
327 PARA7c = 0x7c, /* Magic transceiver parameter register. */ 327 PARA7c = 0x7c, /* Magic transceiver parameter register. */
328 Config5 = 0xD8, /* absent on RTL-8139A */ 328 Config5 = 0xD8, /* absent on RTL-8139A */
329}; 329};
330 330
331enum ClearBitMasks { 331enum ClearBitMasks {
332 MultiIntrClear = 0xF000, 332 MultiIntrClear = 0xF000,
333 ChipCmdClear = 0xE2, 333 ChipCmdClear = 0xE2,
334 Config1Clear = (1<<7)|(1<<6)|(1<<3)|(1<<2)|(1<<1), 334 Config1Clear = (1<<7)|(1<<6)|(1<<3)|(1<<2)|(1<<1),
335}; 335};
336 336
337enum ChipCmdBits { 337enum ChipCmdBits {
338 CmdReset = 0x10, 338 CmdReset = 0x10,
339 CmdRxEnb = 0x08, 339 CmdRxEnb = 0x08,
340 CmdTxEnb = 0x04, 340 CmdTxEnb = 0x04,
341 RxBufEmpty = 0x01, 341 RxBufEmpty = 0x01,
342}; 342};
343 343
344/* Interrupt register bits, using my own meaningful names. */ 344/* Interrupt register bits, using my own meaningful names. */
345enum IntrStatusBits { 345enum IntrStatusBits {
346 PCIErr = 0x8000, 346 PCIErr = 0x8000,
347 PCSTimeout = 0x4000, 347 PCSTimeout = 0x4000,
348 RxFIFOOver = 0x40, 348 RxFIFOOver = 0x40,
349 RxUnderrun = 0x20, 349 RxUnderrun = 0x20,
350 RxOverflow = 0x10, 350 RxOverflow = 0x10,
351 TxErr = 0x08, 351 TxErr = 0x08,
352 TxOK = 0x04, 352 TxOK = 0x04,
353 RxErr = 0x02, 353 RxErr = 0x02,
354 RxOK = 0x01, 354 RxOK = 0x01,
355 355
356 RxAckBits = RxFIFOOver | RxOverflow | RxOK, 356 RxAckBits = RxFIFOOver | RxOverflow | RxOK,
357}; 357};
358 358
359enum TxStatusBits { 359enum TxStatusBits {
360 TxHostOwns = 0x2000, 360 TxHostOwns = 0x2000,
361 TxUnderrun = 0x4000, 361 TxUnderrun = 0x4000,
362 TxStatOK = 0x8000, 362 TxStatOK = 0x8000,
363 TxOutOfWindow = 0x20000000, 363 TxOutOfWindow = 0x20000000,
364 TxAborted = 0x40000000, 364 TxAborted = 0x40000000,
365 TxCarrierLost = 0x80000000, 365 TxCarrierLost = 0x80000000,
366}; 366};
367enum RxStatusBits { 367enum RxStatusBits {
368 RxMulticast = 0x8000, 368 RxMulticast = 0x8000,
369 RxPhysical = 0x4000, 369 RxPhysical = 0x4000,
370 RxBroadcast = 0x2000, 370 RxBroadcast = 0x2000,
371 RxBadSymbol = 0x0020, 371 RxBadSymbol = 0x0020,
372 RxRunt = 0x0010, 372 RxRunt = 0x0010,
373 RxTooLong = 0x0008, 373 RxTooLong = 0x0008,
374 RxCRCErr = 0x0004, 374 RxCRCErr = 0x0004,
375 RxBadAlign = 0x0002, 375 RxBadAlign = 0x0002,
376 RxStatusOK = 0x0001, 376 RxStatusOK = 0x0001,
377}; 377};
378 378
379/* Bits in RxConfig. */ 379/* Bits in RxConfig. */
380enum rx_mode_bits { 380enum rx_mode_bits {
381 AcceptErr = 0x20, 381 AcceptErr = 0x20,
382 AcceptRunt = 0x10, 382 AcceptRunt = 0x10,
383 AcceptBroadcast = 0x08, 383 AcceptBroadcast = 0x08,
384 AcceptMulticast = 0x04, 384 AcceptMulticast = 0x04,
385 AcceptMyPhys = 0x02, 385 AcceptMyPhys = 0x02,
386 AcceptAllPhys = 0x01, 386 AcceptAllPhys = 0x01,
387}; 387};
388 388
389/* Bits in TxConfig. */ 389/* Bits in TxConfig. */
390enum tx_config_bits { 390enum tx_config_bits {
391
392 /* Interframe Gap Time. Only TxIFG96 doesn't violate IEEE 802.3 */ 391 /* Interframe Gap Time. Only TxIFG96 doesn't violate IEEE 802.3 */
393 TxIFGShift = 24, 392 TxIFGShift = 24,
394 TxIFG84 = (0 << TxIFGShift), /* 8.4us / 840ns (10 / 100Mbps) */ 393 TxIFG84 = (0 << TxIFGShift), /* 8.4us / 840ns (10 / 100Mbps) */
395 TxIFG88 = (1 << TxIFGShift), /* 8.8us / 880ns (10 / 100Mbps) */ 394 TxIFG88 = (1 << TxIFGShift), /* 8.8us / 880ns (10 / 100Mbps) */
396 TxIFG92 = (2 << TxIFGShift), /* 9.2us / 920ns (10 / 100Mbps) */ 395 TxIFG92 = (2 << TxIFGShift), /* 9.2us / 920ns (10 / 100Mbps) */
397 TxIFG96 = (3 << TxIFGShift), /* 9.6us / 960ns (10 / 100Mbps) */ 396 TxIFG96 = (3 << TxIFGShift), /* 9.6us / 960ns (10 / 100Mbps) */
398 397
399 TxLoopBack = (1 << 18) | (1 << 17), /* enable loopback test mode */ 398 TxLoopBack = (1 << 18) | (1 << 17), /* enable loopback test mode */
400 TxCRC = (1 << 16), /* DISABLE appending CRC to end of Tx packets */ 399 TxCRC = (1 << 16), /* DISABLE Tx pkt CRC append */
401 TxClearAbt = (1 << 0), /* Clear abort (WO) */ 400 TxClearAbt = (1 << 0), /* Clear abort (WO) */
402 TxDMAShift = 8, /* DMA burst value (0-7) is shifted this many bits */ 401 TxDMAShift = 8, /* DMA burst value (0-7) is shifted X many bits */
403 TxRetryShift = 4, /* TXRR value (0-15) is shifted this many bits */ 402 TxRetryShift = 4, /* TXRR value (0-15) is shifted X many bits */
404 403
405 TxVersionMask = 0x7C800000, /* mask out version bits 30-26, 23 */ 404 TxVersionMask = 0x7C800000, /* mask out version bits 30-26, 23 */
406}; 405};
407 406
408/* Bits in Config1 */ 407/* Bits in Config1 */
409enum Config1Bits { 408enum Config1Bits {
410 Cfg1_PM_Enable = 0x01, 409 Cfg1_PM_Enable = 0x01,
411 Cfg1_VPD_Enable = 0x02, 410 Cfg1_VPD_Enable = 0x02,
412 Cfg1_PIO = 0x04, 411 Cfg1_PIO = 0x04,
413 Cfg1_MMIO = 0x08, 412 Cfg1_MMIO = 0x08,
414 LWAKE = 0x10, /* not on 8139, 8139A */ 413 LWAKE = 0x10, /* not on 8139, 8139A */
415 Cfg1_Driver_Load = 0x20, 414 Cfg1_Driver_Load = 0x20,
416 Cfg1_LED0 = 0x40, 415 Cfg1_LED0 = 0x40,
417 Cfg1_LED1 = 0x80, 416 Cfg1_LED1 = 0x80,
418 SLEEP = (1 << 1), /* only on 8139, 8139A */ 417 SLEEP = (1 << 1), /* only on 8139, 8139A */
419 PWRDN = (1 << 0), /* only on 8139, 8139A */ 418 PWRDN = (1 << 0), /* only on 8139, 8139A */
420}; 419};
421 420
422/* Bits in Config3 */ 421/* Bits in Config3 */
423enum Config3Bits { 422enum Config3Bits {
424 Cfg3_FBtBEn = (1 << 0), /* 1 = Fast Back to Back */ 423 Cfg3_FBtBEn = (1 << 0), /* 1 = Fast Back to Back */
425 Cfg3_FuncRegEn = (1 << 1), /* 1 = enable CardBus Function registers */ 424 Cfg3_FuncRegEn = (1 << 1), /* 1 = enable CardBus Function registers */
426 Cfg3_CLKRUN_En = (1 << 2), /* 1 = enable CLKRUN */ 425 Cfg3_CLKRUN_En = (1 << 2), /* 1 = enable CLKRUN */
427 Cfg3_CardB_En = (1 << 3), /* 1 = enable CardBus registers */ 426 Cfg3_CardB_En = (1 << 3), /* 1 = enable CardBus registers */
428 Cfg3_LinkUp = (1 << 4), /* 1 = wake up on link up */ 427 Cfg3_LinkUp = (1 << 4), /* 1 = wake up on link up */
429 Cfg3_Magic = (1 << 5), /* 1 = wake up on Magic Packet (tm) */ 428 Cfg3_Magic = (1 << 5), /* 1 = wake up on Magic Packet (tm) */
430 Cfg3_PARM_En = (1 << 6), /* 0 = software can set twister parameters */ 429 Cfg3_PARM_En = (1 << 6), /* 0 = software can set twister parameters */
431 Cfg3_GNTSel = (1 << 7), /* 1 = delay 1 clock from PCI GNT signal */ 430 Cfg3_GNTSel = (1 << 7), /* 1 = delay 1 clock from PCI GNT signal */
432}; 431};
433 432
434/* Bits in Config4 */ 433/* Bits in Config4 */
435enum Config4Bits { 434enum Config4Bits {
436 LWPTN = (1 << 2), /* not on 8139, 8139A */ 435 LWPTN = (1 << 2), /* not on 8139, 8139A */
437}; 436};
438 437
439/* Bits in Config5 */ 438/* Bits in Config5 */
440enum Config5Bits { 439enum Config5Bits {
441 Cfg5_PME_STS = (1 << 0), /* 1 = PCI reset resets PME_Status */ 440 Cfg5_PME_STS = (1 << 0), /* 1 = PCI reset resets PME_Status */
442 Cfg5_LANWake = (1 << 1), /* 1 = enable LANWake signal */ 441 Cfg5_LANWake = (1 << 1), /* 1 = enable LANWake signal */
443 Cfg5_LDPS = (1 << 2), /* 0 = save power when link is down */ 442 Cfg5_LDPS = (1 << 2), /* 0 = save power when link is down */
444 Cfg5_FIFOAddrPtr = (1 << 3), /* Realtek internal SRAM testing */ 443 Cfg5_FIFOAddrPtr= (1 << 3), /* Realtek internal SRAM testing */
445 Cfg5_UWF = (1 << 4), /* 1 = accept unicast wakeup frame */ 444 Cfg5_UWF = (1 << 4), /* 1 = accept unicast wakeup frame */
446 Cfg5_MWF = (1 << 5), /* 1 = accept multicast wakeup frame */ 445 Cfg5_MWF = (1 << 5), /* 1 = accept multicast wakeup frame */
447 Cfg5_BWF = (1 << 6), /* 1 = accept broadcast wakeup frame */ 446 Cfg5_BWF = (1 << 6), /* 1 = accept broadcast wakeup frame */
448}; 447};
449 448
450enum RxConfigBits { 449enum RxConfigBits {
451 /* rx fifo threshold */ 450 /* rx fifo threshold */
452 RxCfgFIFOShift = 13, 451 RxCfgFIFOShift = 13,
453 RxCfgFIFONone = (7 << RxCfgFIFOShift), 452 RxCfgFIFONone = (7 << RxCfgFIFOShift),
454 453
455 /* Max DMA burst */ 454 /* Max DMA burst */
456 RxCfgDMAShift = 8, 455 RxCfgDMAShift = 8,
457 RxCfgDMAUnlimited = (7 << RxCfgDMAShift), 456 RxCfgDMAUnlimited = (7 << RxCfgDMAShift),
458 457
459 /* rx ring buffer length */ 458 /* rx ring buffer length */
460 RxCfgRcv8K = 0, 459 RxCfgRcv8K = 0,
461 RxCfgRcv16K = (1 << 11), 460 RxCfgRcv16K = (1 << 11),
462 RxCfgRcv32K = (1 << 12), 461 RxCfgRcv32K = (1 << 12),
463 RxCfgRcv64K = (1 << 11) | (1 << 12), 462 RxCfgRcv64K = (1 << 11) | (1 << 12),
464 463
465 /* Disable packet wrap at end of Rx buffer. (not possible with 64k) */ 464 /* Disable packet wrap at end of Rx buffer. (not possible with 64k) */
466 RxNoWrap = (1 << 7), 465 RxNoWrap = (1 << 7),
467}; 466};
468 467
469/* Twister tuning parameters from RealTek. 468/* Twister tuning parameters from RealTek.
470 Completely undocumented, but required to tune bad links on some boards. */ 469 Completely undocumented, but required to tune bad links on some boards. */
471enum CSCRBits { 470enum CSCRBits {
472 CSCR_LinkOKBit = 0x0400, 471 CSCR_LinkOKBit = 0x0400,
473 CSCR_LinkChangeBit = 0x0800, 472 CSCR_LinkChangeBit = 0x0800,
474 CSCR_LinkStatusBits = 0x0f000, 473 CSCR_LinkStatusBits = 0x0f000,
475 CSCR_LinkDownOffCmd = 0x003c0, 474 CSCR_LinkDownOffCmd = 0x003c0,
476 CSCR_LinkDownCmd = 0x0f3c0, 475 CSCR_LinkDownCmd = 0x0f3c0,
477}; 476};
478 477
479enum Cfg9346Bits { 478enum Cfg9346Bits {
480 Cfg9346_Lock = 0x00, 479 Cfg9346_Lock = 0x00,
481 Cfg9346_Unlock = 0xC0, 480 Cfg9346_Unlock = 0xC0,
482}; 481};
483 482
484typedef enum { 483typedef enum {
485 CH_8139 = 0, 484 CH_8139 = 0,
486 CH_8139_K, 485 CH_8139_K,
487 CH_8139A, 486 CH_8139A,
488 CH_8139A_G, 487 CH_8139A_G,
@@ -495,8 +494,8 @@ typedef enum {
495} chip_t; 494} chip_t;
496 495
497enum chip_flags { 496enum chip_flags {
498 HasHltClk = (1 << 0), 497 HasHltClk = (1 << 0),
499 HasLWake = (1 << 1), 498 HasLWake = (1 << 1),
500}; 499};
501 500
502#define HW_REVID(b30, b29, b28, b27, b26, b23, b22) \ 501#define HW_REVID(b30, b29, b28, b27, b26, b23, b22) \
@@ -569,38 +568,46 @@ struct rtl_extra_stats {
569}; 568};
570 569
571struct rtl8139_private { 570struct rtl8139_private {
572 void __iomem *mmio_addr; 571 void __iomem *mmio_addr;
573 int drv_flags; 572 int drv_flags;
574 struct pci_dev *pci_dev; 573 struct pci_dev *pci_dev;
575 u32 msg_enable; 574 u32 msg_enable;
576 struct napi_struct napi; 575 struct napi_struct napi;
577 struct net_device *dev; 576 struct net_device *dev;
578 struct net_device_stats stats; 577 struct net_device_stats stats;
579 unsigned char *rx_ring; 578
580 unsigned int cur_rx; /* Index into the Rx buffer of next Rx pkt. */ 579 unsigned char *rx_ring;
581 unsigned int tx_flag; 580 unsigned int cur_rx; /* RX buf index of next pkt */
582 unsigned long cur_tx; 581 dma_addr_t rx_ring_dma;
583 unsigned long dirty_tx; 582
584 unsigned char *tx_buf[NUM_TX_DESC]; /* Tx bounce buffers */ 583 unsigned int tx_flag;
585 unsigned char *tx_bufs; /* Tx bounce buffer region. */ 584 unsigned long cur_tx;
586 dma_addr_t rx_ring_dma; 585 unsigned long dirty_tx;
587 dma_addr_t tx_bufs_dma; 586 unsigned char *tx_buf[NUM_TX_DESC]; /* Tx bounce buffers */
588 signed char phys[4]; /* MII device addresses. */ 587 unsigned char *tx_bufs; /* Tx bounce buffer region. */
589 char twistie, twist_row, twist_col; /* Twister tune state. */ 588 dma_addr_t tx_bufs_dma;
590 unsigned int watchdog_fired : 1; 589
591 unsigned int default_port : 4; /* Last dev->if_port value. */ 590 signed char phys[4]; /* MII device addresses. */
592 unsigned int have_thread : 1; 591
593 spinlock_t lock; 592 /* Twister tune state. */
594 spinlock_t rx_lock; 593 char twistie, twist_row, twist_col;
595 chip_t chipset; 594
596 u32 rx_config; 595 unsigned int watchdog_fired : 1;
597 struct rtl_extra_stats xstats; 596 unsigned int default_port : 4; /* Last dev->if_port value. */
598 597 unsigned int have_thread : 1;
599 struct delayed_work thread; 598
600 599 spinlock_t lock;
601 struct mii_if_info mii; 600 spinlock_t rx_lock;
602 unsigned int regs_len; 601
603 unsigned long fifo_copy_timeout; 602 chip_t chipset;
603 u32 rx_config;
604 struct rtl_extra_stats xstats;
605
606 struct delayed_work thread;
607
608 struct mii_if_info mii;
609 unsigned int regs_len;
610 unsigned long fifo_copy_timeout;
604}; 611};
605 612
606MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>"); 613MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>");
@@ -648,24 +655,11 @@ static const struct ethtool_ops rtl8139_ethtool_ops;
648#define RTL_W16_F(reg, val16) do { iowrite16 ((val16), ioaddr + (reg)); ioread16 (ioaddr + (reg)); } while (0) 655#define RTL_W16_F(reg, val16) do { iowrite16 ((val16), ioaddr + (reg)); ioread16 (ioaddr + (reg)); } while (0)
649#define RTL_W32_F(reg, val32) do { iowrite32 ((val32), ioaddr + (reg)); ioread32 (ioaddr + (reg)); } while (0) 656#define RTL_W32_F(reg, val32) do { iowrite32 ((val32), ioaddr + (reg)); ioread32 (ioaddr + (reg)); } while (0)
650 657
651
652#define MMIO_FLUSH_AUDIT_COMPLETE 1
653#if MMIO_FLUSH_AUDIT_COMPLETE
654
655/* write MMIO register */ 658/* write MMIO register */
656#define RTL_W8(reg, val8) iowrite8 ((val8), ioaddr + (reg)) 659#define RTL_W8(reg, val8) iowrite8 ((val8), ioaddr + (reg))
657#define RTL_W16(reg, val16) iowrite16 ((val16), ioaddr + (reg)) 660#define RTL_W16(reg, val16) iowrite16 ((val16), ioaddr + (reg))
658#define RTL_W32(reg, val32) iowrite32 ((val32), ioaddr + (reg)) 661#define RTL_W32(reg, val32) iowrite32 ((val32), ioaddr + (reg))
659 662
660#else
661
662/* write MMIO register, then flush */
663#define RTL_W8 RTL_W8_F
664#define RTL_W16 RTL_W16_F
665#define RTL_W32 RTL_W32_F
666
667#endif /* MMIO_FLUSH_AUDIT_COMPLETE */
668
669/* read MMIO register */ 663/* read MMIO register */
670#define RTL_R8(reg) ioread8 (ioaddr + (reg)) 664#define RTL_R8(reg) ioread8 (ioaddr + (reg))
671#define RTL_R16(reg) ioread16 (ioaddr + (reg)) 665#define RTL_R16(reg) ioread16 (ioaddr + (reg))