Subversion Repositories Kolibri OS

Rev

Rev 5074 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved.    ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;;  Broadcom NetXtreme 57xx driver for KolibriOS                   ;;
  7. ;;                                                                 ;;
  8. ;;                                                                 ;;
  9. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  10. ;;             Version 2, June 1991                                ;;
  11. ;;                                                                 ;;
  12. ;; Broadcom's programmers's manual for the BCM57xx                 ;;
  13. ;; http://www.broadcom.com/collateral/pg/57XX-PG105-R.pdf          ;;
  14. ;;                                                                 ;;
  15. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  16.  
  17. format PE DLL native
  18. entry START
  19.  
  20.         CURRENT_API             = 0x0200
  21.         COMPATIBLE_API          = 0x0100
  22.         API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
  23.  
  24.         MAX_DEVICES             = 16
  25.  
  26.         __DEBUG__               = 1
  27.         __DEBUG_LEVEL__         = 2
  28.  
  29. section '.flat' readable writable executable
  30.  
  31. include '../proc32.inc'
  32. include '../struct.inc'
  33. include '../macros.inc'
  34. include '../fdo.inc'
  35. include '../netdrv.inc'
  36.  
  37. struct  device          ETH_DEVICE
  38.  
  39.         mmio_addr       dd ?
  40.         pci_bus         dd ?
  41.         pci_dev         dd ?
  42.         irq_line        db ?
  43.  
  44.         cur_tx          dd ?
  45.         last_tx         dd ?
  46.  
  47.         rb 0x100 - ($ and 0xff) ; align 256
  48.         rx_desc         rd 256/8
  49.  
  50.         rb 0x100 - ($ and 0xff) ; align 256
  51.         tx_desc         rd 256/8
  52.  
  53. ends
  54.  
  55.  
  56. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  57. ;;                        ;;
  58. ;; proc START             ;;
  59. ;;                        ;;
  60. ;; (standard driver proc) ;;
  61. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  62.  
  63. proc START c, reason:dword, cmdline:dword
  64.  
  65.         cmp     [reason], DRV_ENTRY
  66.         jne     .fail
  67.  
  68.         DEBUGF  1,"Loading driver\n"
  69.         invoke  RegService, my_service, service_proc
  70.         ret
  71.  
  72.   .fail:
  73.         xor     eax, eax
  74.         ret
  75.  
  76. endp
  77.  
  78.  
  79.  
  80. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  81. ;;                        ;;
  82. ;; proc SERVICE_PROC      ;;
  83. ;;                        ;;
  84. ;; (standard driver proc) ;;
  85. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  86.  
  87. proc service_proc stdcall, ioctl:dword
  88.  
  89.         mov     edx, [ioctl]
  90.         mov     eax, [edx + IOCTL.io_code]
  91.  
  92. ;------------------------------------------------------
  93.  
  94.         cmp     eax, 0 ;SRV_GETVERSION
  95.         jne     @F
  96.  
  97.         cmp     [edx + IOCTL.out_size], 4
  98.         jb      .fail
  99.         mov     eax, [edx + IOCTL.output]
  100.         mov     [eax], dword API_VERSION
  101.  
  102.         xor     eax, eax
  103.         ret
  104.  
  105. ;------------------------------------------------------
  106.   @@:
  107.         cmp     eax, 1 ;SRV_HOOK
  108.         jne     .fail
  109.  
  110.         cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
  111.         jb      .fail
  112.  
  113.         mov     eax, [edx + IOCTL.input]
  114.         cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
  115.         jne     .fail                                   ; other types arent supported for this card yet
  116.  
  117. ; check if the device is already listed
  118.  
  119.         mov     esi, device_list
  120.         mov     ecx, [devices]
  121.         test    ecx, ecx
  122.         jz      .firstdevice
  123.  
  124. ;        mov     eax, [edx + IOCTL.input]                      ; get the pci bus and device numbers
  125.         mov     ax, [eax+1]                             ;
  126.   .nextdevice:
  127.         mov     ebx, [esi]
  128.         cmp     al, byte [ebx + device.pci_bus]
  129.         jne     .next
  130.         cmp     ah, byte [ebx + device.pci_dev]
  131.         je      .find_devicenum                         ; Device is already loaded, let's find it's device number
  132.   .next:
  133.         add     esi, 4
  134.         loop    .nextdevice
  135.  
  136.  
  137. ; This device doesnt have its own eth_device structure yet, lets create one
  138.   .firstdevice:
  139.         cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
  140.         jae     .fail
  141.  
  142.         allocate_and_clear ebx, sizeof.device, .fail      ; Allocate the buffer for device structure
  143.  
  144. ; Fill in the direct call addresses into the struct
  145.  
  146.         mov     [ebx + device.reset], reset
  147.         mov     [ebx + device.transmit], transmit
  148.         mov     [ebx + device.unload], unload
  149.         mov     [ebx + device.name], my_service
  150.  
  151. ; save the pci bus and device numbers
  152.  
  153.         mov     eax, [edx + IOCTL.input]
  154.         movzx   ecx, byte [eax+1]
  155.         mov     [ebx + device.pci_bus], ecx
  156.         movzx   ecx, byte [eax+2]
  157.         mov     [ebx + device.pci_dev], ecx
  158.  
  159. ; Now, it's time to find the base mmio addres of the PCI device
  160.  
  161.         stdcall PCI_find_mmio32, [ebx + device.pci_bus], [ebx + device.pci_dev]
  162.  
  163. ; Create virtual mapping of the physical memory
  164.  
  165.         push    1Bh             ; PG_SW+PG_NOCACHE
  166.         push    10000h          ; size of the map
  167.         push    eax
  168.         invoke  MapIoMem
  169.         mov     [ebx + device.mmio_addr], eax
  170.  
  171. ; We've found the mmio address, find IRQ now
  172.  
  173.         invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
  174.         mov     [ebx + device.irq_line], al
  175.  
  176.         DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
  177.         [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.mmio_addr]:8
  178.  
  179. ; Ok, the eth_device structure is ready, let's probe the device
  180.         call    probe                                                   ; this function will output in eax
  181.         test    eax, eax
  182.         jnz     .err                                                    ; If an error occured, exit
  183.  
  184.         mov     eax, [devices]                                          ; Add the device structure to our device list
  185.         mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
  186.         inc     [devices]                                               ;
  187.  
  188.         mov     [ebx + device.type], NET_TYPE_ETH
  189.         invoke  NetRegDev
  190.  
  191.         cmp     eax, -1
  192.         je      .destroy
  193.  
  194.         ret
  195.  
  196. ; If the device was already loaded, find the device number and return it in eax
  197.  
  198.   .find_devicenum:
  199.         DEBUGF  1,"Trying to find device number of already registered device\n"
  200.         invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
  201.                                                                         ; into a device number in edi
  202.         mov     eax, edi                                                ; Application wants it in eax instead
  203.         DEBUGF  1,"Kernel says: %u\n", eax
  204.         ret
  205.  
  206. ; If an error occured, remove all allocated data and exit (returning -1 in eax)
  207.  
  208.   .destroy:
  209.         ; todo: reset device into virgin state
  210.  
  211.   .err:
  212.         invoke  KernelFree, ebx
  213.  
  214.   .fail:
  215.         or      eax, -1
  216.         ret
  217.  
  218. ;------------------------------------------------------
  219. endp
  220.  
  221.  
  222. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  223. ;;                                                                        ;;
  224. ;;        Actual Hardware dependent code starts here                      ;;
  225. ;;                                                                        ;;
  226. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  227.  
  228. unload:
  229.         ; TODO: (in this particular order)
  230.         ;
  231.         ; - Stop the device
  232.         ; - Detach int handler
  233.         ; - Remove device from local list (device_list)
  234.         ; - call unregister function in kernel
  235.         ; - Remove all allocated structures and buffers the card used
  236.  
  237.         or      eax, -1
  238.  
  239. ret
  240.  
  241.  
  242.  
  243. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  244. ;;
  245. ;;  probe: enables the device (if it really is BCM57XX)
  246. ;;
  247. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  248.  
  249. probe:
  250.  
  251.         DEBUGF  1,"Probe\n"
  252.  
  253. ; Make the device a bus master
  254.         invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
  255.         or      al, PCI_CMD_MASTER
  256.         invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
  257.  
  258.  
  259.         ; TODO: validate the device
  260.  
  261.  
  262.  
  263.  
  264. reset:
  265.  
  266.         DEBUGF  1,"Reset\n"
  267.  
  268.         movzx   eax, [ebx + device.irq_line]
  269.         DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
  270.         invoke  AttachIntHandler, eax, int_handler, ebx
  271.         test    eax, eax
  272.         jnz     @f
  273.         DEBUGF  1,"\nCould not attach int handler!\n"
  274. ;        or      eax, -1
  275. ;        ret
  276.   @@:
  277.  
  278.         call    read_mac
  279.  
  280. ; Set the mtu, kernel will be able to send now
  281.         mov     [ebx + device.mtu], 1514
  282.  
  283. ; Set link state to unknown
  284.         mov     [ebx + device.state], ETH_LINK_UNKNOWN
  285.  
  286.         ret
  287.  
  288.  
  289.  
  290.  
  291. align 4
  292. read_mac:
  293.  
  294.         DEBUGF  1,"Read MAC\n"
  295.  
  296.         mov     esi, [ebx + device.mmio_addr]
  297.         lea     edi, [ebx + device.mac]
  298.         movsd
  299.         movsw
  300.  
  301.   .mac_ok:
  302.         DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
  303.         [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
  304.  
  305.         ret
  306.  
  307.  
  308. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  309. ;;                                         ;;
  310. ;; Transmit                                ;;
  311. ;;                                         ;;
  312. ;; In: buffer pointer in [esp+4]           ;;
  313. ;;     size of buffer in [esp+8]           ;;
  314. ;;     pointer to device structure in ebx  ;;
  315. ;;                                         ;;
  316. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  317.  
  318. proc transmit stdcall bufferptr, buffersize
  319.  
  320.         pushf
  321.         cli
  322.  
  323.         DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
  324.         mov     eax, [bufferptr]
  325.         DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
  326.         [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
  327.         [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
  328.         [eax+13]:2,[eax+12]:2
  329.  
  330.         cmp     [buffersize], 1514
  331.         ja      .fail
  332.         cmp     [buffersize], 60
  333.         jb      .fail
  334.  
  335.  
  336.  
  337.  
  338.  
  339. ; Update stats
  340.         inc     [ebx + device.packets_tx]
  341.         mov     eax, [buffersize]
  342.         add     dword[ebx + device.bytes_tx], eax
  343.         adc     dword[ebx + device.bytes_tx + 4], 0
  344.  
  345.         DEBUGF  1,"Transmit OK\n"
  346.         popf
  347.         xor     eax, eax
  348.         ret
  349.  
  350.   .fail:
  351.         DEBUGF  2,"Transmit failed\n"
  352.         invoke  KernelFree, [bufferptr]
  353.         popf
  354.         or      eax, -1
  355.         ret
  356.  
  357. endp
  358.  
  359.  
  360. ;;;;;;;;;;;;;;;;;;;;;;;
  361. ;;                   ;;
  362. ;; Interrupt handler ;;
  363. ;;                   ;;
  364. ;;;;;;;;;;;;;;;;;;;;;;;
  365.  
  366. align 4
  367. int_handler:
  368.  
  369.         push    ebx esi edi
  370.  
  371.         DEBUGF  1,"INT\n"
  372. ;-------------------------------------------
  373. ; Find pointer of device wich made IRQ occur
  374.  
  375.         mov     ecx, [devices]
  376.         test    ecx, ecx
  377.         jz      .nothing
  378.         mov     esi, device_list
  379.   .nextdevice:
  380.         mov     ebx, [esi]
  381.  
  382. ;        mov     edi, [ebx + device.mmio_addr]
  383. ;        mov     eax, [edi + REG_ICR]
  384.         test    eax, eax
  385.         jnz     .got_it
  386.   .continue:
  387.         add     esi, 4
  388.         dec     ecx
  389.         jnz     .nextdevice
  390.   .nothing:
  391.         pop     edi esi ebx
  392.         xor     eax, eax
  393.  
  394.         ret
  395.  
  396.   .got_it:
  397.  
  398.         DEBUGF  1,"Device: %x Status: %x ", ebx, eax
  399.  
  400.         pop     edi esi ebx
  401.         xor     eax, eax
  402.         inc     eax
  403.  
  404.         ret
  405.  
  406.  
  407.  
  408.  
  409. ; End of code
  410.  
  411. data fixups
  412. end data
  413.  
  414. include '../peimport.inc'
  415.  
  416. my_service      db 'BCM57XX',0                   ; max 16 chars include zero
  417.  
  418. include_debug_strings                           ; All data wich FDO uses will be included here
  419.  
  420. align 4
  421. devices         dd 0
  422. device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling
  423.  
  424.  
  425.