Subversion Repositories Kolibri OS

Rev

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

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