Subversion Repositories Kolibri OS

Rev

Rev 431 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved.    ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;;  RTL8169.INC                                                    ;;
  7. ;;                                                                 ;;
  8. ;;  Ethernet driver for Menuet OS                                  ;;
  9. ;;                                                                 ;;
  10. ;;  Version 0.1  11 February 2007                                  ;;
  11. ;;                                                                 ;;
  12. ;;  Driver for chips of RealTek 8169 family                        ;;
  13. ;;  References:                                                    ;;
  14. ;;    r8169.c - linux driver (etherboot project)                   ;;
  15. ;;    ethernet driver template by Mike Hibbett                     ;;
  16. ;;                                                                 ;;
  17. ;;  The copyright statement is                                     ;;
  18. ;;                                                                 ;;
  19. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  20. ;;             Version 2, June 1991                                ;;
  21. ;;                                                                 ;;
  22. ;;  Copyright 2007 mike.dld,                                       ;;
  23. ;;   mike.dld@gmail.com                                            ;;
  24. ;;                                                                 ;;
  25. ;;  See file COPYING for details                                   ;;
  26. ;;                                                                 ;;
  27. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  28.  
  29. $Revision: 593 $
  30.  
  31.  
  32.         ETH_ALEN               equ 6
  33.         ETH_HLEN               equ (2 * ETH_ALEN + 2)
  34.         ETH_ZLEN               equ 60 ; 60 + 4bytes auto payload for
  35.                                       ; mininmum 64bytes frame length
  36.  
  37.         RTL8169_REG_MAC0               equ 0x0 ; Ethernet hardware address
  38.         RTL8169_REG_MAR0               equ 0x8 ; Multicast filter
  39.         RTL8169_REG_TxDescStartAddr    equ 0x20
  40.         RTL8169_REG_TxHDescStartAddr   equ 0x28
  41.         RTL8169_REG_FLASH              equ 0x30
  42.         RTL8169_REG_ERSR               equ 0x36
  43.         RTL8169_REG_ChipCmd            equ 0x37
  44.         RTL8169_REG_TxPoll             equ 0x38
  45.         RTL8169_REG_IntrMask           equ 0x3C
  46.         RTL8169_REG_IntrStatus         equ 0x3E
  47.         RTL8169_REG_TxConfig           equ 0x40
  48.         RTL8169_REG_RxConfig           equ 0x44
  49.         RTL8169_REG_RxMissed           equ 0x4C
  50.         RTL8169_REG_Cfg9346            equ 0x50
  51.         RTL8169_REG_Config0            equ 0x51
  52.         RTL8169_REG_Config1            equ 0x52
  53.         RTL8169_REG_Config2            equ 0x53
  54.         RTL8169_REG_Config3            equ 0x54
  55.         RTL8169_REG_Config4            equ 0x55
  56.         RTL8169_REG_Config5            equ 0x56
  57.         RTL8169_REG_MultiIntr          equ 0x5C
  58.         RTL8169_REG_PHYAR              equ 0x60
  59.         RTL8169_REG_TBICSR             equ 0x64
  60.         RTL8169_REG_TBI_ANAR           equ 0x68
  61.         RTL8169_REG_TBI_LPAR           equ 0x6A
  62.         RTL8169_REG_PHYstatus          equ 0x6C
  63.         RTL8169_REG_RxMaxSize          equ 0xDA
  64.         RTL8169_REG_CPlusCmd           equ 0xE0
  65.         RTL8169_REG_RxDescStartAddr    equ 0xE4
  66.         RTL8169_REG_ETThReg            equ 0xEC
  67.         RTL8169_REG_FuncEvent          equ 0xF0
  68.         RTL8169_REG_FuncEventMask      equ 0xF4
  69.         RTL8169_REG_FuncPresetState    equ 0xF8
  70.         RTL8169_REG_FuncForceEvent     equ 0xFC
  71.  
  72.         ; InterruptStatusBits
  73.         RTL8169_ISB_SYSErr             equ 0x8000
  74.         RTL8169_ISB_PCSTimeout         equ 0x4000
  75.         RTL8169_ISB_SWInt              equ 0x0100
  76.         RTL8169_ISB_TxDescUnavail      equ 0x80
  77.         RTL8169_ISB_RxFIFOOver         equ 0x40
  78.         RTL8169_ISB_LinkChg            equ 0x20
  79.         RTL8169_ISB_RxOverflow         equ 0x10
  80.         RTL8169_ISB_TxErr              equ 0x08
  81.         RTL8169_ISB_TxOK               equ 0x04
  82.         RTL8169_ISB_RxErr              equ 0x02
  83.         RTL8169_ISB_RxOK               equ 0x01
  84.  
  85.         ; RxStatusDesc
  86.         RTL8169_SD_RxRES               equ 0x00200000
  87.         RTL8169_SD_RxCRC               equ 0x00080000
  88.         RTL8169_SD_RxRUNT              equ 0x00100000
  89.         RTL8169_SD_RxRWT               equ 0x00400000
  90.  
  91.         ; ChipCmdBits
  92.         RTL8169_CMD_Reset              equ 0x10
  93.         RTL8169_CMD_RxEnb              equ 0x08
  94.         RTL8169_CMD_TxEnb              equ 0x04
  95.         RTL8169_CMD_RxBufEmpty         equ 0x01
  96.  
  97.         ; Cfg9346Bits
  98.         RTL8169_CFG_9346_Lock          equ 0x00
  99.         RTL8169_CFG_9346_Unlock        equ 0xC0
  100.  
  101.         ; rx_mode_bits
  102.         RTL8169_RXM_AcceptErr          equ 0x20
  103.         RTL8169_RXM_AcceptRunt         equ 0x10
  104.         RTL8169_RXM_AcceptBroadcast    equ 0x08
  105.         RTL8169_RXM_AcceptMulticast    equ 0x04
  106.         RTL8169_RXM_AcceptMyPhys       equ 0x02
  107.         RTL8169_RXM_AcceptAllPhys      equ 0x01
  108.  
  109.         ; RxConfigBits
  110.         RTL8169_RXC_FIFOShift          equ 13
  111.         RTL8169_RXC_DMAShift           equ 8
  112.  
  113.         ; TxConfigBits
  114.         RTL8169_TXC_InterFrameGapShift equ 24
  115.         RTL8169_TXC_DMAShift           equ 8    ; DMA burst value (0-7) is shift this many bits
  116.  
  117.         ; rtl8169_PHYstatus
  118.         RTL8169_PHYS_TBI_Enable        equ 0x80
  119.         RTL8169_PHYS_TxFlowCtrl        equ 0x40
  120.         RTL8169_PHYS_RxFlowCtrl        equ 0x20
  121.         RTL8169_PHYS_1000bpsF          equ 0x10
  122.         RTL8169_PHYS_100bps            equ 0x08
  123.         RTL8169_PHYS_10bps             equ 0x04
  124.         RTL8169_PHYS_LinkStatus        equ 0x02
  125.         RTL8169_PHYS_FullDup           equ 0x01
  126.  
  127.         ; GIGABIT_PHY_registers
  128.         RTL8169_PHY_CTRL_REG           equ 0
  129.         RTL8169_PHY_STAT_REG           equ 1
  130.         RTL8169_PHY_AUTO_NEGO_REG      equ 4
  131.         RTL8169_PHY_1000_CTRL_REG      equ 9
  132.  
  133.         ; GIGABIT_PHY_REG_BIT
  134.         RTL8169_PHY_Restart_Auto_Nego  equ 0x0200
  135.         RTL8169_PHY_Enable_Auto_Nego   equ 0x1000
  136.  
  137.         ; PHY_STAT_REG = 1;
  138.         RTL8169_PHY_Auto_Neco_Comp     equ 0x0020
  139.  
  140.         ; PHY_AUTO_NEGO_REG = 4;
  141.         RTL8169_PHY_Cap_10_Half        equ 0x0020
  142.         RTL8169_PHY_Cap_10_Full        equ 0x0040
  143.         RTL8169_PHY_Cap_100_Half       equ 0x0080
  144.         RTL8169_PHY_Cap_100_Full       equ 0x0100
  145.  
  146.         ; PHY_1000_CTRL_REG = 9;
  147.         RTL8169_PHY_Cap_1000_Full      equ 0x0200
  148.         RTL8169_PHY_Cap_1000_Half      equ 0x0100
  149.  
  150.         RTL8169_PHY_Cap_PAUSE          equ 0x0400
  151.         RTL8169_PHY_Cap_ASYM_PAUSE     equ 0x0800
  152.  
  153.         RTL8169_PHY_Cap_Null           equ 0x0
  154.  
  155.         ; _MediaType
  156.         RTL8169_MT_10_Half             equ 0x01
  157.         RTL8169_MT_10_Full             equ 0x02
  158.         RTL8169_MT_100_Half            equ 0x04
  159.         RTL8169_MT_100_Full            equ 0x08
  160.         RTL8169_MT_1000_Full           equ 0x10
  161.  
  162.         ; _TBICSRBit
  163.         RTL8169_TBI_LinkOK             equ 0x02000000
  164.  
  165.         ; _DescStatusBit
  166.         RTL8169_DSB_OWNbit             equ 0x80000000
  167.         RTL8169_DSB_EORbit             equ 0x40000000
  168.         RTL8169_DSB_FSbit              equ 0x20000000
  169.         RTL8169_DSB_LSbit              equ 0x10000000
  170.  
  171. ; MAC address length
  172. MAC_ADDR_LEN        equ 6
  173.  
  174. ; max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4)
  175. MAX_ETH_FRAME_SIZE  equ 1536
  176.  
  177. TX_FIFO_THRESH      equ 256     ; In bytes
  178.  
  179. RX_FIFO_THRESH      equ 7       ; 7 means NO threshold, Rx buffer level before first PCI xfer
  180. RX_DMA_BURST        equ 7       ; Maximum PCI burst, '6' is 1024
  181. TX_DMA_BURST        equ 7       ; Maximum PCI burst, '6' is 1024
  182. ETTh                equ 0x3F    ; 0x3F means NO threshold
  183.  
  184. EarlyTxThld         equ 0x3F    ; 0x3F means NO early transmit
  185. RxPacketMaxSize     equ 0x0800  ; Maximum size supported is 16K-1
  186. InterFrameGap       equ 0x03    ; 3 means InterFrameGap = the shortest one
  187.  
  188. NUM_TX_DESC         equ 1       ; Number of Tx descriptor registers
  189. NUM_RX_DESC         equ 4       ; Number of Rx descriptor registers
  190. RX_BUF_SIZE         equ 1536    ; Rx Buffer size
  191.  
  192. HZ                  equ 1000
  193.  
  194. RTL_MIN_IO_SIZE     equ 0x80
  195. TX_TIMEOUT          equ (6*HZ)
  196.  
  197. RTL8169_TIMER_EXPIRE_TIME equ 100
  198.  
  199. ETH_HDR_LEN         equ 14
  200. DEFAULT_MTU         equ 1500
  201. DEFAULT_RX_BUF_LEN  equ 1536
  202.  
  203.  
  204. ;#ifdef RTL8169_JUMBO_FRAME_SUPPORT
  205. ;#define MAX_JUMBO_FRAME_MTU    ( 10000 )
  206. ;#define MAX_RX_SKBDATA_SIZE    ( MAX_JUMBO_FRAME_MTU + ETH_HDR_LEN )
  207. ;#else
  208. MAX_RX_SKBDATA_SIZE equ 1600
  209. ;#endif                         //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT
  210.  
  211. ;#ifdef RTL8169_USE_IO
  212. ;!!!#define RTL_W8(reg, val8)   outb ((val8), ioaddr + (reg))
  213. macro RTL_W8 reg,val8 {
  214.   if ~reg eq dx
  215.     mov dx,word[rtl8169_tpc.mmio_addr]
  216.     add dx,reg
  217.   end if
  218.   if ~val8 eq al
  219.     mov al,val8
  220.   end if
  221.   out dx,al
  222. }
  223. ;!!!#define RTL_W16(reg, val16) outw ((val16), ioaddr + (reg))
  224. macro RTL_W16 reg,val16 {
  225.   if ~reg eq dx
  226.     mov dx,word[rtl8169_tpc.mmio_addr]
  227.     add dx,reg
  228.   end if
  229.   if ~val16 eq ax
  230.     mov ax,val16
  231.   end if
  232.   out dx,ax
  233. }
  234. ;!!!#define RTL_W32(reg, val32) outl ((val32), ioaddr + (reg))
  235. macro RTL_W32 reg,val32 {
  236.   if ~reg eq dx
  237.     mov dx,word[rtl8169_tpc.mmio_addr]
  238.     add dx,reg
  239.   end if
  240.   if ~val32 eq eax
  241.     mov eax,val32
  242.   end if
  243.   out dx,eax
  244. }
  245. ;!!!#define RTL_R8(reg)         inb (ioaddr + (reg))
  246. macro RTL_R8 reg {
  247.   if ~reg eq dx
  248.     mov dx,word[rtl8169_tpc.mmio_addr]
  249.     add dx,reg
  250.   end if
  251.   in  al,dx
  252. }
  253. ;!!!#define RTL_R16(reg)        inw (ioaddr + (reg))
  254. macro RTL_R16 reg {
  255.   if ~reg eq dx
  256.     mov dx,word[rtl8169_tpc.mmio_addr]
  257.     add dx,reg
  258.   end if
  259.   in  ax,dx
  260. }
  261. ;!!!#define RTL_R32(reg)        ((unsigned long) inl (ioaddr + (reg)))
  262. macro RTL_R32 reg {
  263.   if ~reg eq dx
  264.     mov dx,word[rtl8169_tpc.mmio_addr]
  265.     add dx,reg
  266.   end if
  267.   in  eax,dx
  268. }
  269. ;#else
  270. ; write/read MMIO register
  271. ;#define RTL_W8(reg, val8)      writeb ((val8), ioaddr + (reg))
  272. ;#define RTL_W16(reg, val16)    writew ((val16), ioaddr + (reg))
  273. ;#define RTL_W32(reg, val32)    writel ((val32), ioaddr + (reg))
  274. ;#define RTL_R8(reg)            readb (ioaddr + (reg))
  275. ;#define RTL_R16(reg)           readw (ioaddr + (reg))
  276. ;#define RTL_R32(reg)           ((unsigned long) readl (ioaddr + (reg)))
  277. ;#endif
  278.  
  279. MCFG_METHOD_01       equ 0x01
  280. MCFG_METHOD_02       equ 0x02
  281. MCFG_METHOD_03       equ 0x03
  282. MCFG_METHOD_04       equ 0x04
  283. MCFG_METHOD_05       equ 0x05
  284. MCFG_METHOD_11       equ 0x0b
  285. MCFG_METHOD_12       equ 0x0c
  286. MCFG_METHOD_13       equ 0x0d
  287. MCFG_METHOD_14       equ 0x0e
  288. MCFG_METHOD_15       equ 0x0f
  289.  
  290. PCFG_METHOD_1       equ 0x01    ; PHY Reg 0x03 bit0-3 == 0x0000
  291. PCFG_METHOD_2       equ 0x02    ; PHY Reg 0x03 bit0-3 == 0x0001
  292. PCFG_METHOD_3       equ 0x03    ; PHY Reg 0x03 bit0-3 == 0x0002
  293.  
  294. PCI_COMMAND_IO          equ 0x1   ; Enable response in I/O space
  295. PCI_COMMAND_MEM         equ 0x2   ; Enable response in mem space
  296. PCI_COMMAND_MASTER      equ 0x4   ; Enable bus mastering
  297. PCI_LATENCY_TIMER       equ 0x0d  ; 8 bits
  298. PCI_COMMAND_SPECIAL     equ 0x8   ; Enable response to special cycles
  299. PCI_COMMAND_INVALIDATE  equ 0x10  ; Use memory write and invalidate
  300. PCI_COMMAND_VGA_PALETTE equ 0x20  ; Enable palette snooping
  301. PCI_COMMAND_PARITY      equ 0x40  ; Enable parity checking
  302. PCI_COMMAND_WAIT        equ 0x80  ; Enable address/data stepping
  303. PCI_COMMAND_SERR        equ 0x100 ; Enable SERR
  304. PCI_COMMAND_FAST_BACK   equ 0x200 ; Enable back-to-back writes
  305.  
  306. struc rtl8169_TxDesc {
  307.   .status    dd ?
  308.   .vlan_tag  dd ?
  309.   .buf_addr  dd ?
  310.   .buf_Haddr dd ?
  311. }
  312. virtual at 0
  313.   rtl8169_TxDesc rtl8169_TxDesc
  314.   sizeof.rtl8169_TxDesc = $ - rtl8169_TxDesc
  315. end virtual
  316.  
  317. struc rtl8169_RxDesc {
  318.   .status    dd ?
  319.   .vlan_tag  dd ?
  320.   .buf_addr  dd ?
  321.   .buf_Haddr dd ?
  322. }
  323. virtual at 0
  324.   rtl8169_RxDesc rtl8169_RxDesc
  325.   sizeof.rtl8169_RxDesc = $ - rtl8169_RxDesc
  326. end virtual
  327.  
  328. virtual at eth_data_start
  329.  
  330. ; Define the TX Descriptor
  331. align 256
  332. rtl8169_tx_ring rb NUM_TX_DESC * sizeof.rtl8169_TxDesc
  333.  
  334. ; Create a static buffer of size RX_BUF_SZ for each
  335. ; TX Descriptor.  All descriptors point to a
  336. ; part of this buffer
  337. align 256
  338. rtl8169_txb rb NUM_TX_DESC * RX_BUF_SIZE
  339.  
  340. ; Define the RX Descriptor
  341. align 256
  342. rtl8169_rx_ring rb NUM_RX_DESC * sizeof.rtl8169_TxDesc
  343.  
  344. ; Create a static buffer of size RX_BUF_SZ for each
  345. ; RX Descriptor   All descriptors point to a
  346. ; part of this buffer
  347. align 256
  348. rtl8169_rxb rb NUM_RX_DESC * RX_BUF_SIZE
  349.  
  350. rtl8169_tpc:
  351.   .mmio_addr    dd ? ; memory map physical address
  352.   .chipset      dd ?
  353.   .pcfg         dd ?
  354.   .mcfg         dd ?
  355.   .cur_rx       dd ? ; Index into the Rx descriptor buffer of next Rx pkt
  356.   .cur_tx       dd ? ; Index into the Tx descriptor buffer of next Rx pkt
  357.   .TxDescArrays dd ? ; Index of Tx Descriptor buffer
  358.   .RxDescArrays dd ? ; Index of Rx Descriptor buffer
  359.   .TxDescArray  dd ? ; Index of 256-alignment Tx Descriptor buffer
  360.   .RxDescArray  dd ? ; Index of 256-alignment Rx Descriptor buffer
  361.   .RxBufferRing rd NUM_RX_DESC ; Index of Rx Buffer array
  362.   .Tx_skbuff    rd NUM_TX_DESC
  363.  
  364. end virtual
  365.  
  366. rtl8169_intr_mask = RTL8169_ISB_LinkChg or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxFIFOOver or RTL8169_ISB_TxErr or RTL8169_ISB_TxOK or RTL8169_ISB_RxErr or RTL8169_ISB_RxOK
  367. rtl8169_rx_config = (RX_FIFO_THRESH shl RTL8169_RXC_FIFOShift) or (RX_DMA_BURST shl RTL8169_RXC_DMAShift) or 0x0000000E
  368.  
  369. iglobal
  370.  
  371. ;static struct {
  372. ;       const char *name;
  373. ;       u8 mcfg;                /* depend on RTL8169 docs */
  374. ;       u32 RxConfigMask;       /* should clear the bits supported by this chip */
  375. ;}
  376. rtl_chip_info dd \
  377.   MCFG_METHOD_01, 0xff7e1880, \ ; RTL8169
  378.   MCFG_METHOD_02, 0xff7e1880, \ ; RTL8169s/8110s
  379.   MCFG_METHOD_03, 0xff7e1880, \ ; RTL8169s/8110s
  380.   MCFG_METHOD_04, 0xff7e1880, \ ; RTL8169sb/8110sb
  381.   MCFG_METHOD_05, 0xff7e1880, \ ; RTL8169sc/8110sc
  382.   MCFG_METHOD_11, 0xff7e1880, \ ; RTL8168b/8111b   // PCI-E
  383.   MCFG_METHOD_12, 0xff7e1880, \ ; RTL8168b/8111b   // PCI-E
  384.   MCFG_METHOD_13, 0xff7e1880, \ ; RTL8101e         // PCI-E 8139
  385.   MCFG_METHOD_14, 0xff7e1880, \ ; RTL8100e         // PCI-E 8139
  386.   MCFG_METHOD_15, 0xff7e1880    ; RTL8100e         // PCI-E 8139
  387.  
  388. mac_info dd \
  389.   0x38800000, MCFG_METHOD_15, \
  390.   0x38000000, MCFG_METHOD_12, \
  391.   0x34000000, MCFG_METHOD_13, \
  392.   0x30800000, MCFG_METHOD_14, \
  393.   0x30000000, MCFG_METHOD_11, \
  394.   0x18000000, MCFG_METHOD_05, \
  395.   0x10000000, MCFG_METHOD_04, \
  396.   0x04000000, MCFG_METHOD_03, \
  397.   0x00800000, MCFG_METHOD_02, \
  398.   0x00000000, MCFG_METHOD_01    ; catch-all
  399.  
  400. endg
  401.  
  402. PCI_COMMAND_IO          equ 0x1    ; Enable response in I/O space
  403. PCI_COMMAND_MEM         equ 0x2    ; Enable response in mem space
  404. PCI_COMMAND_MASTER      equ 0x4    ; Enable bus mastering
  405. PCI_LATENCY_TIMER       equ 0x0d   ; 8 bits
  406. PCI_COMMAND_SPECIAL     equ 0x8    ; Enable response to special cycles
  407. PCI_COMMAND_INVALIDATE  equ 0x10   ; Use memory write and invalidate
  408. PCI_COMMAND_VGA_PALETTE equ 0x20   ; Enable palette snooping
  409. PCI_COMMAND_PARITY      equ 0x40   ; Enable parity checking
  410. PCI_COMMAND_WAIT        equ 0x80   ; Enable address/data stepping
  411. PCI_COMMAND_SERR        equ 0x100  ; Enable SERR
  412. PCI_COMMAND_FAST_BACK   equ 0x200  ; Enable back-to-back writes
  413.  
  414. PCI_VENDOR_ID           equ 0x00   ; 16 bits
  415. PCI_DEVICE_ID           equ 0x02   ; 16 bits
  416. PCI_COMMAND             equ 0x04   ; 16 bits
  417.  
  418. PCI_BASE_ADDRESS_0      equ 0x10   ; 32 bits
  419. PCI_BASE_ADDRESS_1      equ 0x14   ; 32 bits
  420. PCI_BASE_ADDRESS_2      equ 0x18   ; 32 bits
  421. PCI_BASE_ADDRESS_3      equ 0x1c   ; 32 bits
  422. PCI_BASE_ADDRESS_4      equ 0x20   ; 32 bits
  423. PCI_BASE_ADDRESS_5      equ 0x24   ; 32 bits
  424.  
  425. PCI_BASE_ADDRESS_MEM_TYPE_MASK equ 0x06
  426. PCI_BASE_ADDRESS_MEM_TYPE_32   equ 0x00 ; 32 bit address
  427. PCI_BASE_ADDRESS_MEM_TYPE_1M   equ 0x02 ; Below 1M [obsolete]
  428. PCI_BASE_ADDRESS_MEM_TYPE_64   equ 0x04 ; 64 bit address
  429.  
  430. PCI_BASE_ADDRESS_IO_MASK  equ (not 0x03)
  431. PCI_BASE_ADDRESS_MEM_MASK equ (not 0x0f)
  432. PCI_BASE_ADDRESS_SPACE_IO equ 0x01
  433. PCI_ROM_ADDRESS           equ 0x30      ; 32 bits
  434.  
  435. proc CONFIG_CMD,where:byte
  436.         movzx   eax,byte[pci_bus]
  437.         shl     eax,8
  438.         mov     al,[pci_dev]
  439.         shl     eax,8
  440.         mov     al,[where]
  441.         and     al,not 3
  442.         or      eax,0x80000000
  443.         ret
  444. endp
  445.  
  446. proc pci_read_config_byte,where:dword
  447.         push    edx
  448.         stdcall CONFIG_CMD,[where]
  449.         mov     dx,0xCF8
  450.         out     dx,eax
  451.         mov     edx,[where]
  452.         and     edx,3
  453.         add     edx,0xCFC
  454.         in      al,dx
  455.         pop     edx
  456.         ret
  457. endp
  458.  
  459. proc pci_read_config_word,where:dword
  460.         push    edx
  461.         stdcall CONFIG_CMD,[where]
  462.         mov     dx,0xCF8
  463.         out     dx,eax
  464.         mov     edx,[where]
  465.         and     edx,2
  466.         add     edx,0xCFC
  467.         in      ax,dx
  468.         pop     edx
  469.         ret
  470. endp
  471.  
  472. proc pci_read_config_dword,where:dword
  473.         push    edx
  474.         stdcall CONFIG_CMD,[where]
  475.         mov     edx,0xCF8
  476.         out     dx,eax
  477.         mov     edx,0xCFC
  478.         in      eax,dx
  479.         pop     edx
  480.         ret
  481. endp
  482.  
  483. proc pci_write_config_byte,where:dword,value:byte
  484.         push    edx
  485.         stdcall CONFIG_CMD,[where]
  486.         mov     dx,0xCF8
  487.         out     dx,eax
  488.         mov     edx,[where]
  489.         and     edx,3
  490.         add     edx,0xCFC
  491.         mov     al,[value]
  492.         out     dx,al
  493.         pop     edx
  494.         ret
  495. endp
  496.  
  497. proc pci_write_config_word,where:dword,value:word
  498.         push    edx
  499.         stdcall CONFIG_CMD,[where]
  500.         mov     dx,0xCF8
  501.         out     dx,eax
  502.         mov     edx,[where]
  503.         and     edx,2
  504.         add     edx,0xCFC
  505.         mov     ax,[value]
  506.         out     dx,ax
  507.         pop     edx
  508.         ret
  509. endp
  510.  
  511. proc pci_write_config_dword,where:dword,value:dword
  512.         push    edx
  513.         stdcall CONFIG_CMD,[where]
  514.         mov     edx,0xCF8
  515.         out     dx,eax
  516.         mov     edx,0xCFC
  517.         mov     eax,[value]
  518.         out     dx,eax
  519.         pop     edx
  520.         ret
  521. endp
  522.  
  523. ; Set device to be a busmaster in case BIOS neglected to do so.
  524. ; Also adjust PCI latency timer to a reasonable value, 32.
  525. proc adjust_pci_device
  526.  
  527.         DEBUGF  1,"K : adjust_pci_device\n"
  528.  
  529.         stdcall pci_read_config_word,PCI_COMMAND
  530.         mov     bx,ax
  531.         or      bx,PCI_COMMAND_MASTER or PCI_COMMAND_IO
  532.         cmp     ax,bx
  533.         je      @f
  534.         DEBUGF  1,"K : adjust_pci_device: The PCI BIOS has not enabled this device!\nK :   Updating PCI command %x->%x. pci_bus %x pci_device_fn %x\n",ax,bx,[pci_bus]:2,[pci_dev]:2
  535.         stdcall pci_write_config_word,PCI_COMMAND,ebx
  536.     @@:
  537.         stdcall pci_read_config_byte,PCI_LATENCY_TIMER
  538.         cmp     al,32
  539.         jae     @f
  540.         DEBUGF  1,"K : adjust_pci_device: PCI latency timer (CFLT) is unreasonably low at %d.\nK :   Setting to 32 clocks.\n",al
  541.         stdcall pci_write_config_byte,PCI_LATENCY_TIMER,32
  542.     @@:
  543.         ret
  544. endp
  545.  
  546. ; Find the start of a pci resource
  547. proc pci_bar_start,index:dword
  548.         stdcall pci_read_config_dword,[index]
  549.         test    eax,PCI_BASE_ADDRESS_SPACE_IO
  550.         jz      @f
  551.         and     eax,PCI_BASE_ADDRESS_IO_MASK
  552.         jmp     .exit
  553.     @@: push    eax
  554.         and     eax,PCI_BASE_ADDRESS_MEM_TYPE_MASK
  555.         cmp     eax,PCI_BASE_ADDRESS_MEM_TYPE_64
  556.         jne     .not64
  557.         mov     eax,[index]
  558.         add     eax,4
  559.         stdcall pci_read_config_dword,eax
  560.         or      eax,eax
  561.         jz      .not64
  562.         DEBUGF  1,"K : pci_bar_start: Unhandled 64bit BAR\n"
  563.         add     esp,4
  564.         or      eax,-1
  565.         ret
  566.   .not64:
  567.         pop     eax
  568.         and     eax,PCI_BASE_ADDRESS_MEM_MASK
  569.   .exit:
  570.         ret
  571. endp
  572.  
  573. proc rtl8169_init_board
  574.  
  575.         DEBUGF  1,"K : rtl8169_init_board\n"
  576.  
  577.         call    adjust_pci_device
  578.  
  579.         stdcall pci_bar_start,PCI_BASE_ADDRESS_0
  580.         mov     [rtl8169_tpc.mmio_addr],eax
  581.         ; Soft reset the chip
  582.         RTL_W8  RTL8169_REG_ChipCmd,RTL8169_CMD_Reset
  583.  
  584.         ; Check that the chip has finished the reset
  585.         mov     ecx,1000
  586.     @@: RTL_R8  RTL8169_REG_ChipCmd
  587.         test    al,RTL8169_CMD_Reset
  588.         jz      @f
  589.         stdcall udelay,10
  590.         loop    @b
  591.     @@:
  592.         ; identify config method
  593.         RTL_R32 RTL8169_REG_TxConfig
  594.         and     eax,0x7c800000
  595.         DEBUGF  1,"K : rtl8169_init_board: TxConfig & 0x7c800000 = 0x%x\n",eax
  596.         mov     esi,mac_info-8
  597.     @@: add     esi,8
  598.         mov     ecx,eax
  599.         and     ecx,[esi]
  600.         cmp     ecx,[esi]
  601.         jne     @b
  602.         mov     eax,[esi+4]
  603.         mov     [rtl8169_tpc.mcfg],eax
  604.  
  605.         mov     [rtl8169_tpc.pcfg],PCFG_METHOD_3
  606.         stdcall RTL8169_READ_GMII_REG,3
  607.         and     al,0x0f
  608.         or      al,al
  609.         jnz     @f
  610.         mov     [rtl8169_tpc.pcfg],PCFG_METHOD_1
  611.         jmp     .pconf
  612.     @@: dec     al
  613.         jnz     .pconf
  614.         mov     [rtl8169_tpc.pcfg],PCFG_METHOD_2
  615.   .pconf:
  616.  
  617.         ; identify chip attached to board
  618.         mov     ecx,10
  619.         mov     eax,[rtl8169_tpc.mcfg]
  620.     @@: dec     ecx
  621.         js      @f
  622.         cmp     eax,[rtl_chip_info+ecx*8]
  623.         jne     @b
  624.         mov     [rtl8169_tpc.chipset],ecx
  625.         jmp     .match
  626.     @@:
  627.         ; if unknown chip, assume array element #0, original RTL-8169 in this case
  628.         DEBUGF  1,"K : rtl8169_init_board: PCI device: unknown chip version, assuming RTL-8169\n"
  629.         RTL_R32 RTL8169_REG_TxConfig
  630.         DEBUGF  1,"K : rtl8169_init_board: PCI device: TxConfig = 0x%x\n",eax
  631.  
  632.         mov     [rtl8169_tpc.chipset],0
  633.  
  634.         xor     eax,eax
  635.         inc     eax
  636.         ret
  637.  
  638.   .match:
  639.         xor     eax,eax
  640.         ret
  641. endp
  642.  
  643. proc rtl8169_hw_PHY_config
  644.  
  645.         DEBUGF  1,"K : rtl8169_hw_PHY_config: priv.mcfg=%d, priv.pcfg=%d\n",[rtl8169_tpc.mcfg],[rtl8169_tpc.pcfg]
  646.  
  647. ;       DBG_PRINT("priv->mcfg=%d, priv->pcfg=%d\n", tpc->mcfg, tpc->pcfg);
  648.  
  649.         cmp     [rtl8169_tpc.mcfg],MCFG_METHOD_04
  650.         jne     .not_4
  651. ;       stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001
  652. ;       stdcall RTL8169_WRITE_GMII_REG,0x1b,0x841e
  653. ;       stdcall RTL8169_WRITE_GMII_REG,0x0e,0x7bfb
  654. ;       stdcall RTL8169_WRITE_GMII_REG,0x09,0x273a
  655.         stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0002
  656.         stdcall RTL8169_WRITE_GMII_REG,0x01,0x90D0
  657.         stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0000
  658.         jmp     .exit
  659.   .not_4:
  660.         cmp     [rtl8169_tpc.mcfg],MCFG_METHOD_02
  661.         je      @f
  662.         cmp     [rtl8169_tpc.mcfg],MCFG_METHOD_03
  663.         jne     .not_2_or_3
  664.     @@: stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001
  665.         stdcall RTL8169_WRITE_GMII_REG,0x15,0x1000
  666.         stdcall RTL8169_WRITE_GMII_REG,0x18,0x65C7
  667.         stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000
  668.         stdcall RTL8169_WRITE_GMII_REG,0x03,0x00A1
  669.         stdcall RTL8169_WRITE_GMII_REG,0x02,0x0008
  670.         stdcall RTL8169_WRITE_GMII_REG,0x01,0x1020
  671.         stdcall RTL8169_WRITE_GMII_REG,0x00,0x1000
  672.         stdcall RTL8169_WRITE_GMII_REG,0x04,0x0800
  673.         stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000
  674.         stdcall RTL8169_WRITE_GMII_REG,0x04,0x7000
  675.         stdcall RTL8169_WRITE_GMII_REG,0x03,0xFF41
  676.         stdcall RTL8169_WRITE_GMII_REG,0x02,0xDE60
  677.         stdcall RTL8169_WRITE_GMII_REG,0x01,0x0140
  678.         stdcall RTL8169_WRITE_GMII_REG,0x00,0x0077
  679.         stdcall RTL8169_WRITE_GMII_REG,0x04,0x7800
  680.         stdcall RTL8169_WRITE_GMII_REG,0x04,0x7000
  681.         stdcall RTL8169_WRITE_GMII_REG,0x04,0xA000
  682.         stdcall RTL8169_WRITE_GMII_REG,0x03,0xDF01
  683.         stdcall RTL8169_WRITE_GMII_REG,0x02,0xDF20
  684.         stdcall RTL8169_WRITE_GMII_REG,0x01,0xFF95
  685.         stdcall RTL8169_WRITE_GMII_REG,0x00,0xFA00
  686.         stdcall RTL8169_WRITE_GMII_REG,0x04,0xA800
  687.         stdcall RTL8169_WRITE_GMII_REG,0x04,0xA000
  688.         stdcall RTL8169_WRITE_GMII_REG,0x04,0xB000
  689.         stdcall RTL8169_WRITE_GMII_REG,0x03,0xFF41
  690.         stdcall RTL8169_WRITE_GMII_REG,0x02,0xDE20
  691.         stdcall RTL8169_WRITE_GMII_REG,0x01,0x0140
  692.         stdcall RTL8169_WRITE_GMII_REG,0x00,0x00BB
  693.         stdcall RTL8169_WRITE_GMII_REG,0x04,0xB800
  694.         stdcall RTL8169_WRITE_GMII_REG,0x04,0xB000
  695.         stdcall RTL8169_WRITE_GMII_REG,0x04,0xF000
  696.         stdcall RTL8169_WRITE_GMII_REG,0x03,0xDF01
  697.         stdcall RTL8169_WRITE_GMII_REG,0x02,0xDF20
  698.         stdcall RTL8169_WRITE_GMII_REG,0x01,0xFF95
  699.         stdcall RTL8169_WRITE_GMII_REG,0x00,0xBF00
  700.         stdcall RTL8169_WRITE_GMII_REG,0x04,0xF800
  701.         stdcall RTL8169_WRITE_GMII_REG,0x04,0xF000
  702.         stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000
  703.         stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0000
  704.         stdcall RTL8169_WRITE_GMII_REG,0x0B,0x0000
  705.         jmp     .exit
  706.   .not_2_or_3:
  707. ;       DBG_PRINT("tpc->mcfg=%d. Discard hw PHY config.\n", tpc->mcfg);
  708.         DEBUGF  1,"K :   tpc.mcfg=%d, discard hw PHY config\n",[rtl8169_tpc.mcfg]
  709.   .exit:
  710.         ret
  711. endp
  712.  
  713. ;proc pci_write_config_byte
  714. ;       ret
  715. ;endp
  716.  
  717. proc RTL8169_WRITE_GMII_REG,RegAddr:byte,value:dword
  718.  
  719.         DEBUGF  1,"K : RTL8169_WRITE_GMII_REG: 0x%x 0x%x\n",[RegAddr]:2,[value]
  720.  
  721.         movzx   eax,[RegAddr]
  722.         shl     eax,16
  723.         or      eax,[value]
  724.         or      eax,0x80000000
  725.         RTL_W32 RTL8169_REG_PHYAR,eax
  726.         stdcall udelay,1000
  727.  
  728.         mov     ecx,2000
  729.         ; Check if the RTL8169 has completed writing to the specified MII register
  730.     @@: RTL_R32 RTL8169_REG_PHYAR
  731.         test    eax,0x80000000
  732.         jz      .exit
  733.         stdcall udelay,100
  734.         loop    @b
  735.   .exit:
  736.         ret
  737. endp
  738.  
  739. proc RTL8169_READ_GMII_REG,RegAddr:byte
  740.  
  741.         DEBUGF  1,"K : RTL8169_READ_GMII_REG: 0x%x\n",[RegAddr]:2
  742.  
  743.         push    ecx
  744.         movzx   eax,[RegAddr]
  745.         shl     eax,16
  746. ;       or      eax,0x0
  747.         RTL_W32 RTL8169_REG_PHYAR,eax
  748.         stdcall udelay,1000
  749.  
  750.         mov     ecx,2000
  751.         ; Check if the RTL8169 has completed retrieving data from the specified MII register
  752.     @@: RTL_R32 RTL8169_REG_PHYAR
  753.         test    eax,0x80000000
  754.         jnz     .exit
  755.         stdcall udelay,100
  756.         loop    @b
  757.  
  758.         or      eax,-1
  759.         pop     ecx
  760.         ret
  761.   .exit:
  762.         RTL_R32 RTL8169_REG_PHYAR
  763.         and     eax,0xFFFF
  764.         pop     ecx
  765.         ret
  766. endp
  767.  
  768. proc rtl8169_set_rx_mode
  769.  
  770.         DEBUGF  1,"K : rtl8169_set_rx_mode\n"
  771.  
  772.         ; IFF_ALLMULTI
  773.         ; Too many to filter perfectly -- accept all multicasts
  774.         RTL_R32 RTL8169_REG_RxConfig
  775.         mov     ecx,[rtl8169_tpc.chipset]
  776.         and     eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask
  777.         or      eax,rtl8169_rx_config or (RTL8169_RXM_AcceptBroadcast or RTL8169_RXM_AcceptMulticast or RTL8169_RXM_AcceptMyPhys)
  778.         RTL_W32 RTL8169_REG_RxConfig,eax
  779.  
  780.         ; Multicast hash filter
  781.         RTL_W32 RTL8169_REG_MAR0 + 0,0xffffffff
  782.         RTL_W32 RTL8169_REG_MAR0 + 4,0xffffffff
  783.         ret
  784. endp
  785.  
  786. proc rtl8169_init_ring
  787.  
  788.         DEBUGF  1,"K : rtl8169_init_ring\n"
  789.  
  790.         xor     eax,eax
  791.         mov     [rtl8169_tpc.cur_rx],eax
  792.         mov     [rtl8169_tpc.cur_tx],eax
  793.  
  794.         mov     edi,[rtl8169_tpc.TxDescArray]
  795.         mov     ecx,(NUM_TX_DESC * sizeof.rtl8169_TxDesc) / 4
  796.         cld
  797.         rep     stosd
  798.         mov     edi,[rtl8169_tpc.RxDescArray]
  799.         mov     ecx,(NUM_RX_DESC * sizeof.rtl8169_RxDesc) / 4
  800.         rep     stosd
  801.  
  802.         mov     edi,rtl8169_tpc.Tx_skbuff
  803.         mov     eax,rtl8169_txb
  804.         mov     ecx,NUM_TX_DESC
  805.     @@: stosd
  806.         inc     eax           ; add eax,RX_BUF_SIZE ???
  807.         loop    @b
  808.  
  809. ;!!!    for (i = 0; i < NUM_RX_DESC; i++) {
  810. ;!!!            if (i == (NUM_RX_DESC - 1))
  811. ;!!!                    tpc->RxDescArray[i].status = (OWNbit | EORbit) | RX_BUF_SIZE;
  812. ;!!!            else
  813. ;!!!                    tpc->RxDescArray[i].status = OWNbit | RX_BUF_SIZE;
  814. ;!!!            tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE];
  815. ;!!!            tpc->RxDescArray[i].buf_addr = virt_to_bus(tpc->RxBufferRing[i]);
  816. ;!!!    }
  817.         mov     esi,rtl8169_tpc.RxBufferRing
  818.         mov     edi,[rtl8169_tpc.RxDescArray]
  819.         mov     eax,rtl8169_rxb
  820.         mov     ecx,NUM_RX_DESC
  821.     @@: mov     [esi],eax
  822.         mov     [edi+rtl8169_RxDesc.buf_addr],eax
  823.         mov     [edi+rtl8169_RxDesc.status],RTL8169_DSB_OWNbit or RX_BUF_SIZE
  824.         add     esi,4
  825.         add     edi,sizeof.rtl8169_RxDesc
  826.         add     eax,RX_BUF_SIZE
  827.         loop    @b
  828.  
  829.         or      [edi - sizeof.rtl8169_RxDesc + rtl8169_RxDesc.status],RTL8169_DSB_EORbit
  830.  
  831.         ret
  832. endp
  833.  
  834. proc rtl8169_hw_start
  835.  
  836.         DEBUGF  1,"K : rtl8169_hw_start\n"
  837.  
  838.         ; Soft reset the chip
  839.         RTL_W8  RTL8169_REG_ChipCmd,RTL8169_CMD_Reset
  840.         ; Check that the chip has finished the reset
  841.         mov     ecx,1000
  842.     @@: RTL_R8  RTL8169_REG_ChipCmd
  843.         and     al,RTL8169_CMD_Reset
  844.         jz      @f
  845.         stdcall udelay,10
  846.         loop    @b
  847.     @@:
  848.         RTL_W8  RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Unlock
  849.         RTL_W8  RTL8169_REG_ChipCmd,RTL8169_CMD_TxEnb or RTL8169_CMD_RxEnb
  850.         RTL_W8  RTL8169_REG_ETThReg,ETTh
  851.         ; For gigabit rtl8169
  852.         RTL_W16 RTL8169_REG_RxMaxSize,RxPacketMaxSize
  853.         ; Set Rx Config register
  854.         RTL_R32 RTL8169_REG_RxConfig
  855.         mov     ecx,[rtl8169_tpc.chipset]
  856.         and     eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask
  857.         or      eax,rtl8169_rx_config
  858.         RTL_W32 RTL8169_REG_RxConfig,eax
  859.         ; Set DMA burst size and Interframe Gap Time
  860.         RTL_W32 RTL8169_REG_TxConfig,(TX_DMA_BURST shl RTL8169_TXC_DMAShift) or (InterFrameGap shl RTL8169_TXC_InterFrameGapShift)
  861.         RTL_R16 RTL8169_REG_CPlusCmd
  862.         RTL_W16 RTL8169_REG_CPlusCmd,ax
  863.  
  864.         RTL_R16 RTL8169_REG_CPlusCmd
  865.         or      ax,1 shl 3
  866.         cmp     [rtl8169_tpc.mcfg],MCFG_METHOD_02
  867.         jne     @f
  868.         cmp     [rtl8169_tpc.mcfg],MCFG_METHOD_03
  869.         jne     @f
  870.         or      ax,1 shl 14
  871. ;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n"
  872.         jmp     .set
  873.     @@:;DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0xE0: bit-3\n"
  874.   .set: RTL_W16 RTL8169_REG_CPlusCmd,ax
  875.  
  876. ;       RTL_W16 0xE2,0x1517
  877. ;       RTL_W16 0xE2,0x152a
  878. ;       RTL_W16 0xE2,0x282a
  879.         RTL_W16 0xE2,0x0000
  880.  
  881.         MOV     [rtl8169_tpc.cur_rx],0
  882.         RTL_W32 RTL8169_REG_TxDescStartAddr,[rtl8169_tpc.TxDescArray]
  883.         RTL_W32 RTL8169_REG_RxDescStartAddr,[rtl8169_tpc.RxDescArray]
  884.         RTL_W8  RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Lock
  885.         stdcall udelay,10
  886.         RTL_W32 RTL8169_REG_RxMissed,0
  887.         call    rtl8169_set_rx_mode
  888.         ; no early-rx interrupts
  889.         RTL_R16 RTL8169_REG_MultiIntr
  890.         and     ax,0xF000
  891.         RTL_W16 RTL8169_REG_MultiIntr,ax
  892.         RTL_W16 RTL8169_REG_IntrMask,0 ; rtl8169_intr_mask
  893.         ret
  894. endp
  895.  
  896. proc udelay,msec:dword
  897.         push    esi
  898.         mov     esi,[msec]
  899.         call    delay_ms
  900.         pop     esi
  901.         ret
  902. endp
  903.  
  904. ;***************************************************************************
  905. ;   Function
  906. ;      rtl8169_probe
  907. ;   Description
  908. ;      Searches for an ethernet card, enables it and clears the rx buffer
  909. ;      If a card was found, it enables the ethernet -> TCPIP link
  910. ;   Destroyed registers
  911. ;      eax, ebx, ecx, edx
  912. ;
  913. ;***************************************************************************
  914. proc rtl8169_probe
  915.  
  916.         DEBUGF  1,"K : rtl8169_probe: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2
  917.  
  918.         call    rtl8169_init_board
  919.  
  920.         mov     ecx,MAC_ADDR_LEN
  921.         mov     edx,[rtl8169_tpc.mmio_addr]
  922.         add     edx,RTL8169_REG_MAC0
  923.         xor     ebx,ebx
  924.         ; Get MAC address. FIXME: read EEPROM
  925.     @@: RTL_R8  dx
  926.         mov     [node_addr+ebx],al
  927.         inc     edx
  928.         inc     ebx
  929.         loop    @b
  930.  
  931.         DEBUGF  1,"K : rtl8169_probe: MAC = %x-%x-%x-%x-%x-%x\n",[node_addr+0]:2,[node_addr+1]:2,[node_addr+2]:2,[node_addr+3]:2,[node_addr+4]:2,[node_addr+5]:2
  932.  
  933.         ; Config PHY
  934.         stdcall rtl8169_hw_PHY_config
  935. ;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
  936.         RTL_W8  0x82,0x01
  937.         cmp     [rtl8169_tpc.mcfg],MCFG_METHOD_03
  938.         jae     @f
  939. ;       DEBUGF  1,"K :   Set PCI Latency=0x40\n"
  940. ;       stdcall pci_write_config_byte,PCI_LATENCY_TIMER,0x40
  941.    @@:
  942.         cmp     [rtl8169_tpc.mcfg],MCFG_METHOD_02
  943.         jne     @f
  944. ;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
  945.         RTL_W8  0x82,0x01
  946. ;       DEBUGF  1,"K :   Set PHY Reg 0x0bh = 0x00h\n"
  947.         stdcall RTL8169_WRITE_GMII_REG,0x0b,0x0000      ; w 0x0b 15 0 0
  948.     @@:
  949.         ; if TBI is not enabled
  950.         RTL_R8  RTL8169_REG_PHYstatus
  951.         test    al,RTL8169_PHYS_TBI_Enable
  952.         jz      .tbi_dis
  953.         stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG
  954.         ; enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged
  955.         and     eax,0x0C1F
  956.         or      eax,RTL8169_PHY_Cap_10_Half or RTL8169_PHY_Cap_10_Full or RTL8169_PHY_Cap_100_Half or RTL8169_PHY_Cap_100_Full
  957.         stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG,eax
  958.         ; enable 1000 Full Mode
  959.         stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_1000_CTRL_REG,RTL8169_PHY_Cap_1000_Full or RTL8169_PHY_Cap_1000_Half ; rtl8168
  960.         ; Enable auto-negotiation and restart auto-nigotiation
  961.         stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_CTRL_REG,RTL8169_PHY_Enable_Auto_Nego or RTL8169_PHY_Restart_Auto_Nego
  962.         stdcall udelay,100
  963.         mov     ecx,10000
  964.         ; wait for auto-negotiation process
  965.     @@: dec     ecx
  966.         jz      @f
  967.         stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_STAT_REG
  968.         stdcall udelay,100
  969.         test    eax,RTL8169_PHY_Auto_Neco_Comp
  970.         jz      @b
  971.         RTL_R8  RTL8169_REG_PHYstatus
  972.         jmp     @f
  973.   .tbi_dis:
  974.         stdcall udelay,100
  975.     @@:
  976.         call    rtl8169_reset
  977.         ret
  978. endp
  979.  
  980. ;***************************************************************************
  981. ;   Function
  982. ;      rt8169_reset
  983. ;   Description
  984. ;      Place the chip (ie, the ethernet card) into a virgin state
  985. ;   Destroyed registers
  986. ;      eax, ebx, ecx, edx
  987. ;
  988. ;***************************************************************************
  989. proc rtl8169_reset
  990.  
  991.         DEBUGF  1,"K : rtl8169_reset: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2
  992.  
  993.         mov     [rtl8169_tpc.TxDescArrays],rtl8169_tx_ring
  994.         ; Tx Desscriptor needs 256 bytes alignment
  995.         mov     [rtl8169_tpc.TxDescArray],rtl8169_tx_ring
  996.  
  997.         mov     [rtl8169_tpc.RxDescArrays],rtl8169_rx_ring
  998.         ; Rx Desscriptor needs 256 bytes alignment
  999.         mov     [rtl8169_tpc.RxDescArray],rtl8169_rx_ring
  1000.  
  1001.         call    rtl8169_init_ring
  1002.         call    rtl8169_hw_start
  1003.         ; Construct a perfect filter frame with the mac address as first match
  1004.         ; and broadcast for all others
  1005.         mov     edi,rtl8169_txb
  1006.         or      al,-1
  1007.         mov     ecx,192
  1008.         cld
  1009.         rep     stosb
  1010.  
  1011.         mov     esi,node_addr
  1012.         mov     edi,rtl8169_txb
  1013.         movsd
  1014.         movsw
  1015.  
  1016.         mov     eax,[pci_data]
  1017.         mov     [eth_status],eax
  1018.         ret
  1019. endp
  1020.  
  1021. ;***************************************************************************
  1022. ;   Function
  1023. ;      rtl8169_transmit
  1024. ;   Description
  1025. ;      Transmits a packet of data via the ethernet card
  1026. ;         d - edi - Pointer to 48 bit destination address
  1027. ;         t -  bx - Type of packet
  1028. ;         s - ecx - size of packet
  1029. ;         p - esi - pointer to packet data
  1030. ;   Destroyed registers
  1031. ;      eax, edx, esi, edi
  1032. ;
  1033. ;***************************************************************************
  1034. proc rtl8169_transmit
  1035.  
  1036.         DEBUGF  1,"K : rtl8169_transmit\n" ;: 0x%x : 0x%x 0x%x 0x%x 0x%x\n",[io_addr]:8,edi,bx,ecx,esi
  1037.  
  1038.         push    ecx edx esi
  1039.         mov     eax,MAX_ETH_FRAME_SIZE
  1040.         mul     [rtl8169_tpc.cur_tx]
  1041.         mov     esi,edi
  1042.         ; point to the current txb incase multiple tx_rings are used
  1043.         mov     edi,[rtl8169_tpc.Tx_skbuff + eax * 4]
  1044.         mov     eax,edi
  1045.         cld
  1046. ; copy destination address
  1047.         movsd
  1048.         movsw
  1049. ; copy source address
  1050.         mov     esi,node_addr
  1051.         movsd
  1052.         movsw
  1053. ; copy packet type
  1054.         mov     [edi],bx
  1055.         add     edi,2
  1056. ; copy the packet data
  1057.         pop     esi edx ecx
  1058.         push    ecx
  1059.         shr     ecx,2
  1060.         rep     movsd
  1061.         pop     ecx
  1062.         push    ecx
  1063.         and     ecx,3
  1064.         rep     movsb
  1065.  
  1066. ;!!!    s += ETH_HLEN;
  1067. ;!!!    s &= 0x0FFF;
  1068. ;!!!    while (s < ETH_ZLEN)
  1069. ;!!!            ptxb[s++] = '\0';
  1070.         mov     edi,eax
  1071.         pop     ecx
  1072.         push    eax
  1073.         add     ecx,ETH_HLEN
  1074.         and     ecx,0x0FFF
  1075.         xor     al,al
  1076.         add     edi,ecx
  1077.     @@: cmp     ecx,ETH_ZLEN
  1078.         jae     @f
  1079.         stosb
  1080.         inc     ecx
  1081.         jmp     @b
  1082.     @@: pop     eax
  1083.  
  1084.         mov     ebx,eax
  1085.         mov     eax,sizeof.rtl8169_TxDesc
  1086.         mul     [rtl8169_tpc.cur_tx]
  1087.         add     eax,[rtl8169_tpc.TxDescArray]
  1088.         xchg    eax,ebx
  1089.         mov     [ebx + rtl8169_TxDesc.buf_addr],eax
  1090.  
  1091.         mov     eax,ecx
  1092.         cmp     eax,ETH_ZLEN
  1093.         jae     @f
  1094.         mov     eax,ETH_ZLEN
  1095.     @@: or      eax,RTL8169_DSB_OWNbit or RTL8169_DSB_FSbit or RTL8169_DSB_LSbit
  1096.         cmp     [rtl8169_tpc.cur_tx],NUM_TX_DESC - 1
  1097.         jne     @f
  1098.         or      eax,RTL8169_DSB_EORbit
  1099.     @@: mov     [ebx + rtl8169_TxDesc.status],eax
  1100.  
  1101.         RTL_W8  RTL8169_REG_TxPoll,0x40     ; set polling bit
  1102.  
  1103.         inc     [rtl8169_tpc.cur_tx]
  1104.         and     [rtl8169_tpc.cur_tx],NUM_TX_DESC - 1
  1105.  
  1106. ;!!!    to = currticks() + TX_TIMEOUT;
  1107. ;!!!    while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() < to));        /* wait */
  1108.         mov     ecx,TX_TIMEOUT / 10
  1109.     @@: test    [ebx + rtl8169_TxDesc.status],RTL8169_DSB_OWNbit
  1110.         jnz     @f
  1111.         stdcall udelay,10
  1112.         loop    @b
  1113.         DEBUGF  1,"K : rtl8169_transmit: TX Time Out\n"
  1114.     @@:
  1115.  
  1116.         ret
  1117. endp
  1118.  
  1119. ;***************************************************************************
  1120. ; Function
  1121. ;    rtl8169_poll
  1122. ;
  1123. ; Description
  1124. ;    Polls the ethernet card for a received packet
  1125. ;    Received data, if any, ends up in Ether_buffer
  1126. ; Destroyed register(s)
  1127. ;    eax, edx, ecx
  1128. ;
  1129. ;***************************************************************************
  1130. proc rtl8169_poll
  1131.  
  1132. ;       DEBUGF  1,"K : rtl8169_poll\n" ;: 0x%x : none\n",[io_addr]:8
  1133.  
  1134.         mov     word[eth_rx_data_len],0
  1135.  
  1136.         mov     eax,sizeof.rtl8169_RxDesc
  1137.         mul     [rtl8169_tpc.cur_rx]
  1138.         add     eax,[rtl8169_tpc.RxDescArray]
  1139.         mov     ebx,eax
  1140.  
  1141. ;       DEBUGF  1,"K :   rtl8169_RxDesc.status = 0x%x\n",[ebx + rtl8169_RxDesc.status]
  1142.  
  1143.         test    [ebx + rtl8169_RxDesc.status],RTL8169_DSB_OWNbit ; 0x80000600
  1144.         jnz     .exit
  1145.  
  1146. ;       DEBUGF  1,"K :   rtl8169_tpc.cur_rx = %u\n",[rtl8169_tpc.cur_rx]
  1147.  
  1148.         ; h/w no longer present (hotplug?) or major error, bail
  1149.         RTL_R16 RTL8169_REG_IntrStatus
  1150.  
  1151. ;       DEBUGF  1,"K :   IntrStatus = 0x%x\n",ax
  1152.  
  1153.         cmp     ax,0xFFFF
  1154.         je      .exit
  1155.  
  1156.         push    eax
  1157.         and     ax,not (RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK)
  1158.         RTL_W16 RTL8169_REG_IntrStatus,ax
  1159.  
  1160.         mov     eax,[ebx + rtl8169_RxDesc.status]
  1161.  
  1162. ;       DEBUGF  1,"K :   RxDesc.status = 0x%x\n",eax
  1163.  
  1164.         test    eax,RTL8169_SD_RxRES
  1165.         jnz     .else
  1166.         and     eax,0x00001FFF
  1167. ;       jz      .exit.pop
  1168.         add     eax,-4
  1169.         mov     [eth_rx_data_len],ax
  1170.  
  1171.         DEBUGF  1,"K : rtl8169_poll: data length = %u\n",ax
  1172.  
  1173.         push    eax
  1174.         mov     ecx,eax
  1175.         shr     ecx,2
  1176.         mov     eax,[rtl8169_tpc.cur_rx]
  1177.         mov     edx,[rtl8169_tpc.RxBufferRing + eax * 4]
  1178.         mov     esi,edx
  1179.         mov     edi,Ether_buffer
  1180.         cld
  1181.         rep     movsd
  1182.         pop     ecx
  1183.         and     ecx,3
  1184.         rep     movsb
  1185.  
  1186.         mov     eax,RTL8169_DSB_OWNbit or RX_BUF_SIZE
  1187.         cmp     [rtl8169_tpc.cur_rx],NUM_RX_DESC - 1
  1188.         jne     @f
  1189.         or      eax,RTL8169_DSB_EORbit
  1190.     @@: mov     [ebx + rtl8169_RxDesc.status],eax
  1191.  
  1192.         mov     [ebx + rtl8169_RxDesc.buf_addr],edx
  1193.         jmp     @f
  1194.   .else:
  1195.         DEBUGF  1,"K : rtl8169_poll: Rx Error\n"
  1196.         ; FIXME: shouldn't I reset the status on an error
  1197.     @@:
  1198.         inc     [rtl8169_tpc.cur_rx]
  1199.         and     [rtl8169_tpc.cur_rx],NUM_RX_DESC - 1
  1200.   .exit.pop:
  1201.         pop     eax
  1202.         and     ax,RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK
  1203.         RTL_W16 RTL8169_REG_IntrStatus,ax
  1204.   .exit:
  1205.         ret
  1206. endp
  1207.  
  1208. proc rtl8169_cable
  1209.         ret
  1210. endp
  1211.