Subversion Repositories Kolibri OS

Rev

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

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