Subversion Repositories Kolibri OS

Rev

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

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