Subversion Repositories Kolibri OS

Rev

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

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