Subversion Repositories Kolibri OS

Rev

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