Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2011. 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. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  11. ;;             Version 2, June 1991                                ;;
  12. ;;                                                                 ;;
  13. ;;                                                                 ;;
  14. ;; Good read about how to program this family of devices:          ;;
  15. ;; http://www.intel.com/design/network/manuals/8255x_opensdm.htm   ;;
  16. ;;                                                                 ;;
  17. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  18.  
  19.  
  20. format MS COFF
  21.  
  22.         API_VERSION             equ 0x01000100
  23.         DRIVER_VERSION          equ 5
  24.  
  25.         MAX_DEVICES             equ 16
  26.  
  27.         DEBUG                   equ 1
  28.         __DEBUG__               equ 1
  29.         __DEBUG_LEVEL__         equ 1
  30.  
  31. include 'proc32.inc'
  32. include 'imports.inc'
  33. include 'fdo.inc'
  34. include 'netdrv.inc'
  35.  
  36. public START
  37. public service_proc
  38. public version
  39.  
  40. virtual at ebx
  41.  
  42.         device:
  43.  
  44.         ETH_DEVICE
  45.  
  46.         .io_addr        dd ?
  47.         .pci_bus        db ?
  48.         .pci_dev        db ?
  49.         .irq_line       db ?
  50.  
  51.         .rx_buffer      dd ?
  52.         .tx_buffer      dd ?
  53.  
  54.         .ee_bus_width   dd ?
  55.  
  56.         rb 5+8 ;;;; align
  57.  
  58.         rxfd:
  59.         .status         dw ?
  60.         .command        dw ?
  61.         .link           dd ?
  62.         .rx_buf_addr    dd ?
  63.         .count          dw ?
  64.         .size           dw ?
  65.         .packet         dd ?
  66.  
  67.         rb 12 ;;;;
  68.  
  69.         txfd:
  70.         .status         dw ?
  71.         .command        dw ?
  72.         .link           dd ?
  73.         .tx_desc_addr   dd ?
  74.         .count          dd ?
  75.         .tx_buf_addr0   dd ?
  76.         .tx_buf_size0   dd ?
  77.         .tx_buf_addr1   dd ?
  78.         .tx_buf_size1   dd ?
  79.  
  80.         confcmd:
  81.         .status:        dw ?
  82.         .command:       dw ?
  83.         .link:          dd ?
  84.         .data           rb 64
  85.  
  86.         lstats:
  87.         tx_good_frames          dd ?
  88.         tx_coll16_errs          dd ?
  89.         tx_late_colls           dd ?
  90.         tx_underruns            dd ?
  91.         tx_lost_carrier         dd ?
  92.         tx_deferred             dd ?
  93.         tx_one_colls            dd ?
  94.         tx_multi_colls          dd ?
  95.         tx_total_colls          dd ?
  96.  
  97.         rx_good_frames          dd ?
  98.         rx_crc_errs             dd ?
  99.         rx_align_errs           dd ?
  100.         rx_resource_errs        dd ?
  101.         rx_overrun_errs         dd ?
  102.         rx_colls_errs           dd ?
  103.         rx_runt_errs            dd ?
  104.  
  105.         device_size = $ - device
  106.  
  107. end virtual
  108.  
  109.  
  110. ; Serial EEPROM
  111.  
  112. EE_SK           equ 1 shl 16   ; serial clock
  113. EE_CS           equ 1 shl 17   ; chip select
  114. EE_DI           equ 1 shl 18   ; data in
  115. EE_DO           equ 1 shl 19   ; data out
  116.  
  117. EE_READ         equ 110b
  118. EE_WRITE        equ 101b
  119. EE_ERASE        equ 111b
  120.  
  121. ; The SCB accepts the following controls for the Tx and Rx units:
  122.  
  123. CU_START        equ 0x0010
  124. CU_RESUME       equ 0x0020
  125. CU_STATSADDR    equ 0x0040
  126. CU_SHOWSTATS    equ 0x0050   ; Dump statistics counters.
  127. CU_CMD_BASE     equ 0x0060   ; Base address to add to add CU commands.
  128. CU_DUMPSTATS    equ 0x0070   ; Dump then reset stats counters.
  129.  
  130. RX_START        equ 0x0001
  131. RX_RESUME       equ 0x0002
  132. RX_ABORT        equ 0x0004
  133. RX_ADDR_LOAD    equ 0x0006
  134. RX_RESUMENR     equ 0x0007
  135. INT_MASK        equ 0x0100
  136. DRVR_INT        equ 0x0200   ; Driver generated interrupt
  137.  
  138. CmdIASetup      equ 0x0001
  139. CmdConfigure    equ 0x0002
  140. CmdTx           equ 0x0004 ;;;;
  141. CmdTxFlex       equ 0x0008 ;;;
  142. Cmdsuspend      equ 0x4000
  143.  
  144.  
  145. reg_scb_status  equ 0
  146. reg_scb_cmd     equ 2
  147. reg_scb_ptr     equ 4
  148. reg_port        equ 8
  149. reg_eeprom_ctrl equ 12
  150. reg_eeprom      equ 14
  151. reg_mdi_ctrl    equ 16
  152.  
  153.  
  154. macro delay {
  155.         push    eax
  156.         in      eax, dx
  157.         in      eax, dx
  158.         in      eax, dx
  159.         in      eax, dx
  160.         in      eax, dx
  161.         in      eax, dx
  162.         in      eax, dx
  163.         in      eax, dx
  164.         in      eax, dx
  165.         in      eax, dx
  166.         pop     eax
  167. }
  168.  
  169. section '.flat' code readable align 16
  170.  
  171. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  172. ;;                        ;;
  173. ;; proc START             ;;
  174. ;;                        ;;
  175. ;; (standard driver proc) ;;
  176. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  177.  
  178. proc START stdcall, state:dword
  179.  
  180.         cmp [state], 1
  181.         jne .exit
  182.  
  183.   .entry:
  184.  
  185.         DEBUGF 1,"Loading i8255x driver\n"
  186.         stdcall RegService, my_service, service_proc
  187.         ret
  188.  
  189.   .fail:
  190.   .exit:
  191.         xor eax, eax
  192.         ret
  193.  
  194. endp
  195.  
  196.  
  197. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  198. ;;                        ;;
  199. ;; proc SERVICE_PROC      ;;
  200. ;;                        ;;
  201. ;; (standard driver proc) ;;
  202. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  203.  
  204. align 4
  205. proc service_proc stdcall, ioctl:dword
  206.  
  207.         mov     edx, [ioctl]
  208.         mov     eax, [IOCTL.io_code]
  209.  
  210. ;------------------------------------------------------
  211.  
  212.         cmp     eax, 0 ;SRV_GETVERSION
  213.         jne     @F
  214.  
  215.         cmp     [IOCTL.out_size], 4
  216.         jl      .fail
  217.         mov     eax, [IOCTL.output]
  218.         mov     [eax], dword API_VERSION
  219.  
  220.         xor     eax, eax
  221.         ret
  222.  
  223. ;------------------------------------------------------
  224.   @@:
  225.         cmp     eax, 1 ;SRV_HOOK
  226.         jne     .fail
  227.  
  228.         cmp     [IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
  229.         jl      .fail
  230.  
  231.         mov     eax, [IOCTL.input]
  232.         cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
  233.         jne     .fail                                   ; other types arent supported for this card yet
  234.  
  235. ; check if the device is already listed
  236.  
  237.         mov     esi, device_list
  238.         mov     ecx, [devices]
  239.         test    ecx, ecx
  240.         jz      .firstdevice
  241.  
  242. ;        mov     eax, [IOCTL.input]                      ; get the pci bus and device numbers
  243.         mov     ax , [eax+1]                            ;
  244.   .nextdevice:
  245.         mov     ebx, [esi]
  246.         cmp     ax , word [device.pci_bus]              ; compare with pci and device num in device list (notice the usage of word instead of byte)
  247.         je      .find_devicenum                         ; Device is already loaded, let's find it's device number
  248.         add     esi, 4
  249.         loop    .nextdevice
  250.  
  251.  
  252. ; This device doesnt have its own eth_device structure yet, lets create one
  253.   .firstdevice:
  254.         cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
  255.         jge     .fail
  256.  
  257.         push    edx
  258.         stdcall KernelAlloc, device_size
  259.         pop     edx
  260.         test    eax, eax
  261.         jz      .fail
  262.         mov     ebx, eax                                ; ebx is always used as a pointer to the structure (in driver, but also in kernel code)
  263.  
  264. ; Fill in the direct call addresses into the struct
  265.  
  266.         mov     [device.reset], reset
  267.         mov     [device.transmit], transmit
  268. ;        mov     [device.get_MAC], read_mac
  269.         mov     [device.set_MAC], MAC_write
  270.         mov     [device.unload], unload
  271.         mov     [device.name], my_service
  272.  
  273. ; save the pci bus and device numbers
  274.  
  275.         mov     eax, [IOCTL.input]
  276.         mov     cl , [eax+1]
  277.         mov     [device.pci_bus], cl
  278.         mov     cl , [eax+2]
  279.         mov     [device.pci_dev], cl
  280.  
  281. ; Now, it's time to find the base io addres of the PCI device
  282.  
  283.         find_io [device.pci_bus], [device.pci_dev], [device.io_addr]
  284.  
  285. ; We've found the io address, find IRQ now
  286.  
  287.         find_irq [device.pci_bus], [device.pci_dev], [device.irq_line]
  288.  
  289.         DEBUGF  2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
  290.         [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4
  291.  
  292.         allocate_and_clear [device.rx_buffer], (4096), .err
  293.         allocate_and_clear [device.tx_buffer], (4096), .err
  294.  
  295. ; Ok, the eth_device structure is ready, let's probe the device
  296.  
  297.         call    probe                                                   ; this function will output in eax
  298.         test    eax, eax
  299.         jnz     .err                                                    ; If an error occured, exit
  300.  
  301.         mov     eax, [devices]                                          ; Add the device structure to our device list
  302.         mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
  303.         inc     [devices]                                               ;
  304.  
  305.  
  306.         mov     [device.type], NET_TYPE_ETH
  307.         call    NetRegDev
  308.  
  309.         cmp     eax, -1
  310.         je      .err
  311.  
  312.         ret
  313.  
  314. ; If the device was already loaded, find the device number and return it in eax
  315.  
  316.   .find_devicenum:
  317.         DEBUGF  2,"Trying to find device number of already registered device\n"
  318.         call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
  319.                                                                         ; into a device number in edi
  320.         mov     eax, edi                                                ; Application wants it in eax instead
  321.         DEBUGF  2,"Kernel says: %u\n", eax
  322.         ret
  323.  
  324. ; If an error occured, remove all allocated data and exit (returning -1 in eax)
  325.  
  326.   .err:
  327.         stdcall KernelFree, [device.rx_buffer]
  328.         stdcall KernelFree, [device.tx_buffer]
  329.         stdcall KernelFree, ebx
  330.  
  331.   .fail:
  332.         or      eax, -1
  333.         ret
  334.  
  335. ;------------------------------------------------------
  336. endp
  337.  
  338.  
  339.  
  340.  
  341.  
  342. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  343. ;;                                                                        ;;
  344. ;;        Actual Hardware dependent code starts here                      ;;
  345. ;;                                                                        ;;
  346. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  347.  
  348.  
  349. unload:
  350.         ; TODO: (in this particular order)
  351.         ;
  352.         ; - Stop the device
  353.         ; - Detach int handler
  354.         ; - Remove device from local list (device_list)
  355.         ; - call unregister function in kernel
  356.         ; - Remove all allocated structures and buffers the card used
  357.  
  358.         or      eax,-1
  359.  
  360. ret
  361.  
  362.  
  363. ;-------------
  364. ;
  365. ; Probe
  366. ;
  367. ;-------------
  368.  
  369. align 4
  370. probe:
  371.  
  372.         DEBUGF  1,"Probing i8255x\n"
  373.  
  374.         make_bus_master [device.pci_bus], [device.pci_dev]
  375.  
  376. ;---------------------------
  377. ; First, identify the device
  378.  
  379.         movzx   ecx, [device.pci_bus]
  380.         movzx   edx, [device.pci_dev]
  381.         stdcall PciRead32, ecx ,edx ,0                                ; get device/vendor id
  382.  
  383.         DEBUGF  1,"Vendor_id=0x%x\n", ax
  384.  
  385.         cmp     ax, 0x8086
  386.         jne     .notfound
  387.         shr     eax, 16
  388.  
  389.         DEBUGF  1,"Device_id=0x%x\n", ax
  390.  
  391.         mov     ecx, DEVICE_IDs
  392.         mov     edi, device_id_list
  393.         repne   scasw
  394.         jne     .notfound
  395.         jmp     .found
  396.  
  397.   .notfound:
  398.         DEBUGF  1,"ERROR: Unsupported device!\n"
  399.         or      eax, -1
  400.         ret
  401.  
  402.   .found:
  403.  
  404.         call    ee_get_width
  405.         call    MAC_read_eeprom
  406.  
  407.         ;;; TODO: detect phy
  408.  
  409.  
  410.  
  411. ;----------
  412. ;
  413. ;  Reset
  414. ;
  415. ;----------
  416.  
  417. align 4
  418. reset:
  419.  
  420. ;---------------
  421. ; reset the card
  422.  
  423.         set_io  0
  424.         set_io  reg_port
  425.         xor     eax, eax        ; Software Reset
  426.         out     dx, eax
  427.  
  428.         mov     esi, 10
  429.         call    Sleep           ; Give the card time to warm up.
  430.  
  431. ;---------------------------------
  432. ; Tell device where to store stats
  433.  
  434.         lea     eax, [lstats]
  435.         GetRealAddr
  436.         set_io  reg_scb_ptr
  437.         out     dx, eax
  438.  
  439.         mov     ax, INT_MASK + CU_STATSADDR
  440.         set_io  reg_scb_cmd
  441.         out     dx, ax
  442.         call    cmd_wait
  443.  
  444. ;-----------------
  445. ; Set CU base to 0
  446.  
  447.         xor     eax, eax
  448.         set_io  reg_scb_ptr
  449.         out     dx, eax
  450.  
  451.         mov     ax, INT_MASK + RX_ADDR_LOAD
  452.         set_io  reg_scb_cmd
  453.         out     dx, ax
  454.         call    cmd_wait
  455.  
  456. ;---------------------
  457. ; build rxfd structure
  458.  
  459.         mov     ax, 0x0001
  460.         mov     [rxfd.status], ax
  461.         mov     ax, 0x0000
  462.         mov     [rxfd.command], ax
  463.  
  464.         lea     eax, [rxfd.status]
  465.         GetRealAddr
  466.         mov     [rxfd.link], eax
  467.  
  468.         lea     eax, [device.rx_buffer]
  469.         GetRealAddr
  470.         mov     [rxfd.rx_buf_addr], eax
  471.  
  472.         xor     ax, ax
  473.         mov     [rxfd.count], ax
  474.  
  475.         mov     ax, 1528
  476.         mov     [rxfd.size], ax
  477.  
  478. ;-------------------------------
  479. ; Set ptr to first command block
  480.  
  481.         set_io  reg_scb_ptr
  482.         lea     eax, [rxfd]
  483.         GetRealAddr
  484.         out     dx, eax
  485.  
  486.         set_io  reg_scb_cmd
  487.         mov     ax, INT_MASK + RX_START
  488.         out     dx, ax
  489.         call    cmd_wait
  490.  
  491. ;-------------------
  492. ; start the receiver
  493.  
  494.         mov     [rxfd.status], 0
  495.         mov     [rxfd.command], 0xc000
  496.  
  497.         set_io  reg_scb_ptr
  498.         lea     eax, [rxfd]
  499.         GetRealAddr
  500.         out     dx, eax
  501.  
  502.         set_io  reg_scb_cmd
  503.         mov     ax, INT_MASK + RX_START
  504.         out     dx, ax
  505.         call    cmd_wait
  506.  
  507. ;-----------------
  508. ; set CU base to 0
  509.  
  510.         set_io  reg_scb_ptr
  511.         xor     eax, eax
  512.         out     dx, eax
  513.  
  514.         set_io  reg_scb_cmd
  515.         mov     ax, INT_MASK + CU_CMD_BASE
  516.         out     dx, ax
  517.         call    cmd_wait
  518.  
  519. ;--------------------
  520. ; Set TX Base address
  521.  
  522. ; First, set up confcmd values
  523.  
  524.         mov     [txfd.command], CmdIASetup
  525.         mov     [txfd.status], 0
  526.         lea     eax, [confcmd]
  527.         GetRealAddr
  528.         mov     [txfd.link], eax
  529.  
  530.         mov     word [confcmd.command], Cmdsuspend + CmdConfigure
  531.         mov     word [confcmd.status], 0
  532.         lea     eax, [txfd]
  533.         GetRealAddr
  534.         mov     [confcmd.link], eax
  535.  
  536.         mov     byte [confcmd.data + 1], 0x88  ; fifo of 8 each
  537.         mov     byte [confcmd.data + 4], 0
  538.         mov     byte [confcmd.data + 5], 0x80
  539.         mov     byte [confcmd.data + 15], 0x48
  540.         mov     byte [confcmd.data + 19], 0x80
  541.         mov     byte [confcmd.data + 21], 0x05
  542.  
  543.  
  544. ; CU start
  545.  
  546. ;        lea     eax, [txfd]
  547. ;        GetRealAddr
  548.         set_io  0
  549.         set_io  reg_scb_ptr
  550.         out     dx, eax
  551.  
  552.         mov     ax, INT_MASK + CU_START
  553.         set_io  reg_scb_cmd
  554.         out     dx, ax
  555.         call    cmd_wait
  556.  
  557. ; wait for thing to start
  558.  
  559. ;  drp004:
  560. ;
  561. ;        cmp     [txfd.status], 0
  562. ;        jz      drp004
  563.  
  564. ; Indicate that we have successfully reset the card
  565.  
  566.  
  567. ;;; enable interrupts
  568.  
  569.         xor     eax, eax
  570.  
  571.         ret
  572.  
  573.  
  574.  
  575.  
  576.  
  577. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  578. ;;                                         ;;
  579. ;; Transmit                                ;;
  580. ;;                                         ;;
  581. ;; In: buffer pointer in [esp+4]           ;;
  582. ;;     size of buffer in [esp+8]           ;;
  583. ;;     pointer to device structure in ebx  ;;
  584. ;;                                         ;;
  585. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  586.  
  587. align 4
  588. transmit:
  589.  
  590.         DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
  591.         mov     eax, [esp+4]
  592.         DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
  593.         [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
  594.         [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
  595.         [eax+13]:2,[eax+12]:2
  596.  
  597.         cmp     dword [esp+8], 1500
  598.         jg      .error                          ; packet is too long
  599.         cmp     dword [esp+8], 60
  600.         jl      .error                          ; packet is too short
  601.  
  602.         set_io  0
  603.         in      ax, dx
  604.         and     ax, 0xfc00
  605.         out     dx, ax
  606.  
  607.         mov     [txfd.status], 0
  608.         mov     [txfd.command], Cmdsuspend + CmdTx + CmdTxFlex
  609.         lea     eax, [txfd]
  610.         GetRealAddr
  611.         mov     [txfd.link], eax
  612.         mov     [txfd.count], 0x02208000
  613.         lea     eax, [txfd.tx_buf_addr0]
  614.         GetRealAddr
  615.         mov     [txfd.tx_desc_addr], eax
  616.  
  617.         mov     eax, [esp+4]
  618.         mov     [txfd.tx_buf_addr0], eax
  619.         mov     eax, [esp+8]
  620.         mov     [txfd.tx_buf_size0], eax
  621.  
  622.         ; Copy the buffer address and size in
  623.         mov     [txfd.tx_buf_addr1], 0
  624.         mov     [txfd.tx_buf_size1], 0
  625.  
  626.         lea     eax, [txfd]
  627.         GetRealAddr
  628.         set_io  reg_scb_ptr
  629.         out     dx, eax
  630.  
  631.         mov     ax, INT_MASK + CU_START
  632.         set_io  reg_scb_cmd
  633.         out     dx, ax
  634.  
  635.         call    cmd_wait
  636.  
  637.         in      ax, dx
  638.  
  639.   .I8t_001:
  640.         cmp     [txfd.status], 0
  641.         je      .I8t_001
  642.  
  643.         in      ax, dx
  644.  
  645.   .finish:
  646.         xor     eax, eax
  647.         ret     8
  648.  
  649.   .error:
  650.         stdcall KernelFree, [esp+4]
  651.         or      eax, -1
  652.         ret     8
  653.  
  654. ;;;;;;;;;;;;;;;;;;;;;;;
  655. ;;                   ;;
  656. ;; Interrupt handler ;;
  657. ;;                   ;;
  658. ;;;;;;;;;;;;;;;;;;;;;;;
  659.  
  660. align 4
  661. int_handler:
  662.  
  663.         DEBUGF  1,"IRQ %x ",eax:2                   ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
  664.  
  665. ; find pointer of device wich made IRQ occur
  666.  
  667.         mov     esi, device_list
  668.         mov     ecx, [devices]
  669.         test    ecx, ecx
  670.         jz      .fail
  671. .nextdevice:
  672.         mov     ebx, dword [esi]
  673.  
  674.         set_io  0
  675.   ;;      set_io  REG_ISR
  676.    ;;     in      ax , dx
  677.     ;;    out     dx , ax                             ; send it back to ACK
  678.  
  679.         add     esi, 4
  680.  
  681.         test    ax , ax
  682.         jnz     .got_it
  683.  
  684.         dec     ecx
  685.         jnz     .nextdevice
  686.  
  687.         ret                                         ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
  688.  
  689.   .got_it:
  690.  
  691.  
  692.        ;;; receive
  693.  
  694.         cmp     [rxfd.status], 0
  695.         je      .nodata
  696.  
  697.         mov     [rxfd.status], 0
  698.         mov     [rxfd.command], 0xc000
  699.  
  700.         set_io  reg_scb_ptr
  701.         lea     eax, [rxfd.status]
  702.         GetRealAddr
  703.         out     dx, eax
  704.  
  705.         set_io  reg_scb_cmd
  706.         mov     ax, INT_MASK + RX_START
  707.         out     dx, ax
  708.  
  709.         call    cmd_wait
  710.  
  711.         movzx   ecx, [rxfd.count]
  712.         and     ecx, 0x3fff
  713.  
  714.         stdcall KernelAlloc, ecx        ; Allocate a buffer to put packet into
  715.         push    ecx
  716.         push    eax
  717.  
  718.         lea     esi, [device.rx_buffer]
  719.  
  720.   .copy:
  721.         shr     ecx, 1
  722.         jnc     .nb
  723.         movsb
  724.   .nb:
  725.         shr     ecx, 1
  726.         jnc     .nw
  727.         movsw
  728.   .nw:
  729.         jz      .nd
  730.         rep     movsd
  731.   .nd:
  732.  
  733.         jmp     EthReceiver                         ; Send it to kernel
  734.  
  735.   .nodata:
  736.   .fail:
  737.  
  738.         ret
  739.  
  740.  
  741.  
  742.  
  743. align 4
  744. cmd_wait:
  745.  
  746.         in      al, dx
  747.         test    al, al
  748.         jnz     cmd_wait
  749.  
  750.         ret
  751.  
  752.  
  753.  
  754.  
  755.  
  756.  
  757. align 4
  758. ee_read:        ; esi = address to read
  759.  
  760.         set_io  0
  761.         set_io  reg_eeprom
  762.  
  763. ;-----------------------------------------------------
  764. ; Prepend start bit + read opcode to the address field
  765. ; and shift it to the very left bits of esi
  766.  
  767.         mov     ecx, 32
  768.         sub     ecx, [device.ee_bus_width]
  769.         shl     esi, cl
  770.         or      esi, EE_READ shl 28
  771.  
  772.         mov     ecx, [device.ee_bus_width]
  773.         add     ecx, 3
  774.  
  775. ;-----------------------
  776. ; Write this to the chip
  777.  
  778.   .loop:
  779.         mov     eax, EE_CS
  780.         shl     esi, 1
  781.         jnc     @f
  782.         or      eax, EE_DI
  783.        @@:
  784.         out     dx , eax
  785.         delay
  786.  
  787.         or      eax, EE_SK
  788.         out     dx , eax
  789.         delay
  790.  
  791.         loop    .loop
  792.  
  793. ;------------------------------
  794. ; Now read the data from eeprom
  795.  
  796.         xor     esi, esi
  797.         mov     ecx, 16
  798.  
  799.   .loop2:
  800.         mov     eax, EE_CS + EE_SK
  801.         out     dx , eax
  802.         delay
  803.  
  804.         in      eax, dx
  805.         test    eax, EE_DO
  806.         jz      @f
  807.         inc     esi
  808.        @@:
  809.         shl     esi, 1
  810.  
  811.         mov     eax, EE_CS
  812.         out     dx , eax
  813.         delay
  814.  
  815.         loop    .loop2
  816.  
  817. ;-----------------------
  818. ; de-activate the eeprom
  819.  
  820.         xor     eax, eax
  821.         out     dx, eax
  822.  
  823.  
  824.         DEBUGF  1,"data=%x\n", esi
  825.         ret
  826.  
  827.  
  828.  
  829. align 4
  830. ee_write:       ; esi = address to write to, di = data
  831.  
  832.         set_io  0
  833.         set_io  reg_eeprom
  834.  
  835. ;-----------------------------------------------------
  836. ; Prepend start bit + write opcode to the address field
  837. ; and shift it to the very left bits of esi
  838.  
  839.         mov     ecx, 32
  840.         sub     ecx, [device.ee_bus_width]
  841.         shl     esi, cl
  842.         or      esi, EE_WRITE shl 28
  843.  
  844.         mov     ecx, [device.ee_bus_width]
  845.         add     ecx, 3
  846.  
  847. ;-----------------------
  848. ; Write this to the chip
  849.  
  850.   .loop:
  851.         mov     eax, EE_CS
  852.         shl     esi, 1
  853.         jnc     @f
  854.         or      eax, EE_DI
  855.        @@:
  856.         out     dx , eax
  857.         delay
  858.  
  859.         or      eax, EE_SK
  860.         out     dx , eax
  861.         delay
  862.  
  863.         loop    .loop
  864.  
  865. ;-----------------------------
  866. ; Now write the data to eeprom
  867.  
  868.         mov     ecx, 16
  869.  
  870.   .loop2:
  871.         mov     eax, EE_CS
  872.         shl     di , 1
  873.         jnc     @f
  874.         or      eax, EE_DI
  875.        @@:
  876.         out     dx , eax
  877.         delay
  878.  
  879.         or      eax, EE_SK
  880.         out     dx , eax
  881.         delay
  882.  
  883.         loop    .loop2
  884.  
  885. ;-----------------------
  886. ; de-activate the eeprom
  887.  
  888.         xor     eax, eax
  889.         out     dx, eax
  890.  
  891.  
  892.         ret
  893.  
  894.  
  895.  
  896. align 4
  897. ee_get_width:
  898.  
  899.         set_io  0
  900.         set_io  reg_eeprom
  901.  
  902.         mov     esi, EE_READ shl 28
  903.         xor     ecx, ecx
  904.  
  905.   .loop:
  906.         mov     eax, EE_CS
  907.         out     dx , eax
  908.         delay
  909.  
  910.         or      eax, EE_SK
  911.         out     dx , eax
  912.         delay
  913.  
  914.         inc     ecx
  915.  
  916.         in      eax, dx
  917.         test    eax, EE_DO
  918.         jnz     .loop
  919.  
  920.         mov     [device.ee_bus_width], ecx
  921.  
  922. ;------------------------------
  923. ; Now read the data from eeprom
  924.  
  925.         mov     ecx, 16
  926.   .loop2:
  927.         mov     eax, EE_CS + EE_SK
  928.         out     dx , eax
  929.         delay
  930.  
  931.         mov     eax, EE_CS
  932.         out     dx , eax
  933.         delay
  934.         loop    .loop2
  935.  
  936. ;-----------------------
  937. ; de-activate the eeprom
  938.  
  939.         xor     eax, eax
  940.         out     dx, eax
  941.  
  942.         ret
  943.  
  944.  
  945.  
  946. ; cx = phy addr
  947. ; dx = phy reg addr
  948.  
  949. ; ax = data
  950.  
  951. align 4
  952. mdio_read:
  953.  
  954.         shl     ecx, 21                 ; PHY addr
  955.         shl     edx, 16                 ; PHY reg addr
  956.  
  957.         mov     eax, ecx
  958.         or      eax, edx
  959.         or      eax, 10b shl 26         ; read opcode
  960.  
  961.         set_io  0
  962.         set_io  reg_mdi_ctrl
  963.         out     dx, eax
  964.  
  965.   .wait:
  966.         delay
  967.         in      eax, dx
  968.         test    eax, 1 shl 28           ; ready bit
  969.         jz      .wait
  970.  
  971.         ret
  972.  
  973. ; ax = data
  974. ; cx = phy addr
  975. ; dx = phy reg addr
  976.  
  977. ; ax = data
  978.  
  979. align 4
  980. mdio_write:
  981.  
  982.         and     eax, 0xffff
  983.  
  984.         shl     ecx, 21                 ; PHY addr
  985.         shl     edx, 16                 ; PHY reg addr
  986.  
  987.         or      eax, ecx
  988.         or      eax, edx
  989.         or      eax, 01b shl 26         ; write opcode
  990.  
  991.         set_io  0
  992.         set_io  reg_mdi_ctrl
  993.         out     dx, eax
  994.  
  995.   .wait:
  996.         delay
  997.         in      eax, dx
  998.         test    eax, 1 shl 28           ; ready bit
  999.         jz      .wait
  1000.  
  1001.         ret
  1002.  
  1003.  
  1004.  
  1005. align 4
  1006. MAC_read_eeprom:
  1007.  
  1008. ;;;;
  1009.  
  1010.         ret
  1011.  
  1012.  
  1013. align 4
  1014. MAC_write:
  1015.  
  1016. ;;;;
  1017.  
  1018.         ret
  1019.  
  1020.  
  1021.  
  1022.  
  1023. ; End of code
  1024.  
  1025. align 4                                         ; Place all initialised data here
  1026.  
  1027. devices       dd 0                              ; number of currently running devices
  1028. version       dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
  1029. my_service    db 'i8255x',0                     ; max 16 chars include zero
  1030. devicename    db 'Intel Etherexpress pro/100',0
  1031.  
  1032.  
  1033. device_id_list:
  1034.  
  1035.         dw 0x1029
  1036.         dw 0x1030
  1037.         dw 0x1031
  1038.         dw 0x1032
  1039.         dw 0x1033
  1040.         dw 0x1034
  1041.         dw 0x1038
  1042.         dw 0x1039
  1043.         dw 0x103A
  1044.         dw 0x103B
  1045.         dw 0x103C
  1046.         dw 0x103D
  1047.         dw 0x103E
  1048.         dw 0x1050
  1049.         dw 0x1051
  1050.         dw 0x1052
  1051.         dw 0x1053
  1052.         dw 0x1054
  1053.         dw 0x1055
  1054.         dw 0x1056
  1055.         dw 0x1057
  1056.         dw 0x1059
  1057.         dw 0x1064
  1058.         dw 0x1065
  1059.         dw 0x1066
  1060.         dw 0x1067
  1061.         dw 0x1068
  1062.         dw 0x1069
  1063.         dw 0x106A
  1064.         dw 0x106B
  1065.         dw 0x1091
  1066.         dw 0x1092
  1067.         dw 0x1093
  1068.         dw 0x1094
  1069.         dw 0x1095
  1070.         dw 0x10fe
  1071.         dw 0x1209
  1072.         dw 0x1229
  1073.         dw 0x2449
  1074.         dw 0x2459
  1075.         dw 0x245D
  1076.         dw 0x27DC
  1077.  
  1078. DEVICE_IDs = ($ - device_id_list) / 2
  1079.  
  1080. mac_82557_D100_A  = 0
  1081. mac_82557_D100_B  = 1
  1082. mac_82557_D100_C  = 2
  1083. mac_82558_D101_A4 = 4
  1084. mac_82558_D101_B0 = 5
  1085. mac_82559_D101M   = 8
  1086. mac_82559_D101S   = 9
  1087. mac_82550_D102    = 12
  1088. mac_82550_D102_C  = 13
  1089. mac_82551_E       = 14
  1090. mac_82551_F       = 15
  1091. mac_82551_10      = 16
  1092. mac_unknown       = 0xFF
  1093.  
  1094. phy_100a     = 0x000003E0
  1095. phy_100c     = 0x035002A8
  1096. phy_82555_tx = 0x015002A8
  1097. phy_nsc_tx   = 0x5C002000
  1098. phy_82562_et = 0x033002A8
  1099. phy_82562_em = 0x032002A8
  1100. phy_82562_ek = 0x031002A8
  1101. phy_82562_eh = 0x017002A8
  1102. phy_82552_v  = 0xd061004d
  1103. phy_unknown  = 0xFFFFFFFF
  1104.  
  1105.  
  1106. include_debug_strings                           ; All data wich FDO uses will be included here
  1107.  
  1108. section '.data' data readable writable align 16 ; place all uninitialized data place here
  1109.  
  1110. device_list   rd MAX_DEVICES                    ; This list contains all pointers to device structures the driver is handling
  1111.  
  1112.