Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2009. All rights reserved.    ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;; RTL8029/ne2000 driver for KolibriOS                             ;;
  7. ;;                                                                 ;;
  8. ;;    Written by hidnplayr@kolibrios.org                           ;;
  9. ;;     with help from CleverMouse                                  ;;
  10. ;;                                                                 ;;
  11. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  12. ;;             Version 2, June 1991                                ;;
  13. ;;                                                                 ;;
  14. ;; current status (september 2009) - UNSTABLE                      ;;
  15. ;;                                                                 ;;
  16. ;; based on RTL8029.asm driver for menuetos                        ;;
  17. ;; and realtek8029.asm for SolarOS by Eugen Brasoveanu             ;;
  18. ;;                                                                 ;;
  19. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  20.  
  21. $Revision: 1254 $
  22.  
  23. format MS COFF
  24.  
  25. API_VERSION     equ 0x01000100
  26.  
  27. DEBUG equ 1
  28. __DEBUG__ equ 1
  29. __DEBUG_LEVEL__ equ 1
  30.  
  31. include 'proc32.inc'
  32. include 'imports.inc'
  33. include 'fdo.inc'
  34.  
  35. OS_BASE         equ 0x80000000
  36. new_app_base    equ 0x0
  37. PROC_BASE       equ OS_BASE+0x0080000
  38.  
  39. ; PCI Bus defines
  40. PCI_HEADER_TYPE             equ     0x0e  ;8 bit
  41. PCI_BASE_ADDRESS_0          equ     0x10  ;32 bit
  42. PCI_BASE_ADDRESS_5          equ     0x24  ;32 bits
  43. PCI_BASE_ADDRESS_SPACE_IO   equ     0x01
  44. PCI_VENDOR_ID               equ     0x00  ;16 bit
  45. PCI_BASE_ADDRESS_IO_MASK    equ     0xFFFFFFFC
  46.  
  47. struc IOCTL {
  48.       .handle      dd ?
  49.       .io_code     dd ?
  50.       .input       dd ?
  51.       .inp_size    dd ?
  52.       .output      dd ?
  53.       .out_size    dd ?
  54. }
  55.  
  56. virtual at 0
  57.   IOCTL IOCTL
  58. end virtual
  59.  
  60. struc ETH_DEVICE {
  61. ; pointers to procedures
  62.       .unload           dd ?
  63.       .reset            dd ?
  64.       .transmit         dd ?
  65.       .set_MAC          dd ?
  66.       .get_MAC          dd ?
  67.       .set_mode         dd ?
  68.       .get_mode         dd ?
  69. ; status
  70.       .bytes_tx         dq ?
  71.       .bytes_rx         dq ?
  72.       .packets_tx       dd ?
  73.       .packets_rx       dd ?
  74.       .mode             dd ?  ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..)
  75.       .name             dd ?
  76.       .mac              dp ?
  77. ; device specific
  78.       .io_addr          dw ?
  79.       .irq_line         db ?
  80.       .pci_bus          db ?
  81.       .pci_dev          db ?
  82.  
  83.       .flags            db ?
  84.       .vendor           db ?
  85.       .asic_base        dw ?
  86.       .memsize          db ?
  87.       .rx_start         db ?
  88.       .tx_start         db ?
  89.       .bmem             dd ?
  90.       .rmem             dd ?
  91.       .romdata          rb 16
  92.       .size:
  93.  
  94. }
  95.  
  96. virtual at 0
  97.   device ETH_DEVICE
  98. end virtual
  99.  
  100. public START
  101. public service_proc
  102. public version
  103.  
  104.         MAX_ne2000                equ 16          ; Max number of devices this driver may handle
  105.  
  106.         P0_PSTART                 equ 0x01
  107.         P0_PSTOP                  equ 0x02
  108.         P0_BOUND                  equ 0x03
  109.         P0_TSR                    equ 0x04
  110.         P0_TPSR                   equ 0x04
  111.         P0_TBCR0                  equ 0x05
  112.         P0_TBCR1                  equ 0x06
  113.         P0_ISR                    equ 0x07
  114.         P0_RSAR0                  equ 0x08
  115.         P0_RSAR1                  equ 0x09
  116.         P0_RBCR0                  equ 0x0A
  117.         P0_RBCR1                  equ 0x0B
  118.         P0_RSR                    equ 0x0C
  119.         P0_RCR                    equ 0x0C
  120.         P0_TCR                    equ 0x0D
  121.         P0_DCR                    equ 0x0E
  122.         P0_IMR                    equ 0x0F
  123.  
  124.         P1_PAR0                   equ 0x01
  125.         P1_PAR1                   equ 0x02
  126.         P1_PAR2                   equ 0x03
  127.         P1_PAR3                   equ 0x04
  128.         P1_PAR4                   equ 0x05
  129.         P1_PAR5                   equ 0x06
  130.         P1_CURR                   equ 0x07
  131.         P1_MAR0                   equ 0x08
  132.  
  133.         CMD_PS0                   equ 0x00        ;  Page 0 select
  134.         CMD_PS1                   equ 0x40        ;  Page 1 select
  135.         CMD_PS2                   equ 0x80        ;  Page 2 select
  136.         CMD_RD2                   equ 0x20        ;  Remote DMA control
  137.         CMD_RD1                   equ 0x10
  138.         CMD_RD0                   equ 0x08
  139.         CMD_TXP                   equ 0x04        ;  transmit packet
  140.         CMD_STA                   equ 0x02        ;  start
  141.         CMD_STP                   equ 0x01        ;  stop
  142.  
  143.         RCR_MON                   equ 0x20        ;  monitor mode
  144.  
  145.         DCR_FT1                   equ 0x40
  146.         DCR_LS                    equ 0x08        ;  Loopback select
  147.         DCR_WTS                   equ 0x01        ;  Word transfer select
  148.  
  149.         ISR_PRX                   equ 0x01        ;  successful recv
  150.         ISR_PTX                   equ 0x02        ;  successful xmit
  151.         ISR_RXE                   equ 0x04        ;  receive error
  152.         ISR_TXE                   equ 0x08        ;  transmit error
  153.         ISR_OVW                   equ 0x10        ;  Overflow
  154.         ISR_CNT                   equ 0x20        ;  Counter overflow
  155.         ISR_RDC                   equ 0x40        ;  Remote DMA complete
  156.         ISR_RST                   equ 0x80        ;  reset
  157.  
  158.         IRQ_MASK                  equ ISR_PRX ; + ISR_PTX + ISR_TXE
  159.  
  160.         RSTAT_PRX                 equ 0x01        ;  successful recv
  161.         RSTAT_CRC                 equ 0x02        ;  CRC error
  162.         RSTAT_FAE                 equ 0x04        ;  Frame alignment error
  163.         RSTAT_OVER                equ 0x08        ;  FIFO overrun
  164.  
  165.         TXBUF_SIZE                equ 6
  166.         RXBUF_END                 equ 32
  167.         PAGE_SIZE                 equ 256
  168.  
  169.         ETH_ALEN                  equ 6
  170.         ETH_HLEN                  equ 14
  171.         ETH_ZLEN                  equ 60
  172.         ETH_FRAME_LEN             equ 1514
  173.  
  174.         FLAG_PIO                  equ 0x01
  175.         FLAG_16BIT                equ 0x02
  176.         ASIC_PIO                  equ 0
  177.  
  178.         VENDOR_NONE               equ 0
  179.         VENDOR_WD                 equ 1
  180.         VENDOR_NOVELL             equ 2
  181.         VENDOR_3COM               equ 3
  182.  
  183.         NE_ASIC_OFFSET            equ 0x10
  184.         NE_RESET                  equ 0x0F        ; Used to reset card
  185.         NE_DATA                   equ 0x00        ; Used to read/write NIC mem
  186.  
  187.         MEM_8192                  equ 32
  188.         MEM_16384                 equ 64
  189.         MEM_32768                 equ 128
  190.  
  191.         ISA_MAX_ADDR              equ 0x400
  192.  
  193. ;------------------------------------------------
  194.  
  195.         LAST_IO = 0
  196.  
  197. macro set_io addr {
  198.  
  199.         if      addr = 0
  200.                 mov     dx, [ebp + device.io_addr]
  201.         else
  202.                 add     edx, addr - LAST_IO
  203.         end if
  204.  
  205.         LAST_IO = addr
  206.  
  207.  
  208. }
  209.  
  210. ;-------------------------------------------------
  211.  
  212.  
  213. section '.flat' code readable align 16
  214.  
  215. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  216. ;;
  217. ;; proc START
  218. ;;
  219. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  220.  
  221. proc START stdcall, state:dword
  222.  
  223.         cmp     [state], 1
  224.         jne     .exit
  225.   .entry:
  226.         DEBUGF 2,"Registering rtl8029 service \n"
  227.         stdcall RegService, my_service, service_proc
  228.         ret
  229.   .fail:
  230.   .exit:
  231.         xor     eax, eax
  232.         ret
  233.  
  234. endp
  235.  
  236.  
  237. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  238. ;;
  239. ;; proc SERVICE_PROC
  240. ;;
  241. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  242. align 4
  243. proc service_proc ;stdcall, ioctl:dword
  244.         push    ebp
  245.  
  246.         mov     edx, [esp+8];[ioctl]
  247.         mov     eax, [edx+IOCTL.io_code]
  248.  
  249. ;------------------------------------------------------
  250.                        ;---------------
  251.         cmp     eax, 0 ;SRV_GETVERSION
  252.         jne     @F     ;---------------
  253.  
  254.         cmp     [edx+IOCTL.out_size], 4
  255.         jl      .fail
  256.         mov     eax, [edx+IOCTL.output]
  257.         mov     [eax], dword API_VERSION
  258.  
  259.         xor     eax, eax
  260.         pop     ebp
  261.         ret     4
  262.  
  263. ;------------------------------------------------------
  264.   @@:                  ;---------
  265.         cmp     eax, 1 ;SRV_HOOK
  266.         jne     @F     ;---------
  267.  
  268.         DEBUGF  2,"Checking if device is already listed..\n"
  269.  
  270.         mov     eax, [edx+IOCTL.input]
  271.  
  272.         cmp     [edx+IOCTL.inp_size], 3
  273.         jl      .fail
  274.         cmp     byte [eax], 1
  275.         je      .pci
  276.  
  277.         cmp     [edx+IOCTL.inp_size], 4
  278.         jl      .fail
  279.         cmp     byte [eax], 0
  280.         je      .isa
  281.  
  282.         jmp     .fail
  283.  
  284.   .pci:
  285.  
  286.         mov     esi, ne2000_LIST
  287.         mov     ecx, [ne2000_DEV]
  288.         test    ecx, ecx
  289.         jz      .firstdevice_pci
  290.         mov     bx , [eax+1]
  291.   .nextdevice:
  292.         lodsd
  293.         cmp     bx , word [eax + device.pci_bus] ; compare with pci and device num in ne2000 list
  294.         je      find_device_num
  295.         loop    .nextdevice
  296.  
  297.   .firstdevice_pci:
  298.         call    create_new_struct
  299.  
  300.         mov     eax, [edx+IOCTL.input]         ; save the pci bus and device numbers
  301.         mov     cx , [eax+1]                     ;
  302.         mov     [ebx+device.pci_bus], cl       ;
  303.         mov     [ebx+device.pci_dev], ch       ;
  304.  
  305.         mov     edx, PCI_BASE_ADDRESS_0        ; find the base io address
  306.   .sb_reg_check:
  307.  
  308.         movzx   eax, byte [ebx+device.pci_bus] ;
  309.         movzx   ecx, byte [ebx+device.pci_dev] ;
  310.                                                ;
  311.         push    edx ecx
  312.         stdcall PciRead16, eax ,ecx ,edx       ;
  313.         pop     ecx edx
  314.                                                ;
  315.         mov     [ebx+device.io_addr], ax       ;
  316.         and     eax, PCI_BASE_ADDRESS_IO_MASK  ;
  317.         test    eax, eax                       ;
  318.         jz      .sb_inc_reg                    ;
  319.         movzx   eax, [ebx+device.io_addr]      ;
  320.         and     eax, PCI_BASE_ADDRESS_SPACE_IO ;
  321.         test    eax, eax                       ;
  322.         jz      .sb_inc_reg                    ;
  323.                                                ;
  324.         movzx   eax, [ebx+device.io_addr]      ;
  325.         and     eax, PCI_BASE_ADDRESS_IO_MASK  ;
  326.         mov     [ebx+device.io_addr], ax       ;
  327.                                                ;
  328.         jmp     .got_io                        ;
  329.                                                ;
  330.   .sb_inc_reg:                             ;
  331.         add     edx, 4                         ;
  332.         cmp     edx, PCI_BASE_ADDRESS_5        ;
  333.         jbe     .sb_reg_check                  ;
  334.  
  335.   .got_io:
  336.         movzx   eax, byte [ebx+device.pci_bus] ; find IRQ line
  337.         movzx   ecx, byte [ebx+device.pci_dev] ;
  338.         push    ebx
  339.         stdcall PciRead8, eax ,ecx ,0x3c       ; 0x3c is the offset where irq can be found
  340.         pop     ebx
  341.         mov     byte [ebx+device.irq_line], al ;
  342.  
  343.         jmp     .hook
  344.  
  345.   .isa:
  346.  
  347.         mov     esi, ne2000_LIST
  348.         mov     ecx, [ne2000_DEV]
  349.         test    ecx, ecx
  350.         jz      .firstdevice_isa
  351.         mov     bx , [eax+1]
  352.         mov     dl , [eax+3]
  353.   .nextdevice_isa:
  354.         lodsd
  355.         cmp     bx , [eax + device.io_addr]
  356.         jne     .maybenext
  357.         cmp     dl , [eax + device.irq_line]
  358.         je      find_device_num
  359.   .maybenext:
  360.         loop    .nextdevice_isa
  361.  
  362.  
  363.  
  364.   .firstdevice_isa:
  365.         call    create_new_struct
  366.  
  367.         mov     eax, [edx+IOCTL.input]
  368.         mov     cx , [eax+1]
  369.         mov     [ebx+device.io_addr], cx
  370.         mov     cl, [eax+3]
  371.         mov     [ebx+device.irq_line], cl
  372.  
  373.   .hook:
  374.  
  375.         DEBUGF  2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",[ebx+device.pci_dev]:1,[ebx+device.pci_bus]:1,[ebx+device.irq_line]:1,[ebx+device.io_addr]:4
  376.  
  377.         call    probe                                                   ; this function will output in eax
  378.         test    eax, eax
  379.         jnz     .err                                                    ; If an error occured, exit
  380.  
  381.         mov     eax, [ne2000_DEV]
  382.         mov     [ne2000_LIST+4*eax], ebx
  383.         inc     [ne2000_DEV]
  384.  
  385.         call    EthRegDev                                    ; Register the device to kernel (ebx points to device struct)
  386.         cmp     eax, -1
  387.         jz      .err
  388.         pop     ebp
  389.         ret     4
  390.  
  391.   .err:
  392.         stdcall KernelFree, ebx
  393.  
  394.         jmp     .fail
  395.  
  396. ;------------------------------------------------------
  397.   @@:
  398. .fail:
  399.         or      eax, -1
  400.         pop     ebp
  401.         ret     4
  402.  
  403. ;------------------------------------------------------
  404. endp
  405.  
  406.  
  407. create_new_struct:
  408.  
  409.         cmp     [ne2000_DEV], MAX_ne2000
  410.         jge     .fail
  411.  
  412.         push    edx
  413.         stdcall KernelAlloc, device.size
  414.         pop     edx
  415.         test    eax, eax
  416.         jz      .fail
  417.         mov     ebx, eax
  418.  
  419.         mov     dword [ebx+device.reset], reset
  420.         mov     dword [ebx+device.transmit], transmit
  421.         mov     dword [ebx+device.get_MAC], read_mac
  422.         mov     dword [ebx+device.set_MAC], write_mac
  423.         mov     dword [ebx+device.unload], unload
  424.         mov     dword [ebx+device.name], my_service
  425.  
  426.         ret
  427.  
  428. .fail:
  429.         add     esp, 4
  430.         or      eax, -1
  431.         ret
  432.  
  433. find_device_num:
  434.  
  435.         DEBUGF  1,"Trying to find device number of already registered device\n"
  436.         mov     ebx, eax
  437.         call    EthStruc2Dev                                            ; This kernel procedure converts a pointer to device struct in ebx
  438.                                                                         ; into a device number in edi
  439.         mov     eax, edi                                                ; Application wants it in eax instead
  440.         DEBUGF  1,"Kernel says: %u\n", eax
  441.         ret
  442.  
  443.  
  444. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  445. ;;                                                                        ;;
  446. ;;        Actual Hardware dependent code starts here                      ;;
  447. ;;                                                                        ;;
  448. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  449.  
  450.  
  451. unload:   ; TODO
  452.         or      eax, -1
  453.         ret
  454.  
  455.  
  456.  
  457. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  458. ;;
  459. ;;  probe: enables the device and clears the rx buffer
  460. ;;
  461. ;;  Destroys: eax, ebx, ecx, edx
  462. ;;
  463. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  464.  
  465. probe:
  466.         mov     ebp, ebx        ;---
  467.  
  468.         mov     [ebp + device.vendor], VENDOR_NONE
  469.         mov     [ebp + device.bmem], 0
  470.         mov     ax, [ebp + device.io_addr]
  471.         add     ax, NE_ASIC_OFFSET
  472.         mov     [ebp + device.asic_base], ax
  473.  
  474.         DEBUGF  2,"Trying 16-bit mode\n"
  475.  
  476.         or      [ebp + device.flags], FLAG_16BIT or FLAG_PIO
  477.         mov     [ebp + device.memsize], MEM_32768
  478.         mov     [ebp + device.tx_start], 64
  479.         mov     [ebp + device.rx_start], TXBUF_SIZE + 64
  480.  
  481.         set_io  0
  482.         set_io  P0_DCR
  483.         mov     al, DCR_WTS + DCR_FT1 + DCR_LS
  484.         out     dx, al
  485.  
  486.         set_io  P0_PSTART
  487.         mov     al, MEM_16384
  488.         out     dx, al
  489.  
  490.         set_io  P0_PSTOP
  491.         mov     al, MEM_32768
  492.         out     dx, al
  493.  
  494.         mov     esi, test_data
  495.         mov     bx, 16384
  496.         mov     cx, 14
  497.         call    eth_pio_write
  498.  
  499.         mov     bx, 16384
  500.         mov     cx, 14
  501.         lea     edi, [ebp + device.romdata]
  502.         call    eth_pio_read
  503.  
  504.         lea     esi, [ebp + device.romdata]
  505.         mov     edi, test_data
  506.         mov     ecx, 13
  507.  
  508.      repz    cmpsb
  509.      jz      ep_set_vendor
  510.  
  511.  
  512.         DEBUGF  2,"Trying 8-bit mode\n"
  513.  
  514.         mov     [ebp + device.flags], FLAG_PIO
  515.         mov     [ebp + device.memsize], MEM_16384
  516.         mov     [ebp + device.tx_start], 32
  517.         mov     [ebp + device.rx_start], TXBUF_SIZE + 32
  518.  
  519.         mov     dx, [ebp + device.asic_base]
  520.         add     dx, NE_RESET
  521.  
  522.         in      al, dx
  523.         out     dx, al
  524.  
  525.         in      al, 0x84
  526.  
  527.         set_io  0
  528.         mov     al, CMD_RD2 + CMD_STP
  529.         out     dx, al
  530.  
  531.         set_io  P0_RCR
  532.         mov     al, RCR_MON
  533.         out     dx, al
  534.  
  535.         set_io  P0_DCR
  536.         mov     al, DCR_FT1 + DCR_LS
  537.         out     dx, al
  538.  
  539.         set_io  P0_PSTART
  540.         mov     al, MEM_8192
  541.         out     dx, al
  542.  
  543.         set_io  P0_PSTOP
  544.         mov     al, MEM_16384
  545.         out     dx, al
  546.  
  547.         mov     esi, test_data
  548.         mov     bx, 8192
  549.         mov     cx, 14
  550.         call    eth_pio_write
  551.  
  552.         mov     bx, 8192
  553.         mov     cx, 14
  554.         lea     edi, [ebp + device.romdata]
  555.         call    eth_pio_read
  556.  
  557.         mov     esi, test_data
  558.         lea     edi, [ebp + device.romdata]
  559.         mov     ecx, 13
  560.  
  561.     repz      cmpsb
  562.     jz        ep_set_vendor
  563.  
  564.         DEBUGF  2,"This is not a valid ne2000 device!\n"
  565.         or      eax, -1
  566.         ret
  567.  
  568.  
  569. ep_set_vendor:
  570.  
  571.         cmp     [ebp + device.io_addr], ISA_MAX_ADDR
  572.         jbe     ep_001
  573.  
  574.         DEBUGF  2,"Card is using PCI bus\n"
  575.  
  576. ;;;        or      [ebp + device.flags], FLAG_16BIT
  577.  
  578. ep_001:
  579.         mov     [ebp + device.vendor], VENDOR_NOVELL
  580.  
  581. ep_check_have_vendor:
  582.  
  583.         mov     ebx, ebp        ;----
  584.  
  585.         mov     al, [ebp + device.vendor]
  586.         cmp     al, VENDOR_NONE
  587.   ;;;;      je      rtl8029_exit
  588.  
  589.         cmp     al, VENDOR_3COM
  590.         je      reset
  591.  
  592.         mov     eax, [ebp + device.bmem]
  593.         mov     [ebp + device.rmem], eax
  594.  
  595.         ;-- hack (read mac from eeprom ant write it to hardware's register)
  596.         mov     ebx, ebp
  597.         call    read_mac
  598.  
  599.         push    .hack
  600.         sub     esp, 6
  601.         mov     edi, esp
  602.         lea     esi, [ebp + device.mac]
  603.         movsd
  604.         movsw
  605.         jmp     write_mac
  606.        .hack:
  607.         ;--- hack
  608.  
  609.  
  610. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  611. ;;
  612. ;;   reset: Place the chip into a virgin state
  613. ;;
  614. ;;   Destroys: eax, ebx, ecx, edx
  615. ;;
  616. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  617.  
  618. reset:
  619.         mov     ebp, ebx        ;---
  620.  
  621.         DEBUGF  2,"Resetting device\n"
  622.  
  623. ; attach int handler
  624.         movzx   eax, [ebp+device.irq_line]
  625.         DEBUGF  1,"Attaching int handler to irq %x\n",eax:1
  626.         stdcall AttachIntHandler, eax, int_handler, dword 0
  627.  
  628. ; Stop mode
  629.  
  630.         set_io  0
  631.         mov     al, CMD_PS0 + CMD_RD2 + CMD_STP
  632.         out     dx, al
  633.  
  634.         set_io  P0_DCR
  635.         test    [ebp + device.flags], FLAG_16BIT
  636.         jz      nsr_001
  637.  
  638.         mov     al, 0x49
  639.         jmp     nsr_002
  640.  
  641. nsr_001:
  642.         mov     al, 0x48
  643.  
  644. nsr_002:
  645.         out     dx, al
  646.  
  647.  
  648. ;clear remote bytes count
  649.         set_io  0
  650.  
  651.         xor     al, al
  652.  
  653.         set_io  P0_RBCR0
  654.         out     dx, al
  655.  
  656.         set_io  P0_RBCR1
  657.         out     dx, al
  658.  
  659.  
  660. ;initialize Receive configuration register
  661.         set_io  P0_RCR
  662.         mov     al, 0x20        ; monitor mode
  663.         out     dx, al
  664.  
  665.  
  666. ; transmit configuration register
  667.         set_io  P0_TCR
  668.         mov     al, 2           ; internal loopback
  669.         out     dx, al
  670.  
  671.  
  672. ; transmit page stuff
  673.         set_io  P0_TPSR
  674.         mov     al, [ebp + device.tx_start]
  675.         out     dx, al
  676.  
  677. ; set receive control register ;;;;
  678.         set_io  P0_RCR
  679.         mov     al, 4           ; accept broadcast
  680.         out     dx, al
  681.  
  682. ; pagestart
  683.         set_io  P0_PSTART
  684.         mov     al, [ebp + device.rx_start]
  685.         out     dx, al
  686.  
  687. ; pagestop
  688.         set_io  P0_PSTOP
  689.         mov     al, [ebp + device.memsize]
  690.         out     dx, al
  691.  
  692. ; page boundary
  693.         set_io  P0_BOUND
  694.         mov     al, [ebp + device.memsize]
  695.         dec     al
  696.         out     dx, al
  697.  
  698.  
  699. ;;clear IRQ mask
  700. ;        set_io  P0_IMR
  701. ;        xor     al, al
  702. ;        out     dx, al
  703.  
  704.         set_io  0
  705.         mov     al, CMD_PS1 + CMD_RD2 + CMD_STP ; page 1, stop mode
  706.         out     dx, al
  707.  
  708.         set_io  P1_CURR
  709.         mov     al, [ebp + device.rx_start]
  710.         out     dx, al
  711.  
  712.         set_io  0
  713.         mov     al, CMD_PS0 + CMD_RD2 + CMD_STA ; go to page 0
  714.         out     dx, al
  715.  
  716. ; Read MAC address
  717.         mov     ebx, ebp        ;----
  718.         call    read_mac
  719.  
  720. ; clear interupt status
  721.         set_io  0
  722.         set_io  P0_ISR
  723.         mov     al, 0xff
  724.         out     dx, al
  725.  
  726. ; set IRQ mask
  727.         set_io  P0_IMR
  728.         mov     al, IRQ_MASK
  729.         out     dx, al
  730.  
  731. ;; start mode
  732. ;        set_io  0
  733. ;        mov     al, CMD_STA
  734. ;        out     dx, al
  735.  
  736. ; clear transmit control register
  737.         set_io  P0_TCR
  738.         mov     al, 0           ; no loopback
  739.         out     dx, al
  740.  
  741. ; clear packet/byte counters
  742.  
  743.         lea     edi, [ebp+device.bytes_tx]
  744.         mov     ecx, 6
  745.         rep     stosd
  746.  
  747.  
  748. ; Indicate that we have successfully reset the card
  749.         DEBUGF  2,"Done!\n"
  750.         xor     eax, eax
  751.  
  752.         mov     ebx, ebp        ;------
  753.  
  754.         ret
  755.  
  756.  
  757.  
  758. ;***************************************************************************
  759. ;   Function
  760. ;      transmit
  761. ; buffer in [esp+4], size in [esp+8], pointer to device struct in ebx
  762. ;***************************************************************************
  763.  
  764. align 4
  765. transmit:
  766.         mov     ebp, ebx
  767.  
  768.         mov     esi, [esp + 4]
  769.         mov     ecx, [esp + 8]
  770.         DEBUGF  2,"Transmitting packet, buffer:%x, size:%u\n",esi, ecx
  771.         DEBUGF  2,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",[esi+0]:2,[esi+1]:2,[esi+2]:2,[esi+3]:2,[esi+4]:2,[esi+5]:2,[esi+6]:2,[esi+7]:2,[esi+8]:2,[esi+9]:2,[esi+10]:2,[esi+11]:2,[esi+13]:2,[esi+12]:2
  772.  
  773.         cmp     dword [esp + 8], ETH_FRAME_LEN
  774.         jg      .finish ; packet is too long
  775.         cmp     dword [esp + 8], 60
  776.         jl      .finish ; packet is too short
  777.  
  778.         xor     bl, bl
  779.         mov     bh, [ebp + device.tx_start]
  780.         push    cx
  781.         call    eth_pio_write
  782.         pop     cx
  783.  
  784.         set_io  0
  785.         mov     al, CMD_PS0 + CMD_RD2 + CMD_STA
  786.         out     dx, al
  787.  
  788.         set_io  P0_TPSR
  789.         mov     al, [ebp + device.tx_start]
  790.         out     dx, al
  791.  
  792.         set_io  P0_TBCR0
  793.         mov     al, cl
  794.         out     dx, al
  795.  
  796.         set_io  P0_TBCR1
  797.         mov     al, ch
  798.         out     dx, al
  799.  
  800.         set_io  0
  801.         mov     al, CMD_PS0 + CMD_TXP + CMD_RD2 + CMD_STA
  802.         out     dx, al
  803.  
  804.         DEBUGF  2," - Packet Sent!\n"
  805.  
  806.         inc     [ebp+device.packets_tx]          ;
  807.         mov     eax, [esp + 8]                   ; Get packet size in eax
  808.  
  809.         add     dword [ebp + device.bytes_tx], eax
  810.         adc     dword [ebp + device.bytes_tx + 4], 0
  811. .finish:
  812.         mov     ebx, ebp
  813.         xor     eax, eax
  814.  
  815.         ret
  816.  
  817.  
  818. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  819. ;
  820. ; Interrupt handler
  821. ;
  822. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  823. align 4
  824. int_handler:
  825.  
  826.         DEBUGF  2,"IRQ %x ",eax:2
  827.  
  828. ; find pointer of device wich made INT occur
  829.         mov     esi, ne2000_LIST
  830.         mov     ecx, [ne2000_DEV]
  831. .nextdevice:
  832.         mov     ebp, dword [esi]
  833.  
  834.         set_io  0
  835.         set_io  P0_ISR
  836.         in      al, dx
  837.  
  838.         DEBUGF  2,"isr %x ",eax:2
  839.  
  840.         test    al, ISR_PRX    ; packet received ok ?
  841.         jnz     .rx
  842.  
  843.         add     esi, 4
  844.  
  845.         loop    .nextdevice
  846.         ret
  847.  
  848.  
  849.  
  850. ; looks like we've found a device wich received a packet..
  851. .rx:
  852.         stdcall KernelAlloc, ETH_FRAME_LEN  ; size doesnt really matter as packet size is smaller then kernel's page size
  853.         test    eax, eax
  854.         jz      .fail_2
  855.  
  856. ;--------------------------------------
  857. ; allocate memory for temp variables in stack
  858.  
  859.         sub     esp, 14+8
  860.  
  861.         eth_type        equ esp
  862.         pkthdr          equ esp + 2
  863.         pktoff          equ esp + 6
  864.         eth_rx_data_ptr equ esp + 8
  865.         eth_tmp_len     equ esp + 12
  866.  
  867. ; These will be used by eth_receiver when the packet gets there
  868.  
  869.         pointer         equ esp + 14
  870.         size            equ esp + 18
  871.  
  872. ;-------------------------------------
  873.  
  874.         mov     [pointer], eax
  875.         mov     [eth_rx_data_ptr], eax
  876.  
  877.         set_io  P0_BOUND
  878.         in      al, dx
  879.         inc     al
  880.  
  881.         cmp     al, [ebp + device.memsize]
  882.         jb      .nsp_001
  883.  
  884.         mov     al, [ebp + device.rx_start]
  885.  
  886. .nsp_001:
  887.         mov     ch, al
  888.  
  889.         set_io  0
  890.         mov     al, CMD_PS1
  891.         out     dx, al
  892.  
  893.         set_io  P1_CURR
  894.         in      al, dx               ; get current page
  895.         mov     cl, al
  896.  
  897.         set_io  0
  898.         mov     al, CMD_PS0
  899.         out     dx, al
  900.  
  901.         cmp     cl, [ebp + device.memsize]
  902.         jb      .nsp_002
  903.  
  904.         mov     cl, [ebp + device.rx_start]
  905.  
  906. .nsp_002:
  907.         cmp     cl, ch
  908.         je      .fail
  909.  
  910.         xor     ax, ax
  911.         mov     ah, ch
  912.  
  913.         mov     [pktoff], ax
  914.  
  915.         mov     al, [ebp + device.flags]
  916.         test    al, FLAG_PIO
  917.         jz      .nsp_003
  918.  
  919.         mov     bx, word [pktoff]
  920.         lea     edi, [pkthdr]
  921.         mov     cx, 4
  922.         call    eth_pio_read
  923.         jmp     .nsp_004
  924.  
  925. .nsp_003:
  926.         mov     edi, [ebp + device.rmem]
  927.         movzx   eax, word [pktoff]
  928.         add     edi, eax
  929.         mov     eax, [edi]
  930.         mov     [pkthdr], eax
  931.  
  932. .nsp_004:
  933.         add     word[pktoff] , 4
  934.  
  935.         xor     eax, eax
  936.         mov     ax , [pkthdr + 2]
  937.         sub     ax , 4
  938.  
  939.         DEBUGF  2,"Received %u bytes\n",eax
  940.  
  941.         add     dword [ebp + device.bytes_rx], eax  ; Update stats
  942.         adc     dword [ebp + device.bytes_rx + 4], 0
  943.         inc     dword [ebp + device.packets_rx]     ;
  944.  
  945.         mov     [eth_tmp_len], ax
  946.         mov     dword[size], eax
  947.  
  948.         cmp     ax, ETH_ZLEN
  949.         jb      .fail
  950.  
  951.         cmp     ax , ETH_FRAME_LEN
  952.         ja      .fail
  953.  
  954.         mov     al , [pkthdr]
  955.         test    al , RSTAT_PRX
  956.         jz      .fail
  957.  
  958.    ; Right, we can now get the data
  959.  
  960.         xor     ebx, ebx
  961.         mov     bh , [ebp + device.memsize]
  962.         sub     bx , [pktoff]
  963.  
  964.         cmp     [eth_tmp_len], bx
  965.         jbe     .nsp_005
  966.  
  967.         DEBUGF  2,"WRAP!\n"
  968.  
  969.         mov     al , [ebp + device.flags]
  970.         test    al , FLAG_PIO
  971.         jz      .nsp_006
  972.  
  973.         push    ebx
  974.         mov     cx , bx
  975.         mov     bx , [pktoff+4]
  976.         mov     edi, [eth_rx_data_ptr+4]
  977.         call    eth_pio_read
  978.         pop     ebx
  979.         jmp     .nsp_007
  980.  
  981. .nsp_006:
  982.         DEBUGF  2,"PIO mode not supported by HW!\n"
  983.    ; Not implemented, as we are using PIO mode on this card
  984.  
  985. .nsp_007:
  986.         xor     al, al
  987.         mov     ah, [ebp + device.rx_start]
  988.         mov     [pktoff], ax
  989.  
  990.         add     [eth_rx_data_ptr], ebx
  991.         sub     [eth_tmp_len], bx
  992.  
  993. .nsp_005:
  994.         test    [ebp + device.flags], FLAG_PIO
  995.         jz      .nsp_008
  996.  
  997.         xor     ebx, ebx
  998.         mov     bx, [pktoff]
  999.         xor     ecx, ecx
  1000.         mov     cx, [eth_tmp_len]
  1001.         mov     edi, [eth_rx_data_ptr]
  1002.         call    eth_pio_read
  1003.         jmp     .nsp_009
  1004.  
  1005. .nsp_008:
  1006.         DEBUGF  2,"PIO mode not supported by HW!\n"
  1007.    ; Not implemented, as we are using PIO mode on this card
  1008.  
  1009. .nsp_009:
  1010.         mov     al, [pkthdr+1]
  1011.         cmp     al, [ebp + device.rx_start]
  1012.         jne     .nsp_010
  1013.  
  1014.         mov     al, [ebp + device.memsize]
  1015.  
  1016. .nsp_010:
  1017.         set_io  0
  1018.         set_io  P0_BOUND
  1019.         dec     al
  1020.         out     dx, al
  1021.  
  1022.         mov     ebx, ebp
  1023.         add     esp, 14
  1024.  
  1025.         mov     ebx, ebp
  1026.         jmp     EthReceiver     ; send it to the kernel
  1027.  
  1028. .fail:
  1029.         add     esp, 14+8
  1030. .fail_2:
  1031.         DEBUGF  2,"done\n"
  1032. ret
  1033.  
  1034.  
  1035.  
  1036.  
  1037.  
  1038. ;;;;;;;;;;;;;;;;;;;;;;;
  1039. ;;                   ;;
  1040. ;; Write MAC address ;;
  1041. ;;                   ;;
  1042. ;;;;;;;;;;;;;;;;;;;;;;;
  1043.  
  1044. align 4
  1045. write_mac:      ; in: mac on stack (6 bytes)
  1046.  
  1047.         mov     ebp, ebx        ;---
  1048.  
  1049.         DEBUGF  1,"Writing MAC: "
  1050.  
  1051.         set_io  0
  1052.         mov     al, CMD_PS1; + CMD_RD2 + CMD_STP
  1053.         out     dx, al
  1054.  
  1055.         set_io  P1_PAR0
  1056.         mov     esi, esp
  1057.         mov     cx, 6
  1058.  @@:
  1059.         lodsb
  1060.         out     dx, al
  1061.         inc     dx
  1062.         loopw   @r
  1063.  
  1064.         add     esp, 6
  1065.  
  1066.         mov     ebx, ebp        ;---
  1067.  
  1068. ; Notice this procedure does not ret, but continues to read_mac instead.
  1069.  
  1070. ;;;;;;;;;;;;;;;;;;;;;;
  1071. ;;                  ;;
  1072. ;; Read MAC address ;;
  1073. ;;                  ;;
  1074. ;;;;;;;;;;;;;;;;;;;;;;
  1075.  
  1076. read_mac:
  1077.  
  1078.         mov     ebp, ebx        ;-----
  1079.  
  1080.         DEBUGF  1,"Reading MAC: "
  1081.  
  1082. ;        set_io  0
  1083. ;        mov     al, CMD_PS1; + CMD_RD2 + CMD_STP ; select page 1
  1084. ;        out     dx, al
  1085. ;
  1086. ;        set_io  P1_PAR0
  1087. ;        lea     edi, [ebp + device.mac]
  1088. ;
  1089. ;        mov     cx, 6
  1090. ; .loop:
  1091. ;        in      al, dx
  1092. ;        stosb
  1093. ;        inc     dx
  1094. ;        loopw   .loop
  1095. ;
  1096. ;        set_io  0
  1097. ;        mov     al, CMD_PS0; + CMD_RD2 + CMD_STA  ; set page back to 0
  1098. ;        out     dx, al
  1099.  
  1100.  
  1101.         mov     bx, 0
  1102.         mov     cx, 16
  1103.         lea     edi, [ebp + device.romdata]
  1104.         call    eth_pio_read
  1105.  
  1106.         lea     esi, [ebp + device.romdata]
  1107.         lea     edi, [ebp + device.mac]
  1108.         mov     ecx, 6
  1109.  
  1110.   .loop:
  1111.         movsb
  1112.         test    [ebp + device.flags], FLAG_16BIT
  1113.         jz      .8bit
  1114.         inc     esi
  1115.   .8bit:
  1116.         loop    .loop
  1117.  
  1118.         DEBUGF  1,"%x-%x-%x-%x-%x-%x\n",[edi-6]:2,[edi-5]:2,[edi-4]:2,[edi-3]:2,[edi-2]:2,[edi-1]:2
  1119.  
  1120.         mov     ebx, ebp        ;---
  1121.  
  1122.         ret
  1123.  
  1124.  
  1125. ;***************************************************************************
  1126. ;   Function
  1127. ;      eth_pio_read
  1128. ;
  1129. ;   Description
  1130. ;       Read a frame from the ethernet card via Programmed I/O
  1131. ;      src in bx
  1132. ;      cnt in cx
  1133. ;       dst in edi
  1134. ;***************************************************************************
  1135. eth_pio_read:
  1136.  
  1137.         DEBUGF  1,"Eth PIO Read from %x to %x, %u bytes ",bx,edi,cx
  1138.  
  1139.         set_io  0
  1140.         mov     al, CMD_RD2 + CMD_STA
  1141.         out     dx, al
  1142.  
  1143.         mov     al, cl
  1144.         set_io  P0_RBCR0
  1145.         out     dx, al
  1146.  
  1147.         mov     al, ch
  1148.         set_io  P0_RBCR1
  1149.         out     dx, al
  1150.  
  1151.         mov     al, bl
  1152.         set_io  P0_RSAR0
  1153.         out     dx, al
  1154.  
  1155.         mov     al, bh
  1156.         set_io  P0_RSAR1
  1157.         out     dx, al
  1158.  
  1159.         mov     al, CMD_RD0 + CMD_STA
  1160.         set_io  0
  1161.         out     dx, al
  1162.  
  1163.         mov     dx, [ebp + device.asic_base]
  1164.  
  1165.         test    [ebp+device.flags], FLAG_16BIT
  1166.         jz      epr_003
  1167.  
  1168.         DEBUGF  1,"in 16-bits mode"
  1169.  
  1170.         shr     cx, 1   ; note that if the number was odd, carry flag will be set
  1171.         pushf           ; save the flags for later
  1172.  
  1173. epr_002:
  1174.         in      ax, dx
  1175.         stosw
  1176.         loopw   epr_002
  1177.  
  1178.         inc     cx
  1179.         popf
  1180.         jnc     epr_004
  1181.  
  1182. epr_003:
  1183.         in      al, dx
  1184.         stosb
  1185.         loopw   epr_003
  1186.  
  1187.  
  1188. epr_004:
  1189.         set_io  0
  1190.         set_io  P0_ISR
  1191.  
  1192. epr_005:                                ; Wait for Remote DMA Complete
  1193.         in      al, dx
  1194.         test    al, ISR_RDC
  1195.         jz      epr_005
  1196. ;        and     al, not ISR_RDC
  1197.         out     dx, al                  ; clear the bit
  1198.  
  1199.  
  1200.         DEBUGF  1,"\n"
  1201.         ret
  1202.  
  1203.  
  1204.  
  1205.  
  1206. ;***************************************************************************
  1207. ;   Function
  1208. ;      eth_pio_write
  1209. ;
  1210. ;   Description
  1211. ;       writes a frame to the ethernet card via Programmed I/O
  1212. ;      dst in bx
  1213. ;      cnt in cx
  1214. ;       src in esi
  1215. ;***************************************************************************
  1216. eth_pio_write:
  1217.  
  1218.         DEBUGF  1,"Eth PIO Write from %x to %x, %u bytes ",esi,bx,cx
  1219.  
  1220.         set_io  0
  1221.         mov     al, CMD_RD2 + CMD_STA
  1222.         out     dx, al
  1223.  
  1224.         set_io  P0_ISR
  1225.         mov     al, ISR_RDC
  1226.         out     dx, al
  1227.  
  1228.         set_io  P0_RBCR0
  1229.         mov     al, cl
  1230.         out     dx, al
  1231.  
  1232.         set_io  P0_RBCR1
  1233.         mov     al, ch
  1234.         out     dx, al
  1235.  
  1236.         set_io  P0_RSAR0
  1237.         mov     al,   bl
  1238.         out     dx, al
  1239.  
  1240.         set_io  P0_RSAR1
  1241.         mov     al,   bh
  1242.         out     dx, al
  1243.  
  1244.         set_io  0
  1245.         mov     al, CMD_RD1 + CMD_STA
  1246.         out     dx, al
  1247.  
  1248.         mov     dx, [ebp + device.asic_base]
  1249.         test    [ebp + device.flags], FLAG_16BIT
  1250.         jz      epw_003
  1251.  
  1252.         DEBUGF  1,"in 16-bits mode"
  1253.  
  1254.         shr     cx, 1   ; note that if the number was odd, carry flag will be set
  1255.         pushf           ; save the flags for later
  1256.  
  1257. epw_002:
  1258.         lodsw
  1259.         out     dx, ax
  1260.         loopw   epw_002
  1261.  
  1262.         popf
  1263.         jnc     epw_004
  1264.         inc     cx
  1265.  
  1266. epw_003:
  1267.         lodsb
  1268.         out     dx, al
  1269.         loopw   epw_003
  1270.  
  1271. epw_004:
  1272.         set_io  0
  1273.         set_io  P0_ISR
  1274.  
  1275. epw_005:                                ; Wait for Remote DMA Complete
  1276.         in      al, dx
  1277.         test    al, ISR_RDC
  1278.         jz      epw_005
  1279. ;        and     al, not ISR_RDC
  1280.         out     dx, al                  ; clear the bit
  1281.  
  1282.  
  1283.         DEBUGF  1,"\n"
  1284.         ret
  1285.  
  1286.  
  1287.  
  1288. ;all initialized data place here
  1289. align 4
  1290.  
  1291. ne2000_DEV      dd 0
  1292. version         dd (5 shl 16) or (API_VERSION and 0xFFFF)
  1293. my_service      db 'RTL8029/ne2000',0  ;max 16 chars include zero
  1294.  
  1295. device_1        db 'Realtek 8029',0
  1296. device_2        db 'Realtek 8019',0
  1297. device_3        db 'Realtek 8019AS',0
  1298. device_4        db 'ne2000',0
  1299. device_5        db 'DP8390',0
  1300.  
  1301. test_data       db 'NE*000 memory',0
  1302.  
  1303. include_debug_strings
  1304.  
  1305. section '.data' data readable writable align 16  ;place all uninitialized data place here
  1306.  
  1307. ne2000_LIST     rd MAX_ne2000
  1308.  
  1309.  
  1310.  
  1311.  
  1312.  
  1313.