Warning, cross-references for /kernel/drivers/net/r8169.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include "drivers/pci/pci.h"
0023 #include "drivers/net/ethernet.h"
0024 #include "drivers/net/skbuff.h"
0025 #include "arch/i386.h"
0026 #include "util/printf.h"
0027 #include "util/bitrev.h"
0028 #include "util/crc32.h"
0029 #include "smp/smp.h"
0030 #include "smp/apic.h"
0031 #include "mem/physical.h"
0032 #include "mem/virtual.h"
0033 #include "mem/pow2.h"
0034 #include "kernel.h"
0035 #include "sched/vcpu.h"
0036 #include "sched/sched.h"
0037 #include "module/header.h"
0038
0039
0040 #define TX_TIMING
0041
0042 #ifdef TX_TIMING
0043 #include "lwip/udp.h"
0044 #endif
0045
0046 #ifdef DEBUG_R8169
0047 #define DLOG(fmt,...) DLOG_PREFIX("r8169",fmt,##__VA_ARGS__)
0048 #else
0049 #define DLOG(fmt,...) ;
0050 #endif
0051
0052 #define udelay tsc_delay_usec
0053 #define net_device _ethernet_device
0054 #define netdev_priv(x) (x)->drvdata
0055 #define pci_get_drvdata(x) (x)->drvdata
0056
0057 #define PCI_SUBSYSTEM_VENDOR_ID 0x2c
0058 #define PCI_SUBSYSTEM_ID 0x2e
0059 #define PCI_CACHE_LINE_SIZE 0x0c
0060 #define PCI_LATENCY_TIMER 0x0d
0061
0062 static void
0063 pci_write_config_word (pci_device *p, u32 offset, u16 val)
0064 {
0065 pci_write_word (pci_addr (p->bus, p->slot, p->func, offset), val);
0066 }
0067
0068 static void
0069 pci_write_config_byte (pci_device *p, u32 offset, u8 val)
0070 {
0071 pci_write_byte (pci_addr (p->bus, p->slot, p->func, offset), val);
0072 }
0073
0074 static void
0075 pci_read_config_word (pci_device *p, u32 offset, u16 *val)
0076 {
0077 *val = pci_read_word (pci_addr (p->bus, p->slot, p->func, offset));
0078 }
0079
0080
0081 #define SPEED_10 10
0082 #define SPEED_100 100
0083 #define SPEED_1000 1000
0084 #define SPEED_2500 2500
0085 #define SPEED_10000 10000
0086
0087
0088 #define DUPLEX_HALF 0x00
0089 #define DUPLEX_FULL 0x01
0090
0091 #define AUTONEG_DISABLE 0x00
0092 #define AUTONEG_ENABLE 0x01
0093
0094
0095 #define ADVERTISE_1000FULL 0x0200
0096 #define ADVERTISE_1000HALF 0x0100
0097
0098
0099 #define ADVERTISE_SLCT 0x001f
0100 #define ADVERTISE_CSMA 0x0001
0101 #define ADVERTISE_10HALF 0x0020
0102 #define ADVERTISE_1000XFULL 0x0020
0103 #define ADVERTISE_10FULL 0x0040
0104 #define ADVERTISE_1000XHALF 0x0040
0105 #define ADVERTISE_100HALF 0x0080
0106 #define ADVERTISE_1000XPAUSE 0x0080
0107 #define ADVERTISE_100FULL 0x0100
0108 #define ADVERTISE_1000XPSE_ASYM 0x0100
0109 #define ADVERTISE_100BASE4 0x0200
0110 #define ADVERTISE_PAUSE_CAP 0x0400
0111 #define ADVERTISE_PAUSE_ASYM 0x0800
0112 #define ADVERTISE_RESV 0x1000
0113 #define ADVERTISE_RFAULT 0x2000
0114 #define ADVERTISE_LPACK 0x4000
0115 #define ADVERTISE_NPAGE 0x8000
0116
0117 #define MII_BMCR 0x00
0118 #define MII_BMSR 0x01
0119 #define MII_PHYSID1 0x02
0120 #define MII_PHYSID2 0x03
0121 #define MII_ADVERTISE 0x04
0122 #define MII_LPA 0x05
0123 #define MII_EXPANSION 0x06
0124 #define MII_CTRL1000 0x09
0125 #define MII_STAT1000 0x0a
0126 #define MII_ESTATUS 0x0f
0127 #define MII_DCOUNTER 0x12
0128 #define MII_FCSCOUNTER 0x13
0129 #define MII_NWAYTEST 0x14
0130 #define MII_RERRCOUNTER 0x15
0131 #define MII_SREVISION 0x16
0132 #define MII_RESV1 0x17
0133 #define MII_LBRERROR 0x18
0134 #define MII_PHYADDR 0x19
0135 #define MII_RESV2 0x1a
0136 #define MII_TPISTATUS 0x1b
0137 #define MII_NCONFIG 0x1c
0138
0139
0140 #define BMCR_RESV 0x003f
0141 #define BMCR_SPEED1000 0x0040
0142 #define BMCR_CTST 0x0080
0143 #define BMCR_FULLDPLX 0x0100
0144 #define BMCR_ANRESTART 0x0200
0145 #define BMCR_ISOLATE 0x0400
0146 #define BMCR_PDOWN 0x0800
0147 #define BMCR_ANENABLE 0x1000
0148 #define BMCR_SPEED100 0x2000
0149 #define BMCR_LOOPBACK 0x4000
0150 #define BMCR_RESET 0x8000
0151
0152
0153
0154 #define MAC_ADDR_LEN 6
0155
0156 #define MAX_READ_REQUEST_SHIFT 12
0157 #define RX_FIFO_THRESH 7
0158 #define RX_DMA_BURST 6
0159 #define TX_DMA_BURST 6
0160 #define EarlyTxThld 0x3F
0161 #define SafeMtu 0x1c20
0162 #define InterFrameGap 0x03
0163
0164 #define R8169_REGS_SIZE 256
0165 #define R8169_NAPI_WEIGHT 64
0166 #define NUM_TX_DESC 64
0167 #define NUM_RX_DESC 256
0168 #define RX_BUF_SIZE 1536
0169 #define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc))
0170 #define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc))
0171
0172 #define RTL8169_TX_TIMEOUT (6*HZ)
0173 #define RTL8169_PHY_TIMEOUT (10*HZ)
0174
0175 #define RTL_EEPROM_SIG cpu_to_le32(0x8129)
0176 #define RTL_EEPROM_SIG_MASK cpu_to_le32(0xffff)
0177 #define RTL_EEPROM_SIG_ADDR 0x0000
0178
0179 static inline u8
0180 __raw_readb(const volatile void *addr)
0181 {
0182 return *(const volatile u8 *) addr;
0183 }
0184
0185 static inline u16
0186 __raw_readw(const volatile void *addr)
0187 {
0188 return *(const volatile u16 *) addr;
0189 }
0190
0191 static inline u32
0192 __raw_readl(const volatile void *addr)
0193 {
0194 return *(const volatile u32 *) addr;
0195 }
0196
0197 static inline void
0198 __raw_writeb(u8 b, volatile void *addr)
0199 {
0200 *(volatile u8 *) addr = b;
0201 }
0202
0203 static inline void
0204 __raw_writew(u16 b, volatile void *addr)
0205 {
0206 *(volatile u16 *) addr = b;
0207 }
0208
0209 static inline void
0210 __raw_writel(u32 b, volatile void *addr)
0211 {
0212 *(volatile u32 *) addr = b;
0213 }
0214
0215
0216 #define RTL_W8(reg, val8) __raw_writeb ((val8), ioaddr + (reg))
0217 #define RTL_W16(reg, val16) __raw_writew ((val16), ioaddr + (reg))
0218 #define RTL_W32(reg, val32) __raw_writel ((val32), ioaddr + (reg))
0219 #define RTL_R8(reg) __raw_readb (ioaddr + (reg))
0220 #define RTL_R16(reg) __raw_readw (ioaddr + (reg))
0221 #define RTL_R32(reg) __raw_readl (ioaddr + (reg))
0222
0223 enum mac_version {
0224 RTL_GIGA_MAC_NONE = 0x00,
0225 RTL_GIGA_MAC_VER_01 = 0x01,
0226 RTL_GIGA_MAC_VER_02 = 0x02,
0227 RTL_GIGA_MAC_VER_03 = 0x03,
0228 RTL_GIGA_MAC_VER_04 = 0x04,
0229 RTL_GIGA_MAC_VER_05 = 0x05,
0230 RTL_GIGA_MAC_VER_06 = 0x06,
0231 RTL_GIGA_MAC_VER_07 = 0x07,
0232 RTL_GIGA_MAC_VER_08 = 0x08,
0233 RTL_GIGA_MAC_VER_09 = 0x09,
0234 RTL_GIGA_MAC_VER_10 = 0x0a,
0235 RTL_GIGA_MAC_VER_11 = 0x0b,
0236 RTL_GIGA_MAC_VER_12 = 0x0c,
0237 RTL_GIGA_MAC_VER_13 = 0x0d,
0238 RTL_GIGA_MAC_VER_14 = 0x0e,
0239 RTL_GIGA_MAC_VER_15 = 0x0f,
0240 RTL_GIGA_MAC_VER_16 = 0x11,
0241 RTL_GIGA_MAC_VER_17 = 0x10,
0242 RTL_GIGA_MAC_VER_18 = 0x12,
0243 RTL_GIGA_MAC_VER_19 = 0x13,
0244 RTL_GIGA_MAC_VER_20 = 0x14,
0245 RTL_GIGA_MAC_VER_21 = 0x15,
0246 RTL_GIGA_MAC_VER_22 = 0x16,
0247 RTL_GIGA_MAC_VER_23 = 0x17,
0248 RTL_GIGA_MAC_VER_24 = 0x18,
0249 RTL_GIGA_MAC_VER_25 = 0x19,
0250 RTL_GIGA_MAC_VER_26 = 0x1a,
0251 RTL_GIGA_MAC_VER_27 = 0x1b
0252 };
0253
0254 #define _R(NAME,MAC,MASK) \
0255 { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK }
0256
0257 static const struct {
0258 const char *name;
0259 u8 mac_version;
0260 u32 RxConfigMask;
0261 } rtl_chip_info[] = {
0262 _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880),
0263 _R("RTL8169s", RTL_GIGA_MAC_VER_02, 0xff7e1880),
0264 _R("RTL8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880),
0265 _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880),
0266 _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880),
0267 _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880),
0268 _R("RTL8102e", RTL_GIGA_MAC_VER_07, 0xff7e1880),
0269 _R("RTL8102e", RTL_GIGA_MAC_VER_08, 0xff7e1880),
0270 _R("RTL8102e", RTL_GIGA_MAC_VER_09, 0xff7e1880),
0271 _R("RTL8101e", RTL_GIGA_MAC_VER_10, 0xff7e1880),
0272 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880),
0273 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880),
0274 _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880),
0275 _R("RTL8100e", RTL_GIGA_MAC_VER_14, 0xff7e1880),
0276 _R("RTL8100e", RTL_GIGA_MAC_VER_15, 0xff7e1880),
0277 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_17, 0xff7e1880),
0278 _R("RTL8101e", RTL_GIGA_MAC_VER_16, 0xff7e1880),
0279 _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_18, 0xff7e1880),
0280 _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_19, 0xff7e1880),
0281 _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_20, 0xff7e1880),
0282 _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_21, 0xff7e1880),
0283 _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_22, 0xff7e1880),
0284 _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_23, 0xff7e1880),
0285 _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, 0xff7e1880),
0286 _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880),
0287 _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_26, 0xff7e1880),
0288 _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, 0xff7e1880)
0289 };
0290 #undef _R
0291
0292 enum cfg_version {
0293 RTL_CFG_0 = 0x00,
0294 RTL_CFG_1,
0295 RTL_CFG_2
0296 };
0297
0298 #define PCI_VENDOR_ID_REALTEK 0x10ec
0299 #define PCI_VENDOR_ID_DLINK 0x1186
0300 #define PCI_VENDOR_ID_AT 0x1259
0301 #define PCI_VENDOR_ID_GIGABYTE 0x1458
0302
0303
0304 static struct {
0305 uint16 vendor, device, cfg;
0306 } compatible_ids[] = {
0307 { PCI_VENDOR_ID_REALTEK, 0x8129, RTL_CFG_0 },
0308 { PCI_VENDOR_ID_REALTEK, 0x8136, RTL_CFG_2 },
0309 { PCI_VENDOR_ID_REALTEK, 0x8167, RTL_CFG_0 },
0310 { PCI_VENDOR_ID_REALTEK, 0x8168, RTL_CFG_1 },
0311 { PCI_VENDOR_ID_REALTEK, 0x8169, RTL_CFG_0 },
0312 { PCI_VENDOR_ID_DLINK, 0x4300, RTL_CFG_0 },
0313 { PCI_VENDOR_ID_AT, 0xc107, RTL_CFG_0 },
0314 { 0x16ec, 0x0116, RTL_CFG_0 },
0315 { 0xFFFF, 0xFFFF }
0316 };
0317
0318 #define __iomem
0319
0320 enum rtl_registers {
0321 MAC0 = 0,
0322 MAC4 = 4,
0323 MAR0 = 8,
0324 CounterAddrLow = 0x10,
0325 CounterAddrHigh = 0x14,
0326 TxDescStartAddrLow = 0x20,
0327 TxDescStartAddrHigh = 0x24,
0328 TxHDescStartAddrLow = 0x28,
0329 TxHDescStartAddrHigh = 0x2c,
0330 FLASH = 0x30,
0331 ERSR = 0x36,
0332 ChipCmd = 0x37,
0333 TxPoll = 0x38,
0334 IntrMask = 0x3c,
0335 IntrStatus = 0x3e,
0336 TxConfig = 0x40,
0337 RxConfig = 0x44,
0338 RxMissed = 0x4c,
0339 Cfg9346 = 0x50,
0340 Config0 = 0x51,
0341 Config1 = 0x52,
0342 Config2 = 0x53,
0343 Config3 = 0x54,
0344 Config4 = 0x55,
0345 Config5 = 0x56,
0346 MultiIntr = 0x5c,
0347 PHYAR = 0x60,
0348 PHYstatus = 0x6c,
0349 RxMaxSize = 0xda,
0350 CPlusCmd = 0xe0,
0351 IntrMitigate = 0xe2,
0352 RxDescAddrLow = 0xe4,
0353 RxDescAddrHigh = 0xe8,
0354 EarlyTxThres = 0xec,
0355 FuncEvent = 0xf0,
0356 FuncEventMask = 0xf4,
0357 FuncPresetState = 0xf8,
0358 FuncForceEvent = 0xfc,
0359 };
0360
0361 enum rtl8110_registers {
0362 TBICSR = 0x64,
0363 TBI_ANAR = 0x68,
0364 TBI_LPAR = 0x6a,
0365 };
0366
0367 enum rtl8168_8101_registers {
0368 CSIDR = 0x64,
0369 CSIAR = 0x68,
0370 #define CSIAR_FLAG 0x80000000
0371 #define CSIAR_WRITE_CMD 0x80000000
0372 #define CSIAR_BYTE_ENABLE 0x0f
0373 #define CSIAR_BYTE_ENABLE_SHIFT 12
0374 #define CSIAR_ADDR_MASK 0x0fff
0375
0376 EPHYAR = 0x80,
0377 #define EPHYAR_FLAG 0x80000000
0378 #define EPHYAR_WRITE_CMD 0x80000000
0379 #define EPHYAR_REG_MASK 0x1f
0380 #define EPHYAR_REG_SHIFT 16
0381 #define EPHYAR_DATA_MASK 0xffff
0382 DBG_REG = 0xd1,
0383 #define FIX_NAK_1 (1 << 4)
0384 #define FIX_NAK_2 (1 << 3)
0385 EFUSEAR = 0xdc,
0386 #define EFUSEAR_FLAG 0x80000000
0387 #define EFUSEAR_WRITE_CMD 0x80000000
0388 #define EFUSEAR_READ_CMD 0x00000000
0389 #define EFUSEAR_REG_MASK 0x03ff
0390 #define EFUSEAR_REG_SHIFT 8
0391 #define EFUSEAR_DATA_MASK 0xff
0392 };
0393
0394 enum rtl_register_content {
0395
0396 SYSErr = 0x8000,
0397 PCSTimeout = 0x4000,
0398 SWInt = 0x0100,
0399 TxDescUnavail = 0x0080,
0400 RxFIFOOver = 0x0040,
0401 LinkChg = 0x0020,
0402 RxOverflow = 0x0010,
0403 TxErr = 0x0008,
0404 TxOK = 0x0004,
0405 RxErr = 0x0002,
0406 RxOK = 0x0001,
0407
0408
0409 RxFOVF = (1 << 23),
0410 RxRWT = (1 << 22),
0411 RxRES = (1 << 21),
0412 RxRUNT = (1 << 20),
0413 RxCRC = (1 << 19),
0414
0415
0416 CmdReset = 0x10,
0417 CmdRxEnb = 0x08,
0418 CmdTxEnb = 0x04,
0419 RxBufEmpty = 0x01,
0420
0421
0422 HPQ = 0x80,
0423 NPQ = 0x40,
0424 FSWInt = 0x01,
0425
0426
0427 Cfg9346_Lock = 0x00,
0428 Cfg9346_Unlock = 0xc0,
0429
0430
0431 AcceptErr = 0x20,
0432 AcceptRunt = 0x10,
0433 AcceptBroadcast = 0x08,
0434 AcceptMulticast = 0x04,
0435 AcceptMyPhys = 0x02,
0436 AcceptAllPhys = 0x01,
0437
0438
0439 RxCfgFIFOShift = 13,
0440 RxCfgDMAShift = 8,
0441
0442
0443 TxInterFrameGapShift = 24,
0444 TxDMAShift = 8,
0445
0446
0447 LEDS1 = (1 << 7),
0448 LEDS0 = (1 << 6),
0449 MSIEnable = (1 << 5),
0450 Speed_down = (1 << 4),
0451 MEMMAP = (1 << 3),
0452 IOMAP = (1 << 2),
0453 VPD = (1 << 1),
0454 PMEnable = (1 << 0),
0455
0456
0457 PCI_Clock_66MHz = 0x01,
0458 PCI_Clock_33MHz = 0x00,
0459
0460
0461 MagicPacket = (1 << 5),
0462 LinkUp = (1 << 4),
0463 Beacon_en = (1 << 0),
0464
0465
0466 BWF = (1 << 6),
0467 MWF = (1 << 5),
0468 UWF = (1 << 4),
0469 LanWake = (1 << 1),
0470 PMEStatus = (1 << 0),
0471
0472
0473 TBIReset = 0x80000000,
0474 TBILoopback = 0x40000000,
0475 TBINwEnable = 0x20000000,
0476 TBINwRestart = 0x10000000,
0477 TBILinkOk = 0x02000000,
0478 TBINwComplete = 0x01000000,
0479
0480
0481 EnableBist = (1 << 15),
0482 Mac_dbgo_oe = (1 << 14),
0483 Normal_mode = (1 << 13),
0484 Force_half_dup = (1 << 12),
0485 Force_rxflow_en = (1 << 11),
0486 Force_txflow_en = (1 << 10),
0487 Cxpl_dbg_sel = (1 << 9),
0488 ASF = (1 << 8),
0489 PktCntrDisable = (1 << 7),
0490 Mac_dbgo_sel = 0x001c,
0491 RxVlan = (1 << 6),
0492 RxChkSum = (1 << 5),
0493 PCIDAC = (1 << 4),
0494 PCIMulRW = (1 << 3),
0495 INTT_0 = 0x0000,
0496 INTT_1 = 0x0001,
0497 INTT_2 = 0x0002,
0498 INTT_3 = 0x0003,
0499
0500
0501 TBI_Enable = 0x80,
0502 TxFlowCtrl = 0x40,
0503 RxFlowCtrl = 0x20,
0504 _1000bpsF = 0x10,
0505 _100bps = 0x08,
0506 _10bps = 0x04,
0507 LinkStatus = 0x02,
0508 FullDup = 0x01,
0509
0510
0511 TBILinkOK = 0x02000000,
0512
0513
0514 CounterDump = 0x8,
0515 };
0516
0517 enum desc_status_bit {
0518 DescOwn = (1 << 31),
0519 RingEnd = (1 << 30),
0520 FirstFrag = (1 << 29),
0521 LastFrag = (1 << 28),
0522
0523
0524 LargeSend = (1 << 27),
0525 MSSShift = 16,
0526 MSSMask = 0xfff,
0527 IPCS = (1 << 18),
0528 UDPCS = (1 << 17),
0529 TCPCS = (1 << 16),
0530 TxVlanTag = (1 << 17),
0531
0532
0533 PID1 = (1 << 18),
0534 PID0 = (1 << 17),
0535
0536 #define RxProtoUDP (PID1)
0537 #define RxProtoTCP (PID0)
0538 #define RxProtoIP (PID1 | PID0)
0539 #define RxProtoMask RxProtoIP
0540
0541 IPFail = (1 << 16),
0542 UDPFail = (1 << 15),
0543 TCPFail = (1 << 14),
0544 RxVlanTag = (1 << 16),
0545 };
0546
0547 #define RsvdMask 0x3fffc000
0548
0549 struct TxDesc {
0550 __le32 opts1;
0551 __le32 opts2;
0552 __le64 addr;
0553 };
0554
0555 struct RxDesc {
0556 __le32 opts1;
0557 __le32 opts2;
0558 __le64 addr;
0559 };
0560
0561 struct ring_info {
0562 struct sk_buff *skb;
0563 u32 len;
0564 u8 __pad[sizeof(void *) - sizeof(u32)];
0565 };
0566
0567 enum features {
0568 RTL_FEATURE_WOL = (1 << 0),
0569 RTL_FEATURE_MSI = (1 << 1),
0570 RTL_FEATURE_GMII = (1 << 2),
0571 };
0572
0573 struct rtl8169_counters {
0574 __le64 tx_packets;
0575 __le64 rx_packets;
0576 __le64 tx_errors;
0577 __le32 rx_errors;
0578 __le16 rx_missed;
0579 __le16 align_errors;
0580 __le32 tx_one_collision;
0581 __le32 tx_multi_collision;
0582 __le64 rx_unicast;
0583 __le64 rx_broadcast;
0584 __le32 rx_multicast;
0585 __le16 tx_aborted;
0586 __le16 tx_underun;
0587 };
0588
0589 typedef spinlock spinlock_t;
0590 struct napi_struct {
0591 };
0592 struct ethtool_cmd {
0593 };
0594 struct mii_ioctl_data {
0595 };
0596
0597 struct rtl8169_private {
0598 void __iomem *mmio_addr;
0599 struct pci_dev *pci_dev;
0600 struct net_device *dev;
0601 struct napi_struct napi;
0602 spinlock_t lock;
0603 u32 msg_enable;
0604 int chipset;
0605 int mac_version;
0606 u32 cur_rx;
0607 u32 cur_tx;
0608 u32 dirty_rx;
0609 u32 dirty_tx;
0610 struct TxDesc *TxDescArray;
0611 struct RxDesc *RxDescArray;
0612 dma_addr_t TxPhyAddr;
0613 dma_addr_t RxPhyAddr;
0614 struct sk_buff *Rx_skbuff[NUM_RX_DESC];
0615 struct ring_info tx_skb[NUM_TX_DESC];
0616 unsigned align;
0617 unsigned rx_buf_sz;
0618
0619 u16 cp_cmd;
0620 u16 intr_event;
0621 u16 napi_event;
0622 u16 intr_mask;
0623 int phy_1000_ctrl_reg;
0624 #ifdef CONFIG_R8169_VLAN
0625 struct vlan_group *vlgrp;
0626 #endif
0627 int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
0628 int (*get_settings)(struct net_device *, struct ethtool_cmd *);
0629 void (*phy_reset_enable)(void __iomem *);
0630 void (*hw_start)(struct net_device *);
0631 unsigned int (*phy_reset_pending)(void __iomem *);
0632 unsigned int (*link_ok)(void __iomem *);
0633 int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd);
0634 int pcie_cap;
0635
0636 unsigned features;
0637
0638
0639 struct rtl8169_counters counters;
0640 u32 saved_wolopts;
0641 u8 mac_addr[MAC_ADDR_LEN];
0642 ethernet_device ethdev;
0643 };
0644
0645 static void
0646 mdio_write(void __iomem *ioaddr, int reg_addr, int value)
0647 {
0648 int i;
0649
0650 RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0x1f) << 16 | (value & 0xffff));
0651
0652 for (i = 20; i > 0; i--) {
0653
0654
0655
0656
0657 if (!(RTL_R32(PHYAR) & 0x80000000))
0658 break;
0659 udelay(25);
0660 }
0661
0662
0663
0664
0665 udelay(20);
0666 }
0667
0668 static int
0669 mdio_read(void __iomem *ioaddr, int reg_addr)
0670 {
0671 int i, value = -1;
0672
0673 RTL_W32(PHYAR, 0x0 | (reg_addr & 0x1f) << 16);
0674
0675 for (i = 20; i > 0; i--) {
0676
0677
0678
0679
0680 if (RTL_R32(PHYAR) & 0x80000000) {
0681 value = RTL_R32(PHYAR) & 0xffff;
0682 break;
0683 }
0684 udelay(25);
0685 }
0686
0687
0688
0689
0690 udelay(20);
0691
0692 return value;
0693 }
0694
0695 static void
0696 mdio_patch(void __iomem *ioaddr, int reg_addr, int value)
0697 {
0698 mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value);
0699 }
0700
0701 static void
0702 mdio_plus_minus(void __iomem *ioaddr, int reg_addr, int p, int m)
0703 {
0704 int val;
0705
0706 val = mdio_read(ioaddr, reg_addr);
0707 mdio_write(ioaddr, reg_addr, (val | p) & ~m);
0708 }
0709
0710 static void rtl_ephy_write(void __iomem *ioaddr, int reg_addr, int value)
0711 {
0712 unsigned int i;
0713
0714 RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) |
0715 (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
0716
0717 for (i = 0; i < 100; i++) {
0718 if (!(RTL_R32(EPHYAR) & EPHYAR_FLAG))
0719 break;
0720 udelay(10);
0721 }
0722 }
0723
0724 static u16 rtl_ephy_read(void __iomem *ioaddr, int reg_addr)
0725 {
0726 u16 value = 0xffff;
0727 unsigned int i;
0728
0729 RTL_W32(EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
0730
0731 for (i = 0; i < 100; i++) {
0732 if (RTL_R32(EPHYAR) & EPHYAR_FLAG) {
0733 value = RTL_R32(EPHYAR) & EPHYAR_DATA_MASK;
0734 break;
0735 }
0736 udelay(10);
0737 }
0738
0739 return value;
0740 }
0741
0742 static void rtl_csi_write(void __iomem *ioaddr, int addr, int value)
0743 {
0744 unsigned int i;
0745
0746 RTL_W32(CSIDR, value);
0747 RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
0748 CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
0749
0750 for (i = 0; i < 100; i++) {
0751 if (!(RTL_R32(CSIAR) & CSIAR_FLAG))
0752 break;
0753 udelay(10);
0754 }
0755 }
0756
0757 static u32 rtl_csi_read(void __iomem *ioaddr, int addr)
0758 {
0759 u32 value = ~0x00;
0760 unsigned int i;
0761
0762 RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) |
0763 CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
0764
0765 for (i = 0; i < 100; i++) {
0766 if (RTL_R32(CSIAR) & CSIAR_FLAG) {
0767 value = RTL_R32(CSIDR);
0768 break;
0769 }
0770 udelay(10);
0771 }
0772
0773 return value;
0774 }
0775
0776 static u8
0777 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr)
0778 {
0779 u8 value = 0xff;
0780 unsigned int i;
0781
0782 RTL_W32(EFUSEAR, (reg_addr & EFUSEAR_REG_MASK) << EFUSEAR_REG_SHIFT);
0783
0784 for (i = 0; i < 300; i++) {
0785 if (RTL_R32(EFUSEAR) & EFUSEAR_FLAG) {
0786 value = RTL_R32(EFUSEAR) & EFUSEAR_DATA_MASK;
0787 break;
0788 }
0789 udelay(100);
0790 }
0791
0792 return value;
0793 }
0794
0795 #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
0796
0797 static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp,
0798 void __iomem *ioaddr)
0799 {
0800
0801
0802
0803
0804
0805 RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32);
0806 RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_BIT_MASK(32));
0807 RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32);
0808 RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_BIT_MASK(32));
0809 }
0810
0811 static u16 rtl_rw_cpluscmd(void __iomem *ioaddr)
0812 {
0813 u16 cmd;
0814
0815 cmd = RTL_R16(CPlusCmd);
0816 RTL_W16(CPlusCmd, cmd);
0817 return cmd;
0818 }
0819
0820 static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz)
0821 {
0822
0823 RTL_W16(RxMaxSize, rx_buf_sz + 1);
0824 }
0825
0826 static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
0827 {
0828 static const struct {
0829 u32 mac_version;
0830 u32 clk;
0831 u32 val;
0832 } cfg2_info [] = {
0833 { RTL_GIGA_MAC_VER_05, PCI_Clock_33MHz, 0x000fff00 },
0834 { RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff },
0835 { RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 },
0836 { RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff }
0837 }, *p = cfg2_info;
0838 unsigned int i;
0839 u32 clk;
0840
0841 clk = RTL_R8(Config2) & PCI_Clock_66MHz;
0842 for (i = 0; i < ARRAY_SIZE(cfg2_info); i++, p++) {
0843 if ((p->mac_version == mac_version) && (p->clk == clk)) {
0844 RTL_W32(0x7c, p->val);
0845 break;
0846 }
0847 }
0848 }
0849
0850 static const unsigned int rtl8169_rx_config =
0851 (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
0852
0853 static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp)
0854 {
0855 void __iomem *ioaddr = tp->mmio_addr;
0856 u32 cfg = rtl8169_rx_config;
0857
0858 cfg |= (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
0859 RTL_W32(RxConfig, cfg);
0860
0861
0862 RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) |
0863 (InterFrameGap << TxInterFrameGapShift));
0864 }
0865
0866 static void rtl_set_rx_mode(struct net_device *dev)
0867 {
0868 struct rtl8169_private *tp = netdev_priv(dev);
0869 void __iomem *ioaddr = tp->mmio_addr;
0870 u32 mc_filter[2];
0871 int rx_mode;
0872 u32 tmp = 0;
0873
0874 rx_mode = AcceptBroadcast | AcceptMyPhys;
0875 mc_filter[1] = mc_filter[0] = 0;
0876 int bit_nr = ether_crc(ETH_ADDR_LEN, tp->mac_addr) >> 26;
0877 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
0878 rx_mode |= AcceptMulticast;
0879
0880 spinlock_lock(&tp->lock);
0881
0882 tmp = rtl8169_rx_config | rx_mode |
0883 (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
0884
0885 if (tp->mac_version > RTL_GIGA_MAC_VER_06) {
0886 u32 data = mc_filter[0];
0887
0888 #define swab32 ___constant_swab32
0889 mc_filter[0] = swab32(mc_filter[1]);
0890 mc_filter[1] = swab32(data);
0891 }
0892
0893 RTL_W32(MAR0 + 4, mc_filter[1]);
0894 RTL_W32(MAR0 + 0, mc_filter[0]);
0895
0896 RTL_W32(RxConfig, tmp);
0897
0898 spinlock_unlock(&tp->lock);
0899 }
0900
0901 static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
0902 {
0903 struct net_device *dev = pci_get_drvdata(pdev);
0904 struct rtl8169_private *tp = netdev_priv(dev);
0905 int cap = tp->pcie_cap;
0906
0907 if (cap) {
0908 u16 ctl;
0909
0910 #define PCI_EXP_DEVCTL 8
0911 #define PCI_EXP_DEVCTL_READRQ 0x7000
0912 pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl);
0913 ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force;
0914 pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl);
0915 }
0916 }
0917
0918 static void rtl_csi_access_enable(void __iomem *ioaddr)
0919 {
0920 u32 csi;
0921
0922 csi = rtl_csi_read(ioaddr, 0x070c) & 0x00ffffff;
0923 rtl_csi_write(ioaddr, 0x070c, csi | 0x27000000);
0924 }
0925
0926 struct ephy_info {
0927 unsigned int offset;
0928 u16 mask;
0929 u16 bits;
0930 };
0931
0932 static void rtl_ephy_init(void __iomem *ioaddr, const struct ephy_info *e, int len)
0933 {
0934 u16 w;
0935
0936 while (len-- > 0) {
0937 w = (rtl_ephy_read(ioaddr, e->offset) & ~e->mask) | e->bits;
0938 rtl_ephy_write(ioaddr, e->offset, w);
0939 e++;
0940 }
0941 }
0942
0943 static void rtl_disable_clock_request(struct pci_dev *pdev)
0944 {
0945 struct net_device *dev = pci_get_drvdata(pdev);
0946 struct rtl8169_private *tp = netdev_priv(dev);
0947 int cap = tp->pcie_cap;
0948
0949 if (cap) {
0950 u16 ctl;
0951
0952 #define PCI_EXP_LNKCTL 16
0953 #define PCI_EXP_LNKCTL_CLKREQ_EN 0x100
0954 pci_read_config_word(pdev, cap + PCI_EXP_LNKCTL, &ctl);
0955 ctl &= ~PCI_EXP_LNKCTL_CLKREQ_EN;
0956 pci_write_config_word(pdev, cap + PCI_EXP_LNKCTL, ctl);
0957 }
0958 }
0959
0960 static void
0961 rtl_hw_start_8169(struct net_device *dev)
0962 {
0963 struct rtl8169_private *tp = netdev_priv(dev);
0964 void __iomem *ioaddr = tp->mmio_addr;
0965 struct pci_dev *pdev = tp->pci_dev;
0966
0967 if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
0968 RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW);
0969 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08);
0970 }
0971
0972 RTL_W8(Cfg9346, Cfg9346_Unlock);
0973 if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
0974 (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
0975 (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
0976 (tp->mac_version == RTL_GIGA_MAC_VER_04))
0977 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
0978
0979 RTL_W8(EarlyTxThres, EarlyTxThld);
0980
0981 rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
0982
0983 if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
0984 (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
0985 (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
0986 (tp->mac_version == RTL_GIGA_MAC_VER_04))
0987 rtl_set_rx_tx_config_registers(tp);
0988
0989 tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
0990
0991 if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
0992 (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
0993 DLOG("Set MAC Reg C+CR Offset 0xE0. "
0994 "Bit-3 and bit-14 MUST be 1");
0995 tp->cp_cmd |= (1 << 14);
0996 }
0997
0998 RTL_W16(CPlusCmd, tp->cp_cmd);
0999
1000 rtl8169_set_magic_reg(ioaddr, tp->mac_version);
1001
1002
1003
1004
1005
1006 RTL_W16(IntrMitigate, 0x0000);
1007
1008 rtl_set_rx_tx_desc_registers(tp, ioaddr);
1009
1010 if ((tp->mac_version != RTL_GIGA_MAC_VER_01) &&
1011 (tp->mac_version != RTL_GIGA_MAC_VER_02) &&
1012 (tp->mac_version != RTL_GIGA_MAC_VER_03) &&
1013 (tp->mac_version != RTL_GIGA_MAC_VER_04)) {
1014 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
1015 rtl_set_rx_tx_config_registers(tp);
1016 }
1017
1018 RTL_W8(Cfg9346, Cfg9346_Lock);
1019
1020
1021 RTL_R8(IntrMask);
1022
1023 RTL_W32(RxMissed, 0);
1024
1025 rtl_set_rx_mode(dev);
1026
1027
1028 RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
1029
1030
1031 RTL_W16(IntrMask, tp->intr_event);
1032 }
1033
1034 #define R8168_CPCMD_QUIRK_MASK ( \
1035 EnableBist | \
1036 Mac_dbgo_oe | \
1037 Force_half_dup | \
1038 Force_rxflow_en | \
1039 Force_txflow_en | \
1040 Cxpl_dbg_sel | \
1041 ASF | \
1042 PktCntrDisable | \
1043 Mac_dbgo_sel)
1044
1045 static void rtl_hw_start_8168bb(void __iomem *ioaddr, struct pci_dev *pdev)
1046 {
1047 RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
1048
1049 RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
1050
1051 #define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800
1052 rtl_tx_performance_tweak(pdev,
1053 (0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN);
1054 }
1055
1056 static void rtl_hw_start_8168bef(void __iomem *ioaddr, struct pci_dev *pdev)
1057 {
1058 rtl_hw_start_8168bb(ioaddr, pdev);
1059
1060 RTL_W8(EarlyTxThres, EarlyTxThld);
1061
1062 RTL_W8(Config4, RTL_R8(Config4) & ~(1 << 0));
1063 }
1064
1065 static void __rtl_hw_start_8168cp(void __iomem *ioaddr, struct pci_dev *pdev)
1066 {
1067 RTL_W8(Config1, RTL_R8(Config1) | Speed_down);
1068
1069 RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
1070
1071 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
1072
1073 rtl_disable_clock_request(pdev);
1074
1075 RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
1076 }
1077
1078 static void rtl_hw_start_8168cp_1(void __iomem *ioaddr, struct pci_dev *pdev)
1079 {
1080 static const struct ephy_info e_info_8168cp[] = {
1081 { 0x01, 0, 0x0001 },
1082 { 0x02, 0x0800, 0x1000 },
1083 { 0x03, 0, 0x0042 },
1084 { 0x06, 0x0080, 0x0000 },
1085 { 0x07, 0, 0x2000 }
1086 };
1087
1088 rtl_csi_access_enable(ioaddr);
1089
1090 rtl_ephy_init(ioaddr, e_info_8168cp, ARRAY_SIZE(e_info_8168cp));
1091
1092 __rtl_hw_start_8168cp(ioaddr, pdev);
1093 }
1094
1095 static void rtl_hw_start_8168cp_2(void __iomem *ioaddr, struct pci_dev *pdev)
1096 {
1097 rtl_csi_access_enable(ioaddr);
1098
1099 RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
1100
1101 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
1102
1103 RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
1104 }
1105
1106 static void rtl_hw_start_8168cp_3(void __iomem *ioaddr, struct pci_dev *pdev)
1107 {
1108 rtl_csi_access_enable(ioaddr);
1109
1110 RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
1111
1112
1113 RTL_W8(DBG_REG, 0x20);
1114
1115 RTL_W8(EarlyTxThres, EarlyTxThld);
1116
1117 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
1118
1119 RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
1120 }
1121
1122 static void rtl_hw_start_8168c_1(void __iomem *ioaddr, struct pci_dev *pdev)
1123 {
1124 static const struct ephy_info e_info_8168c_1[] = {
1125 { 0x02, 0x0800, 0x1000 },
1126 { 0x03, 0, 0x0002 },
1127 { 0x06, 0x0080, 0x0000 }
1128 };
1129
1130 rtl_csi_access_enable(ioaddr);
1131
1132 RTL_W8(DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2);
1133
1134 rtl_ephy_init(ioaddr, e_info_8168c_1, ARRAY_SIZE(e_info_8168c_1));
1135
1136 __rtl_hw_start_8168cp(ioaddr, pdev);
1137 }
1138
1139 static void rtl_hw_start_8168c_2(void __iomem *ioaddr, struct pci_dev *pdev)
1140 {
1141 static const struct ephy_info e_info_8168c_2[] = {
1142 { 0x01, 0, 0x0001 },
1143 { 0x03, 0x0400, 0x0220 }
1144 };
1145
1146 rtl_csi_access_enable(ioaddr);
1147
1148 rtl_ephy_init(ioaddr, e_info_8168c_2, ARRAY_SIZE(e_info_8168c_2));
1149
1150 __rtl_hw_start_8168cp(ioaddr, pdev);
1151 }
1152
1153 static void rtl_hw_start_8168c_3(void __iomem *ioaddr, struct pci_dev *pdev)
1154 {
1155 rtl_hw_start_8168c_2(ioaddr, pdev);
1156 }
1157
1158 static void rtl_hw_start_8168c_4(void __iomem *ioaddr, struct pci_dev *pdev)
1159 {
1160 rtl_csi_access_enable(ioaddr);
1161
1162 __rtl_hw_start_8168cp(ioaddr, pdev);
1163 }
1164
1165 static void rtl_hw_start_8168d(void __iomem *ioaddr, struct pci_dev *pdev)
1166 {
1167 rtl_csi_access_enable(ioaddr);
1168
1169 rtl_disable_clock_request(pdev);
1170
1171 RTL_W8(EarlyTxThres, EarlyTxThld);
1172
1173 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
1174
1175 RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
1176 }
1177
1178 static void
1179 rtl_hw_start_8168(struct net_device *dev)
1180 {
1181 struct rtl8169_private *tp = netdev_priv(dev);
1182 void __iomem *ioaddr = tp->mmio_addr;
1183 struct pci_dev *pdev = tp->pci_dev;
1184
1185 DLOG ("hw_start_8168 mac_version=0x%X", tp->mac_version);
1186
1187 RTL_W8(Cfg9346, Cfg9346_Unlock);
1188
1189 RTL_W8(EarlyTxThres, EarlyTxThld);
1190
1191 rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
1192
1193 tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1;
1194
1195 RTL_W16(CPlusCmd, tp->cp_cmd);
1196
1197 RTL_W16(IntrMitigate, 0x5151);
1198
1199
1200 if (tp->mac_version == RTL_GIGA_MAC_VER_11) {
1201 tp->intr_event |= RxFIFOOver | PCSTimeout;
1202 tp->intr_event &= ~RxOverflow;
1203 }
1204
1205 rtl_set_rx_tx_desc_registers(tp, ioaddr);
1206
1207 rtl_set_rx_mode(dev);
1208
1209 RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) |
1210 (InterFrameGap << TxInterFrameGapShift));
1211
1212 RTL_R8(IntrMask);
1213
1214 switch (tp->mac_version) {
1215 case RTL_GIGA_MAC_VER_11:
1216 rtl_hw_start_8168bb(ioaddr, pdev);
1217 break;
1218
1219 case RTL_GIGA_MAC_VER_12:
1220 case RTL_GIGA_MAC_VER_17:
1221 rtl_hw_start_8168bef(ioaddr, pdev);
1222 break;
1223
1224 case RTL_GIGA_MAC_VER_18:
1225 rtl_hw_start_8168cp_1(ioaddr, pdev);
1226 break;
1227
1228 case RTL_GIGA_MAC_VER_19:
1229 rtl_hw_start_8168c_1(ioaddr, pdev);
1230 break;
1231
1232 case RTL_GIGA_MAC_VER_20:
1233 rtl_hw_start_8168c_2(ioaddr, pdev);
1234 break;
1235
1236 case RTL_GIGA_MAC_VER_21:
1237 rtl_hw_start_8168c_3(ioaddr, pdev);
1238 break;
1239
1240 case RTL_GIGA_MAC_VER_22:
1241 rtl_hw_start_8168c_4(ioaddr, pdev);
1242 break;
1243
1244 case RTL_GIGA_MAC_VER_23:
1245 rtl_hw_start_8168cp_2(ioaddr, pdev);
1246 break;
1247
1248 case RTL_GIGA_MAC_VER_24:
1249 rtl_hw_start_8168cp_3(ioaddr, pdev);
1250 break;
1251
1252 case RTL_GIGA_MAC_VER_25:
1253 case RTL_GIGA_MAC_VER_26:
1254 case RTL_GIGA_MAC_VER_27:
1255 rtl_hw_start_8168d(ioaddr, pdev);
1256 break;
1257
1258 default:
1259 DLOG("unknown chipset (mac_version = %d).",
1260 tp->mac_version);
1261 break;
1262 }
1263
1264 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
1265
1266 RTL_W8(Cfg9346, Cfg9346_Lock);
1267
1268 RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
1269
1270 DLOG ("IntrMask <- 0x%.04X", tp->intr_event);
1271 RTL_W16(IntrMask, tp->intr_event);
1272 }
1273
1274 static void
1275 rtl_hw_start_8101(struct net_device *dev)
1276 {
1277 #if 0
1278 struct rtl8169_private *tp = netdev_priv(dev);
1279 void __iomem *ioaddr = tp->mmio_addr;
1280 struct pci_dev *pdev = tp->pci_dev;
1281
1282 if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
1283 (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
1284 int cap = tp->pcie_cap;
1285
1286 if (cap) {
1287 pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL,
1288 PCI_EXP_DEVCTL_NOSNOOP_EN);
1289 }
1290 }
1291
1292 switch (tp->mac_version) {
1293 case RTL_GIGA_MAC_VER_07:
1294 rtl_hw_start_8102e_1(ioaddr, pdev);
1295 break;
1296
1297 case RTL_GIGA_MAC_VER_08:
1298 rtl_hw_start_8102e_3(ioaddr, pdev);
1299 break;
1300
1301 case RTL_GIGA_MAC_VER_09:
1302 rtl_hw_start_8102e_2(ioaddr, pdev);
1303 break;
1304 }
1305
1306 RTL_W8(Cfg9346, Cfg9346_Unlock);
1307
1308 RTL_W8(EarlyTxThres, EarlyTxThld);
1309
1310 rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
1311
1312 tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
1313
1314 RTL_W16(CPlusCmd, tp->cp_cmd);
1315
1316 RTL_W16(IntrMitigate, 0x0000);
1317
1318 rtl_set_rx_tx_desc_registers(tp, ioaddr);
1319
1320 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
1321 rtl_set_rx_tx_config_registers(tp);
1322
1323 RTL_W8(Cfg9346, Cfg9346_Lock);
1324
1325 RTL_R8(IntrMask);
1326
1327 rtl_set_rx_mode(dev);
1328
1329 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
1330
1331 RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000);
1332
1333 RTL_W16(IntrMask, tp->intr_event);
1334 #endif
1335 DLOG ("8101 not supported");
1336 }
1337
1338 static int
1339 rtl8169_set_speed_tbi(struct net_device *dev,
1340 u8 autoneg, u16 speed, u8 duplex)
1341 {
1342 return 0;
1343 }
1344
1345 static int rtl8169_set_speed_xmii(struct net_device *dev,
1346 u8 autoneg, u16 speed, u8 duplex)
1347 {
1348 struct rtl8169_private *tp = netdev_priv(dev);
1349 void __iomem *ioaddr = tp->mmio_addr;
1350 int giga_ctrl, bmcr;
1351
1352 if (autoneg == AUTONEG_ENABLE) {
1353 int auto_nego;
1354
1355 auto_nego = mdio_read(ioaddr, MII_ADVERTISE);
1356 auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL |
1357 ADVERTISE_100HALF | ADVERTISE_100FULL);
1358 auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
1359
1360 giga_ctrl = mdio_read(ioaddr, MII_CTRL1000);
1361 giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
1362
1363
1364 if ((tp->mac_version != RTL_GIGA_MAC_VER_07) &&
1365 (tp->mac_version != RTL_GIGA_MAC_VER_08) &&
1366 (tp->mac_version != RTL_GIGA_MAC_VER_09) &&
1367 (tp->mac_version != RTL_GIGA_MAC_VER_10) &&
1368 (tp->mac_version != RTL_GIGA_MAC_VER_13) &&
1369 (tp->mac_version != RTL_GIGA_MAC_VER_14) &&
1370 (tp->mac_version != RTL_GIGA_MAC_VER_15) &&
1371 (tp->mac_version != RTL_GIGA_MAC_VER_16)) {
1372 giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
1373 } else {
1374 DLOG("PHY does not support 1000Mbps");
1375 }
1376
1377 bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
1378
1379 if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
1380 (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
1381 (tp->mac_version >= RTL_GIGA_MAC_VER_17)) {
1382
1383
1384
1385
1386
1387 mdio_write(ioaddr, 0x1f, 0x0000);
1388 mdio_write(ioaddr, 0x0e, 0x0000);
1389 }
1390
1391 mdio_write(ioaddr, MII_ADVERTISE, auto_nego);
1392 mdio_write(ioaddr, MII_CTRL1000, giga_ctrl);
1393 } else {
1394 giga_ctrl = 0;
1395
1396 if (speed == SPEED_10)
1397 bmcr = 0;
1398 else if (speed == SPEED_100)
1399 bmcr = BMCR_SPEED100;
1400 else
1401 return -1;
1402
1403 if (duplex == DUPLEX_FULL)
1404 bmcr |= BMCR_FULLDPLX;
1405
1406 mdio_write(ioaddr, 0x1f, 0x0000);
1407 }
1408
1409 tp->phy_1000_ctrl_reg = giga_ctrl;
1410
1411 mdio_write(ioaddr, MII_BMCR, bmcr);
1412 DLOG ("set_speed_xmii: bmcr=0x%p", bmcr);
1413
1414 if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
1415 (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
1416 if ((speed == SPEED_100) && (autoneg != AUTONEG_ENABLE)) {
1417 mdio_write(ioaddr, 0x17, 0x2138);
1418 mdio_write(ioaddr, 0x0e, 0x0260);
1419 } else {
1420 mdio_write(ioaddr, 0x17, 0x2108);
1421 mdio_write(ioaddr, 0x0e, 0x0000);
1422 }
1423 }
1424
1425 return 0;
1426 }
1427
1428
1429 static int
1430 rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
1431 {
1432 #if 0
1433 struct rtl8169_private *tp = netdev_priv(dev);
1434 void __iomem *ioaddr = tp->mmio_addr;
1435 u32 status;
1436
1437 cmd->supported =
1438 SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE;
1439 cmd->port = PORT_FIBRE;
1440 cmd->transceiver = XCVR_INTERNAL;
1441
1442 status = RTL_R32(TBICSR);
1443 cmd->advertising = (status & TBINwEnable) ? ADVERTISED_Autoneg : 0;
1444 cmd->autoneg = !!(status & TBINwEnable);
1445
1446 cmd->speed = SPEED_1000;
1447 cmd->duplex = DUPLEX_FULL;
1448 #endif
1449 return 0;
1450 }
1451
1452 static int rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
1453 {
1454 #if 0
1455 struct rtl8169_private *tp = netdev_priv(dev);
1456
1457 return mii_ethtool_gset(&tp->mii, cmd);
1458 #endif
1459 return 0;
1460 }
1461
1462 static unsigned int
1463 rtl8169_tbi_reset_pending(void __iomem *ioaddr)
1464 {
1465 return RTL_R32(TBICSR) & TBIReset;
1466 }
1467
1468 static unsigned int
1469 rtl8169_xmii_reset_pending(void __iomem *ioaddr)
1470 {
1471 return mdio_read(ioaddr, MII_BMCR) & BMCR_RESET;
1472 }
1473
1474 static unsigned int
1475 rtl8169_tbi_link_ok(void __iomem *ioaddr)
1476 {
1477 return RTL_R32(TBICSR) & TBILinkOk;
1478 }
1479
1480 static unsigned int
1481 rtl8169_xmii_link_ok(void __iomem *ioaddr)
1482 {
1483 return RTL_R8(PHYstatus) & LinkStatus;
1484 }
1485
1486 static void
1487 rtl8169_tbi_reset_enable(void __iomem *ioaddr)
1488 {
1489 RTL_W32(TBICSR, RTL_R32(TBICSR) | TBIReset);
1490 }
1491
1492 static void
1493 rtl8169_xmii_reset_enable(void __iomem *ioaddr)
1494 {
1495 unsigned int val;
1496
1497 val = mdio_read(ioaddr, MII_BMCR) | BMCR_RESET;
1498 mdio_write(ioaddr, MII_BMCR, val & 0xffff);
1499 }
1500
1501 static void
1502 rtl8169_check_link_status(struct net_device *dev,
1503 struct rtl8169_private *tp,
1504 void __iomem *ioaddr)
1505 {
1506 spinlock_lock(&tp->lock);
1507 if (tp->link_ok(ioaddr)) {
1508 DLOG ("link up");
1509 } else {
1510 DLOG ("link down");
1511 }
1512 spinlock_unlock(&tp->lock);
1513 }
1514
1515 static int
1516 rtl_tbi_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd)
1517 {
1518 return -1;
1519 }
1520
1521 static int
1522 rtl_xmii_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd)
1523 {
1524 #if 0
1525 switch (cmd) {
1526 case SIOCGMIIPHY:
1527 data->phy_id = 32;
1528 return 0;
1529
1530 case SIOCGMIIREG:
1531 data->val_out = mdio_read(tp->mmio_addr, data->reg_num & 0x1f);
1532 return 0;
1533
1534 case SIOCSMIIREG:
1535 mdio_write(tp->mmio_addr, data->reg_num & 0x1f, data->val_in);
1536 return 0;
1537 }
1538 #endif
1539 return -1;
1540 }
1541
1542
1543
1544 static const struct rtl_cfg_info {
1545 void (*hw_start)(struct net_device *);
1546 unsigned int region;
1547 unsigned int align;
1548 u16 intr_event;
1549 u16 napi_event;
1550 unsigned features;
1551 u8 default_ver;
1552 } rtl_cfg_infos [] = {
1553 [RTL_CFG_0] = {
1554 .hw_start = rtl_hw_start_8169,
1555 .region = 1,
1556 .align = 0,
1557 .intr_event = SYSErr | LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
1558 .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
1559 .features = RTL_FEATURE_GMII,
1560 .default_ver = RTL_GIGA_MAC_VER_01,
1561 },
1562 [RTL_CFG_1] = {
1563 .hw_start = rtl_hw_start_8168,
1564 .region = 2,
1565 .align = 8,
1566 .intr_event = SYSErr | RxFIFOOver | LinkChg | RxOverflow | TxErr | TxOK | RxOK | RxErr,
1567 .napi_event = TxErr | TxOK | RxOK | RxOverflow,
1568 .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI,
1569 .default_ver = RTL_GIGA_MAC_VER_11,
1570 },
1571 [RTL_CFG_2] = {
1572 .hw_start = rtl_hw_start_8101,
1573 .region = 2,
1574 .align = 8,
1575 .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout | RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
1576 .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
1577 .features = RTL_FEATURE_MSI,
1578 .default_ver = RTL_GIGA_MAC_VER_13,
1579 }
1580 };
1581
1582 static uint device_index;
1583 static pci_device pdev;
1584
1585 static inline void rtl8169_mark_to_asic(struct RxDesc *desc, u32 rx_buf_sz);
1586
1587 #define MIN(a,b) ((a) < (b) ? (a) : (b))
1588 static void
1589 rx_int (struct rtl8169_private *tp)
1590 {
1591 uint cur_rx;
1592
1593 cur_rx = tp->cur_rx;
1594 for (;;) {
1595 uint entry = cur_rx & (NUM_RX_DESC - 1);
1596 struct RxDesc *desc = tp->RxDescArray + entry;
1597 u32 status;
1598
1599 status = __le32_to_cpu (desc->opts1);
1600 if (status & DescOwn)
1601 break;
1602 else {
1603 struct sk_buff *skb = tp->Rx_skbuff[entry];
1604 int pkt_size = (status & 0x00001FFF) - 4;
1605 DLOG ("RX: entry=%d size=%d", entry, pkt_size);
1606 u8 *p = skb->data;
1607 DLOG (" %.02X %.02X %.02X %.02X %.02X %.02X",
1608 p[0], p[1], p[2], p[3], p[4], p[5]);
1609 p+=6;
1610 DLOG (" %.02X %.02X %.02X %.02X %.02X %.02X",
1611 p[0], p[1], p[2], p[3], p[4], p[5]);
1612 if (tp->ethdev.recv_func)
1613 tp->ethdev.recv_func (&tp->ethdev, skb->data, pkt_size);
1614 rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
1615 }
1616 cur_rx++;
1617 }
1618 tp->cur_rx = cur_rx;
1619 }
1620
1621 static inline void free_skb (struct sk_buff *);
1622 static void
1623 tx_int (struct rtl8169_private *tp)
1624 {
1625 void __iomem *ioaddr = tp->mmio_addr;
1626 uint dirty_tx, tx_left;
1627 dirty_tx = tp->dirty_tx;
1628 tx_left = tp->cur_tx - dirty_tx;
1629 while (tx_left > 0) {
1630 uint entry = dirty_tx & (NUM_TX_DESC - 1);
1631 struct ring_info *tx_skb = tp->tx_skb + entry;
1632 struct TxDesc *desc = tp->TxDescArray + entry;
1633 u32 status;
1634
1635 status = __le32_to_cpu(tp->TxDescArray[entry].opts1);
1636 if (status & DescOwn)
1637 break;
1638
1639 DLOG ("TX: entry %d sent %d bytes", entry, tx_skb->len);
1640 desc->opts1 = desc->opts2 = desc->addr = 0;
1641 tx_skb->len = 0;
1642 free_skb (tx_skb->skb);
1643
1644 dirty_tx++;
1645 tx_left--;
1646 }
1647 if (tp->dirty_tx != dirty_tx) {
1648 tp->dirty_tx = dirty_tx;
1649
1650
1651
1652
1653
1654
1655 if (tp->cur_tx != dirty_tx)
1656 RTL_W8(TxPoll, NPQ);
1657 }
1658 }
1659
1660 static u32 r8169_bh_stack[1024] ALIGNED (0x1000);
1661 static task_id r8169_bh_id = 0;
1662 static void
1663 r8169_bh_thread (void)
1664 {
1665 logger_printf ("r8169: bh: hello from 0x%x\n", str ());
1666 for (;;) {
1667 struct rtl8169_private *tp = pci_get_drvdata(&pdev);
1668 int handled = 0;
1669 int status;
1670 void __iomem *ioaddr = tp->mmio_addr;
1671
1672 status = RTL_R16(IntrStatus);
1673
1674 while (status && status != 0xffff) {
1675 DLOG ("IRQ status=0x%p", status);
1676 handled = 1;
1677
1678
1679
1680
1681
1682
1683 if (unlikely(status & RxFIFOOver)) {
1684
1685
1686 break;
1687 }
1688
1689 if (unlikely(status & SYSErr)) {
1690
1691 break;
1692 }
1693
1694 if (status & LinkChg)
1695 rtl8169_check_link_status(&tp->ethdev, tp, ioaddr);
1696
1697 if (status & RxOK) {
1698 rx_int (tp);
1699 }
1700
1701 if (status & TxOK) {
1702 tx_int (tp);
1703 }
1704
1705
1706
1707
1708
1709
1710 RTL_W16(IntrStatus,
1711 (status & RxFIFOOver) ? (status | RxOverflow) : status);
1712 status = RTL_R16(IntrStatus);
1713 }
1714
1715 iovcpu_job_completion ();
1716 }
1717 }
1718
1719 #ifdef TX_TIMING
1720 static u64 tx_start = 0, tx_finish;
1721 #endif
1722
1723 static uint
1724 irq_handler (u8 vec)
1725 {
1726 #ifdef TX_TIMING
1727
1728 if (tx_start > 0) {
1729 SERIALIZE0;
1730 RDTSC (tx_finish);
1731 logger_printf ("r8169: TX: IRQ received: diff=0x%llX\n", tx_finish - tx_start);
1732 tx_start = 0;
1733 }
1734 #endif
1735
1736 if (r8169_bh_id) {
1737 extern vcpu *vcpu_lookup (int);
1738
1739 iovcpu_job_wakeup (r8169_bh_id, vcpu_lookup (2)->T);
1740 }
1741
1742 return 0;
1743 }
1744
1745 static void
1746 get_mac_version(struct rtl8169_private *tp,
1747 void __iomem *ioaddr)
1748 {
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760 static const struct {
1761 u32 mask;
1762 u32 val;
1763 int mac_version;
1764 } mac_info[] = {
1765
1766 { 0x7cf00000, 0x28300000, RTL_GIGA_MAC_VER_26 },
1767 { 0x7cf00000, 0x28100000, RTL_GIGA_MAC_VER_25 },
1768 { 0x7c800000, 0x28800000, RTL_GIGA_MAC_VER_27 },
1769 { 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_26 },
1770
1771
1772 { 0x7cf00000, 0x3cb00000, RTL_GIGA_MAC_VER_24 },
1773 { 0x7cf00000, 0x3c900000, RTL_GIGA_MAC_VER_23 },
1774 { 0x7cf00000, 0x3c800000, RTL_GIGA_MAC_VER_18 },
1775 { 0x7c800000, 0x3c800000, RTL_GIGA_MAC_VER_24 },
1776 { 0x7cf00000, 0x3c000000, RTL_GIGA_MAC_VER_19 },
1777 { 0x7cf00000, 0x3c200000, RTL_GIGA_MAC_VER_20 },
1778 { 0x7cf00000, 0x3c300000, RTL_GIGA_MAC_VER_21 },
1779 { 0x7cf00000, 0x3c400000, RTL_GIGA_MAC_VER_22 },
1780 { 0x7c800000, 0x3c000000, RTL_GIGA_MAC_VER_22 },
1781
1782
1783 { 0x7cf00000, 0x38000000, RTL_GIGA_MAC_VER_12 },
1784 { 0x7cf00000, 0x38500000, RTL_GIGA_MAC_VER_17 },
1785 { 0x7c800000, 0x38000000, RTL_GIGA_MAC_VER_17 },
1786 { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 },
1787
1788
1789 { 0x7cf00000, 0x34a00000, RTL_GIGA_MAC_VER_09 },
1790 { 0x7cf00000, 0x24a00000, RTL_GIGA_MAC_VER_09 },
1791 { 0x7cf00000, 0x34900000, RTL_GIGA_MAC_VER_08 },
1792 { 0x7cf00000, 0x24900000, RTL_GIGA_MAC_VER_08 },
1793 { 0x7cf00000, 0x34800000, RTL_GIGA_MAC_VER_07 },
1794 { 0x7cf00000, 0x24800000, RTL_GIGA_MAC_VER_07 },
1795 { 0x7cf00000, 0x34000000, RTL_GIGA_MAC_VER_13 },
1796 { 0x7cf00000, 0x34300000, RTL_GIGA_MAC_VER_10 },
1797 { 0x7cf00000, 0x34200000, RTL_GIGA_MAC_VER_16 },
1798 { 0x7c800000, 0x34800000, RTL_GIGA_MAC_VER_09 },
1799 { 0x7c800000, 0x24800000, RTL_GIGA_MAC_VER_09 },
1800 { 0x7c800000, 0x34000000, RTL_GIGA_MAC_VER_16 },
1801
1802 { 0xfc800000, 0x38800000, RTL_GIGA_MAC_VER_15 },
1803 { 0xfc800000, 0x30800000, RTL_GIGA_MAC_VER_14 },
1804
1805
1806 { 0xfc800000, 0x98000000, RTL_GIGA_MAC_VER_06 },
1807 { 0xfc800000, 0x18000000, RTL_GIGA_MAC_VER_05 },
1808 { 0xfc800000, 0x10000000, RTL_GIGA_MAC_VER_04 },
1809 { 0xfc800000, 0x04000000, RTL_GIGA_MAC_VER_03 },
1810 { 0xfc800000, 0x00800000, RTL_GIGA_MAC_VER_02 },
1811 { 0xfc800000, 0x00000000, RTL_GIGA_MAC_VER_01 },
1812
1813
1814 { 0x00000000, 0x00000000, RTL_GIGA_MAC_NONE }
1815 }, *p = mac_info;
1816 u32 reg;
1817
1818 reg = RTL_R32(TxConfig);
1819 while ((reg & p->mask) != p->val)
1820 p++;
1821 tp->mac_version = p->mac_version;
1822 }
1823
1824 static void
1825 print_mac_version(struct rtl8169_private *tp)
1826 {
1827 DLOG ("mac_version = 0x%02x", tp->mac_version);
1828 }
1829
1830 struct phy_reg {
1831 u16 reg;
1832 u16 val;
1833 };
1834
1835 static void rtl_phy_write(void __iomem *ioaddr, const struct phy_reg *regs, int len)
1836 {
1837 while (len-- > 0) {
1838 mdio_write(ioaddr, regs->reg, regs->val);
1839 regs++;
1840 }
1841 }
1842
1843 static void rtl8169s_hw_phy_config(void __iomem *ioaddr)
1844 {
1845 static const struct phy_reg phy_reg_init[] = {
1846 { 0x1f, 0x0001 },
1847 { 0x06, 0x006e },
1848 { 0x08, 0x0708 },
1849 { 0x15, 0x4000 },
1850 { 0x18, 0x65c7 },
1851
1852 { 0x1f, 0x0001 },
1853 { 0x03, 0x00a1 },
1854 { 0x02, 0x0008 },
1855 { 0x01, 0x0120 },
1856 { 0x00, 0x1000 },
1857 { 0x04, 0x0800 },
1858 { 0x04, 0x0000 },
1859
1860 { 0x03, 0xff41 },
1861 { 0x02, 0xdf60 },
1862 { 0x01, 0x0140 },
1863 { 0x00, 0x0077 },
1864 { 0x04, 0x7800 },
1865 { 0x04, 0x7000 },
1866
1867 { 0x03, 0x802f },
1868 { 0x02, 0x4f02 },
1869 { 0x01, 0x0409 },
1870 { 0x00, 0xf0f9 },
1871 { 0x04, 0x9800 },
1872 { 0x04, 0x9000 },
1873
1874 { 0x03, 0xdf01 },
1875 { 0x02, 0xdf20 },
1876 { 0x01, 0xff95 },
1877 { 0x00, 0xba00 },
1878 { 0x04, 0xa800 },
1879 { 0x04, 0xa000 },
1880
1881 { 0x03, 0xff41 },
1882 { 0x02, 0xdf20 },
1883 { 0x01, 0x0140 },
1884 { 0x00, 0x00bb },
1885 { 0x04, 0xb800 },
1886 { 0x04, 0xb000 },
1887
1888 { 0x03, 0xdf41 },
1889 { 0x02, 0xdc60 },
1890 { 0x01, 0x6340 },
1891 { 0x00, 0x007d },
1892 { 0x04, 0xd800 },
1893 { 0x04, 0xd000 },
1894
1895 { 0x03, 0xdf01 },
1896 { 0x02, 0xdf20 },
1897 { 0x01, 0x100a },
1898 { 0x00, 0xa0ff },
1899 { 0x04, 0xf800 },
1900 { 0x04, 0xf000 },
1901
1902 { 0x1f, 0x0000 },
1903 { 0x0b, 0x0000 },
1904 { 0x00, 0x9200 }
1905 };
1906
1907 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
1908 }
1909
1910 static void rtl8169sb_hw_phy_config(void __iomem *ioaddr)
1911 {
1912 static const struct phy_reg phy_reg_init[] = {
1913 { 0x1f, 0x0002 },
1914 { 0x01, 0x90d0 },
1915 { 0x1f, 0x0000 }
1916 };
1917
1918 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
1919 }
1920
1921 static void rtl8169scd_hw_phy_config_quirk(struct rtl8169_private *tp,
1922 void __iomem *ioaddr)
1923 {
1924 struct pci_dev *pdev = tp->pci_dev;
1925 u16 vendor_id, device_id;
1926
1927 pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &vendor_id);
1928 pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &device_id);
1929
1930 if ((vendor_id != PCI_VENDOR_ID_GIGABYTE) || (device_id != 0xe000))
1931 return;
1932
1933 mdio_write(ioaddr, 0x1f, 0x0001);
1934 mdio_write(ioaddr, 0x10, 0xf01b);
1935 mdio_write(ioaddr, 0x1f, 0x0000);
1936 }
1937
1938 static void rtl8169scd_hw_phy_config(struct rtl8169_private *tp,
1939 void __iomem *ioaddr)
1940 {
1941 static const struct phy_reg phy_reg_init[] = {
1942 { 0x1f, 0x0001 },
1943 { 0x04, 0x0000 },
1944 { 0x03, 0x00a1 },
1945 { 0x02, 0x0008 },
1946 { 0x01, 0x0120 },
1947 { 0x00, 0x1000 },
1948 { 0x04, 0x0800 },
1949 { 0x04, 0x9000 },
1950 { 0x03, 0x802f },
1951 { 0x02, 0x4f02 },
1952 { 0x01, 0x0409 },
1953 { 0x00, 0xf099 },
1954 { 0x04, 0x9800 },
1955 { 0x04, 0xa000 },
1956 { 0x03, 0xdf01 },
1957 { 0x02, 0xdf20 },
1958 { 0x01, 0xff95 },
1959 { 0x00, 0xba00 },
1960 { 0x04, 0xa800 },
1961 { 0x04, 0xf000 },
1962 { 0x03, 0xdf01 },
1963 { 0x02, 0xdf20 },
1964 { 0x01, 0x101a },
1965 { 0x00, 0xa0ff },
1966 { 0x04, 0xf800 },
1967 { 0x04, 0x0000 },
1968 { 0x1f, 0x0000 },
1969
1970 { 0x1f, 0x0001 },
1971 { 0x10, 0xf41b },
1972 { 0x14, 0xfb54 },
1973 { 0x18, 0xf5c7 },
1974 { 0x1f, 0x0000 },
1975
1976 { 0x1f, 0x0001 },
1977 { 0x17, 0x0cc0 },
1978 { 0x1f, 0x0000 }
1979 };
1980
1981 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
1982
1983 rtl8169scd_hw_phy_config_quirk(tp, ioaddr);
1984 }
1985
1986 static void rtl8169sce_hw_phy_config(void __iomem *ioaddr)
1987 {
1988 static const struct phy_reg phy_reg_init[] = {
1989 { 0x1f, 0x0001 },
1990 { 0x04, 0x0000 },
1991 { 0x03, 0x00a1 },
1992 { 0x02, 0x0008 },
1993 { 0x01, 0x0120 },
1994 { 0x00, 0x1000 },
1995 { 0x04, 0x0800 },
1996 { 0x04, 0x9000 },
1997 { 0x03, 0x802f },
1998 { 0x02, 0x4f02 },
1999 { 0x01, 0x0409 },
2000 { 0x00, 0xf099 },
2001 { 0x04, 0x9800 },
2002 { 0x04, 0xa000 },
2003 { 0x03, 0xdf01 },
2004 { 0x02, 0xdf20 },
2005 { 0x01, 0xff95 },
2006 { 0x00, 0xba00 },
2007 { 0x04, 0xa800 },
2008 { 0x04, 0xf000 },
2009 { 0x03, 0xdf01 },
2010 { 0x02, 0xdf20 },
2011 { 0x01, 0x101a },
2012 { 0x00, 0xa0ff },
2013 { 0x04, 0xf800 },
2014 { 0x04, 0x0000 },
2015 { 0x1f, 0x0000 },
2016
2017 { 0x1f, 0x0001 },
2018 { 0x0b, 0x8480 },
2019 { 0x1f, 0x0000 },
2020
2021 { 0x1f, 0x0001 },
2022 { 0x18, 0x67c7 },
2023 { 0x04, 0x2000 },
2024 { 0x03, 0x002f },
2025 { 0x02, 0x4360 },
2026 { 0x01, 0x0109 },
2027 { 0x00, 0x3022 },
2028 { 0x04, 0x2800 },
2029 { 0x1f, 0x0000 },
2030
2031 { 0x1f, 0x0001 },
2032 { 0x17, 0x0cc0 },
2033 { 0x1f, 0x0000 }
2034 };
2035
2036 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
2037 }
2038
2039 static void rtl8168bb_hw_phy_config(void __iomem *ioaddr)
2040 {
2041 static const struct phy_reg phy_reg_init[] = {
2042 { 0x10, 0xf41b },
2043 { 0x1f, 0x0000 }
2044 };
2045
2046 mdio_write(ioaddr, 0x1f, 0x0001);
2047 mdio_patch(ioaddr, 0x16, 1 << 0);
2048
2049 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
2050 }
2051
2052 static void rtl8168bef_hw_phy_config(void __iomem *ioaddr)
2053 {
2054 static const struct phy_reg phy_reg_init[] = {
2055 { 0x1f, 0x0001 },
2056 { 0x10, 0xf41b },
2057 { 0x1f, 0x0000 }
2058 };
2059
2060 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
2061 }
2062
2063 static void rtl8168cp_1_hw_phy_config(void __iomem *ioaddr)
2064 {
2065 static const struct phy_reg phy_reg_init[] = {
2066 { 0x1f, 0x0000 },
2067 { 0x1d, 0x0f00 },
2068 { 0x1f, 0x0002 },
2069 { 0x0c, 0x1ec8 },
2070 { 0x1f, 0x0000 }
2071 };
2072
2073 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
2074 }
2075
2076 static void rtl8168cp_2_hw_phy_config(void __iomem *ioaddr)
2077 {
2078 static const struct phy_reg phy_reg_init[] = {
2079 { 0x1f, 0x0001 },
2080 { 0x1d, 0x3d98 },
2081 { 0x1f, 0x0000 }
2082 };
2083
2084 mdio_write(ioaddr, 0x1f, 0x0000);
2085 mdio_patch(ioaddr, 0x14, 1 << 5);
2086 mdio_patch(ioaddr, 0x0d, 1 << 5);
2087
2088 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
2089 }
2090
2091 static void rtl8168c_1_hw_phy_config(void __iomem *ioaddr)
2092 {
2093 static const struct phy_reg phy_reg_init[] = {
2094 { 0x1f, 0x0001 },
2095 { 0x12, 0x2300 },
2096 { 0x1f, 0x0002 },
2097 { 0x00, 0x88d4 },
2098 { 0x01, 0x82b1 },
2099 { 0x03, 0x7002 },
2100 { 0x08, 0x9e30 },
2101 { 0x09, 0x01f0 },
2102 { 0x0a, 0x5500 },
2103 { 0x0c, 0x00c8 },
2104 { 0x1f, 0x0003 },
2105 { 0x12, 0xc096 },
2106 { 0x16, 0x000a },
2107 { 0x1f, 0x0000 },
2108 { 0x1f, 0x0000 },
2109 { 0x09, 0x2000 },
2110 { 0x09, 0x0000 }
2111 };
2112
2113 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
2114
2115 mdio_patch(ioaddr, 0x14, 1 << 5);
2116 mdio_patch(ioaddr, 0x0d, 1 << 5);
2117 mdio_write(ioaddr, 0x1f, 0x0000);
2118 }
2119
2120 static void rtl8168c_2_hw_phy_config(void __iomem *ioaddr)
2121 {
2122 static const struct phy_reg phy_reg_init[] = {
2123 { 0x1f, 0x0001 },
2124 { 0x12, 0x2300 },
2125 { 0x03, 0x802f },
2126 { 0x02, 0x4f02 },
2127 { 0x01, 0x0409 },
2128 { 0x00, 0xf099 },
2129 { 0x04, 0x9800 },
2130 { 0x04, 0x9000 },
2131 { 0x1d, 0x3d98 },
2132 { 0x1f, 0x0002 },
2133 { 0x0c, 0x7eb8 },
2134 { 0x06, 0x0761 },
2135 { 0x1f, 0x0003 },
2136 { 0x16, 0x0f0a },
2137 { 0x1f, 0x0000 }
2138 };
2139
2140 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
2141
2142 mdio_patch(ioaddr, 0x16, 1 << 0);
2143 mdio_patch(ioaddr, 0x14, 1 << 5);
2144 mdio_patch(ioaddr, 0x0d, 1 << 5);
2145 mdio_write(ioaddr, 0x1f, 0x0000);
2146 }
2147
2148 static void rtl8168c_3_hw_phy_config(void __iomem *ioaddr)
2149 {
2150 static const struct phy_reg phy_reg_init[] = {
2151 { 0x1f, 0x0001 },
2152 { 0x12, 0x2300 },
2153 { 0x1d, 0x3d98 },
2154 { 0x1f, 0x0002 },
2155 { 0x0c, 0x7eb8 },
2156 { 0x06, 0x5461 },
2157 { 0x1f, 0x0003 },
2158 { 0x16, 0x0f0a },
2159 { 0x1f, 0x0000 }
2160 };
2161
2162 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
2163
2164 mdio_patch(ioaddr, 0x16, 1 << 0);
2165 mdio_patch(ioaddr, 0x14, 1 << 5);
2166 mdio_patch(ioaddr, 0x0d, 1 << 5);
2167 mdio_write(ioaddr, 0x1f, 0x0000);
2168 }
2169
2170 static void rtl8168c_4_hw_phy_config(void __iomem *ioaddr)
2171 {
2172 rtl8168c_3_hw_phy_config(ioaddr);
2173 }
2174
2175 static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr)
2176 {
2177 static const struct phy_reg phy_reg_init_0[] = {
2178 { 0x1f, 0x0001 },
2179 { 0x06, 0x4064 },
2180 { 0x07, 0x2863 },
2181 { 0x08, 0x059c },
2182 { 0x09, 0x26b4 },
2183 { 0x0a, 0x6a19 },
2184 { 0x0b, 0xdcc8 },
2185 { 0x10, 0xf06d },
2186 { 0x14, 0x7f68 },
2187 { 0x18, 0x7fd9 },
2188 { 0x1c, 0xf0ff },
2189 { 0x1d, 0x3d9c },
2190 { 0x1f, 0x0003 },
2191 { 0x12, 0xf49f },
2192 { 0x13, 0x070b },
2193 { 0x1a, 0x05ad },
2194 { 0x14, 0x94c0 }
2195 };
2196 static const struct phy_reg phy_reg_init_1[] = {
2197 { 0x1f, 0x0002 },
2198 { 0x06, 0x5561 },
2199 { 0x1f, 0x0005 },
2200 { 0x05, 0x8332 },
2201 { 0x06, 0x5561 }
2202 };
2203 static const struct phy_reg phy_reg_init_2[] = {
2204 { 0x1f, 0x0005 },
2205 { 0x05, 0xffc2 },
2206 { 0x1f, 0x0005 },
2207 { 0x05, 0x8000 },
2208 { 0x06, 0xf8f9 },
2209 { 0x06, 0xfaef },
2210 { 0x06, 0x59ee },
2211 { 0x06, 0xf8ea },
2212 { 0x06, 0x00ee },
2213 { 0x06, 0xf8eb },
2214 { 0x06, 0x00e0 },
2215 { 0x06, 0xf87c },
2216 { 0x06, 0xe1f8 },
2217 { 0x06, 0x7d59 },
2218 { 0x06, 0x0fef },
2219 { 0x06, 0x0139 },
2220 { 0x06, 0x029e },
2221 { 0x06, 0x06ef },
2222 { 0x06, 0x1039 },
2223 { 0x06, 0x089f },
2224 { 0x06, 0x2aee },
2225 { 0x06, 0xf8ea },
2226 { 0x06, 0x00ee },
2227 { 0x06, 0xf8eb },
2228 { 0x06, 0x01e0 },
2229 { 0x06, 0xf87c },
2230 { 0x06, 0xe1f8 },
2231 { 0x06, 0x7d58 },
2232 { 0x06, 0x409e },
2233 { 0x06, 0x0f39 },
2234 { 0x06, 0x46aa },
2235 { 0x06, 0x0bbf },
2236 { 0x06, 0x8290 },
2237 { 0x06, 0xd682 },
2238 { 0x06, 0x9802 },
2239 { 0x06, 0x014f },
2240 { 0x06, 0xae09 },
2241 { 0x06, 0xbf82 },
2242 { 0x06, 0x98d6 },
2243 { 0x06, 0x82a0 },
2244 { 0x06, 0x0201 },
2245 { 0x06, 0x4fef },
2246 { 0x06, 0x95fe },
2247 { 0x06, 0xfdfc },
2248 { 0x06, 0x05f8 },
2249 { 0x06, 0xf9fa },
2250 { 0x06, 0xeef8 },
2251 { 0x06, 0xea00 },
2252 { 0x06, 0xeef8 },
2253 { 0x06, 0xeb00 },
2254 { 0x06, 0xe2f8 },
2255 { 0x06, 0x7ce3 },
2256 { 0x06, 0xf87d },
2257 { 0x06, 0xa511 },
2258 { 0x06, 0x1112 },
2259 { 0x06, 0xd240 },
2260 { 0x06, 0xd644 },
2261 { 0x06, 0x4402 },
2262 { 0x06, 0x8217 },
2263 { 0x06, 0xd2a0 },
2264 { 0x06, 0xd6aa },
2265 { 0x06, 0xaa02 },
2266 { 0x06, 0x8217 },
2267 { 0x06, 0xae0f },
2268 { 0x06, 0xa544 },
2269 { 0x06, 0x4402 },
2270 { 0x06, 0xae4d },
2271 { 0x06, 0xa5aa },
2272 { 0x06, 0xaa02 },
2273 { 0x06, 0xae47 },
2274 { 0x06, 0xaf82 },
2275 { 0x06, 0x13ee },
2276 { 0x06, 0x834e },
2277 { 0x06, 0x00ee },
2278 { 0x06, 0x834d },
2279 { 0x06, 0x0fee },
2280 { 0x06, 0x834c },
2281 { 0x06, 0x0fee },
2282 { 0x06, 0x834f },
2283 { 0x06, 0x00ee },
2284 { 0x06, 0x8351 },
2285 { 0x06, 0x00ee },
2286 { 0x06, 0x834a },
2287 { 0x06, 0xffee },
2288 { 0x06, 0x834b },
2289 { 0x06, 0xffe0 },
2290 { 0x06, 0x8330 },
2291 { 0x06, 0xe183 },
2292 { 0x06, 0x3158 },
2293 { 0x06, 0xfee4 },
2294 { 0x06, 0xf88a },
2295 { 0x06, 0xe5f8 },
2296 { 0x06, 0x8be0 },
2297 { 0x06, 0x8332 },
2298 { 0x06, 0xe183 },
2299 { 0x06, 0x3359 },
2300 { 0x06, 0x0fe2 },
2301 { 0x06, 0x834d },
2302 { 0x06, 0x0c24 },
2303 { 0x06, 0x5af0 },
2304 { 0x06, 0x1e12 },
2305 { 0x06, 0xe4f8 },
2306 { 0x06, 0x8ce5 },
2307 { 0x06, 0xf88d },
2308 { 0x06, 0xaf82 },
2309 { 0x06, 0x13e0 },
2310 { 0x06, 0x834f },
2311 { 0x06, 0x10e4 },
2312 { 0x06, 0x834f },
2313 { 0x06, 0xe083 },
2314 { 0x06, 0x4e78 },
2315 { 0x06, 0x009f },
2316 { 0x06, 0x0ae0 },
2317 { 0x06, 0x834f },
2318 { 0x06, 0xa010 },
2319 { 0x06, 0xa5ee },
2320 { 0x06, 0x834e },
2321 { 0x06, 0x01e0 },
2322 { 0x06, 0x834e },
2323 { 0x06, 0x7805 },
2324 { 0x06, 0x9e9a },
2325 { 0x06, 0xe083 },
2326 { 0x06, 0x4e78 },
2327 { 0x06, 0x049e },
2328 { 0x06, 0x10e0 },
2329 { 0x06, 0x834e },
2330 { 0x06, 0x7803 },
2331 { 0x06, 0x9e0f },
2332 { 0x06, 0xe083 },
2333 { 0x06, 0x4e78 },
2334 { 0x06, 0x019e },
2335 { 0x06, 0x05ae },
2336 { 0x06, 0x0caf },
2337 { 0x06, 0x81f8 },
2338 { 0x06, 0xaf81 },
2339 { 0x06, 0xa3af },
2340 { 0x06, 0x81dc },
2341 { 0x06, 0xaf82 },
2342 { 0x06, 0x13ee },
2343 { 0x06, 0x8348 },
2344 { 0x06, 0x00ee },
2345 { 0x06, 0x8349 },
2346 { 0x06, 0x00e0 },
2347 { 0x06, 0x8351 },
2348 { 0x06, 0x10e4 },
2349 { 0x06, 0x8351 },
2350 { 0x06, 0x5801 },
2351 { 0x06, 0x9fea },
2352 { 0x06, 0xd000 },
2353 { 0x06, 0xd180 },
2354 { 0x06, 0x1f66 },
2355 { 0x06, 0xe2f8 },
2356 { 0x06, 0xeae3 },
2357 { 0x06, 0xf8eb },
2358 { 0x06, 0x5af8 },
2359 { 0x06, 0x1e20 },
2360 { 0x06, 0xe6f8 },
2361 { 0x06, 0xeae5 },
2362 { 0x06, 0xf8eb },
2363 { 0x06, 0xd302 },
2364 { 0x06, 0xb3fe },
2365 { 0x06, 0xe2f8 },
2366 { 0x06, 0x7cef },
2367 { 0x06, 0x325b },
2368 { 0x06, 0x80e3 },
2369 { 0x06, 0xf87d },
2370 { 0x06, 0x9e03 },
2371 { 0x06, 0x7dff },
2372 { 0x06, 0xff0d },
2373 { 0x06, 0x581c },
2374 { 0x06, 0x551a },
2375 { 0x06, 0x6511 },
2376 { 0x06, 0xa190 },
2377 { 0x06, 0xd3e2 },
2378 { 0x06, 0x8348 },
2379 { 0x06, 0xe383 },
2380 { 0x06, 0x491b },
2381 { 0x06, 0x56ab },
2382 { 0x06, 0x08ef },
2383 { 0x06, 0x56e6 },
2384 { 0x06, 0x8348 },
2385 { 0x06, 0xe783 },
2386 { 0x06, 0x4910 },
2387 { 0x06, 0xd180 },
2388 { 0x06, 0x1f66 },
2389 { 0x06, 0xa004 },
2390 { 0x06, 0xb9e2 },
2391 { 0x06, 0x8348 },
2392 { 0x06, 0xe383 },
2393 { 0x06, 0x49ef },
2394 { 0x06, 0x65e2 },
2395 { 0x06, 0x834a },
2396 { 0x06, 0xe383 },
2397 { 0x06, 0x4b1b },
2398 { 0x06, 0x56aa },
2399 { 0x06, 0x0eef },
2400 { 0x06, 0x56e6 },
2401 { 0x06, 0x834a },
2402 { 0x06, 0xe783 },
2403 { 0x06, 0x4be2 },
2404 { 0x06, 0x834d },
2405 { 0x06, 0xe683 },
2406 { 0x06, 0x4ce0 },
2407 { 0x06, 0x834d },
2408 { 0x06, 0xa000 },
2409 { 0x06, 0x0caf },
2410 { 0x06, 0x81dc },
2411 { 0x06, 0xe083 },
2412 { 0x06, 0x4d10 },
2413 { 0x06, 0xe483 },
2414 { 0x06, 0x4dae },
2415 { 0x06, 0x0480 },
2416 { 0x06, 0xe483 },
2417 { 0x06, 0x4de0 },
2418 { 0x06, 0x834e },
2419 { 0x06, 0x7803 },
2420 { 0x06, 0x9e0b },
2421 { 0x06, 0xe083 },
2422 { 0x06, 0x4e78 },
2423 { 0x06, 0x049e },
2424 { 0x06, 0x04ee },
2425 { 0x06, 0x834e },
2426 { 0x06, 0x02e0 },
2427 { 0x06, 0x8332 },
2428 { 0x06, 0xe183 },
2429 { 0x06, 0x3359 },
2430 { 0x06, 0x0fe2 },
2431 { 0x06, 0x834d },
2432 { 0x06, 0x0c24 },
2433 { 0x06, 0x5af0 },
2434 { 0x06, 0x1e12 },
2435 { 0x06, 0xe4f8 },
2436 { 0x06, 0x8ce5 },
2437 { 0x06, 0xf88d },
2438 { 0x06, 0xe083 },
2439 { 0x06, 0x30e1 },
2440 { 0x06, 0x8331 },
2441 { 0x06, 0x6801 },
2442 { 0x06, 0xe4f8 },
2443 { 0x06, 0x8ae5 },
2444 { 0x06, 0xf88b },
2445 { 0x06, 0xae37 },
2446 { 0x06, 0xee83 },
2447 { 0x06, 0x4e03 },
2448 { 0x06, 0xe083 },
2449 { 0x06, 0x4ce1 },
2450 { 0x06, 0x834d },
2451 { 0x06, 0x1b01 },
2452 { 0x06, 0x9e04 },
2453 { 0x06, 0xaaa1 },
2454 { 0x06, 0xaea8 },
2455 { 0x06, 0xee83 },
2456 { 0x06, 0x4e04 },
2457 { 0x06, 0xee83 },
2458 { 0x06, 0x4f00 },
2459 { 0x06, 0xaeab },
2460 { 0x06, 0xe083 },
2461 { 0x06, 0x4f78 },
2462 { 0x06, 0x039f },
2463 { 0x06, 0x14ee },
2464 { 0x06, 0x834e },
2465 { 0x06, 0x05d2 },
2466 { 0x06, 0x40d6 },
2467 { 0x06, 0x5554 },
2468 { 0x06, 0x0282 },
2469 { 0x06, 0x17d2 },
2470 { 0x06, 0xa0d6 },
2471 { 0x06, 0xba00 },
2472 { 0x06, 0x0282 },
2473 { 0x06, 0x17fe },
2474 { 0x06, 0xfdfc },
2475 { 0x06, 0x05f8 },
2476 { 0x06, 0xe0f8 },
2477 { 0x06, 0x60e1 },
2478 { 0x06, 0xf861 },
2479 { 0x06, 0x6802 },
2480 { 0x06, 0xe4f8 },
2481 { 0x06, 0x60e5 },
2482 { 0x06, 0xf861 },
2483 { 0x06, 0xe0f8 },
2484 { 0x06, 0x48e1 },
2485 { 0x06, 0xf849 },
2486 { 0x06, 0x580f },
2487 { 0x06, 0x1e02 },
2488 { 0x06, 0xe4f8 },
2489 { 0x06, 0x48e5 },
2490 { 0x06, 0xf849 },
2491 { 0x06, 0xd000 },
2492 { 0x06, 0x0282 },
2493 { 0x06, 0x5bbf },
2494 { 0x06, 0x8350 },
2495 { 0x06, 0xef46 },
2496 { 0x06, 0xdc19 },
2497 { 0x06, 0xddd0 },
2498 { 0x06, 0x0102 },
2499 { 0x06, 0x825b },
2500 { 0x06, 0x0282 },
2501 { 0x06, 0x77e0 },
2502 { 0x06, 0xf860 },
2503 { 0x06, 0xe1f8 },
2504 { 0x06, 0x6158 },
2505 { 0x06, 0xfde4 },
2506 { 0x06, 0xf860 },
2507 { 0x06, 0xe5f8 },
2508 { 0x06, 0x61fc },
2509 { 0x06, 0x04f9 },
2510 { 0x06, 0xfafb },
2511 { 0x06, 0xc6bf },
2512 { 0x06, 0xf840 },
2513 { 0x06, 0xbe83 },
2514 { 0x06, 0x50a0 },
2515 { 0x06, 0x0101 },
2516 { 0x06, 0x071b },
2517 { 0x06, 0x89cf },
2518 { 0x06, 0xd208 },
2519 { 0x06, 0xebdb },
2520 { 0x06, 0x19b2 },
2521 { 0x06, 0xfbff },
2522 { 0x06, 0xfefd },
2523 { 0x06, 0x04f8 },
2524 { 0x06, 0xe0f8 },
2525 { 0x06, 0x48e1 },
2526 { 0x06, 0xf849 },
2527 { 0x06, 0x6808 },
2528 { 0x06, 0xe4f8 },
2529 { 0x06, 0x48e5 },
2530 { 0x06, 0xf849 },
2531 { 0x06, 0x58f7 },
2532 { 0x06, 0xe4f8 },
2533 { 0x06, 0x48e5 },
2534 { 0x06, 0xf849 },
2535 { 0x06, 0xfc04 },
2536 { 0x06, 0x4d20 },
2537 { 0x06, 0x0002 },
2538 { 0x06, 0x4e22 },
2539 { 0x06, 0x0002 },
2540 { 0x06, 0x4ddf },
2541 { 0x06, 0xff01 },
2542 { 0x06, 0x4edd },
2543 { 0x06, 0xff01 },
2544 { 0x05, 0x83d4 },
2545 { 0x06, 0x8000 },
2546 { 0x05, 0x83d8 },
2547 { 0x06, 0x8051 },
2548 { 0x02, 0x6010 },
2549 { 0x03, 0xdc00 },
2550 { 0x05, 0xfff6 },
2551 { 0x06, 0x00fc },
2552 { 0x1f, 0x0000 },
2553
2554 { 0x1f, 0x0000 },
2555 { 0x0d, 0xf880 },
2556 { 0x1f, 0x0000 }
2557 };
2558
2559 rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
2560
2561 mdio_write(ioaddr, 0x1f, 0x0002);
2562 mdio_plus_minus(ioaddr, 0x0b, 0x0010, 0x00ef);
2563 mdio_plus_minus(ioaddr, 0x0c, 0xa200, 0x5d00);
2564
2565 rtl_phy_write(ioaddr, phy_reg_init_1, ARRAY_SIZE(phy_reg_init_1));
2566
2567 if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) {
2568 static const struct phy_reg phy_reg_init[] = {
2569 { 0x1f, 0x0002 },
2570 { 0x05, 0x669a },
2571 { 0x1f, 0x0005 },
2572 { 0x05, 0x8330 },
2573 { 0x06, 0x669a },
2574 { 0x1f, 0x0002 }
2575 };
2576 int val;
2577
2578 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
2579
2580 val = mdio_read(ioaddr, 0x0d);
2581
2582 if ((val & 0x00ff) != 0x006c) {
2583 static const u32 set[] = {
2584 0x0065, 0x0066, 0x0067, 0x0068,
2585 0x0069, 0x006a, 0x006b, 0x006c
2586 };
2587 int i;
2588
2589 mdio_write(ioaddr, 0x1f, 0x0002);
2590
2591 val &= 0xff00;
2592 for (i = 0; i < ARRAY_SIZE(set); i++)
2593 mdio_write(ioaddr, 0x0d, val | set[i]);
2594 }
2595 } else {
2596 static const struct phy_reg phy_reg_init[] = {
2597 { 0x1f, 0x0002 },
2598 { 0x05, 0x6662 },
2599 { 0x1f, 0x0005 },
2600 { 0x05, 0x8330 },
2601 { 0x06, 0x6662 }
2602 };
2603
2604 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
2605 }
2606
2607 mdio_write(ioaddr, 0x1f, 0x0002);
2608 mdio_patch(ioaddr, 0x0d, 0x0300);
2609 mdio_patch(ioaddr, 0x0f, 0x0010);
2610
2611 mdio_write(ioaddr, 0x1f, 0x0002);
2612 mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600);
2613 mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000);
2614
2615 rtl_phy_write(ioaddr, phy_reg_init_2, ARRAY_SIZE(phy_reg_init_2));
2616 }
2617
2618 static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr)
2619 {
2620 static const struct phy_reg phy_reg_init_0[] = {
2621 { 0x1f, 0x0001 },
2622 { 0x06, 0x4064 },
2623 { 0x07, 0x2863 },
2624 { 0x08, 0x059c },
2625 { 0x09, 0x26b4 },
2626 { 0x0a, 0x6a19 },
2627 { 0x0b, 0xdcc8 },
2628 { 0x10, 0xf06d },
2629 { 0x14, 0x7f68 },
2630 { 0x18, 0x7fd9 },
2631 { 0x1c, 0xf0ff },
2632 { 0x1d, 0x3d9c },
2633 { 0x1f, 0x0003 },
2634 { 0x12, 0xf49f },
2635 { 0x13, 0x070b },
2636 { 0x1a, 0x05ad },
2637 { 0x14, 0x94c0 },
2638
2639 { 0x1f, 0x0002 },
2640 { 0x06, 0x5561 },
2641 { 0x1f, 0x0005 },
2642 { 0x05, 0x8332 },
2643 { 0x06, 0x5561 }
2644 };
2645 static const struct phy_reg phy_reg_init_1[] = {
2646 { 0x1f, 0x0005 },
2647 { 0x05, 0xffc2 },
2648 { 0x1f, 0x0005 },
2649 { 0x05, 0x8000 },
2650 { 0x06, 0xf8f9 },
2651 { 0x06, 0xfaee },
2652 { 0x06, 0xf8ea },
2653 { 0x06, 0x00ee },
2654 { 0x06, 0xf8eb },
2655 { 0x06, 0x00e2 },
2656 { 0x06, 0xf87c },
2657 { 0x06, 0xe3f8 },
2658 { 0x06, 0x7da5 },
2659 { 0x06, 0x1111 },
2660 { 0x06, 0x12d2 },
2661 { 0x06, 0x40d6 },
2662 { 0x06, 0x4444 },
2663 { 0x06, 0x0281 },
2664 { 0x06, 0xc6d2 },
2665 { 0x06, 0xa0d6 },
2666 { 0x06, 0xaaaa },
2667 { 0x06, 0x0281 },
2668 { 0x06, 0xc6ae },
2669 { 0x06, 0x0fa5 },
2670 { 0x06, 0x4444 },
2671 { 0x06, 0x02ae },
2672 { 0x06, 0x4da5 },
2673 { 0x06, 0xaaaa },
2674 { 0x06, 0x02ae },
2675 { 0x06, 0x47af },
2676 { 0x06, 0x81c2 },
2677 { 0x06, 0xee83 },
2678 { 0x06, 0x4e00 },
2679 { 0x06, 0xee83 },
2680 { 0x06, 0x4d0f },
2681 { 0x06, 0xee83 },
2682 { 0x06, 0x4c0f },
2683 { 0x06, 0xee83 },
2684 { 0x06, 0x4f00 },
2685 { 0x06, 0xee83 },
2686 { 0x06, 0x5100 },
2687 { 0x06, 0xee83 },
2688 { 0x06, 0x4aff },
2689 { 0x06, 0xee83 },
2690 { 0x06, 0x4bff },
2691 { 0x06, 0xe083 },
2692 { 0x06, 0x30e1 },
2693 { 0x06, 0x8331 },
2694 { 0x06, 0x58fe },
2695 { 0x06, 0xe4f8 },
2696 { 0x06, 0x8ae5 },
2697 { 0x06, 0xf88b },
2698 { 0x06, 0xe083 },
2699 { 0x06, 0x32e1 },
2700 { 0x06, 0x8333 },
2701 { 0x06, 0x590f },
2702 { 0x06, 0xe283 },
2703 { 0x06, 0x4d0c },
2704 { 0x06, 0x245a },
2705 { 0x06, 0xf01e },
2706 { 0x06, 0x12e4 },
2707 { 0x06, 0xf88c },
2708 { 0x06, 0xe5f8 },
2709 { 0x06, 0x8daf },
2710 { 0x06, 0x81c2 },
2711 { 0x06, 0xe083 },
2712 { 0x06, 0x4f10 },
2713 { 0x06, 0xe483 },
2714 { 0x06, 0x4fe0 },
2715 { 0x06, 0x834e },
2716 { 0x06, 0x7800 },
2717 { 0x06, 0x9f0a },
2718 { 0x06, 0xe083 },
2719 { 0x06, 0x4fa0 },
2720 { 0x06, 0x10a5 },
2721 { 0x06, 0xee83 },
2722 { 0x06, 0x4e01 },
2723 { 0x06, 0xe083 },
2724 { 0x06, 0x4e78 },
2725 { 0x06, 0x059e },
2726 { 0x06, 0x9ae0 },
2727 { 0x06, 0x834e },
2728 { 0x06, 0x7804 },
2729 { 0x06, 0x9e10 },
2730 { 0x06, 0xe083 },
2731 { 0x06, 0x4e78 },
2732 { 0x06, 0x039e },
2733 { 0x06, 0x0fe0 },
2734 { 0x06, 0x834e },
2735 { 0x06, 0x7801 },
2736 { 0x06, 0x9e05 },
2737 { 0x06, 0xae0c },
2738 { 0x06, 0xaf81 },
2739 { 0x06, 0xa7af },
2740 { 0x06, 0x8152 },
2741 { 0x06, 0xaf81 },
2742 { 0x06, 0x8baf },
2743 { 0x06, 0x81c2 },
2744 { 0x06, 0xee83 },
2745 { 0x06, 0x4800 },
2746 { 0x06, 0xee83 },
2747 { 0x06, 0x4900 },
2748 { 0x06, 0xe083 },
2749 { 0x06, 0x5110 },
2750 { 0x06, 0xe483 },
2751 { 0x06, 0x5158 },
2752 { 0x06, 0x019f },
2753 { 0x06, 0xead0 },
2754 { 0x06, 0x00d1 },
2755 { 0x06, 0x801f },
2756 { 0x06, 0x66e2 },
2757 { 0x06, 0xf8ea },
2758 { 0x06, 0xe3f8 },
2759 { 0x06, 0xeb5a },
2760 { 0x06, 0xf81e },
2761 { 0x06, 0x20e6 },
2762 { 0x06, 0xf8ea },
2763 { 0x06, 0xe5f8 },
2764 { 0x06, 0xebd3 },
2765 { 0x06, 0x02b3 },
2766 { 0x06, 0xfee2 },
2767 { 0x06, 0xf87c },
2768 { 0x06, 0xef32 },
2769 { 0x06, 0x5b80 },
2770 { 0x06, 0xe3f8 },
2771 { 0x06, 0x7d9e },
2772 { 0x06, 0x037d },
2773 { 0x06, 0xffff },
2774 { 0x06, 0x0d58 },
2775 { 0x06, 0x1c55 },
2776 { 0x06, 0x1a65 },
2777 { 0x06, 0x11a1 },
2778 { 0x06, 0x90d3 },
2779 { 0x06, 0xe283 },
2780 { 0x06, 0x48e3 },
2781 { 0x06, 0x8349 },
2782 { 0x06, 0x1b56 },
2783 { 0x06, 0xab08 },
2784 { 0x06, 0xef56 },
2785 { 0x06, 0xe683 },
2786 { 0x06, 0x48e7 },
2787 { 0x06, 0x8349 },
2788 { 0x06, 0x10d1 },
2789 { 0x06, 0x801f },
2790 { 0x06, 0x66a0 },
2791 { 0x06, 0x04b9 },
2792 { 0x06, 0xe283 },
2793 { 0x06, 0x48e3 },
2794 { 0x06, 0x8349 },
2795 { 0x06, 0xef65 },
2796 { 0x06, 0xe283 },
2797 { 0x06, 0x4ae3 },
2798 { 0x06, 0x834b },
2799 { 0x06, 0x1b56 },
2800 { 0x06, 0xaa0e },
2801 { 0x06, 0xef56 },
2802 { 0x06, 0xe683 },
2803 { 0x06, 0x4ae7 },
2804 { 0x06, 0x834b },
2805 { 0x06, 0xe283 },
2806 { 0x06, 0x4de6 },
2807 { 0x06, 0x834c },
2808 { 0x06, 0xe083 },
2809 { 0x06, 0x4da0 },
2810 { 0x06, 0x000c },
2811 { 0x06, 0xaf81 },
2812 { 0x06, 0x8be0 },
2813 { 0x06, 0x834d },
2814 { 0x06, 0x10e4 },
2815 { 0x06, 0x834d },
2816 { 0x06, 0xae04 },
2817 { 0x06, 0x80e4 },
2818 { 0x06, 0x834d },
2819 { 0x06, 0xe083 },
2820 { 0x06, 0x4e78 },
2821 { 0x06, 0x039e },
2822 { 0x06, 0x0be0 },
2823 { 0x06, 0x834e },
2824 { 0x06, 0x7804 },
2825 { 0x06, 0x9e04 },
2826 { 0x06, 0xee83 },
2827 { 0x06, 0x4e02 },
2828 { 0x06, 0xe083 },
2829 { 0x06, 0x32e1 },
2830 { 0x06, 0x8333 },
2831 { 0x06, 0x590f },
2832 { 0x06, 0xe283 },
2833 { 0x06, 0x4d0c },
2834 { 0x06, 0x245a },
2835 { 0x06, 0xf01e },
2836 { 0x06, 0x12e4 },
2837 { 0x06, 0xf88c },
2838 { 0x06, 0xe5f8 },
2839 { 0x06, 0x8de0 },
2840 { 0x06, 0x8330 },
2841 { 0x06, 0xe183 },
2842 { 0x06, 0x3168 },
2843 { 0x06, 0x01e4 },
2844 { 0x06, 0xf88a },
2845 { 0x06, 0xe5f8 },
2846 { 0x06, 0x8bae },
2847 { 0x06, 0x37ee },
2848 { 0x06, 0x834e },
2849 { 0x06, 0x03e0 },
2850 { 0x06, 0x834c },
2851 { 0x06, 0xe183 },
2852 { 0x06, 0x4d1b },
2853 { 0x06, 0x019e },
2854 { 0x06, 0x04aa },
2855 { 0x06, 0xa1ae },
2856 { 0x06, 0xa8ee },
2857 { 0x06, 0x834e },
2858 { 0x06, 0x04ee },
2859 { 0x06, 0x834f },
2860 { 0x06, 0x00ae },
2861 { 0x06, 0xabe0 },
2862 { 0x06, 0x834f },
2863 { 0x06, 0x7803 },
2864 { 0x06, 0x9f14 },
2865 { 0x06, 0xee83 },
2866 { 0x06, 0x4e05 },
2867 { 0x06, 0xd240 },
2868 { 0x06, 0xd655 },
2869 { 0x06, 0x5402 },
2870 { 0x06, 0x81c6 },
2871 { 0x06, 0xd2a0 },
2872 { 0x06, 0xd6ba },
2873 { 0x06, 0x0002 },
2874 { 0x06, 0x81c6 },
2875 { 0x06, 0xfefd },
2876 { 0x06, 0xfc05 },
2877 { 0x06, 0xf8e0 },
2878 { 0x06, 0xf860 },
2879 { 0x06, 0xe1f8 },
2880 { 0x06, 0x6168 },
2881 { 0x06, 0x02e4 },
2882 { 0x06, 0xf860 },
2883 { 0x06, 0xe5f8 },
2884 { 0x06, 0x61e0 },
2885 { 0x06, 0xf848 },
2886 { 0x06, 0xe1f8 },
2887 { 0x06, 0x4958 },
2888 { 0x06, 0x0f1e },
2889 { 0x06, 0x02e4 },
2890 { 0x06, 0xf848 },
2891 { 0x06, 0xe5f8 },
2892 { 0x06, 0x49d0 },
2893 { 0x06, 0x0002 },
2894 { 0x06, 0x820a },
2895 { 0x06, 0xbf83 },
2896 { 0x06, 0x50ef },
2897 { 0x06, 0x46dc },
2898 { 0x06, 0x19dd },
2899 { 0x06, 0xd001 },
2900 { 0x06, 0x0282 },
2901 { 0x06, 0x0a02 },
2902 { 0x06, 0x8226 },
2903 { 0x06, 0xe0f8 },
2904 { 0x06, 0x60e1 },
2905 { 0x06, 0xf861 },
2906 { 0x06, 0x58fd },
2907 { 0x06, 0xe4f8 },
2908 { 0x06, 0x60e5 },
2909 { 0x06, 0xf861 },
2910 { 0x06, 0xfc04 },
2911 { 0x06, 0xf9fa },
2912 { 0x06, 0xfbc6 },
2913 { 0x06, 0xbff8 },
2914 { 0x06, 0x40be },
2915 { 0x06, 0x8350 },
2916 { 0x06, 0xa001 },
2917 { 0x06, 0x0107 },
2918 { 0x06, 0x1b89 },
2919 { 0x06, 0xcfd2 },
2920 { 0x06, 0x08eb },
2921 { 0x06, 0xdb19 },
2922 { 0x06, 0xb2fb },
2923 { 0x06, 0xfffe },
2924 { 0x06, 0xfd04 },
2925 { 0x06, 0xf8e0 },
2926 { 0x06, 0xf848 },
2927 { 0x06, 0xe1f8 },
2928 { 0x06, 0x4968 },
2929 { 0x06, 0x08e4 },
2930 { 0x06, 0xf848 },
2931 { 0x06, 0xe5f8 },
2932 { 0x06, 0x4958 },
2933 { 0x06, 0xf7e4 },
2934 { 0x06, 0xf848 },
2935 { 0x06, 0xe5f8 },
2936 { 0x06, 0x49fc },
2937 { 0x06, 0x044d },
2938 { 0x06, 0x2000 },
2939 { 0x06, 0x024e },
2940 { 0x06, 0x2200 },
2941 { 0x06, 0x024d },
2942 { 0x06, 0xdfff },
2943 { 0x06, 0x014e },
2944 { 0x06, 0xddff },
2945 { 0x06, 0x0100 },
2946 { 0x05, 0x83d8 },
2947 { 0x06, 0x8000 },
2948 { 0x03, 0xdc00 },
2949 { 0x05, 0xfff6 },
2950 { 0x06, 0x00fc },
2951 { 0x1f, 0x0000 },
2952
2953 { 0x1f, 0x0000 },
2954 { 0x0d, 0xf880 },
2955 { 0x1f, 0x0000 }
2956 };
2957
2958 rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
2959
2960 if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) {
2961 static const struct phy_reg phy_reg_init[] = {
2962 { 0x1f, 0x0002 },
2963 { 0x05, 0x669a },
2964 { 0x1f, 0x0005 },
2965 { 0x05, 0x8330 },
2966 { 0x06, 0x669a },
2967
2968 { 0x1f, 0x0002 }
2969 };
2970 int val;
2971
2972 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
2973
2974 val = mdio_read(ioaddr, 0x0d);
2975 if ((val & 0x00ff) != 0x006c) {
2976 u32 set[] = {
2977 0x0065, 0x0066, 0x0067, 0x0068,
2978 0x0069, 0x006a, 0x006b, 0x006c
2979 };
2980 int i;
2981
2982 mdio_write(ioaddr, 0x1f, 0x0002);
2983
2984 val &= 0xff00;
2985 for (i = 0; i < ARRAY_SIZE(set); i++)
2986 mdio_write(ioaddr, 0x0d, val | set[i]);
2987 }
2988 } else {
2989 static const struct phy_reg phy_reg_init[] = {
2990 { 0x1f, 0x0002 },
2991 { 0x05, 0x2642 },
2992 { 0x1f, 0x0005 },
2993 { 0x05, 0x8330 },
2994 { 0x06, 0x2642 }
2995 };
2996
2997 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
2998 }
2999
3000 mdio_write(ioaddr, 0x1f, 0x0002);
3001 mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600);
3002 mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000);
3003
3004 mdio_write(ioaddr, 0x1f, 0x0001);
3005 mdio_write(ioaddr, 0x17, 0x0cc0);
3006
3007 mdio_write(ioaddr, 0x1f, 0x0002);
3008 mdio_patch(ioaddr, 0x0f, 0x0017);
3009
3010 rtl_phy_write(ioaddr, phy_reg_init_1, ARRAY_SIZE(phy_reg_init_1));
3011 }
3012
3013 static void rtl8168d_3_hw_phy_config(void __iomem *ioaddr)
3014 {
3015 static const struct phy_reg phy_reg_init[] = {
3016 { 0x1f, 0x0002 },
3017 { 0x10, 0x0008 },
3018 { 0x0d, 0x006c },
3019
3020 { 0x1f, 0x0000 },
3021 { 0x0d, 0xf880 },
3022
3023 { 0x1f, 0x0001 },
3024 { 0x17, 0x0cc0 },
3025
3026 { 0x1f, 0x0001 },
3027 { 0x0b, 0xa4d8 },
3028 { 0x09, 0x281c },
3029 { 0x07, 0x2883 },
3030 { 0x0a, 0x6b35 },
3031 { 0x1d, 0x3da4 },
3032 { 0x1c, 0xeffd },
3033 { 0x14, 0x7f52 },
3034 { 0x18, 0x7fc6 },
3035 { 0x08, 0x0601 },
3036 { 0x06, 0x4063 },
3037 { 0x10, 0xf074 },
3038 { 0x1f, 0x0003 },
3039 { 0x13, 0x0789 },
3040 { 0x12, 0xf4bd },
3041 { 0x1a, 0x04fd },
3042 { 0x14, 0x84b0 },
3043 { 0x1f, 0x0000 },
3044 { 0x00, 0x9200 },
3045
3046 { 0x1f, 0x0005 },
3047 { 0x01, 0x0340 },
3048 { 0x1f, 0x0001 },
3049 { 0x04, 0x4000 },
3050 { 0x03, 0x1d21 },
3051 { 0x02, 0x0c32 },
3052 { 0x01, 0x0200 },
3053 { 0x00, 0x5554 },
3054 { 0x04, 0x4800 },
3055 { 0x04, 0x4000 },
3056 { 0x04, 0xf000 },
3057 { 0x03, 0xdf01 },
3058 { 0x02, 0xdf20 },
3059 { 0x01, 0x101a },
3060 { 0x00, 0xa0ff },
3061 { 0x04, 0xf800 },
3062 { 0x04, 0xf000 },
3063 { 0x1f, 0x0000 },
3064
3065 { 0x1f, 0x0007 },
3066 { 0x1e, 0x0023 },
3067 { 0x16, 0x0000 },
3068 { 0x1f, 0x0000 }
3069 };
3070
3071 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
3072 }
3073
3074 static void rtl8102e_hw_phy_config(void __iomem *ioaddr)
3075 {
3076 static const struct phy_reg phy_reg_init[] = {
3077 { 0x1f, 0x0003 },
3078 { 0x08, 0x441d },
3079 { 0x01, 0x9100 },
3080 { 0x1f, 0x0000 }
3081 };
3082
3083 mdio_write(ioaddr, 0x1f, 0x0000);
3084 mdio_patch(ioaddr, 0x11, 1 << 12);
3085 mdio_patch(ioaddr, 0x19, 1 << 13);
3086 mdio_patch(ioaddr, 0x10, 1 << 15);
3087
3088 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
3089 }
3090
3091 static void rtl_hw_phy_config(struct net_device *dev)
3092 {
3093 struct rtl8169_private *tp = netdev_priv(dev);
3094 void __iomem *ioaddr = tp->mmio_addr;
3095
3096 switch (tp->mac_version) {
3097 case RTL_GIGA_MAC_VER_01:
3098 break;
3099 case RTL_GIGA_MAC_VER_02:
3100 case RTL_GIGA_MAC_VER_03:
3101 rtl8169s_hw_phy_config(ioaddr);
3102 break;
3103 case RTL_GIGA_MAC_VER_04:
3104 rtl8169sb_hw_phy_config(ioaddr);
3105 break;
3106 case RTL_GIGA_MAC_VER_05:
3107 rtl8169scd_hw_phy_config(tp, ioaddr);
3108 break;
3109 case RTL_GIGA_MAC_VER_06:
3110 rtl8169sce_hw_phy_config(ioaddr);
3111 break;
3112 case RTL_GIGA_MAC_VER_07:
3113 case RTL_GIGA_MAC_VER_08:
3114 case RTL_GIGA_MAC_VER_09:
3115 rtl8102e_hw_phy_config(ioaddr);
3116 break;
3117 case RTL_GIGA_MAC_VER_11:
3118 rtl8168bb_hw_phy_config(ioaddr);
3119 break;
3120 case RTL_GIGA_MAC_VER_12:
3121 rtl8168bef_hw_phy_config(ioaddr);
3122 break;
3123 case RTL_GIGA_MAC_VER_17:
3124 rtl8168bef_hw_phy_config(ioaddr);
3125 break;
3126 case RTL_GIGA_MAC_VER_18:
3127 rtl8168cp_1_hw_phy_config(ioaddr);
3128 break;
3129 case RTL_GIGA_MAC_VER_19:
3130 rtl8168c_1_hw_phy_config(ioaddr);
3131 break;
3132 case RTL_GIGA_MAC_VER_20:
3133 rtl8168c_2_hw_phy_config(ioaddr);
3134 break;
3135 case RTL_GIGA_MAC_VER_21:
3136 rtl8168c_3_hw_phy_config(ioaddr);
3137 break;
3138 case RTL_GIGA_MAC_VER_22:
3139 rtl8168c_4_hw_phy_config(ioaddr);
3140 break;
3141 case RTL_GIGA_MAC_VER_23:
3142 case RTL_GIGA_MAC_VER_24:
3143 rtl8168cp_2_hw_phy_config(ioaddr);
3144 break;
3145 case RTL_GIGA_MAC_VER_25:
3146 rtl8168d_1_hw_phy_config(ioaddr);
3147 break;
3148 case RTL_GIGA_MAC_VER_26:
3149 rtl8168d_2_hw_phy_config(ioaddr);
3150 break;
3151 case RTL_GIGA_MAC_VER_27:
3152 rtl8168d_3_hw_phy_config(ioaddr);
3153 break;
3154
3155 default:
3156 break;
3157 }
3158 }
3159
3160 static int
3161 rtl8169_set_speed(struct net_device *dev,
3162 u8 autoneg, u16 speed, u8 duplex)
3163 {
3164 struct rtl8169_private *tp = netdev_priv(dev);
3165 int ret;
3166
3167 ret = tp->set_speed(dev, autoneg, speed, duplex);
3168
3169
3170
3171
3172
3173
3174 return ret;
3175 }
3176
3177 static void
3178 rtl8169_phy_reset(struct net_device *dev,
3179 struct rtl8169_private *tp)
3180 {
3181 void __iomem *ioaddr = tp->mmio_addr;
3182 unsigned int i;
3183
3184 tp->phy_reset_enable(ioaddr);
3185 for (i = 0; i < 100; i++) {
3186 if (!tp->phy_reset_pending(ioaddr))
3187 return;
3188 udelay(1000);
3189 }
3190 DLOG("PHY reset failed");
3191 }
3192
3193 static void
3194 init_phy(struct net_device *dev, struct rtl8169_private *tp)
3195 {
3196 void __iomem *ioaddr = tp->mmio_addr;
3197
3198 rtl_hw_phy_config(dev);
3199
3200 if (tp->mac_version <= RTL_GIGA_MAC_VER_06) {
3201 DLOG("Set MAC Reg C+CR Offset 0x82h = 0x01h");
3202 RTL_W8(0x82, 0x01);
3203 }
3204
3205 pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
3206
3207 if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
3208 pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08);
3209
3210 if (tp->mac_version == RTL_GIGA_MAC_VER_02) {
3211 DLOG("Set MAC Reg C+CR Offset 0x82h = 0x01h");
3212 RTL_W8(0x82, 0x01);
3213 DLOG("Set PHY Reg 0x0bh = 0x00h");
3214 mdio_write(ioaddr, 0x0b, 0x0000);
3215 }
3216
3217 rtl8169_phy_reset(dev, tp);
3218
3219
3220
3221
3222
3223 rtl8169_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL);
3224
3225 if (RTL_R8(PHYstatus) & TBI_Enable)
3226 DLOG("TBI auto-negotiating");
3227 }
3228
3229 #define cpu_to_le32 __cpu_to_le32
3230 #define le32_to_cpu __le32_to_cpu
3231 #define cpu_to_le64 __cpu_to_le64
3232 #define wmb() ;
3233
3234 static inline struct sk_buff *
3235 alloc_skb (u32 size)
3236 {
3237 struct sk_buff *skb;
3238 pow2_alloc (sizeof (struct sk_buff), (u8 **) &skb);
3239 if (!skb) return NULL;
3240 skb->len = size;
3241 pow2_alloc (size, (u8 **) &skb->data);
3242 if (!skb->data) return NULL;
3243 memset (skb->data, 0, size);
3244 return skb;
3245 }
3246
3247 static inline void
3248 free_skb (struct sk_buff *skb)
3249 {
3250 pow2_free ((u8 *)skb->data);
3251 pow2_free ((u8 *)skb);
3252 }
3253
3254 static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc)
3255 {
3256 desc->addr = cpu_to_le64(0x0badbadbadbadbadull);
3257 desc->opts1 &= ~cpu_to_le32(DescOwn | RsvdMask);
3258 }
3259
3260 static void rtl8169_free_rx_skb(struct rtl8169_private *tp,
3261 struct sk_buff **sk_buff, struct RxDesc *desc)
3262 {
3263 free_skb (*sk_buff);
3264 *sk_buff = NULL;
3265 rtl8169_make_unusable_by_asic(desc);
3266 }
3267
3268 static inline void rtl8169_mark_to_asic(struct RxDesc *desc, u32 rx_buf_sz)
3269 {
3270 u32 eor = le32_to_cpu(desc->opts1) & RingEnd;
3271
3272 desc->opts1 = cpu_to_le32(DescOwn | eor | rx_buf_sz);
3273 }
3274
3275 static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping,
3276 u32 rx_buf_sz)
3277 {
3278 desc->addr = cpu_to_le64(mapping);
3279 wmb();
3280 rtl8169_mark_to_asic(desc, rx_buf_sz);
3281 }
3282
3283 static void rtl8169_rx_clear(struct rtl8169_private *tp)
3284 {
3285 unsigned int i;
3286
3287 for (i = 0; i < NUM_RX_DESC; i++) {
3288 if (tp->Rx_skbuff[i]) {
3289 rtl8169_free_rx_skb(tp, tp->Rx_skbuff + i,
3290 tp->RxDescArray + i);
3291 }
3292 }
3293 }
3294
3295 typedef int gfp_t;
3296
3297 static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev,
3298 struct net_device *dev,
3299 struct RxDesc *desc, int rx_buf_sz,
3300 unsigned int align, gfp_t gfp)
3301 {
3302 struct sk_buff *skb;
3303 dma_addr_t mapping;
3304 unsigned int pad;
3305
3306 #define NET_IP_ALIGN 2
3307 pad = align ? align : NET_IP_ALIGN;
3308
3309 skb = alloc_skb (rx_buf_sz + pad);
3310 if (!skb)
3311 goto err_out;
3312
3313 mapping = (uint) get_phys_addr (skb->data);
3314
3315 rtl8169_map_to_asic(desc, mapping, rx_buf_sz);
3316 out:
3317 return skb;
3318
3319 err_out:
3320 rtl8169_make_unusable_by_asic(desc);
3321 goto out;
3322 }
3323
3324 static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev,
3325 u32 start, u32 end, gfp_t gfp)
3326 {
3327 u32 cur;
3328
3329 for (cur = start; end - cur != 0; cur++) {
3330 struct sk_buff *skb;
3331 unsigned int i = cur % NUM_RX_DESC;
3332
3333 if (tp->Rx_skbuff[i])
3334 continue;
3335
3336 skb = rtl8169_alloc_rx_skb(tp->pci_dev, dev,
3337 tp->RxDescArray + i,
3338 tp->rx_buf_sz, tp->align, gfp);
3339 if (!skb)
3340 break;
3341
3342 tp->Rx_skbuff[i] = skb;
3343 }
3344 return cur - start;
3345 }
3346
3347 static inline void rtl8169_mark_as_last_descriptor(struct RxDesc *desc)
3348 {
3349 desc->opts1 |= cpu_to_le32(RingEnd);
3350 }
3351
3352 static void rtl8169_init_ring_indexes(struct rtl8169_private *tp)
3353 {
3354 tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0;
3355 }
3356
3357 static int rtl8169_init_ring(struct net_device *dev)
3358 {
3359 struct rtl8169_private *tp = netdev_priv(dev);
3360
3361 rtl8169_init_ring_indexes(tp);
3362
3363 memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info));
3364
3365 memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *));
3366
3367 if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC, 0) != NUM_RX_DESC)
3368 goto err_out;
3369
3370 rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1);
3371
3372 return 0;
3373
3374 err_out:
3375 rtl8169_rx_clear(tp);
3376 return -1;
3377 }
3378
3379 static void rtl_hw_start(struct net_device *dev)
3380 {
3381 struct rtl8169_private *tp = netdev_priv(dev);
3382 void __iomem *ioaddr = tp->mmio_addr;
3383 unsigned int i;
3384
3385
3386 RTL_W8(ChipCmd, CmdReset);
3387
3388
3389 for (i = 0; i < 100; i++) {
3390 if ((RTL_R8(ChipCmd) & CmdReset) == 0)
3391 break;
3392 udelay(1000);
3393 }
3394
3395 tp->hw_start(dev);
3396 }
3397
3398 struct rtl8169_private *tp;
3399
3400 static sint
3401 r8169_transmit (u8 *buffer, sint len)
3402 {
3403 DLOG ("TX: buffer=0x%p len=%d", buffer, len);
3404 u8 *p = buffer;
3405 DLOG (" %.02X %.02X %.02X %.02X %.02X %.02X",
3406 p[0], p[1], p[2], p[3], p[4], p[5]);
3407 p+=6;
3408 DLOG (" %.02X %.02X %.02X %.02X %.02X %.02X",
3409 p[0], p[1], p[2], p[3], p[4], p[5]);
3410 uint entry = tp->cur_tx % NUM_TX_DESC;
3411 struct TxDesc *txd = tp->TxDescArray + entry;
3412 void __iomem *ioaddr = tp->mmio_addr;
3413 dma_addr_t mapping;
3414 u32 status;
3415 u32 opts1;
3416
3417 if (le32_to_cpu (txd->opts1) & DescOwn)
3418 goto abort;
3419 if (len > MAX_FRAME_SIZE)
3420 goto abort;
3421
3422 opts1 = DescOwn | FirstFrag | LastFrag;
3423 tp->tx_skb[entry].len = len;
3424 struct sk_buff *skb = alloc_skb (len);
3425 if (!skb) goto abort;
3426 memcpy (skb->data, buffer, len);
3427 tp->tx_skb[entry].skb = skb;
3428 mapping = (uint) get_phys_addr (skb->data);
3429 txd->addr = __cpu_to_le64 (mapping);
3430 status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
3431 DLOG (" cur_tx=%d mapping=0x%p status=0x%p", tp->cur_tx, mapping, status);
3432
3433 #ifdef TX_TIMING
3434 SERIALIZE0;
3435 RDTSC (tx_start);
3436 #endif
3437
3438
3439 txd->opts2 = 0;
3440 txd->opts1 = __cpu_to_le32 (status);
3441
3442 tp->cur_tx++;
3443
3444 RTL_W8 (TxPoll, NPQ);
3445
3446 return len;
3447 abort:
3448 return -1;
3449 }
3450
3451 #ifdef TX_TIMING
3452 static u32 timing_stack[1024] ALIGNED (0x1000);
3453 static task_id timing_id;
3454 static void timing_thread (void) {
3455 struct udp_pcb *pcb = udp_new ();
3456 struct pbuf *p = pbuf_alloc (PBUF_TRANSPORT, 4, PBUF_RAM);
3457 struct ip_addr ip;
3458 struct in_addr inaddr;
3459 inet_aton ("192.168.2.123", &inaddr);
3460 ip.addr = inaddr.s_addr;
3461 pbuf_take (p, "TEST", 4);
3462 logger_printf ("r8169: timing_thread: id=0x%x\n", timing_id);
3463 for (;;) {
3464 sched_usleep (1000000);
3465 udp_sendto (pcb, p, &ip, 7890);
3466 }
3467 }
3468 #endif
3469
3470 static void
3471 r8169_poll (void)
3472 {
3473 rx_int (tp);
3474 tx_int (tp);
3475 }
3476
3477 static bool
3478 r8169_get_hwaddr (u8 addr[ETH_ADDR_LEN])
3479 {
3480 int i;
3481 for (i=0; i<ETH_ADDR_LEN; i++)
3482 addr[i] = tp->mac_addr[i];
3483 return TRUE;
3484 }
3485
3486 extern bool
3487 r8169_init (void)
3488 {
3489 int i;
3490 if (mp_ISA_PC) {
3491 DLOG ("Requires PCI support");
3492 goto abort;
3493 }
3494
3495 for (i=0; compatible_ids[i].vendor != 0xFFFF; i++)
3496 if (pci_find_device (compatible_ids[i].vendor, compatible_ids[i].device,
3497 0xFF, 0xFF, 0, &device_index))
3498 break;
3499 else
3500 device_index = ~0;
3501
3502 if (device_index == (uint)(~0)) {
3503 DLOG ("Unable to detect compatible device.");
3504 goto abort;
3505 }
3506
3507 const struct rtl_cfg_info *cfg = &rtl_cfg_infos[compatible_ids[i].cfg];
3508 const unsigned int region = cfg->region;
3509 DLOG ("Found device_index=%d", device_index);
3510
3511 if (!pci_get_device (device_index, &pdev)) {
3512 DLOG ("pci_get_device");
3513 goto abort;
3514 }
3515
3516 u32 phys_addr; void *ioaddr;
3517 pci_decode_bar (pdev.index, region, &phys_addr, NULL, NULL);
3518
3519 uint irq_line, irq_pin;
3520 pci_irq_t irq;
3521 if (!pci_get_interrupt (pdev.index, &irq_line, &irq_pin)) {
3522 DLOG ("Unable to get IRQ");
3523 goto abort;
3524 }
3525
3526 if (pci_irq_find (pdev.bus, pdev.slot, irq_pin, &irq)) {
3527
3528 DLOG ("Found PCI routing entry irq.gsi=0x%x", irq.gsi);
3529 if (!pci_irq_map_handler (&irq, irq_handler, 0x01,
3530 IOAPIC_DESTINATION_LOGICAL,
3531 IOAPIC_DELIVERY_FIXED)) {
3532 DLOG ("Failed to map IRQ");
3533 goto abort;
3534 }
3535 irq_line = irq.gsi;
3536 u8 vector;
3537 IOAPIC_get_GSI_mapping (irq.gsi, &vector, NULL);
3538 DLOG ("Using vector=0x%X", vector);
3539 } else {
3540 DLOG ("Unable to find PCI routing entry");
3541 goto abort;
3542 }
3543
3544 ioaddr = map_virtual_page (phys_addr | 3);
3545
3546 DLOG ("BAR%d phys=0x%p virt=0x%p", region, phys_addr, ioaddr);
3547
3548 RTL_W16(IntrMask, 0x0000);
3549
3550
3551 RTL_W8(ChipCmd, CmdReset);
3552
3553
3554 for (i = 0; i < 100; i++) {
3555 if ((RTL_R8(ChipCmd) & CmdReset) == 0)
3556 break;
3557 udelay (1000);
3558 }
3559
3560 RTL_W16(IntrStatus, 0xffff);
3561
3562
3563 pci_write_word (pci_addr (pdev.bus, pdev.slot, pdev.func, 0x04), 0x0006);
3564
3565
3566 pow2_alloc (sizeof (struct rtl8169_private), (u8 **) &tp);
3567 if (!tp)
3568 goto abort_virt;
3569 DLOG ("tp=0x%p (%d bytes)", tp, sizeof (struct rtl8169_private));
3570
3571
3572 get_mac_version(tp, ioaddr);
3573
3574
3575 if (tp->mac_version == RTL_GIGA_MAC_NONE) {
3576 DLOG ("unknown MAC, using family default");
3577 tp->mac_version = cfg->default_ver;
3578 }
3579
3580 print_mac_version(tp);
3581
3582 for (i = 0; i < ARRAY_SIZE(rtl_chip_info); i++) {
3583 if (tp->mac_version == rtl_chip_info[i].mac_version)
3584 break;
3585 }
3586 if (i == ARRAY_SIZE(rtl_chip_info)) {
3587 DLOG ("driver bug, MAC version not found in rtl_chip_info");
3588 goto abort_tp;
3589 }
3590 tp->chipset = i;
3591
3592 RTL_W8(Cfg9346, Cfg9346_Unlock);
3593 RTL_W8(Config1, RTL_R8(Config1) | PMEnable);
3594 RTL_W8(Config5, RTL_R8(Config5) & PMEStatus);
3595 if ((RTL_R8(Config3) & (LinkUp | MagicPacket)) != 0)
3596 tp->features |= RTL_FEATURE_WOL;
3597 if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0)
3598 tp->features |= RTL_FEATURE_WOL;
3599 RTL_W8(Cfg9346, Cfg9346_Lock);
3600
3601 if ((tp->mac_version <= RTL_GIGA_MAC_VER_06) &&
3602 (RTL_R8(PHYstatus) & TBI_Enable)) {
3603 DLOG ("TBI");
3604 tp->set_speed = rtl8169_set_speed_tbi;
3605 tp->get_settings = rtl8169_gset_tbi;
3606 tp->phy_reset_enable = rtl8169_tbi_reset_enable;
3607 tp->phy_reset_pending = rtl8169_tbi_reset_pending;
3608 tp->link_ok = rtl8169_tbi_link_ok;
3609 tp->do_ioctl = rtl_tbi_ioctl;
3610
3611 tp->phy_1000_ctrl_reg = ADVERTISE_1000FULL;
3612 } else {
3613 DLOG ("XMII");
3614 tp->set_speed = rtl8169_set_speed_xmii;
3615 tp->get_settings = rtl8169_gset_xmii;
3616 tp->phy_reset_enable = rtl8169_xmii_reset_enable;
3617 tp->phy_reset_pending = rtl8169_xmii_reset_pending;
3618 tp->link_ok = rtl8169_xmii_link_ok;
3619 tp->do_ioctl = rtl_xmii_ioctl;
3620 }
3621
3622 spinlock_init (&tp->lock);
3623 tp->mmio_addr = ioaddr;
3624
3625
3626 for (i = 0; i < MAC_ADDR_LEN; i++)
3627 tp->mac_addr[i] = RTL_R8(MAC0 + i);
3628 DLOG ("mac_addr=%.02X:%.02X:%.02X:%.02X:%.02X:%.02X",
3629 tp->mac_addr[0], tp->mac_addr[1], tp->mac_addr[2],
3630 tp->mac_addr[3], tp->mac_addr[4], tp->mac_addr[5]);
3631
3632 tp->intr_mask = 0xffff;
3633 tp->align = cfg->align;
3634 tp->hw_start = cfg->hw_start;
3635 tp->intr_event = cfg->intr_event;
3636 tp->napi_event = cfg->napi_event;
3637
3638
3639 tp->ethdev.recv_func = NULL;
3640 tp->ethdev.send_func = r8169_transmit;
3641 tp->ethdev.get_hwaddr_func = r8169_get_hwaddr;
3642 tp->ethdev.poll_func = r8169_poll;
3643 tp->ethdev.drvdata = tp;
3644
3645 tp->pci_dev = &pdev;
3646 pdev.drvdata = tp;
3647
3648 init_phy(&tp->ethdev, tp);
3649
3650 if (!net_register_device (&tp->ethdev)) {
3651 DLOG ("registration failed");
3652 goto abort_tp;
3653 }
3654
3655 #define ETH_FCS_LEN 4
3656 #define VLAN_ETH_HLEN 18
3657 uint mtu = MAX_FRAME_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN;
3658 uint max_frame = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
3659 tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE;
3660
3661 pow2_alloc (R8169_RX_RING_BYTES, (u8 **) &tp->RxDescArray);
3662 if (!tp->RxDescArray)
3663 goto abort_tp;
3664 tp->RxPhyAddr = (uint) get_phys_addr (tp->RxDescArray);
3665
3666 pow2_alloc (R8169_TX_RING_BYTES, (u8 **) &tp->TxDescArray);
3667 if (!tp->TxDescArray)
3668 goto abort_rxdesc;
3669 tp->TxPhyAddr = (uint) get_phys_addr (tp->TxDescArray);
3670
3671 sint retval = rtl8169_init_ring(&tp->ethdev);
3672 if (retval < 0)
3673 goto abort_txdesc;
3674
3675 rtl_hw_start(&tp->ethdev);
3676
3677
3678
3679 rtl8169_check_link_status(&tp->ethdev, tp, tp->mmio_addr);
3680
3681 r8169_bh_id = create_kernel_thread_args ((u32) r8169_bh_thread,
3682 (u32) &r8169_bh_stack[1023],
3683 FALSE, 0);
3684 set_iovcpu (r8169_bh_id, IOVCPU_CLASS_NET);
3685
3686 #ifdef TX_TIMING
3687 timing_id =
3688 start_kernel_thread ((u32) timing_thread, (u32) &timing_stack[1023]);
3689 #endif
3690
3691 return TRUE;
3692 abort_txdesc:
3693 pow2_free ((u8 *) tp->TxDescArray);
3694 abort_rxdesc:
3695 pow2_free ((u8 *) tp->RxDescArray);
3696 abort_tp:
3697 pow2_free ((u8 *) tp);
3698 abort_virt:
3699 unmap_virtual_page (ioaddr);
3700 abort:
3701 return FALSE;
3702 }
3703
3704 static const struct module_ops mod_ops = {
3705 .init = r8169_init
3706 };
3707
3708 DEF_MODULE (net___r8169, "r8169 network driver", &mod_ops, {"net___ethernet", "pci"});
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720