Subversion Repositories Kolibri OS

Rev

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

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