Subversion Repositories Kolibri OS

Rev

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

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