Subversion Repositories Kolibri OS

Rev

Rev 2935 | 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             =   0x01000100
  22.         DRIVER_VERSION          =   5
  23.  
  24.         MAX_DEVICES             =   16
  25.  
  26.         DEBUG                   =   1
  27.         __DEBUG__               =   1
  28.         __DEBUG_LEVEL__         =   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                 =   0x01
  66.         P0_PSTOP                  =   0x02
  67.         P0_BOUND                  =   0x03
  68.         P0_TSR                    =   0x04
  69.         P0_TPSR                   =   0x04
  70.         P0_TBCR0                  =   0x05
  71.         P0_TBCR1                  =   0x06
  72.         P0_ISR                    =   0x07
  73.         P0_RSAR0                  =   0x08
  74.         P0_RSAR1                  =   0x09
  75.         P0_RBCR0                  =   0x0A
  76.         P0_RBCR1                  =   0x0B
  77.         P0_RSR                    =   0x0C
  78.         P0_RCR                    =   0x0C
  79.         P0_TCR                    =   0x0D
  80.         P0_DCR                    =   0x0E
  81.         P0_IMR                    =   0x0F
  82.  
  83.         P1_PAR0                   =   0x01
  84.         P1_PAR1                   =   0x02
  85.         P1_PAR2                   =   0x03
  86.         P1_PAR3                   =   0x04
  87.         P1_PAR4                   =   0x05
  88.         P1_PAR5                   =   0x06
  89.         P1_CURR                   =   0x07
  90.         P1_MAR0                   =   0x08
  91.  
  92.         CMD_PS0                   =   0x00        ;  Page 0 select
  93.         CMD_PS1                   =   0x40        ;  Page 1 select
  94.         CMD_PS2                   =   0x80        ;  Page 2 select
  95.         CMD_RD2                   =   0x20        ;  Remote DMA control
  96.         CMD_RD1                   =   0x10
  97.         CMD_RD0                   =   0x08
  98.         CMD_TXP                   =   0x04        ;  transmit packet
  99.         CMD_STA                   =   0x02        ;  start
  100.         CMD_STP                   =   0x01        ;  stop
  101.  
  102.         RCR_MON                   =   0x20        ;  monitor mode
  103.  
  104.         DCR_FT1                   =   0x40
  105.         DCR_LS                    =   0x08        ;  Loopback select
  106.         DCR_WTS                   =   0x01        ;  Word transfer select
  107.  
  108.         ISR_PRX                   =   0x01        ;  successful recv
  109.         ISR_PTX                   =   0x02        ;  successful xmit
  110.         ISR_RXE                   =   0x04        ;  receive error
  111.         ISR_TXE                   =   0x08        ;  transmit error
  112.         ISR_OVW                   =   0x10        ;  Overflow
  113.         ISR_CNT                   =   0x20        ;  Counter overflow
  114.         ISR_RDC                   =   0x40        ;  Remote DMA complete
  115.         ISR_RST                   =   0x80        ;  reset
  116.  
  117.         IRQ_MASK                  =   ISR_PRX ; + ISR_PTX + ISR_TXE
  118.  
  119.         RSTAT_PRX                 =   0x01        ;  successful recv
  120.         RSTAT_CRC                 =   0x02        ;  CRC error
  121.         RSTAT_FAE                 =   0x04        ;  Frame alignment error
  122.         RSTAT_OVER                =   0x08        ;  FIFO overrun
  123.  
  124.         TXBUF_SIZE                =   6
  125.         RXBUF_END                 =   32
  126.         PAGE_SIZE                 =   256
  127.  
  128.         ETH_ALEN                  =   6
  129.         ETH_HLEN                  =   14
  130.         ETH_ZLEN                  =   60
  131.         ETH_FRAME_LEN             =   1514
  132.  
  133.         FLAG_PIO                  =   0x01
  134.         FLAG_16BIT                =   0x02
  135.         ASIC_PIO                  =   0
  136.  
  137.         VENDOR_NONE               =   0
  138.         VENDOR_WD                 =   1
  139.         VENDOR_NOVELL             =   2
  140.         VENDOR_3COM               =   3
  141.  
  142.         NE_ASIC_OFFSET            =   0x10
  143.         NE_RESET                  =   0x0F        ; Used to reset card
  144.         NE_DATA                   =   0x00        ; Used to read/write NIC mem
  145.  
  146.         MEM_8192                  =   32
  147.         MEM_16384                 =   64
  148.         MEM_32768                 =   128
  149.  
  150.         ISA_MAX_ADDR              =   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
  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     ax , [eax+1]                            ; get the pci bus and device numbers
  235.   .nextdevice:
  236.         mov     ebx, [esi]
  237.         cmp     ax , word [device.pci_bus]              ; compare with pci and device num in device list (notice the usage of word instead of byte)
  238.         je      .find_devicenum                         ; Device is already loaded, let's find it's device number
  239.         add     esi, 4
  240.         loop    .nextdevice
  241.  
  242.   .firstdevice_pci:
  243.         call    create_new_struct
  244.  
  245.         mov     eax, [IOCTL.input]
  246.         mov     cl , [eax+1]
  247.         mov     [device.pci_bus], cl
  248.         mov     cl , [eax+2]
  249.         mov     [device.pci_dev], cl
  250.  
  251. ; Now, it's time to find the base io addres of the PCI device
  252.  
  253.         find_io [device.pci_bus], [device.pci_dev], [device.io_addr]
  254.  
  255. ; We've found the io address, find IRQ now
  256.  
  257.         find_irq [device.pci_bus], [device.pci_dev], [device.irq_line]
  258.  
  259.         jmp     .hook
  260.  
  261.   .isa:
  262.  
  263.         mov     esi, device_list
  264.         mov     ecx, [devices]
  265.         test    ecx, ecx
  266.         jz      .firstdevice_isa
  267.         mov     al , [eax+3]
  268.         movzx   edi, word [eax+1]
  269.   .nextdevice_isa:
  270.         mov     ebx, [esi]
  271.         cmp     edi, [device.io_addr]
  272.         jne     .maybenext
  273.         cmp     al , [device.irq_line]
  274.         je      find_device_num
  275.   .maybenext:
  276.         add     esi, 4
  277.         loop    .nextdevice_isa
  278.  
  279.  
  280.  
  281.   .firstdevice_isa:
  282.         call    create_new_struct
  283.  
  284.         mov     eax, [IOCTL.input]
  285.         movzx   ecx , word [eax+1]
  286.         mov     [device.io_addr], ecx
  287.         mov     cl, [eax+3]
  288.         mov     [device.irq_line], cl
  289.  
  290.   .hook:
  291.  
  292.         DEBUGF  2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
  293.         [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4
  294.  
  295.         call    probe                                                   ; this function will output in eax
  296.         test    eax, eax
  297.         jnz     .err                                                    ; If an error occured, exit
  298.  
  299.         mov     eax, [devices]
  300.         mov     [device_list+4*eax], ebx
  301.         inc     [devices]
  302.  
  303.         mov     [device.type], NET_TYPE_ETH
  304.         call    NetRegDev
  305.  
  306.         cmp     eax, -1
  307.         jz      .err
  308.         ret
  309.  
  310.  
  311. ; If the device was already loaded, find the device number and return it in eax
  312.  
  313.   .find_devicenum:
  314.         DEBUGF  1,"Trying to find device number of already registered device\n"
  315.         call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
  316.                                                                         ; into a device number in edi
  317.         mov     eax, edi                                                ; Application wants it in eax instead
  318.         DEBUGF  1,"Kernel says: %u\n", eax
  319.         ret
  320.  
  321.   .err:
  322.         DEBUGF  1,"Failed, removing device structure\n"
  323.         stdcall KernelFree, ebx
  324.  
  325.         jmp     .fail
  326.  
  327. ;------------------------------------------------------
  328.   @@:
  329. .fail:
  330.         or      eax, -1
  331.         ret
  332.  
  333. ;------------------------------------------------------
  334. endp
  335.  
  336.  
  337. create_new_struct:
  338.  
  339.         cmp     [devices], MAX_DEVICES
  340.         jge     .fail
  341.  
  342.         allocate_and_clear ebx, device.size, .fail      ; Allocate the buffer for device structure
  343.  
  344.         mov     [device.reset], reset
  345.         mov     [device.transmit], transmit
  346.         mov     [device.get_MAC], read_mac
  347.         mov     [device.set_MAC], write_mac
  348.         mov     [device.unload], unload
  349.         mov     [device.name], my_service
  350.  
  351.         ret
  352.  
  353.   .fail:
  354.         add     esp, 4          ; return to caller of 'hook'
  355.         or      eax, -1
  356.         ret
  357.  
  358. find_device_num:
  359.  
  360.         DEBUGF  1,"Trying to find device number of already registered device\n"
  361.         mov     ebx, eax
  362.         call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
  363.                                                                         ; into a device number in edi
  364.         mov     eax, edi                                                ; Application wants it in eax instead
  365.         DEBUGF  1,"Kernel says: %u\n", eax
  366.         ret
  367.  
  368.  
  369. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  370. ;;                                                                        ;;
  371. ;;        Actual Hardware dependent code starts here                      ;;
  372. ;;                                                                        ;;
  373. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  374.  
  375.  
  376. unload:   ; TODO
  377.         or      eax, -1
  378.         ret
  379.  
  380.  
  381.  
  382. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  383. ;;
  384. ;;  probe: enables the device and clears the rx buffer
  385. ;;
  386. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  387.  
  388. probe:
  389.         mov     [device.vendor], VENDOR_NONE
  390.         mov     [device.bmem], 0
  391.         mov     eax,[device.io_addr]
  392.         add     eax, NE_ASIC_OFFSET
  393.         mov     [device.asic_base], ax
  394.  
  395.         DEBUGF  2,"Trying 16-bit mode\n"
  396.  
  397.         or      [device.flags], FLAG_16BIT or FLAG_PIO
  398.         mov     [device.memsize], MEM_32768
  399.         mov     [device.tx_start], 64
  400.         mov     [device.rx_start], TXBUF_SIZE + 64
  401.  
  402.         set_io  0
  403.         set_io  P0_DCR
  404.         mov     al, DCR_WTS + DCR_FT1 + DCR_LS
  405.         out     dx, al
  406.  
  407.         set_io  P0_PSTART
  408.         mov     al, MEM_16384
  409.         out     dx, al
  410.  
  411.         set_io  P0_PSTOP
  412.         mov     al, MEM_32768
  413.         out     dx, al
  414.  
  415.         mov     esi, test_data
  416.         mov     di, 16384
  417.         mov     cx, 14
  418.         call    eth_pio_write
  419.  
  420.         mov     si, 16384
  421.         mov     cx, 14
  422.         lea     edi, [device.romdata]
  423.         call    eth_pio_read
  424.  
  425.         lea     esi, [device.romdata]
  426.         mov     edi, test_data
  427.         mov     ecx, 13
  428.  
  429.      repz    cmpsb
  430.      jz      ep_set_vendor
  431.  
  432.  
  433.         DEBUGF  2,"Trying 8-bit mode\n"
  434.  
  435.         mov     [device.flags], FLAG_PIO
  436.         mov     [device.memsize], MEM_16384
  437.         mov     [device.tx_start], 32
  438.         mov     [device.rx_start], TXBUF_SIZE + 32
  439.  
  440.         mov     dx, [device.asic_base]
  441.         add     dx, NE_RESET
  442.  
  443.         in      al, dx
  444.         out     dx, al
  445.  
  446.         in      al, 0x84
  447.  
  448.         set_io  0
  449.         mov     al, CMD_RD2 + CMD_STP
  450.         out     dx, al
  451.  
  452.         set_io  P0_RCR
  453.         mov     al, RCR_MON
  454.         out     dx, al
  455.  
  456.         set_io  P0_DCR
  457.         mov     al, DCR_FT1 + DCR_LS
  458.         out     dx, al
  459.  
  460.         set_io  P0_PSTART
  461.         mov     al, MEM_8192
  462.         out     dx, al
  463.  
  464.         set_io  P0_PSTOP
  465.         mov     al, MEM_16384
  466.         out     dx, al
  467.  
  468.         mov     esi, test_data
  469.         mov     di, 8192
  470.         mov     cx, 14
  471.         call    eth_pio_write
  472.  
  473.         mov     si, 8192
  474.         mov     cx, 14
  475.         lea     edi, [device.romdata]
  476.         call    eth_pio_read
  477.  
  478.         mov     esi, test_data
  479.         lea     edi, [device.romdata]
  480.         mov     ecx, 13
  481.  
  482.     repz      cmpsb
  483.     jz        ep_set_vendor
  484.  
  485.         DEBUGF  2,"This is not a valid ne2000 device!\n"
  486.         or      eax, -1
  487.         ret
  488.  
  489.  
  490. ep_set_vendor:
  491.  
  492.         cmp     [device.io_addr], ISA_MAX_ADDR
  493.         jbe     ep_001
  494.  
  495.         DEBUGF  2,"Card is using PCI bus\n"
  496.  
  497. ;        or      [flags], FLAG_16BIT
  498.  
  499. ep_001:
  500.         mov     [device.vendor], VENDOR_NOVELL
  501.  
  502. ep_check_have_vendor:
  503.  
  504.  
  505.         mov     al, [device.vendor]
  506.         cmp     al, VENDOR_NONE
  507. ;        je      rtl8029_exit
  508.  
  509.         cmp     al, VENDOR_3COM
  510.         je      reset
  511.  
  512.         mov     eax, [device.bmem]
  513.         mov     [device.rmem], eax
  514.  
  515.         call    read_mac
  516.  
  517.         push    .hack
  518.         sub     esp, 6
  519.         mov     edi, esp
  520.         lea     esi, [device.mac]
  521.         movsd
  522.         movsw
  523.         jmp     write_mac
  524.        .hack:
  525.  
  526.  
  527. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  528. ;;
  529. ;;   reset: Place the chip into a virgin state
  530. ;;
  531. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  532.  
  533. reset:
  534.         DEBUGF  2,"Resetting device\n"
  535.  
  536. ; attach int handler
  537.         movzx   eax, [device.irq_line]
  538.         DEBUGF  1,"Attaching int handler to irq %x\n",eax:1
  539.         stdcall AttachIntHandler, eax, int_handler, dword 0
  540.  
  541. ; Stop mode
  542.  
  543.         set_io  0
  544.         mov     al, CMD_PS0 + CMD_RD2 + CMD_STP
  545.         out     dx, al
  546.  
  547.         set_io  P0_DCR
  548.         test    [device.flags], FLAG_16BIT
  549.         jz      nsr_001
  550.  
  551.         mov     al, 0x49
  552.         jmp     nsr_002
  553.  
  554. nsr_001:
  555.         mov     al, 0x48
  556.  
  557. nsr_002:
  558.         out     dx, al
  559.  
  560. ; clear remote bytes count
  561.         set_io  0
  562.  
  563.         xor     al, al
  564.  
  565.         set_io  P0_RBCR0
  566.         out     dx, al
  567.  
  568.         set_io  P0_RBCR1
  569.         out     dx, al
  570.  
  571.  
  572. ; initialize Receive configuration register
  573.         set_io  P0_RCR
  574.         mov     al, 0x20        ; monitor mode
  575.         out     dx, al
  576.  
  577.  
  578. ; transmit configuration register
  579.         set_io  P0_TCR
  580.         mov     al, 2           ; internal loopback
  581.         out     dx, al
  582.  
  583.  
  584. ; transmit page stuff
  585.         set_io  P0_TPSR
  586.         mov     al, [device.tx_start]
  587.         out     dx, al
  588.  
  589. ; set receive control register ;;;;
  590.         set_io  P0_RCR
  591.         mov     al, 4           ; accept broadcast
  592.         out     dx, al
  593.  
  594. ; pagestart
  595.         set_io  P0_PSTART
  596.         mov     al, [device.rx_start]
  597.         out     dx, al
  598.  
  599. ; pagestop
  600.         set_io  P0_PSTOP
  601.         mov     al, [device.memsize]
  602.         out     dx, al
  603.  
  604. ; page boundary
  605.         set_io  P0_BOUND
  606.         mov     al, [device.memsize]
  607.         dec     al
  608.         out     dx, al
  609.  
  610.  
  611. ;;clear IRQ mask
  612. ;        set_io  P0_IMR
  613. ;        xor     al, al
  614. ;        out     dx, al
  615.  
  616.         set_io  0
  617.         mov     al, CMD_PS1 + CMD_RD2 + CMD_STP ; page 1, stop mode
  618.         out     dx, al
  619.  
  620.         set_io  P1_CURR
  621.         mov     al, [device.rx_start]
  622.         out     dx, al
  623.  
  624.         set_io  0
  625.         mov     al, CMD_PS0 + CMD_RD2 + CMD_STA ; go to page 0
  626.         out     dx, al
  627.  
  628. ; Read MAC address
  629.         call    read_mac
  630.  
  631. ; clear interupt status
  632.         set_io  0
  633.         set_io  P0_ISR
  634.         mov     al, 0xff
  635.         out     dx, al
  636.  
  637. ; set IRQ mask
  638.         set_io  P0_IMR
  639.         mov     al, IRQ_MASK
  640.         out     dx, al
  641.  
  642. ;; start mode
  643. ;        set_io  0
  644. ;        mov     al, CMD_STA
  645. ;        out     dx, al
  646.  
  647. ; clear transmit control register
  648.         set_io  P0_TCR
  649.         mov     al, 0           ; no loopback
  650.         out     dx, al
  651.  
  652. ; clear packet/byte counters
  653.         xor     eax, eax
  654.         lea     edi, [device.bytes_tx]
  655.         mov     ecx, 6
  656.         rep     stosd
  657.  
  658. ; Set the mtu, kernel will be able to send now
  659.         mov     [device.mtu], 1514
  660.  
  661. ; Indicate that we have successfully reset the card
  662.         xor     eax, eax
  663.         DEBUGF  2,"Done!\n"
  664.  
  665.         ret
  666.  
  667.  
  668.  
  669. ;***************************************************************************
  670. ;   Function
  671. ;      transmit
  672. ; buffer in [esp+4], size in [esp+8], pointer to device struct in ebx
  673. ;***************************************************************************
  674.  
  675. align 4
  676. transmit:
  677.  
  678.         mov     esi, [esp + 4]
  679.         mov     ecx, [esp + 8]
  680.         DEBUGF  2,"Transmitting packet, buffer:%x, size:%u\n",esi, ecx
  681.         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
  682.  
  683.         cmp     ecx, ETH_FRAME_LEN
  684.         jg      .err ; packet is too long
  685.         cmp     ecx, 60
  686.         jl      .err ; packet is too short
  687.  
  688.         movzx   edi, [device.tx_start]
  689.         shl     edi, 8
  690.         push    cx
  691.         call    eth_pio_write
  692.         pop     cx
  693.  
  694.         set_io  0
  695.         mov     al, CMD_PS0 + CMD_RD2 + CMD_STA
  696.         out     dx, al
  697.  
  698.         set_io  P0_TPSR
  699.         mov     al, [device.tx_start]
  700.         out     dx, al
  701.  
  702.         set_io  P0_TBCR0
  703.         mov     al, cl
  704.         out     dx, al
  705.  
  706.         set_io  P0_TBCR1
  707.         mov     al, ch
  708.         out     dx, al
  709.  
  710.         set_io  0
  711.         mov     al, CMD_PS0 + CMD_TXP + CMD_RD2 + CMD_STA
  712.         out     dx, al
  713.  
  714.         DEBUGF  2," - Packet Sent!\n"
  715.  
  716.         inc     [device.packets_tx]
  717.         mov     eax, [esp + 8]                   ; Get packet size in eax
  718.  
  719.         add     dword [device.bytes_tx], eax
  720.         adc     dword [device.bytes_tx + 4], 0
  721.  
  722.         stdcall KernelFree, [esp+4]
  723.         xor     eax, eax
  724.         ret     8
  725.  
  726. .err:
  727.         or      eax, -1
  728.         stdcall KernelFree, [esp+4]
  729.         ret     8
  730.  
  731.  
  732.  
  733. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  734. ;
  735. ; Interrupt handler
  736. ;
  737. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  738.  
  739. align 4
  740. int_handler:
  741.  
  742.         DEBUGF  1,"\n%s int\n", my_service
  743.  
  744. ; find pointer of device wich made INT occur
  745.  
  746.         mov     ecx, [devices]
  747.         test    ecx, ecx
  748.         jz      .nothing
  749.         mov     esi, device_list
  750.   .nextdevice:
  751.         mov     ebx, [esi]
  752.  
  753.         set_io  0
  754.         set_io  P0_ISR
  755.         in      al, dx
  756.         test    al, al
  757.         jnz     .got_it
  758.   .continue:
  759.         add     esi, 4
  760.         dec     ecx
  761.         jnz     .nextdevice
  762.   .nothing:
  763.         ret
  764.  
  765.   .got_it:
  766.  
  767.         DEBUGF  1,"Device: %x Status: %x ", ebx, eax:2
  768.  
  769.         test    al, ISR_PRX    ; packet received ok ?
  770.         jz      .no_rx
  771.  
  772. ; looks like we've found a device wich received a packet..
  773.  
  774.         stdcall KernelAlloc, ETH_FRAME_LEN  ; size doesnt really matter as packet size is smaller then kernel's page size
  775.         test    eax, eax
  776.         jz      .fail_2
  777.  
  778. ;--------------------------------------
  779. ; allocate memory for temp variables in stack
  780.  
  781.         sub     esp, 14+8
  782.  
  783.         eth_type        equ esp
  784.         pkthdr          equ esp + 2
  785.         pktoff          equ esp + 6
  786.         eth_rx_data_ptr equ esp + 8
  787.         eth_tmp_len     equ esp + 12
  788.  
  789. ; These will be used by eth_receiver when the packet gets there
  790.  
  791.         pointer         equ esp + 14
  792.         size            equ esp + 18
  793.  
  794. ;-------------------------------------
  795.  
  796.         mov     [pointer], eax
  797.         mov     [eth_rx_data_ptr], eax
  798.  
  799.         set_io  P0_BOUND
  800.         in      al, dx
  801.         inc     al
  802.  
  803.         cmp     al, [device.memsize]
  804.         jb      .nsp_001
  805.  
  806.         mov     al, [device.rx_start]
  807.  
  808. .nsp_001:
  809.         mov     ch, al
  810.  
  811.         set_io  0
  812.         mov     al, CMD_PS1
  813.         out     dx, al
  814.  
  815.         set_io  P1_CURR
  816.         in      al, dx               ; get current page
  817.         mov     cl, al
  818.  
  819.         set_io  0
  820.         mov     al, CMD_PS0
  821.         out     dx, al
  822.  
  823.         cmp     cl, [device.memsize]
  824.         jb      .nsp_002
  825.  
  826.         mov     cl, [device.rx_start]
  827.  
  828. .nsp_002:
  829.         cmp     cl, ch
  830.         je      .fail
  831.  
  832.         xor     ax, ax
  833.         mov     ah, ch
  834.  
  835.         mov     [pktoff], ax
  836.  
  837.         mov     al, [device.flags]
  838.         test    al, FLAG_PIO
  839.         jz      .nsp_003
  840.  
  841.         mov     si, word [pktoff]
  842.         lea     edi, [pkthdr]
  843.         mov     cx, 4
  844.         call    eth_pio_read
  845.         jmp     .nsp_004
  846.  
  847. .nsp_003:
  848.         mov     edi, [device.rmem]
  849.         movzx   eax, word [pktoff]
  850.         add     edi, eax
  851.         mov     eax, [edi]
  852.         mov     [pkthdr], eax
  853.  
  854. .nsp_004:
  855.         add     word[pktoff] , 4
  856.  
  857.         xor     eax, eax
  858.         mov     ax , [pkthdr + 2]
  859.         sub     ax , 4
  860.  
  861.         DEBUGF  2,"Received %u bytes\n",eax
  862.  
  863.         add     dword [device.bytes_rx], eax  ; Update stats
  864.         adc     dword [device.bytes_rx + 4], 0
  865.         inc     dword [device.packets_rx]     ;
  866.  
  867.         mov     [eth_tmp_len], ax
  868.         mov     dword[size], eax
  869.  
  870.         cmp     ax, ETH_ZLEN
  871.         jb      .fail
  872.  
  873.         cmp     ax , ETH_FRAME_LEN
  874.         ja      .fail
  875.  
  876.         mov     al , [pkthdr]
  877.         test    al , RSTAT_PRX
  878.         jz      .fail
  879.  
  880.    ; Right, we can now get the data
  881.  
  882.         movzx   esi, [device.memsize]
  883.         sub     si , [pktoff]
  884.  
  885.         cmp     [eth_tmp_len], si
  886.         jbe     .nsp_005
  887.  
  888.         DEBUGF  2,"WRAP!\n"
  889.  
  890.         mov     al , [device.flags]
  891.         test    al , FLAG_PIO
  892.         jz      .nsp_006
  893.  
  894.         push    esi
  895.         mov     cx , si
  896.         mov     si , [pktoff+4]
  897.         mov     edi, [eth_rx_data_ptr+4]
  898.         call    eth_pio_read
  899.         pop     esi
  900.         jmp     .nsp_007
  901.  
  902. .nsp_006:
  903.         DEBUGF  2,"PIO mode not supported by HW!\n"
  904.    ; Not implemented, as we are using PIO mode on this card
  905.  
  906. .nsp_007:
  907.         xor     al, al
  908.         mov     ah, [device.rx_start]
  909.         mov     [pktoff], ax
  910.  
  911.         add     [eth_rx_data_ptr], esi
  912.         sub     [eth_tmp_len], si
  913.  
  914. .nsp_005:
  915.         test    [device.flags], FLAG_PIO
  916.         jz      .nsp_008
  917.  
  918.         movzx   esi, word [pktoff]
  919.         movzx   ecx, word [eth_tmp_len]
  920.         mov     edi, [eth_rx_data_ptr]
  921.         call    eth_pio_read
  922.         jmp     .nsp_009
  923.  
  924. .nsp_008:
  925.         DEBUGF  2,"PIO mode not supported by HW!\n"
  926.    ; Not implemented, as we are using PIO mode on this card
  927.  
  928. .nsp_009:
  929.         mov     al, [pkthdr+1]
  930.         cmp     al, [device.rx_start]
  931.         jne     .nsp_010
  932.  
  933.         mov     al, [device.memsize]
  934.  
  935. .nsp_010:
  936.         set_io  0
  937.         set_io  P0_BOUND
  938.         dec     al
  939.         out     dx, al
  940.  
  941.         add     esp, 14
  942.         jmp     Eth_input
  943.  
  944. .fail:
  945.         add     esp, 14+8
  946. .fail_2:
  947.         DEBUGF  2,"done\n"
  948.  
  949.   .no_rx:
  950.  
  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.