Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2008. All rights reserved.    ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;; I8255x (Intel eepro 100) driver for KolibriOS                   ;;
  7. ;;                                                                 ;;
  8. ;;    Written by hidnplayr@kolibrios.org                           ;;
  9. ;;                                                                 ;;
  10. ;;    v0.0 - march 2009                                            ;;
  11. ;;                                                                 ;;
  12. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  13. ;;             Version 2, June 1991                                ;;
  14. ;;                                                                 ;;
  15. ;; current status (september 2009) - INCOMPLETE                    ;;
  16. ;;                                                                 ;;
  17. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  18.  
  19. format MS COFF
  20.  
  21.         API_VERSION             equ 0x01000100
  22.  
  23.         DEBUG                   equ 1
  24.         __DEBUG__               equ 1
  25.         __DEBUG_LEVEL__         equ 1
  26.  
  27. include 'proc32.inc'
  28. include 'imports.inc'
  29. include 'fdo.inc'
  30.  
  31. OS_BASE         equ 0;
  32. new_app_base    equ 0x60400000
  33. PROC_BASE       equ OS_BASE+0x0080000
  34.  
  35. public START
  36. public service_proc
  37. public version
  38.  
  39. struc IOCTL {
  40.       .handle           dd ?
  41.       .io_code          dd ?
  42.       .input            dd ?
  43.       .inp_size         dd ?
  44.       .output           dd ?
  45.       .out_size         dd ?
  46. }
  47.  
  48. virtual at 0
  49.   IOCTL IOCTL
  50. end virtual
  51.  
  52. struc ETH_DEVICE {
  53. ; pointers to procedures
  54.       .unload           dd ?
  55.       .reset            dd ?
  56.       .transmit         dd ?
  57.       .set_MAC          dd ?
  58.       .get_MAC          dd ?
  59.       .set_mode         dd ?
  60.       .get_mode         dd ?
  61. ; status
  62.       .bytes_tx         dd ?
  63.       .bytes_rx         dd ?
  64.       .packets_tx       dd ?
  65.       .packets_rx       dd ?
  66.       .mode             dd ?  ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..)
  67.       .name             dd ?
  68. ; device specific
  69.       .io_addr          dd ?
  70.       .pci_bus          db ?
  71.       .pci_dev          db ?
  72.       .irq_line         db ?
  73.       .status           dw ? ;
  74.       .command          dw ? ;
  75.       .link             dd ? ;
  76.       .rx_buf_addr      dd ? ;
  77.       .count            dw ? ;
  78.       .size             dw ? ;
  79.       .packet           dd ? ;
  80.       .eeprom_data      rd 16
  81.  
  82.         .txfd:
  83.         .txfd_status             dw  ?
  84.         .txfd_command            dw  ?
  85.         .txfd_link               dd  ?
  86.         .txfd_tx_desc_addr       dd  ?
  87.         .txfd_count              dd  ?
  88.         .txfd_tx_buf_addr0       dd  ?
  89.         .txfd_tx_buf_size0       dd  ?
  90.         .txfd_tx_buf_addr1       dd  ?
  91.         .txfd_tx_buf_size1       dd  ?
  92.  
  93.       .size_:
  94.  
  95. }
  96.  
  97. virtual at 0
  98.   device ETH_DEVICE
  99. end virtual
  100.  
  101.  
  102. lstats:
  103. tx_good_frames:         dd 0
  104. tx_coll16_errs:         dd 0
  105. tx_late_colls:          dd 0
  106. tx_underruns:           dd 0
  107. tx_lost_carrier:        dd 0
  108. tx_deferred:            dd 0
  109. tx_one_colls:           dd 0
  110. tx_multi_colls:         dd 0
  111. tx_total_colls:         dd 0
  112.  
  113. rx_good_frames:         dd 0
  114. rx_crc_errs:            dd 0
  115. rx_align_errs:          dd 0
  116. rx_resource_errs:       dd 0
  117. rx_overrun_errs:        dd 0
  118. rx_colls_errs:          dd 0
  119. rx_runt_errs:           dd 0
  120.  
  121. done_marker:            dd 0
  122.  
  123.  
  124. confcmd:
  125.         .status:         dw  0
  126.         .command:        dw  0
  127.         .link:           dd  0
  128.  
  129. confcmd_data:           db  22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1
  130.                         db  0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2
  131.                         db  0x80, 0x3f, 0x05
  132.  
  133.  
  134.         MAX_I8255x              equ 16   ; Max number of devices this driver may handle
  135.  
  136.  
  137. ; PCI Bus defines
  138.  
  139.         PCI_HEADER_TYPE                 equ     0x0e  ;8 bit
  140.         PCI_BASE_ADDRESS_0              equ     0x10  ;32 bit
  141.         PCI_BASE_ADDRESS_5              equ     0x24  ;32 bits
  142.         PCI_BASE_ADDRESS_SPACE_IO       equ     0x01
  143.         PCI_VENDOR_ID                   equ     0x00  ;16 bit
  144.         PCI_BASE_ADDRESS_IO_MASK        equ     0xFFFFFFFC
  145.  
  146.  
  147.  
  148. ;/***********************************************************************/
  149. ;/*                       I82557 related defines                        */
  150. ;/***********************************************************************/
  151.  
  152. ; Serial EEPROM section.
  153. ;   A "bit" grungy, but we work our way through bit-by-bit :->.
  154. ;  EEPROM_Ctrl bits.
  155. EE_SHIFT_CLK   equ   0x01    ; EEPROM shift clock.
  156. EE_CS          equ   0x02    ; EEPROM chip select.
  157. EE_DATA_WRITE  equ   0x04    ; EEPROM chip data in.
  158. EE_DATA_READ   equ   0x08    ; EEPROM chip data out.
  159. EE_WRITE_0     equ   0x4802
  160. EE_WRITE_1     equ   0x4806
  161. EE_ENB         equ   0x4802
  162.  
  163.  
  164. ; The EEPROM commands include the alway-set leading bit.
  165. EE_READ_CMD    equ   6
  166.  
  167. ; The SCB accepts the following controls for the Tx and Rx units:
  168. CU_START       equ   0x0010
  169. CU_RESUME      equ   0x0020
  170. CU_STATSADDR   equ   0x0040
  171. CU_SHOWSTATS   equ   0x0050   ; Dump statistics counters.
  172. CU_CMD_BASE    equ   0x0060   ; Base address to add to add CU commands.
  173. CU_DUMPSTATS   equ   0x0070   ; Dump then reset stats counters.
  174.  
  175. RX_START       equ   0x0001
  176. RX_RESUME      equ   0x0002
  177. RX_ABORT       equ   0x0004
  178. RX_ADDR_LOAD   equ   0x0006
  179. RX_RESUMENR    equ   0x0007
  180. INT_MASK       equ   0x0100
  181. DRVR_INT       equ   0x0200   ; Driver generated interrupt.
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188. section '.flat' code readable align 16
  189.  
  190. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  191. ;;                        ;;
  192. ;; proc START             ;;
  193. ;;                        ;;
  194. ;; (standard driver proc) ;;
  195. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  196.  
  197. proc START stdcall, state:dword
  198.  
  199.         cmp [state], 1
  200.         jne .exit
  201.  
  202.   .entry:
  203.  
  204.         DEBUGF 1,"Loading I8255x driver\n"
  205.         stdcall RegService, my_service, service_proc
  206.         ret
  207.  
  208.   .fail:
  209.   .exit:
  210.         xor eax, eax
  211.         ret
  212.  
  213. endp
  214.  
  215.  
  216. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  217. ;;                        ;;
  218. ;; proc SERVICE_PROC      ;;
  219. ;;                        ;;
  220. ;; (standard driver proc) ;;
  221. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  222.  
  223. align 4
  224. proc service_proc stdcall, ioctl:dword
  225.  
  226.         mov     edx, [ioctl]
  227.         mov     eax, [ebx+IOCTL.io_code]
  228.  
  229. ;------------------------------------------------------
  230.  
  231.         cmp     eax, 0 ;SRV_GETVERSION
  232.         jne     @F
  233.  
  234.         cmp     [edx+IOCTL.out_size], 4
  235.         jl      .fail
  236.         mov     eax, [edx+IOCTL.output]
  237.         mov     [eax], dword API_VERSION
  238.  
  239.         xor     eax, eax
  240.         ret
  241.  
  242. ;------------------------------------------------------
  243.   @@:
  244.         cmp     eax, 1 ;SRV_HOOK
  245.         jne     .fail
  246.  
  247.         mov     eax, [esp]
  248.         DEBUGF 1,"esp=%x [esp]=%x\n",esp,eax
  249.  
  250.         cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
  251.         jl      .fail
  252.  
  253.         mov     eax, [edx + IOCTL.input]
  254.         cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
  255.         jne     .fail                                   ; other types arent supported for this card yet
  256.  
  257. ; check if the device is already listed
  258.  
  259.         mov     esi, I8255x_LIST
  260.         mov     ecx, [I8255x_DEV]
  261.         test    ecx, ecx
  262.         jz      .firstdevice
  263.         mov     eax, [edx+IOCTL.input]                  ; get the pci bus and device numbers
  264.         mov     bx , [eax+1]                            ;
  265.   .nextdevice:
  266.         DEBUGF 1,"1"
  267.         lodsd
  268.         cmp     bx , word [eax + device.pci_bus]        ; compare with pci and device num in RTL8139 list (notice the usage of word instead of byte)
  269.         je      .find_devicenum                         ; Device is already loaded, let's find it's device number
  270.  
  271.         loop    .nextdevice
  272.  
  273. ; This device doesnt have its own eth_device structure yet, lets create one
  274.   .firstdevice:
  275.         cmp     [I8255x_DEV], MAX_I8255x                ; First check if the driver can handle one more card
  276.         jge     .fail
  277.  
  278.         push    edx
  279.         stdcall KernelAlloc, device.size                ; Allocate the buffer for eth_device structure
  280.         pop     edx
  281.         test    eax, eax
  282.         jz      .fail
  283.         mov     ebx, eax                                ; ebx is always used as a pointer to the structure (in driver, but also in kernel code)
  284.  
  285. ; Fill in the direct call addresses into the struct
  286.  
  287.         mov     dword [ebx+device.reset], reset
  288.         mov     dword [ebx+device.transmit], transmit
  289. ;        mov     dword [ebx+device.get_MAC], read_mac
  290. ;        mov     dword [ebx+device.set_MAC], write_mac
  291.         mov     dword [ebx+device.unload], unload
  292.         mov     dword [ebx+device.name], devicename
  293.  
  294. ; save the pci bus and device numbers
  295.  
  296.         mov     eax, [edx+IOCTL.input]
  297.         mov     cl , [eax+1]
  298.         mov     [ebx+device.pci_bus], cl
  299.         mov     cl , [eax+2]
  300.         mov     [ebx+device.pci_dev], cl
  301.  
  302. ; Now, it's time to find the base io addres of the PCI device
  303. ; TODO: implement check if bus and dev exist on this machine
  304.  
  305.         mov     edx, PCI_BASE_ADDRESS_0
  306.   .reg_check:
  307.         movzx   eax, byte [ebx+device.pci_bus]
  308.         movzx   ecx, byte [ebx+device.pci_dev]
  309.  
  310.         push    edx ecx
  311.         stdcall PciRead16, eax ,ecx ,edx
  312.         pop     ecx edx
  313.  
  314.         mov     [ebx+device.io_addr], eax
  315.         and     eax, PCI_BASE_ADDRESS_IO_MASK
  316.         test    eax, eax
  317.         jz      .inc_reg
  318.         mov     eax, [ebx+device.io_addr]
  319.         and     eax, PCI_BASE_ADDRESS_SPACE_IO
  320.         test    eax, eax
  321.         jz      .inc_reg
  322.  
  323.         mov     eax, [ebx+device.io_addr]
  324.         and     eax, PCI_BASE_ADDRESS_IO_MASK
  325.         mov     [ebx+device.io_addr], eax
  326.         jmp     .got_io
  327.  
  328.   .inc_reg:
  329.         add     edx, 4
  330.         cmp     edx, PCI_BASE_ADDRESS_5
  331.         jbe     .reg_check
  332.  
  333.   .got_io:
  334.  
  335. ; We've found the io address, find IRQ now
  336.  
  337.         movzx   eax, byte [ebx+device.pci_bus]
  338.         movzx   ecx, byte [ebx+device.pci_dev]
  339.         push    ebx
  340.         stdcall PciRead8, eax ,ecx ,0x3c                                ; 0x3c is the offset where irq can be found
  341.         pop     ebx
  342.         mov     byte [ebx+device.irq_line], al
  343.  
  344.         DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
  345.         [ebx+device.pci_dev]:1,[ebx+device.pci_bus]:1,[ebx+device.irq_line]:1,[ebx+device.io_addr]:4
  346.  
  347. ; Allocate the Receive buffer
  348.  
  349.         stdcall KernelAlloc, dword (RX_BUFFER_SIZE+MAX_ETH_FRAME_SIZE)
  350.         test    eax, eax
  351.         jz      .err
  352.         mov     [ebx+device.rx_buffer], eax                             ; Save the address to it into the device struct
  353.  
  354. ; Now, Clear the allocated buffer
  355.  
  356.         cld
  357.         mov     edi, eax
  358.         mov     ecx, (RX_BUFFER_SIZE)/4                                 ; divide by 4 because we are going to use DWORD
  359.         xor     eax, eax
  360.         rep     stosd
  361.  
  362. ; Allocate the Transmit Buffer
  363.  
  364.         stdcall KernelAlloc, dword (TX_BUFFER_SIZE)
  365.         test    eax, eax
  366.         jz      .err
  367.         mov     [ebx+device.tx_buffer], eax
  368.  
  369. ; This one needs to be cleared too..
  370.  
  371.         mov     edi, eax
  372.         mov     ecx, (TX_BUFFER_SIZE)/4
  373.         xor     eax, eax
  374.         rep     stosd
  375.  
  376. ; Ok, the eth_device structure is ready, let's probe the device
  377.  
  378.         call    probe                                                   ; this function will output in eax
  379.         test    eax, eax
  380.         jnz     .err                                                    ; If an error occured, exit
  381.  
  382.         mov     eax, [I8255x_DEV]                                       ; Add the device structure to our device list
  383.         mov     [I8255x_LIST+4*eax], ebx                                ; (IRQ handler uses this list to find device)
  384.         inc     [I8255x_DEV]                                            ;
  385.  
  386.         jmp     EthRegDev                                               ; Register the device to kernel (ebx points to device struct)
  387.                                                                         ; Notice the jump instead of call, it is the same as
  388.                                                                         ;
  389.                                                                         ; call EthRegDev
  390.                                                                         ; ret
  391.                                                                         ;
  392.                                                                         ; Also notice that the value EthRegDev returned in eax, will be returned to
  393.                                                                         ; the caller application
  394.  
  395. ; If the device was already loaded, find the device number and return it in eax
  396.  
  397.   .find_devicenum:
  398.         DEBUGF  1,"Trying to find device number of already registered device\n"
  399.         mov     ebx, eax
  400.         call    EthStruc2Dev                                            ; This kernel procedure converts a pointer to device struct in ebx
  401.                                                                         ; into a device number in edi
  402.         mov     eax, edi                                                ; Application wants it in eax instead
  403.         DEBUGF  1,"Kernel says: %u\n", eax
  404.         ret
  405.  
  406. ; If an error occured, remove all allocated data and exit (returning -1 in eax)
  407.  
  408.   .err:
  409.         stdcall KernelFree, dword [ebx+device.rx_buffer]
  410.         stdcall KernelFree, dword [ebx+device.tx_buffer]
  411.         stdcall KernelFree, ebx
  412.  
  413.   .fail:
  414.         or      eax, -1
  415.         ret
  416.  
  417. ;------------------------------------------------------
  418. endp
  419.  
  420.  
  421. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  422. ;;                                                                        ;;
  423. ;;        Actual Hardware dependent code starts here                      ;;
  424. ;;                                                                        ;;
  425. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  426.  
  427.  
  428. unload:
  429.         ; TODO: (in this particular order)
  430.         ;
  431.         ; - Stop the device
  432.         ; - Detach int handler
  433.         ; - Remove device from local list (RTL8139_LIST)
  434.         ; - call unregister function in kernel
  435.         ; - Remove all allocated structures and buffers the card used
  436.  
  437.         or      eax,-1
  438.  
  439. ret
  440.  
  441. ;***************************************************************************
  442. ;   Function
  443. ;      I8255x_probe
  444. ;   Description
  445. ;      Searches for an ethernet card, enables it and clears the rx buffer
  446. ;      If a card was found, it enables the ethernet -> TCPIP link
  447. ;
  448. ;***************************************************************************
  449.  
  450. probe:
  451.  
  452.         DEBUGF 1," Probing i8255x device: "
  453.  
  454. ; enable the device
  455.  
  456.         movzx   eax, byte [ebx+device.pci_bus]
  457.         movzx   ecx, byte [ebx+device.pci_dev]
  458.         stdcall PciRead16, eax ,ecx ,PCI_REG_CMD
  459.  
  460.         mov     cx , ax
  461.         or      cx , 0x05
  462.         movzx   eax, byte [ebx+device.pci_bus]
  463.         movzx   edx, byte [ebx+device.pci_dev]
  464.         stdcall PciWrite16, eax ,edx ,PCI_REG_CMD, ecx
  465.  
  466. ; do something else TODO
  467.  
  468.         mov     ebx, 0x6000000
  469.         mov     ecx, 27
  470.         call    do_eeprom_cmd
  471.         and     eax, 0xffe0000
  472.         cmp     eax, 0xffe0000
  473.         je      bige
  474.  
  475.         mov     ebx, 0x1800000
  476.         mov     ecx, 0x40
  477.         jmp     doread
  478.  
  479. bige:
  480.         mov     ebx, 0x6000000
  481.         mov     ecx, 0x100
  482.  
  483. doread:
  484.  
  485.         ; do-eeprom-cmd will destroy all registers
  486.         ; we have eesize in ecx
  487.         ; read_cmd in ebx
  488.  
  489.         ; Ignore full eeprom - just load the mac address
  490.         mov     ecx, 0
  491.  
  492. drlp:
  493.  
  494.  
  495.         push    ecx      ; save count
  496.         push    ebx
  497.         mov     eax, ecx
  498.         shl     eax, 16
  499.         or      ebx, eax
  500.         mov     ecx, 27
  501.         call    do_eeprom_cmd
  502.  
  503.         pop     ebx
  504.         pop     ecx
  505.  
  506.         mov     edx, ecx
  507.         shl     edx, 2
  508.         mov     esi, eeprom_data
  509.         add     esi, edx
  510.         mov     [esi], eax
  511.  
  512.         inc     ecx
  513.         cmp     ecx, 16
  514.         jne     drlp
  515.  
  516.         ; OK, we have the MAC address.
  517.  
  518. ;***************************************************************************
  519. ;   Function
  520. ;      I8255x_reset
  521. ;   Description
  522. ;      Place the chip (ie, the ethernet card) into a virgin state
  523. ;      No inputs
  524. ;      All registers destroyed
  525. ;
  526. ;***************************************************************************
  527.  
  528. reset:
  529.  
  530.         ; Now reset the card
  531.  
  532.         mov     edx, [ebx+device.io_addr]
  533.         add     dx, 8         ; SCBPort
  534.         xor     eax, eax      ; The reset cmd == 0
  535.         out     dx, eax
  536.  
  537.         mov     esi, 10
  538.         call    delay_ms      ; Give the card time to warm up.
  539.  
  540.         mov     eax, lstats
  541.         mov     edx, [ebx+device.io_addr]
  542.         add     edx, 4            ; SCBPointer
  543.         out     dx, eax
  544.  
  545.         mov     eax, 0x0140         ; INT_MASK | CU_STATSADDR
  546.         mov     edx, [ebx+device.io_addr]
  547.         add     edx, 2            ; SCBCmd
  548.         out     dx, ax
  549.  
  550.         call    wait_for_cmd_done
  551.  
  552.         mov     eax, 0
  553.         mov     edx, [ebx+device.io_addr]
  554.         add     edx, 4            ; SCBPointer
  555.         out     dx, eax
  556.  
  557.         mov     eax, 0x0106         ; INT_MASK | RX_ADDR_LOAD
  558.         mov     edx, [ebx+device.io_addr]
  559.         add     edx, 2            ; SCBCmd
  560.         out     dx, ax
  561.  
  562.         call    wait_for_cmd_done
  563.    ; build rxrd structure
  564.         mov     ax, 0x0001
  565.         mov     [ebx+device.status], ax
  566.         mov     ax, 0x0000
  567.         mov     [rxfd_command], ax
  568.  
  569.         mov     eax, rxfd_status
  570.         sub     eax, OS_BASE
  571.         mov     [ebx+device.link], eax
  572.  
  573.         mov     eax, Ether_buffer
  574.         sub     eax, OS_BASE
  575.         mov     [ebx+device.rx_buf_addr], eax
  576.  
  577.         mov     ax, 0
  578.         mov     [ebx+device.count], ax
  579.  
  580.         mov     ax, 1528
  581.         mov     [ebx+device.size], ax
  582.  
  583.         mov     edx, [ebx+device.io_addr]
  584.         add     edx, 4           ; SCBPointer
  585.  
  586.         mov     eax, rxfd_status
  587.         sub     eax, OS_BASE
  588.         out     dx, eax
  589.  
  590.         mov     edx, [ebx+device.io_addr]
  591.         add     edx, 2           ; SCBCmd
  592.  
  593.         mov     ax, 0x0101         ; INT_MASK | RX_START
  594.         out     dx, ax
  595.  
  596.         call    wait_for_cmd_done
  597.  
  598.    ; start the receiver
  599.  
  600.         mov     ax, 0
  601.         mov     [ebx+device.status], ax
  602.  
  603.         mov     ax, 0xc000
  604.         mov     [ebx+device.command], ax
  605.  
  606.         mov     edx, [ebx+device.io_addr]
  607.         add     edx, 4           ; SCBPointer
  608.  
  609.         mov     eax, rxfd_status
  610.         sub     eax, OS_BASE
  611.         out     dx, eax
  612.  
  613.         mov     edx, [ebx+device.io_addr]
  614.         add     edx, 2           ; SCBCmd
  615.  
  616.         mov     ax, 0x0101         ; INT_MASK | RX_START
  617.         out     dx, ax
  618.  
  619.    ; Init TX Stuff
  620.  
  621.         mov     edx, [ebx+device.io_addr]
  622.         add     edx, 4           ; SCBPointer
  623.  
  624.         mov     eax, 0
  625.         out     dx, eax
  626.  
  627.         mov     edx, [ebx+device.io_addr]
  628.         add     edx, 2           ; SCBCmd
  629.  
  630.         mov     ax, 0x0160         ; INT_MASK | CU_CMD_BASE
  631.         out     dx, ax
  632.  
  633.         call    wait_for_cmd_done
  634.  
  635.    ; Set TX Base address
  636.  
  637.    ; First, set up confcmd values
  638.  
  639.         mov     ax, 2
  640.         mov     [confcmd_command], ax
  641.         mov     eax, txfd
  642.         sub     eax, OS_BASE
  643.         mov     [confcmd_link], eax
  644.  
  645.         mov     ax, 1
  646.         mov     [txfd_command], ax         ; CmdIASetup
  647.  
  648.         mov     ax, 0
  649.         mov     [txfd_status], ax
  650.  
  651.         mov     eax, confcmd
  652.         sub     eax, OS_BASE
  653.         mov     [txfd_link], eax
  654.  
  655.  
  656.  
  657.    ; ETH_ALEN is 6 bytes
  658.  
  659.         mov     esi, eeprom_data
  660.         mov     edi, node_addr
  661.         mov     ecx, 3
  662.  
  663. drp000:
  664.  
  665.         mov     eax, [esi]
  666.         mov     [edi], al
  667.         shr     eax, 8
  668.         inc     edi
  669.         mov     [edi], al
  670.         inc     edi
  671.         add     esi, 4
  672.         loop    drp000
  673.  
  674.    ; Hard code your MAC address into node_addr at this point,
  675.    ; If you cannot read the MAC address from the eeprom in the previous step.
  676.    ; You also have to write the mac address into txfd_tx_desc_addr, rather
  677.    ; than taking data from eeprom_data
  678.  
  679.         mov     esi, eeprom_data
  680.         mov     edi, txfd_tx_desc_addr
  681.         mov     ecx, 3
  682.  
  683. drp001:
  684.  
  685.         mov     eax, [esi]
  686.         mov     [edi], al
  687.         shr     eax, 8
  688.         inc     edi
  689.         mov     [edi], al
  690.         inc     edi
  691.         add     esi, 4
  692.         loop    drp001
  693.  
  694.         mov     esi, eeprom_data + (6 * 4)
  695.         mov     eax, [esi]
  696.         shr     eax, 8
  697.         and     eax, 0x3f
  698.         cmp     eax, 4            ; DP83840
  699.         je      drp002
  700.         cmp     eax, 10            ; DP83840A
  701.         je      drp002
  702.         jmp     drp003
  703.  
  704. drp002:
  705.  
  706.         mov     ebx, [esi]
  707.         and     ebx, 0x1f
  708.         push    ebx
  709.         mov     ecx, 23
  710.         call    mdio_read
  711.         pop     ebx
  712.         or      eax, 0x0422
  713.         mov     ecx, 23
  714.         mov     edx, eax
  715.         call    mdio_write
  716.  
  717. drp003:
  718.  
  719.         mov     ax, 0x4002         ; Cmdsuspend | CmdConfigure
  720.         mov     [confcmd_command], ax
  721.         mov     ax, 0
  722.         mov     [confcmd_status], ax
  723.         mov     eax, txfd
  724.         mov     [confcmd_link], eax
  725.         mov     ebx, confcmd_data
  726.         mov     al, 0x88         ; fifo of 8 each
  727.         mov     [ebx + 1], al
  728.         mov     al, 0
  729.         mov     [ebx + 4], al
  730.         mov     al, 0x80
  731.         mov     [ebx + 5], al
  732.         mov     al, 0x48
  733.         mov     [ebx + 15], al
  734.         mov     al, 0x80
  735.         mov     [ebx + 19], al
  736.         mov     al, 0x05
  737.         mov     [ebx + 21], al
  738.  
  739.         mov     eax, txfd
  740.         sub     eax, OS_BASE
  741.         mov     edx, [ebx+device.io_addr]
  742.         add     edx, 4            ; SCBPointer
  743.         out     dx, eax
  744.  
  745.         mov     eax, 0x0110         ; INT_MASK | CU_START
  746.         mov     edx, [ebx+device.io_addr]
  747.         add     edx, 2            ; SCBCmd
  748.         out     dx, ax
  749.  
  750.         call    wait_for_cmd_done
  751.  
  752. jmp skip
  753.  
  754.    ; wait for thing to start
  755. drp004:
  756.  
  757.         mov     ax, [txfd_status]
  758.         test    ax, ax
  759.         jz      drp004
  760.  
  761. skip:
  762.    ; Indicate that we have successfully reset the card
  763.  
  764.         xor     eax, eax
  765.  
  766.         ret
  767.  
  768.  
  769. ;***************************************************************************
  770. ;   Function
  771. ;      I8255x_transmit
  772. ;
  773. ;   Description
  774. ;       Transmits a packet of data via the ethernet card
  775. ;          Pointer to 48 bit destination address in edi
  776. ;         Type of packet in bx
  777. ;         size of packet in ecx
  778. ;         pointer to packet data in esi
  779. ;
  780. ;***************************************************************************
  781.  
  782. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  783. ;;                                         ;;
  784. ;; Transmit                                ;;
  785. ;;                                         ;;
  786. ;; In: buffer pointer in [esp]             ;;
  787. ;;     size of buffer in [esp+4]           ;;
  788. ;;     pointer to device structure in ebx  ;;
  789. ;;                                         ;;
  790. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  791.  
  792. align 4
  793. transmit:
  794.  
  795.         DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n",[esp],[esp+4]
  796.         mov     eax, [esp]
  797.         DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
  798.         [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
  799.         [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
  800.         [eax+13]:2,[eax+12]:2
  801.  
  802.         cmp     dword [esp+4], MAX_ETH_FRAME_SIZE
  803.         jg      .finish                         ; packet is too long
  804.         cmp     dword [esp+4], 60
  805.         jl      .finish                         ; packet is too short
  806.  
  807. ;        mov     [hdr_type], bx
  808.  
  809. ;        mov     eax, [edi]
  810. ;        mov     [hdr_dst_addr], eax
  811. ;        mov     ax, [edi+4]
  812. ;        mov     [hdr_dst_addr+4], ax
  813.  
  814. ;        mov     eax, [node_addr]
  815. ;        mov     [hdr_src_addr], eax
  816. ;        mov     ax, [node_addr+4]
  817. ;        mov     [hdr_src_addr+4], ax
  818.  
  819.         mov     edx, [ebx+device.io_addr]
  820.         in      ax, dx
  821.         and     ax, 0xfc00
  822.         out     dx, ax
  823.  
  824.         mov     [ebx+device.txfd_status], 0
  825.         mov     [ebx+device.txfd_command], 0x400C                 ; Cmdsuspend | CmdTx | CmdTxFlex
  826.         lea     eax, [ebx+device.txfd]
  827.         mov     [txfd_link], eax
  828.         mov     [txfd_count], 0x02208000
  829.         mov     eax, txfd_tx_buf_addr0
  830.         call    GetPgAddr
  831.         mov     [txfd_tx_desc_addr], eax
  832.         mov     eax, hdr
  833.         call    GetPgAddr
  834.         mov     [txfd_tx_buf_addr0], eax
  835.         mov     eax, 14   ; sizeof hdr
  836.         mov     [txfd_tx_buf_size0], eax
  837.  
  838.         ; Copy the buffer address and size in
  839. ;        mov     eax, esi
  840. ;        sub     eax, OS_BASE
  841. ;        mov     [txfd_tx_buf_addr1], eax
  842. ;        mov     eax, ecx
  843. ;        mov     [txfd_tx_buf_size1], eax
  844.  
  845.         mov     eax, ebx
  846.         call    GetPgAddr
  847.         add     eax, device.txfd
  848.         mov     edx, [ebx+device.io_addr]
  849.         add     edx, 4            ; SCBPointer
  850.         out     dx, eax
  851.  
  852.         mov     ax, 0x0110         ; INT_MASK | CU_START
  853.         mov     edx, [ebx+device.io_addr]
  854.         add     edx, 2            ; SCBCmd
  855.         out     dx, ax
  856.  
  857.         call    wait_for_cmd_done
  858.  
  859.         mov     edx, [ebx+device.io_addr]
  860.         in      ax, dx
  861.  
  862. I8t_001:
  863.  
  864.         mov     ax, [ebx+device.txfd_status]
  865.         cmp     ax, 0
  866.         je      I8t_001
  867.  
  868.         mov     edx, [ebx+device.io_addr]
  869.         in      ax, dx
  870.  
  871.   .finish:
  872.  
  873.         ret
  874.  
  875.  
  876.  
  877. ;***************************************************************************
  878. ; Function
  879. ;    I8255x_poll
  880. ;
  881. ; Description
  882. ;    Polls the ethernet card for a received packet
  883. ;    Received data, if any, ends up in Ether_buffer
  884. ;
  885. ;***************************************************************************
  886. I8255x_poll:
  887.  
  888.         mov     ax, 0      ; assume no data
  889.         mov     [eth_rx_data_len], ax
  890.  
  891.         mov     ax, [rxfd_status]
  892.         cmp     ax, 0
  893.         je      i8p_exit
  894.  
  895.         mov     ax, 0
  896.         mov     [rxfd_status], ax
  897.  
  898.         mov     ax, 0xc000
  899.         mov     [rxfd_command], ax
  900.  
  901.         mov     edx, [io_addr]
  902.         add     edx, 4           ; SCBPointer
  903.  
  904.         mov     eax, rxfd_status
  905.         sub     eax, OS_BASE
  906.         out     dx, eax
  907.  
  908.         mov     edx, [ebx+device.io_addr]
  909.         add     edx, 2           ; SCBCmd
  910.  
  911.         mov     ax, 0x0101         ; INT_MASK | RX_START
  912.         out     dx, ax
  913.  
  914.         call    wait_for_cmd_done
  915.  
  916.         mov     esi, rxfd_packet
  917.         mov     edi, Ether_buffer
  918.         mov     ecx, 1518
  919.         cld
  920.         rep     movsb
  921.  
  922.         mov     ax, [rxfd_count]
  923.         and     ax, 0x3fff
  924.         mov     [eth_rx_data_len], ax
  925.  
  926. i8p_exit:
  927.    ret
  928.  
  929.  
  930.  
  931.  
  932. ;***************************************************************************
  933. ;   Function
  934. ;      wait_for_cmd_done
  935. ;
  936. ;   Description
  937. ;       waits for the hardware to complete a command
  938. ;       port address in edx
  939. ;
  940. ;       al destroyed
  941. ;***************************************************************************
  942.  
  943. wait_for_cmd_done:
  944.  
  945. ;        mov     edx, [ebx + device.io_addr]
  946.  
  947.   .loop:
  948.         in      al , dx
  949.         test    al , al
  950.         jnz     .loop
  951.  
  952.         ret
  953.  
  954.  
  955.  
  956. ;***************************************************************************
  957. ;   Function
  958. ;      mdio_read
  959. ;
  960. ;   Description
  961. ;       This probably reads a register in the "physical media interface chip"
  962. ;         Phy_id in ebx   NOW EAX
  963. ;         location in ecx
  964. ;
  965. ;       Data returned in eax
  966. ;
  967. ;***************************************************************************
  968.  
  969. mdio_read:
  970.  
  971.         mov     edx, [ebx + device.io_addr]
  972.         add     edx, 16         ; SCBCtrlMDI
  973.  
  974. ;        mov     eax, 0x08000000
  975. ;        shl     ecx, 16
  976. ;        or      eax, ecx
  977. ;        shl     ebx, 21
  978. ;        or      eax, ebx
  979.                                    ;
  980.         shl     ecx, 16            ;
  981.         shl     eax, 21            ;
  982.         or      eax, ecx           ;
  983.         or      eax, 0x08000000    ;
  984.         out     dx , eax           ;
  985.                                    ;
  986. mrlp:
  987.         call    delay_us
  988.         in      eax, dx
  989.         mov     ecx, eax
  990.         and     ecx, 0x10000000
  991.         jz      mrlp
  992.  
  993.         and     eax, 0xffff
  994.         ret
  995.  
  996.  
  997.  
  998. ;***************************************************************************
  999. ;   Function
  1000. ;      mdio_write
  1001. ;
  1002. ;   Description
  1003. ;       This probably writes a register in the "physical media interface chip"
  1004. ;         Phy_id in ebx   NOW EAX
  1005. ;         location in ecx
  1006. ;         data in edx
  1007. ;       Data returned in eax
  1008. ;
  1009. ;***************************************************************************
  1010.  
  1011. mdio_write:
  1012.  
  1013. ;        mov     eax, 0x04000000
  1014. ;        shl     ecx, 16
  1015. ;        or      eax, ecx
  1016. ;        shl     ebx, 21
  1017. ;        or      eax, ebx
  1018. ;        or      eax, edx
  1019.  
  1020.         shl     ecx, 16           ;
  1021.         shl     ebx, 21           ;
  1022.         or      eax, ecx          ;
  1023.         or      eax, edx          ;
  1024.         or      eax, 0x04000000   ;
  1025.  
  1026.         mov     edx, [ebx + device.io_addr]
  1027.         add     edx, 16         ; SCBCtrlMDI
  1028.         out     dx, eax
  1029.  
  1030. mwlp:
  1031.         call    delay_us
  1032.         in      eax, dx
  1033.         mov     ecx, eax
  1034.         and     ecx, 0x10000000
  1035.         jz      mwlp
  1036.  
  1037.         and     eax, 0xffff
  1038.         ret
  1039.  
  1040.  
  1041. ;***************************************************************************
  1042. ;   Function
  1043. ;      do_eeprom_cmd
  1044. ;
  1045. ;   Description
  1046. ;       writes a cmd to the ethernet cards eeprom, by bit bashing
  1047. ;       cmd in ebx        NOW EAX
  1048. ;       cmd length in ecx
  1049. ;       return in eax
  1050. ;***************************************************************************
  1051.  
  1052. do_eeprom_cmd:
  1053.  
  1054.         push    eax
  1055.         mov     edx, [ebx + device.io_addr]
  1056.         add     dx, 14            ; the value SCBeeprom
  1057.  
  1058.         mov     ax, EE_ENB
  1059.         out     dx, ax
  1060.         call    delay_us
  1061.  
  1062.         mov     ax, 0x4803        ; EE_ENB | EE_SHIFT_CLK
  1063.         out     dx, ax
  1064.         call    delay_us
  1065.  
  1066.          ; dx holds ee_addr
  1067.          ; ecx holds count
  1068.          ; eax holds cmd
  1069.         xor     edi, edi          ; this will be the receive data
  1070.  
  1071. dec_001:
  1072.  
  1073.         mov     esi, 1
  1074.  
  1075.         dec     ecx
  1076.         shl     esi, cl
  1077.         inc     ecx
  1078.         and     esi, [esp]
  1079.         mov     eax, EE_WRITE_0   ; I am assuming this doesnt affect the flags..
  1080.         cmp     esi, 0
  1081.         jz      dec_002
  1082.         mov     eax, EE_WRITE_1
  1083.  
  1084. dec_002:
  1085.  
  1086.         out     dx, ax
  1087.         call    delay_us
  1088.  
  1089.         or      ax, EE_SHIFT_CLK
  1090.         out     dx, ax
  1091.         call    delay_us
  1092.  
  1093.         shl     edi,1
  1094.  
  1095.         in      ax, dx
  1096.         and     ax, EE_DATA_READ
  1097.         cmp     ax,0
  1098.         jz      dec_003
  1099.         inc     edi
  1100.  
  1101. dec_003:
  1102.  
  1103.         loop    dec_001
  1104.  
  1105.         mov     ax, EE_ENB
  1106.         out     dx, ax
  1107.         call    delay_us
  1108.  
  1109.         mov     ax, 0x4800
  1110.         out     dx, ax
  1111.         call    delay_us
  1112.  
  1113.         add     esp, 4
  1114.         mov     eax, edi
  1115.  
  1116.         ret
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122. ; End of code
  1123.  
  1124. align 4                                         ; Place all initialised data here
  1125.  
  1126. I8255x_DEV    dd 0
  1127. version       dd (5 shl 16) or (API_VERSION and 0xFFFF)
  1128. my_service    db 'I8255x',0                     ; max 16 chars include zero
  1129. devicename    db 'Intel Etherexpress pro/100',0
  1130.  
  1131.  
  1132.  
  1133. include_debug_strings                           ; All data wich FDO uses will be included here
  1134.  
  1135. section '.data' data readable writable align 16 ; place all uninitialized data place here
  1136.  
  1137. I8255x_LIST rd I8255x                     ; This list contains all pointers to device structures the driver is handling
  1138.  
  1139.