Subversion Repositories Kolibri OS

Rev

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

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