Subversion Repositories Kolibri OS

Rev

Rev 1161 | 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 or FLAG_PIO
  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  0
  711.         set_io  P0_ISR
  712.         mov     al, 0xff
  713.         out     dx, al
  714.  
  715. ; set IRQ mask
  716.         set_io  P0_IMR
  717.         mov     al, IRQ_MASK
  718.         out     dx, al
  719.  
  720. ;; start mode
  721. ;        set_io  0
  722. ;        mov     al, CMD_STA
  723. ;        out     dx, al
  724.  
  725. ; clear transmit control register
  726.         set_io  P0_TCR
  727.         mov     al, 0           ; no loopback
  728.         out     dx, al
  729.  
  730.  
  731. ; Indicate that we have successfully reset the card
  732.         DEBUGF  2,"Done!\n"
  733.         xor     eax, eax
  734.  
  735.         mov     ebx, ebp        ;------
  736.  
  737.         ret
  738.  
  739.  
  740.  
  741. ;***************************************************************************
  742. ;   Function
  743. ;      transmit
  744. ; buffer in [esp], size in [esp+4], pointer to device struct in ebx
  745. ;***************************************************************************
  746.  
  747. align 4
  748. transmit:
  749.         mov     ebp, ebx
  750.  
  751.         mov     esi, [esp]
  752.         mov     ecx, [esp + 4]
  753.         DEBUGF  2,"Transmitting packet, buffer:%x, size:%u\n",esi, ecx
  754.         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
  755.  
  756.         cmp     dword [esp+4], ETH_FRAME_LEN
  757.         jg      .finish ; packet is too long
  758.         cmp     dword [esp+4], 60
  759.         jl      .finish ; packet is too short
  760.  
  761.         xor     bl, bl
  762.         mov     bh, [ebp + device.tx_start]
  763.         push    cx
  764.         call    eth_pio_write
  765.         pop     cx
  766.  
  767.         set_io  0
  768.         mov     al, CMD_PS0 + CMD_RD2 + CMD_STA
  769.         out     dx, al
  770.  
  771.         set_io  P0_TPSR
  772.         mov     al, [ebp + device.tx_start]
  773.         out     dx, al
  774.  
  775.         set_io  P0_TBCR0
  776.         mov     al, cl
  777.         out     dx, al
  778.  
  779.         set_io  P0_TBCR1
  780.         mov     al, ch
  781.         out     dx, al
  782.  
  783.         set_io  0
  784.         mov     al, CMD_PS0 + CMD_TXP + CMD_RD2 + CMD_STA
  785.         out     dx, al
  786.  
  787.         DEBUGF  2," - Packet Sent!\n"
  788. .finish:
  789.         mov     ebx, ebp
  790.  
  791.         call    KernelFree
  792.         add     esp, 4 ; pop (balance stack)
  793.         xor     eax, eax
  794.  
  795.         ret
  796.  
  797.  
  798. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  799. ;
  800. ; Interrupt handler
  801. ;
  802. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  803. align 4
  804. int_handler:
  805.  
  806.         DEBUGF  2,"IRQ %x ",eax:2
  807.  
  808. ; find pointer of device wich made INT occur
  809.         mov     esi, ne2000_LIST
  810.         mov     ecx, [ne2000_DEV]
  811. .nextdevice:
  812.         mov     ebp, dword [esi]
  813.  
  814.         set_io  0               ; We chould check ISR instead..
  815.         set_io  P0_ISR
  816.         in      al, dx
  817.  
  818.         DEBUGF  2,"isr %x ",eax:2
  819.  
  820.         test    al, ISR_PRX
  821.         jnz     .rx
  822.  
  823.         add     esi, 4
  824.  
  825.         loop    .nextdevice
  826.         ret
  827.  
  828. ; looks like we've found it!
  829. .rx:
  830.  
  831.  
  832.         sub     esp, 14+8                         ; allocate memory for temp variables in stack
  833.  
  834.         eth_type        equ esp
  835.         pkthdr          equ esp + 2
  836.         pktoff          equ esp + 6
  837.         eth_rx_data_ptr equ esp + 8
  838.         eth_tmp_len     equ esp + 12
  839.  
  840.         pointer         equ esp + 14
  841.         size            equ esp + 18
  842.  
  843.         stdcall KernelAlloc, ETH_FRAME_LEN
  844.         mov     [pointer], eax
  845.         mov     [eth_rx_data_ptr], eax
  846.  
  847.         set_io  P0_BOUND
  848.         in      al, dx
  849.         inc     al
  850.  
  851.         cmp     al, [ebp + device.memsize]
  852.         jb      .nsp_001
  853.  
  854.         mov     al, [ebp + device.rx_start]
  855.  
  856. .nsp_001:
  857.         mov     ch, al
  858.  
  859.         set_io  0
  860.         mov     al, CMD_PS1
  861.         out     dx, al
  862.  
  863.         set_io  P1_CURR
  864.         in      al, dx               ; get current page
  865.         mov     cl, al
  866.  
  867.         set_io  0
  868.         mov     al, CMD_PS0
  869.         out     dx, al
  870.  
  871.         cmp     cl, [ebp + device.memsize]
  872.         jb      .nsp_002
  873.  
  874.         mov     cl, [ebp + device.rx_start]
  875.  
  876. .nsp_002:
  877.         cmp     cl, ch
  878.         je      .fail
  879.  
  880.         xor     ax, ax
  881.         mov     ah, ch
  882.  
  883.         mov     [pktoff], ax
  884.  
  885.         mov     al, [ebp + device.flags]
  886.         test    al, FLAG_PIO
  887.         jz      .nsp_003
  888.  
  889.         mov     bx, word [pktoff]
  890.         lea     edi, [pkthdr]
  891.         mov     cx, 4
  892.         call    eth_pio_read
  893.         jmp     .nsp_004
  894.  
  895. .nsp_003:
  896.         mov     edi, [ebp + device.rmem]
  897.         movzx   eax, word [pktoff]
  898.         add     edi, eax
  899.         mov     eax, [edi]
  900.         mov     [pkthdr], eax
  901.  
  902. .nsp_004:
  903.         add     word[pktoff] , 4
  904.  
  905.         xor     eax, eax
  906.         mov     ax, [pkthdr + 2]
  907.         sub     ax, 4
  908.  
  909.         DEBUGF  2,"Received %u bytes\n",eax
  910.  
  911.         mov     [eth_tmp_len], ax
  912.         mov     dword[size], eax
  913.  
  914.         cmp     ax, ETH_ZLEN
  915.         jb      .fail
  916.  
  917.         cmp     ax, ETH_FRAME_LEN
  918.         ja      .fail
  919.  
  920.         mov     al, [pkthdr]
  921.         test    al, RSTAT_PRX
  922.         jz      .fail
  923.  
  924.    ; Right, we can now get the data
  925.  
  926.         mov     bh, [ebp + device.memsize]
  927.         sub     bx, [pktoff]
  928.  
  929.         cmp     [eth_tmp_len], bx
  930.         jbe     .nsp_005
  931.  
  932.         mov     al, [ebp + device.flags]
  933.         test    al, FLAG_PIO
  934.         jz      .nsp_006
  935.  
  936.         push    bx
  937.         mov     cx, bx
  938.         mov     bx, [pktoff]
  939.         mov     edi, [eth_rx_data_ptr]
  940.         call    eth_pio_read
  941.         pop     bx
  942.         jmp     .nsp_007
  943.  
  944. .nsp_006:
  945.    ; Not implemented, as we are using PIO mode on this card
  946.  
  947. .nsp_007:
  948.         xor     al, al
  949.         mov     ah, [ebp + device.rx_start]
  950.         mov     [pktoff], ax
  951.  
  952.         add     [eth_rx_data_ptr], ebx
  953.  
  954.         mov     ax, [eth_tmp_len]
  955.         sub     ax, bx
  956.         mov     [eth_tmp_len], ax
  957.  
  958. .nsp_005:
  959.         test    [ebp + device.flags], FLAG_PIO
  960.         jz      .nsp_008
  961.  
  962.         xor     ebx, ebx
  963.         mov     bx, [pktoff]
  964.         xor     ecx, ecx
  965.         mov     cx, [eth_tmp_len]
  966.         mov     edi, [eth_rx_data_ptr]
  967.         call    eth_pio_read
  968.         jmp     .nsp_009
  969.  
  970. .nsp_008:
  971.    ; Not implemented, as we are using PIO mode on this card
  972.  
  973. .nsp_009:
  974.         mov     al, [pkthdr+1]
  975.         cmp     al, [ebp + device.rx_start]
  976.         jne     .nsp_010
  977.  
  978.         mov     al, [ebp + device.memsize]
  979.  
  980. .nsp_010:
  981.         set_io  0
  982.         set_io  P0_BOUND
  983.         dec     al
  984.         out     dx, al
  985.  
  986.         add     esp, 14
  987.  
  988.         mov     ebx, ebp
  989.         jmp     EthReceiver     ;;;
  990.  
  991. .fail:
  992.         add     esp, 14+8
  993.         DEBUGF  2,"done\n"
  994. ret
  995.  
  996.  
  997.  
  998.  
  999.  
  1000. ;;;;;;;;;;;;;;;;;;;;;;;
  1001. ;;                   ;;
  1002. ;; Write MAC address ;;
  1003. ;;                   ;;
  1004. ;;;;;;;;;;;;;;;;;;;;;;;
  1005.  
  1006. align 4
  1007. write_mac:      ; in: mac on stack
  1008.  
  1009.         mov     ebp, ebx        ;---
  1010.  
  1011.         DEBUGF  1,"Writing MAC: "
  1012.  
  1013.         set_io  0
  1014.         mov     al, CMD_PS1; + CMD_RD2 + CMD_STP
  1015.         out     dx, al
  1016.  
  1017.         set_io  P1_PAR0
  1018.         mov     esi, esp
  1019.         mov     cx, 6
  1020.  @@:
  1021.         lodsb
  1022.         out     dx, al
  1023.         inc     dx
  1024.         loopw   @r
  1025.  
  1026.         add     esp, 6
  1027.  
  1028.         mov     ebx, ebp        ;---
  1029.  
  1030. ; Notice this procedure does not ret, but continues to read_mac instead.
  1031.  
  1032. ;;;;;;;;;;;;;;;;;;;;;;
  1033. ;;                  ;;
  1034. ;; Read MAC address ;;
  1035. ;;                  ;;
  1036. ;;;;;;;;;;;;;;;;;;;;;;
  1037.  
  1038. read_mac:
  1039.  
  1040.         mov     ebp, ebx        ;-----
  1041.  
  1042.         DEBUGF  1,"Reading MAC: "
  1043.  
  1044. ;        set_io  0
  1045. ;        mov     al, CMD_PS1; + CMD_RD2 + CMD_STP ; select page 1
  1046. ;        out     dx, al
  1047. ;
  1048. ;        set_io  P1_PAR0
  1049. ;        lea     edi, [ebp + device.mac]
  1050. ;
  1051. ;        mov     cx, 6
  1052. ; .loop:
  1053. ;        in      al, dx
  1054. ;        stosb
  1055. ;        inc     dx
  1056. ;        loopw   .loop
  1057. ;
  1058. ;        lea     edi, [ebp + device.mac]
  1059. ;        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
  1060. ;
  1061. ;        set_io  0
  1062. ;        mov     al, CMD_PS0; + CMD_RD2 + CMD_STA  ; set page back to 0
  1063. ;        out     dx, al
  1064.  
  1065.  
  1066.         mov     bx, 0
  1067.         mov     cx, 16
  1068.         lea     edi, [ebp + device.romdata]
  1069.         call    eth_pio_read
  1070.  
  1071.         lea     esi, [ebp + device.romdata]
  1072.         lea     edi, [ebp + device.mac]
  1073.         mov     ecx, 6
  1074.  
  1075.   .loop:
  1076.         movsb
  1077.         test    [ebp + device.flags], FLAG_16BIT
  1078.         jz      .8bit
  1079.         inc     esi
  1080.   .8bit:
  1081.         loop    .loop
  1082.  
  1083.  
  1084.         mov     ebx, ebp        ;---
  1085.  
  1086.         ret
  1087.  
  1088.  
  1089. ;***************************************************************************
  1090. ;   Function
  1091. ;      eth_pio_read
  1092. ;
  1093. ;   Description
  1094. ;       Read a frame from the ethernet card via Programmed I/O
  1095. ;      src in bx
  1096. ;      cnt in cx
  1097. ;       dst in edi
  1098. ;***************************************************************************
  1099. eth_pio_read:
  1100.  
  1101.         DEBUGF  1,"Eth PIO Read from %x to %x, %u bytes ",bx,edi,cx
  1102.  
  1103.         set_io  0
  1104.         mov     al, CMD_RD2 + CMD_STA
  1105.         out     dx, al
  1106.  
  1107.         mov     al, cl
  1108.         set_io  P0_RBCR0
  1109.         out     dx, al
  1110.  
  1111.         mov     al, ch
  1112.         set_io  P0_RBCR1
  1113.         out     dx, al
  1114.  
  1115.         mov     al, bl
  1116.         set_io  P0_RSAR0
  1117.         out     dx, al
  1118.  
  1119.         mov     al, bh
  1120.         set_io  P0_RSAR1
  1121.         out     dx, al
  1122.  
  1123.         mov     al, CMD_RD0 + CMD_STA
  1124.         set_io  0
  1125.         out     dx, al
  1126.  
  1127.         mov     dx, [ebp + device.asic_base]
  1128.  
  1129.         test    [ebp+device.flags], FLAG_16BIT
  1130.         jz      epr_003
  1131.  
  1132.         DEBUGF  1,"in 16-bits mode"
  1133.  
  1134.         shr     cx, 1   ; note that if the number was odd, carry flag will be set
  1135.         pushf           ; save the flags for later
  1136.  
  1137. epr_002:
  1138.         in      ax, dx
  1139.         stosw
  1140.         loopw   epr_002
  1141.  
  1142.         inc     cx
  1143.         popf
  1144.         jnc     epr_004
  1145.  
  1146. epr_003:
  1147.         in      al, dx
  1148.         stosb
  1149.         loopw   epr_003
  1150.  
  1151.  
  1152. epr_004:
  1153.         set_io  0
  1154.         set_io  P0_ISR
  1155.  
  1156. epr_005:                                ; Wait for Remote DMA Complete
  1157.         in      al, dx
  1158.         test    al, ISR_RDC
  1159.         jz      epr_005
  1160. ;        and     al, not ISR_RDC
  1161.         out     dx, al                  ; clear the bit
  1162.  
  1163.  
  1164.         DEBUGF  1,"\n"
  1165.         ret
  1166.  
  1167.  
  1168.  
  1169.  
  1170. ;***************************************************************************
  1171. ;   Function
  1172. ;      eth_pio_write
  1173. ;
  1174. ;   Description
  1175. ;       writes a frame to the ethernet card via Programmed I/O
  1176. ;      dst in bx
  1177. ;      cnt in cx
  1178. ;       src in esi
  1179. ;***************************************************************************
  1180. eth_pio_write:
  1181.  
  1182.         DEBUGF  1,"Eth PIO Write from %x to %x, %u bytes ",esi,bx,cx
  1183.  
  1184.         set_io  0
  1185.         mov     al, CMD_RD2 + CMD_STA
  1186.         out     dx, al
  1187.  
  1188.         set_io  P0_ISR
  1189.         mov     al, ISR_RDC
  1190.         out     dx, al
  1191.  
  1192.         set_io  P0_RBCR0
  1193.         mov     al, cl
  1194.         out     dx, al
  1195.  
  1196.         set_io  P0_RBCR1
  1197.         mov     al, ch
  1198.         out     dx, al
  1199.  
  1200.         set_io  P0_RSAR0
  1201.         mov     al,   bl
  1202.         out     dx, al
  1203.  
  1204.         set_io  P0_RSAR1
  1205.         mov     al,   bh
  1206.         out     dx, al
  1207.  
  1208.         set_io  0
  1209.         mov     al, CMD_RD1 + CMD_STA
  1210.         out     dx, al
  1211.  
  1212.         mov     dx, [ebp + device.asic_base]
  1213.         test    [ebp + device.flags], FLAG_16BIT
  1214.         jz      epw_003
  1215.  
  1216.         DEBUGF  1,"in 16-bits mode"
  1217.  
  1218.         shr     cx, 1   ; note that if the number was odd, carry flag will be set
  1219.         pushf           ; save the flags for later
  1220.  
  1221. epw_002:
  1222.         lodsw
  1223.         out     dx, ax
  1224.         loopw   epw_002
  1225.  
  1226.         popf
  1227.         jnc     epw_004
  1228.         inc     cx
  1229.  
  1230. epw_003:
  1231.         lodsb
  1232.         out     dx, al
  1233.         loopw   epw_003
  1234.  
  1235. epw_004:
  1236.         set_io  0
  1237.         set_io  P0_ISR
  1238.  
  1239. epw_005:                                ; Wait for Remote DMA Complete
  1240.         in      al, dx
  1241.         test    al, ISR_RDC
  1242.         jz      epw_005
  1243. ;        and     al, not ISR_RDC
  1244.         out     dx, al                  ; clear the bit
  1245.  
  1246.  
  1247.         DEBUGF  1,"\n"
  1248.         ret
  1249.  
  1250.  
  1251.  
  1252. ;all initialized data place here
  1253. align 4
  1254.  
  1255. ne2000_DEV      dd 0
  1256. version         dd (5 shl 16) or (API_VERSION and 0xFFFF)
  1257. my_service      db 'ne2000',0  ;max 16 chars include zero
  1258. devicename      db 'Realtek 8029',0
  1259.                 db 'Realtek 8019',0
  1260.                 db 'Realtek 8019AS',0
  1261.                 db 'ne2000',0
  1262.                 db 'DP8390',0
  1263.  
  1264. test_data       db 'NE*000 memory',0
  1265. ;test_buffer     db '             ',0
  1266.  
  1267. include_debug_strings
  1268.  
  1269. section '.data' data readable writable align 16
  1270.  
  1271. ;place all uninitialized data place here
  1272.  
  1273. ne2000_LIST:
  1274. rd MAX_ne2000
  1275.  
  1276.  
  1277.  
  1278.  
  1279.  
  1280.