Subversion Repositories Kolibri OS

Rev

Rev 3545 | Blame | Last modification | View Log | Download | RSS feed

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