Subversion Repositories Kolibri OS

Rev

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