Subversion Repositories Kolibri OS

Rev

Rev 593 | 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: 869 $
  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_RxDesc
  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,1        ;;;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,1        ;;;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,1        ;;;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,1        ;;;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.         sub     [edi+rtl8169_RxDesc.buf_addr],OS_BASE                           ; shurf 28.09.2008
  824.         mov     [edi+rtl8169_RxDesc.status],RTL8169_DSB_OWNbit or RX_BUF_SIZE
  825.         add     esi,4
  826.         add     edi,sizeof.rtl8169_RxDesc
  827.         add     eax,RX_BUF_SIZE
  828.         loop    @b
  829.  
  830.         or      [edi - sizeof.rtl8169_RxDesc + rtl8169_RxDesc.status],RTL8169_DSB_EORbit
  831.  
  832.         ret
  833. endp
  834.  
  835. proc rtl8169_hw_start
  836.  
  837.         DEBUGF  1,"K : rtl8169_hw_start\n"
  838.  
  839.         ; Soft reset the chip
  840.         RTL_W8  RTL8169_REG_ChipCmd,RTL8169_CMD_Reset
  841.         ; Check that the chip has finished the reset
  842.         mov     ecx,1000
  843.     @@: RTL_R8  RTL8169_REG_ChipCmd
  844.         and     al,RTL8169_CMD_Reset
  845.         jz      @f
  846.         stdcall udelay,10
  847.         loop    @b
  848.     @@:
  849.         RTL_W8  RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Unlock
  850.         RTL_W8  RTL8169_REG_ChipCmd,RTL8169_CMD_TxEnb or RTL8169_CMD_RxEnb
  851.         RTL_W8  RTL8169_REG_ETThReg,ETTh
  852.         ; For gigabit rtl8169
  853.         RTL_W16 RTL8169_REG_RxMaxSize,RxPacketMaxSize
  854.         ; Set Rx Config register
  855.         RTL_R32 RTL8169_REG_RxConfig
  856.         mov     ecx,[rtl8169_tpc.chipset]
  857.         and     eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask
  858.         or      eax,rtl8169_rx_config
  859.         RTL_W32 RTL8169_REG_RxConfig,eax
  860.         ; Set DMA burst size and Interframe Gap Time
  861.         RTL_W32 RTL8169_REG_TxConfig,(TX_DMA_BURST shl RTL8169_TXC_DMAShift) or (InterFrameGap shl RTL8169_TXC_InterFrameGapShift)
  862.         RTL_R16 RTL8169_REG_CPlusCmd
  863.         RTL_W16 RTL8169_REG_CPlusCmd,ax
  864.  
  865.         RTL_R16 RTL8169_REG_CPlusCmd
  866.         or      ax,1 shl 3
  867.         cmp     [rtl8169_tpc.mcfg],MCFG_METHOD_02
  868.         jne     @f
  869.         cmp     [rtl8169_tpc.mcfg],MCFG_METHOD_03
  870.         jne     @f
  871.         or      ax,1 shl 14
  872. ;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n"
  873.         jmp     .set
  874.     @@:;DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0xE0: bit-3\n"
  875.   .set: RTL_W16 RTL8169_REG_CPlusCmd,ax
  876.  
  877. ;       RTL_W16 0xE2,0x1517
  878. ;       RTL_W16 0xE2,0x152a
  879. ;       RTL_W16 0xE2,0x282a
  880.         RTL_W16 0xE2,0x0000
  881.  
  882.         MOV     [rtl8169_tpc.cur_rx],0
  883.         push    eax                                                             ; shurf 28.09.2008
  884.         mov     eax, [rtl8169_tpc.TxDescArray]                                  ; shurf 28.09.2008
  885.         sub     eax, OS_BASE                                                    ; shurf 28.09.2008
  886.         RTL_W32 RTL8169_REG_TxDescStartAddr,eax ;[rtl8169_tpc.TxDescArray]      ; shurf 28.09.2008
  887.         mov     eax, [rtl8169_tpc.RxDescArray]                                  ; shurf 28.09.2008
  888.         sub     eax, OS_BASE                                                    ; shurf 28.09.2008
  889.         RTL_W32 RTL8169_REG_RxDescStartAddr,eax ;[rtl8169_tpc.RxDescArray]      ; shurf 28.09.2008
  890.         pop     eax                                                             ; shurf 28.09.2008
  891.         RTL_W8  RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Lock
  892.         stdcall udelay,10
  893.         RTL_W32 RTL8169_REG_RxMissed,0
  894.         call    rtl8169_set_rx_mode
  895.         ; no early-rx interrupts
  896.         RTL_R16 RTL8169_REG_MultiIntr
  897.         and     ax,0xF000
  898.         RTL_W16 RTL8169_REG_MultiIntr,ax
  899.         RTL_W16 RTL8169_REG_IntrMask,0 ; rtl8169_intr_mask
  900.         ret
  901. endp
  902.  
  903. proc udelay,msec:dword
  904.         push    esi
  905.         mov     esi,[msec]
  906.         call    delay_ms
  907.         pop     esi
  908.         ret
  909. endp
  910.  
  911. ;***************************************************************************
  912. ;   Function
  913. ;      rtl8169_probe
  914. ;   Description
  915. ;      Searches for an ethernet card, enables it and clears the rx buffer
  916. ;      If a card was found, it enables the ethernet -> TCPIP link
  917. ;   Destroyed registers
  918. ;      eax, ebx, ecx, edx
  919. ;
  920. ;***************************************************************************
  921. proc rtl8169_probe
  922.  
  923.         DEBUGF  1,"K : rtl8169_probe: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2
  924.  
  925.         call    rtl8169_init_board
  926.  
  927.         mov     ecx,MAC_ADDR_LEN
  928.         mov     edx,[rtl8169_tpc.mmio_addr]
  929.         add     edx,RTL8169_REG_MAC0
  930.         xor     ebx,ebx
  931.         ; Get MAC address. FIXME: read EEPROM
  932.     @@: RTL_R8  dx
  933.         mov     [node_addr+ebx],al
  934.         inc     edx
  935.         inc     ebx
  936.         loop    @b
  937.  
  938.         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
  939.  
  940.         ; Config PHY
  941.         stdcall rtl8169_hw_PHY_config
  942. ;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
  943.         RTL_W8  0x82,0x01
  944.         cmp     [rtl8169_tpc.mcfg],MCFG_METHOD_03
  945.         jae     @f
  946. ;       DEBUGF  1,"K :   Set PCI Latency=0x40\n"
  947. ;       stdcall pci_write_config_byte,PCI_LATENCY_TIMER,0x40
  948.    @@:
  949.         cmp     [rtl8169_tpc.mcfg],MCFG_METHOD_02
  950.         jne     @f
  951. ;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
  952.         RTL_W8  0x82,0x01
  953. ;       DEBUGF  1,"K :   Set PHY Reg 0x0bh = 0x00h\n"
  954.         stdcall RTL8169_WRITE_GMII_REG,0x0b,0x0000      ; w 0x0b 15 0 0
  955.     @@:
  956.         ; if TBI is not enabled
  957.         RTL_R8  RTL8169_REG_PHYstatus
  958.         test    al,RTL8169_PHYS_TBI_Enable
  959.         jz      .tbi_dis
  960.         stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG
  961.         ; enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged
  962.         and     eax,0x0C1F
  963.         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
  964.         stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG,eax
  965.         ; enable 1000 Full Mode
  966.         stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_1000_CTRL_REG,RTL8169_PHY_Cap_1000_Full or RTL8169_PHY_Cap_1000_Half ; rtl8168
  967.         ; Enable auto-negotiation and restart auto-nigotiation
  968.         stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_CTRL_REG,RTL8169_PHY_Enable_Auto_Nego or RTL8169_PHY_Restart_Auto_Nego
  969.         stdcall udelay,100
  970.         mov     ecx,10000
  971.         ; wait for auto-negotiation process
  972.     @@: dec     ecx
  973.         jz      @f
  974.         stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_STAT_REG
  975.         stdcall udelay,100
  976.         test    eax,RTL8169_PHY_Auto_Neco_Comp
  977.         jz      @b
  978.         RTL_R8  RTL8169_REG_PHYstatus
  979.         jmp     @f
  980.   .tbi_dis:
  981.         stdcall udelay,100
  982.     @@:
  983.         call    rtl8169_reset
  984.         ret
  985. endp
  986.  
  987. ;***************************************************************************
  988. ;   Function
  989. ;      rt8169_reset
  990. ;   Description
  991. ;      Place the chip (ie, the ethernet card) into a virgin state
  992. ;   Destroyed registers
  993. ;      eax, ebx, ecx, edx
  994. ;
  995. ;***************************************************************************
  996. proc rtl8169_reset
  997.  
  998.         DEBUGF  1,"K : rtl8169_reset: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2
  999.  
  1000.         mov     [rtl8169_tpc.TxDescArrays],rtl8169_tx_ring
  1001.         ; Tx Desscriptor needs 256 bytes alignment
  1002.         mov     [rtl8169_tpc.TxDescArray],rtl8169_tx_ring
  1003.  
  1004.         mov     [rtl8169_tpc.RxDescArrays],rtl8169_rx_ring
  1005.         ; Rx Desscriptor needs 256 bytes alignment
  1006.         mov     [rtl8169_tpc.RxDescArray],rtl8169_rx_ring
  1007.  
  1008.         call    rtl8169_init_ring
  1009.         call    rtl8169_hw_start
  1010.         ; Construct a perfect filter frame with the mac address as first match
  1011.         ; and broadcast for all others
  1012.         mov     edi,rtl8169_txb
  1013.         or      al,-1
  1014.         mov     ecx,192
  1015.         cld
  1016.         rep     stosb
  1017.  
  1018.         mov     esi,node_addr
  1019.         mov     edi,rtl8169_txb
  1020.         movsd
  1021.         movsw
  1022.  
  1023.         mov     eax,[pci_data]
  1024.         mov     [eth_status],eax
  1025.         ret
  1026. endp
  1027.  
  1028. ;***************************************************************************
  1029. ;   Function
  1030. ;      rtl8169_transmit
  1031. ;   Description
  1032. ;      Transmits a packet of data via the ethernet card
  1033. ;         d - edi - Pointer to 48 bit destination address
  1034. ;         t -  bx - Type of packet
  1035. ;         s - ecx - size of packet
  1036. ;         p - esi - pointer to packet data
  1037. ;   Destroyed registers
  1038. ;      eax, edx, esi, edi
  1039. ;
  1040. ;***************************************************************************
  1041. proc rtl8169_transmit
  1042.  
  1043.         DEBUGF  1,"K : rtl8169_transmit\n" ;: 0x%x : 0x%x 0x%x 0x%x 0x%x\n",[io_addr]:8,edi,bx,ecx,esi
  1044.  
  1045.         push    ecx edx esi
  1046.         mov     eax,MAX_ETH_FRAME_SIZE
  1047.         mul     [rtl8169_tpc.cur_tx]
  1048.         mov     esi,edi
  1049.         ; point to the current txb incase multiple tx_rings are used
  1050.         mov     edi,[rtl8169_tpc.Tx_skbuff + eax * 4]
  1051.         mov     eax,edi
  1052.         cld
  1053. ; copy destination address
  1054.         movsd
  1055.         movsw
  1056. ; copy source address
  1057.         mov     esi,node_addr
  1058.         movsd
  1059.         movsw
  1060. ; copy packet type
  1061.         mov     [edi],bx
  1062.         add     edi,2
  1063. ; copy the packet data
  1064.         pop     esi edx ecx
  1065.         push    ecx
  1066.         shr     ecx,2
  1067.         rep     movsd
  1068.         pop     ecx
  1069.         push    ecx
  1070.         and     ecx,3
  1071.         rep     movsb
  1072.  
  1073. ;!!!    s += ETH_HLEN;
  1074. ;!!!    s &= 0x0FFF;
  1075. ;!!!    while (s < ETH_ZLEN)
  1076. ;!!!            ptxb[s++] = '\0';
  1077.         mov     edi,eax
  1078.         pop     ecx
  1079.         push    eax
  1080.         add     ecx,ETH_HLEN
  1081.         and     ecx,0x0FFF
  1082.         xor     al,al
  1083.         add     edi,ecx
  1084.     @@: cmp     ecx,ETH_ZLEN
  1085.         jae     @f
  1086.         stosb
  1087.         inc     ecx
  1088.         jmp     @b
  1089.     @@: pop     eax
  1090.  
  1091.         mov     ebx,eax
  1092.         mov     eax,sizeof.rtl8169_TxDesc
  1093.         mul     [rtl8169_tpc.cur_tx]
  1094.         add     eax,[rtl8169_tpc.TxDescArray]
  1095.         xchg    eax,ebx
  1096.         mov     [ebx + rtl8169_TxDesc.buf_addr],eax
  1097.         sub     [ebx + rtl8169_TxDesc.buf_addr],OS_BASE                                 ; shurf 28.09.2008
  1098.  
  1099.         mov     eax,ecx
  1100.         cmp     eax,ETH_ZLEN
  1101.         jae     @f
  1102.         mov     eax,ETH_ZLEN
  1103.     @@: or      eax,RTL8169_DSB_OWNbit or RTL8169_DSB_FSbit or RTL8169_DSB_LSbit
  1104.         cmp     [rtl8169_tpc.cur_tx],NUM_TX_DESC - 1
  1105.         jne     @f
  1106.         or      eax,RTL8169_DSB_EORbit
  1107.     @@: mov     [ebx + rtl8169_TxDesc.status],eax
  1108.  
  1109.         RTL_W8  RTL8169_REG_TxPoll,0x40     ; set polling bit
  1110.  
  1111.         inc     [rtl8169_tpc.cur_tx]
  1112.         and     [rtl8169_tpc.cur_tx],NUM_TX_DESC - 1
  1113.  
  1114. ;!!!    to = currticks() + TX_TIMEOUT;
  1115. ;!!!    while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() < to));        /* wait */
  1116.         mov     ecx,TX_TIMEOUT / 10
  1117.     @@: test    [ebx + rtl8169_TxDesc.status],RTL8169_DSB_OWNbit
  1118.         jnz     @f
  1119.         stdcall udelay,10
  1120.         loop    @b
  1121.         DEBUGF  1,"K : rtl8169_transmit: TX Time Out\n"
  1122.     @@:
  1123.  
  1124.         ret
  1125. endp
  1126.  
  1127. ;***************************************************************************
  1128. ; Function
  1129. ;    rtl8169_poll
  1130. ;
  1131. ; Description
  1132. ;    Polls the ethernet card for a received packet
  1133. ;    Received data, if any, ends up in Ether_buffer
  1134. ; Destroyed register(s)
  1135. ;    eax, edx, ecx
  1136. ;
  1137. ;***************************************************************************
  1138. proc rtl8169_poll
  1139.  
  1140. ;       DEBUGF  1,"K : rtl8169_poll\n" ;: 0x%x : none\n",[io_addr]:8
  1141.  
  1142.         mov     word[eth_rx_data_len],0
  1143.  
  1144.         mov     eax,sizeof.rtl8169_RxDesc
  1145.         mul     [rtl8169_tpc.cur_rx]
  1146.         add     eax,[rtl8169_tpc.RxDescArray]
  1147.         mov     ebx,eax
  1148.  
  1149. ;       DEBUGF  1,"K :   rtl8169_RxDesc.status = 0x%x\n",[ebx + rtl8169_RxDesc.status]
  1150.  
  1151.         test    [ebx + rtl8169_RxDesc.status],RTL8169_DSB_OWNbit ; 0x80000600
  1152.         jnz     .exit
  1153.  
  1154. ;       DEBUGF  1,"K :   rtl8169_tpc.cur_rx = %u\n",[rtl8169_tpc.cur_rx]
  1155.  
  1156.         ; h/w no longer present (hotplug?) or major error, bail
  1157.         RTL_R16 RTL8169_REG_IntrStatus
  1158.  
  1159. ;       DEBUGF  1,"K :   IntrStatus = 0x%x\n",ax
  1160.  
  1161.         cmp     ax,0xFFFF
  1162.         je      .exit
  1163.  
  1164.         push    eax
  1165.         and     ax,not (RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK)
  1166.         RTL_W16 RTL8169_REG_IntrStatus,ax
  1167.  
  1168.         mov     eax,[ebx + rtl8169_RxDesc.status]
  1169.  
  1170. ;       DEBUGF  1,"K :   RxDesc.status = 0x%x\n",eax
  1171.  
  1172.         test    eax,RTL8169_SD_RxRES
  1173.         jnz     .else
  1174.         and     eax,0x00001FFF
  1175. ;       jz      .exit.pop
  1176.         add     eax,-4
  1177.         mov     [eth_rx_data_len],ax
  1178.  
  1179.         DEBUGF  1,"K : rtl8169_poll: data length = %u\n",ax
  1180.  
  1181.         push    eax
  1182.         mov     ecx,eax
  1183.         shr     ecx,2
  1184.         mov     eax,[rtl8169_tpc.cur_rx]
  1185.         mov     edx,[rtl8169_tpc.RxBufferRing + eax * 4]
  1186.         mov     esi,edx
  1187.         mov     edi,Ether_buffer
  1188.         cld
  1189.         rep     movsd
  1190.         pop     ecx
  1191.         and     ecx,3
  1192.         rep     movsb
  1193.  
  1194.         mov     eax,RTL8169_DSB_OWNbit or RX_BUF_SIZE
  1195.         cmp     [rtl8169_tpc.cur_rx],NUM_RX_DESC - 1
  1196.         jne     @f
  1197.         or      eax,RTL8169_DSB_EORbit
  1198.     @@: mov     [ebx + rtl8169_RxDesc.status],eax
  1199.  
  1200.         mov     [ebx + rtl8169_RxDesc.buf_addr],edx
  1201.         sub     [ebx + rtl8169_RxDesc.buf_addr],OS_BASE                                 ; shurf 28.09.2008
  1202.         jmp     @f
  1203.   .else:
  1204.         DEBUGF  1,"K : rtl8169_poll: Rx Error\n"
  1205.         ; FIXME: shouldn't I reset the status on an error
  1206.     @@:
  1207.         inc     [rtl8169_tpc.cur_rx]
  1208.         and     [rtl8169_tpc.cur_rx],NUM_RX_DESC - 1
  1209.   .exit.pop:
  1210.         pop     eax
  1211.         and     ax,RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK
  1212.         RTL_W16 RTL8169_REG_IntrStatus,ax
  1213.   .exit:
  1214.         ret
  1215. endp
  1216.  
  1217. proc rtl8169_cable
  1218.         ret
  1219. endp
  1220.