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. ;;  ETHERNET.INC                                                   ;;
  7. ;;                                                                 ;;
  8. ;;  Ethernet network layer for KolibriOS                           ;;
  9. ;;                                                                 ;;
  10. ;;    Written by hidnplayr@kolibrios.org                           ;;
  11. ;;                                                                 ;;
  12. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  13. ;;             Version 2, June 1991                                ;;
  14. ;;                                                                 ;;
  15. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  16.  
  17. $Revision: 983 $
  18.  
  19. MAX_ETH_DEVICES         equ MAX_NET_DEVICES
  20. ETH_QUEUE_SIZE          equ 16
  21.  
  22. struct  ETH_FRAME
  23.         .DstMAC         dp  ?  ; destination MAC-address [6 bytes]
  24.         .SrcMAC         dp  ?  ; source MAC-address [6 bytes]
  25.         .Type           dw  ?  ; type of the upper-layer protocol [2 bytes]
  26.         .Data:                 ; data [46-1500 bytes]
  27. ends
  28.  
  29. struct  ETH_DEVICE
  30.         .unload         dd ?
  31.         .reset          dd ?
  32.         .transmit       dd ?
  33.         .set_MAC        dd ?
  34.         .get_MAC        dd ?
  35.         .set_mode       dd ?
  36.         .get_mode       dd ?
  37.  
  38.         .bytes_tx       dq ?
  39.         .bytes_rx       dq ?
  40.         .packets_tx     dd ?
  41.         .packets_rx     dd ?
  42.         .mode           dd ?  ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..)
  43.         .name           dd ?
  44.         .mac            dp ?
  45. ends                          ; the rest of the device struct depends on the type of device
  46.  
  47.  
  48. align 4
  49. uglobal
  50.  
  51.         ETH_RUNNING     dd  ?
  52.         ETH_DRV_LIST    rd  MAX_ETH_DEVICES
  53.         ETH_IN_QUEUE    rd  3*ETH_QUEUE_SIZE+3
  54.         ETH_OUT_QUEUE   rd  3*ETH_QUEUE_SIZE+3
  55. endg
  56.  
  57.  
  58. ;-----------------------------------------------
  59. ;
  60. ; ETH_init
  61. ;
  62. ;  This function resets all ethernet variables
  63. ;
  64. ;  IN:  /
  65. ;  OUT: /
  66. ;
  67. ;-----------------------------------------------
  68.  
  69. align 4
  70. ETH_init:
  71.  
  72.         xor     eax, eax
  73.         mov     edi, ETH_RUNNING
  74.         mov     ecx, (1+MAX_ETH_DEVICES)
  75.         rep     stosd
  76.  
  77.         mov     dword [ETH_IN_QUEUE], eax
  78.         mov     dword [ETH_IN_QUEUE+4], ETH_IN_QUEUE + queue.data
  79.         mov     dword [ETH_IN_QUEUE+8], ETH_IN_QUEUE + queue.data
  80.  
  81.         mov     dword [ETH_OUT_QUEUE], eax
  82.         mov     dword [ETH_OUT_QUEUE+4], ETH_OUT_QUEUE + queue.data
  83.         mov     dword [ETH_OUT_QUEUE+8], ETH_OUT_QUEUE + queue.data
  84.  
  85.         ret
  86.  
  87.  
  88.  
  89. ;---------------------------------------------------------
  90. ;
  91. ; ETH_Add_Device:
  92. ;
  93. ;  This function is called by ethernet drivers,
  94. ;  to register each running ethernet device to the kernel
  95. ;
  96. ;  IN:  Pointer to device structure in ebx
  97. ;  OUT: Device num in eax, -1 on error
  98. ;
  99. ;---------------------------------------------------------
  100.  
  101. align 4
  102. ETH_Add_Device:
  103.  
  104.         DEBUGF  1,"ETH_Add_Device: %x\n", ebx
  105.         cmp     [ETH_RUNNING], MAX_ETH_DEVICES
  106.         jge     .error
  107.  
  108.         mov     eax, ebx
  109.         mov     ecx, MAX_ETH_DEVICES      ; We need to check whole list because a device may be removed without re-organizing list
  110.         mov     edi, ETH_DRV_LIST
  111.  
  112.         cld
  113.         repne   scasd                     ; See if device is already in the list
  114.         jz      .error
  115.  
  116.         xor     eax, eax
  117.         mov     ecx, MAX_ETH_DEVICES
  118.         mov     edi, ETH_DRV_LIST
  119.  
  120.         repne   scasd                     ; Find empty spot in the list
  121.         jnz     .error
  122.  
  123.         sub     edi, 4
  124.         mov     [edi], ebx                ; add device to list
  125.  
  126.         sub     edi, ETH_DRV_LIST         ; edi = 4*device num       Calculate device number in eax
  127.         mov     eax, edi                  ; edx = 4*device num
  128.         shr     eax, 2
  129.  
  130. ;        shr     eax, 1                    ; edx = 2*device num
  131. ;        add     edi, eax                  ; edi = 6*device_num                   Meanwhile, calculate MAC offset in edi
  132. ;        shr     eax, 1                    ; edx = device num
  133. ;        add     edi, MAC_LIST             ; edi = MAC_LIST+6*device_num
  134. ;        push    eax
  135.  
  136. ;        push    edi
  137. ;        call    [ebx+ETH_DEVICE.get_MAC]  ; Get MAC address from driver
  138. ;        pop     edi
  139. ;
  140. ;        stosd                             ; Write MAC address to the MAC list
  141. ;        mov     ax, bx                    ;
  142. ;        stosw                             ;
  143.  
  144.         inc     [ETH_RUNNING]             ; Indicate that one more ethernet device is up and running
  145. ;        pop     eax                       ; Output device num in eax
  146.         DEBUGF  1,"- succes: %u\n",eax
  147.         ret
  148.  
  149.        .error:
  150.         or      eax, -1
  151.         DEBUGF  1,"- fail\n"
  152.  
  153.         ret
  154.  
  155.  
  156.  
  157.  
  158. ;--------------------------------
  159. ;
  160. ; ETH_Remove_Device:
  161. ;
  162. ;  This function is called by ethernet drivers,
  163. ;  to unregister ethernet devices from the kernel
  164. ;
  165. ;  IN:  Pointer to device structure in ebx
  166. ;  OUT: eax: -1 on error
  167. ;
  168. ;--------------------------------
  169.  
  170. align 4
  171. ETH_Remove_Device:
  172.  
  173.         cmp     [ETH_RUNNING], 0
  174.         je      .error
  175.  
  176.         mov     eax, ebx
  177.         mov     ecx, MAX_ETH_DEVICES
  178.         mov     edi, ETH_DRV_LIST
  179.  
  180.         repne   scasd
  181.         jnz     .error
  182.  
  183.         xor     eax, eax
  184.         mov     dword [edi-4], eax
  185.  
  186.         dec     [ETH_RUNNING]
  187.  
  188.         ret
  189.  
  190.        .error:
  191.         or      eax, -1
  192.  
  193.         ret
  194.  
  195.  
  196.  
  197. ;-------------------------------------------------------------
  198. ;
  199. ; ETH_Receiver:
  200. ;
  201. ;  This function is called by ethernet drivers,
  202. ;  It pushes the received ethernet packets onto the eth_in_queue
  203. ;
  204. ;  IN:  Pointer to buffer in [esp], size of buffer in [esp-4], pointer to eth_device in ebx
  205. ;  OUT: /
  206. ;
  207. ;-------------------------------------------------------------
  208.  
  209. align 4
  210. ETH_Receiver:
  211.         DEBUGF  1,"ETH_Receiver \n"
  212.  
  213.         add_to_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, .gohome
  214.  
  215.   .gohome:
  216.         ret
  217.  
  218.  
  219.  
  220.  
  221.  
  222. ;-------------------------------------------------------------
  223. ;
  224. ; ETH_Handler:
  225. ;
  226. ;  Handles all queued eth packets (called from kernel's main_loop)
  227. ;
  228. ;  IN:  /
  229. ;  OUT: /
  230. ;
  231. ;-------------------------------------------------------------
  232.  
  233. align 4
  234. ETH_Handler:
  235.  
  236.         get_from_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, .gohome
  237.  
  238.         DEBUGF  1,"ETH_Handler - size: %u\n", ecx
  239.         cmp     ecx, 60    ; check packet length
  240.         jl      .dump
  241.         sub     ecx, ETH_FRAME.Data
  242.  
  243.         lea     edx, [eax + ETH_FRAME.Data]
  244.         mov     ax , [eax + ETH_FRAME.Type]
  245.  
  246.         cmp     ax, ETHER_IPv4
  247.         je      IPv4_Handler
  248.  
  249.         cmp     ax, ETHER_ARP
  250.         je      ARP_Handler
  251.  
  252.         DEBUGF  1,"Unknown ethernet packet type %x\n", ax
  253.  
  254.   .dump:
  255.         DEBUGF  1,"Dumping packet\n"
  256.         call    kernel_free
  257.         add     esp, 4
  258.  
  259.   .gohome:
  260.         ret                             ; return 1. to get more from queue / 2. to caller
  261.  
  262.  
  263.  
  264. ;-----------------------------------------------------------------
  265. ;
  266. ; ETH_Sender:
  267. ;
  268. ;  This function sends an ethernet packet to the correct driver.
  269. ;
  270. ;  IN:  Pointer to buffer in [esp]
  271. ;       size of buffer in [esp+4]
  272. ;       pointer to device struct in ebx
  273. ;  OUT: /
  274. ;
  275. ;-----------------------------------------------------------------
  276.  
  277. align 4
  278. ETH_Sender:
  279.         DEBUGF  1,"ETH_Sender \n"
  280.  
  281.         add_to_queue ETH_OUT_QUEUE, ETH_QUEUE_SIZE, .gohome
  282.  
  283.   .gohome:
  284.         ret
  285.  
  286.  
  287. align 4
  288. ETH_send_queued:
  289.  
  290.         get_from_queue ETH_OUT_QUEUE, ETH_QUEUE_SIZE, .gohome
  291.  
  292.         call    ETH_struc2dev            ; convert struct ptr to device num (this way we know if driver is still mounted)
  293.         cmp     edi, -1
  294.         je      .fail
  295.  
  296.         DEBUGF 1,"ETH_Sender - device: %u\n", edi
  297.  
  298.         jmp     [ebx+ETH_DEVICE.transmit]
  299.  
  300.      .fail:
  301.         call    kernel_free
  302.         add     esp, 4 ; pop (balance stack)
  303.         DEBUGF 1,"ETH_Sender - fail\n"
  304.      .gohome:
  305.         ret
  306.  
  307. ;---------------------------------------------------------------------------
  308. ;
  309. ; ETH_struc2dev
  310. ;
  311. ; IN: pointer to device struct in ebx
  312. ;
  313. ; OUT: edi is -1 on error, device number otherwise
  314. ;
  315. ;---------------------------------------------------------------------------
  316.  
  317. align 4
  318. ETH_struc2dev:
  319.         push    eax ecx
  320.  
  321.         mov     eax, ebx
  322.         mov     ecx, MAX_ETH_DEVICES
  323.         mov     edi, ETH_DRV_LIST
  324.  
  325.         repne   scasd
  326.         jnz     .error
  327.  
  328.         sub     edi, ETH_DRV_LIST+4
  329.         shr     edi, 2
  330.  
  331.         pop     ecx eax
  332.         ret
  333.   .error:
  334.         or      edi, -1
  335.         pop     ecx eax
  336.  
  337.         ret
  338.  
  339.  
  340. ;---------------------------------------------------------------------------
  341. ;
  342. ; ETH_create_Packet
  343. ;
  344. ; IN: pointer to source mac in eax
  345. ;     pointer to destination mac in ebx
  346. ;     packet size in ecx
  347. ;     device number in edx
  348. ;     protocol in di
  349. ;
  350. ; OUT: edi is -1 on error, pointer to buffer otherwise                    ;; TODO: XCHG EDX AND EBX output parameters
  351. ;      eax points to buffer start
  352. ;      ebx is size of complete buffer
  353. ;      ecx is unchanged (packet size of embedded data)
  354. ;      edx is pointer to device structure
  355. ;      esi points to procedure wich needs to be called to send packet
  356. ;
  357. ;---------------------------------------------------------------------------
  358.  
  359. align 4
  360. ETH_create_Packet:
  361.  
  362.         DEBUGF 1,"Creating Ethernet Packet:\n"
  363.  
  364.         cmp     ecx, 60-ETH_FRAME.Data
  365.         jl      .exit
  366.         cmp     ecx, 1514-ETH_FRAME.Data
  367.         jg      .exit
  368.  
  369.         push    ecx di eax ebx edx
  370.  
  371.         add     ecx, ETH_FRAME.Data
  372.         push    ecx
  373.         push    ecx
  374.         call    kernel_alloc
  375.         test    eax, eax
  376.         jz      .pop_exit
  377.  
  378.         pop     ecx
  379.         pop     edx
  380.  
  381.         DEBUGF 1,"1"
  382.         mov     edi, eax
  383.         pop     esi
  384.         movsd
  385.         movsw
  386.         DEBUGF 1,"2"
  387.         pop     esi
  388.         movsd
  389.         movsw
  390.         DEBUGF 1,"3"
  391.         pop     ax
  392.         stosw
  393.         DEBUGF 1,"4"
  394.  
  395.         lea     eax, [edi - ETH_FRAME.Data]  ; Set eax to buffer start
  396.         mov     ebx, ecx                     ; Set ebx to complete buffer size
  397.         pop     ecx
  398.         mov     esi, ETH_Sender
  399.  
  400.         xor     edx, edx ;;;; TODO: Fixme
  401.         mov     edx, [ETH_DRV_LIST + edx]
  402.  
  403.         DEBUGF 1,"done: %x size:%u device:%x\n", eax, ebx, edx
  404.         ret
  405.  
  406.   .pop_exit:
  407.         add     esp, 18
  408.   .exit:
  409.         or      edi, -1
  410.         ret
  411.  
  412.  
  413.  
  414.  
  415. ;---------------------------------------------------------------------------
  416. ;
  417. ; ETH_API
  418. ;
  419. ; This function is called by system function 75
  420. ;
  421. ; IN:  subfunction number in bl
  422. ;      device number in bh
  423. ;      ecx, edx, .. depends on subfunction
  424. ;
  425. ; OUT:
  426. ;
  427. ;---------------------------------------------------------------------------
  428.  
  429. align 4
  430. ETH_API:
  431.  
  432.         movzx   eax, bh
  433.         shl     eax, 2
  434.  
  435.         test    bl, bl
  436.         jz      .packets_tx     ; 0
  437.         dec     bl
  438.         jz      .packets_rx     ; 1
  439.         dec     bl
  440.         jz      .bytes_tx       ; 2
  441.         dec     bl
  442.         jz      .bytes_rx       ; 3
  443.         dec     bl
  444.         jz      .read_mac       ; 4
  445.         dec     bl
  446.         jz      .write_mac      ; 5
  447.         dec     bl
  448.         jz      .in_queue       ; 6
  449.         dec     bl
  450.         jz      .out_queue      ; 7
  451.  
  452. .error:
  453.         mov     eax, -1
  454.         ret
  455.  
  456. .packets_tx:
  457.         add     eax, ETH_DRV_LIST
  458.         mov     eax, dword [eax]
  459.         mov     eax, dword [eax + ETH_DEVICE.packets_tx]
  460.  
  461.         ret
  462.  
  463. .packets_rx:
  464.         add     eax, ETH_DRV_LIST
  465.         mov     eax, dword [eax]
  466.         mov     eax, dword [eax + ETH_DEVICE.packets_rx]
  467.         ret
  468.  
  469. .bytes_tx:
  470.         add     eax, ETH_DRV_LIST
  471.         mov     eax, dword [eax]
  472.         mov     eax, dword [eax + ETH_DEVICE.bytes_tx + 4]
  473.         ret
  474.  
  475. .bytes_rx:
  476.         add     eax, ETH_DRV_LIST
  477.         mov     eax, dword [eax]
  478.         mov     eax, dword [eax + ETH_DEVICE.bytes_rx + 4]
  479.         ret
  480.  
  481. .read_mac:
  482.         add     eax, ETH_DRV_LIST
  483.         mov     eax, [eax]
  484. ;        push    eax
  485. ;        call    dword [eax + ETH_DEVICE.get_MAC]
  486. ;        pop     eax
  487.         movzx   ebx, word [eax + ETH_DEVICE.mac]
  488.         mov     eax, dword [eax + ETH_DEVICE.mac + 2]
  489.         mov     [esp+20+4], ebx                         ; TODO: fix this ugly code
  490.         ret
  491.  
  492. .write_mac:
  493.         push    ecx
  494.         push    dx
  495.         add     eax, ETH_DRV_LIST
  496.         mov     eax, [eax]
  497.         mov     eax, dword [eax + ETH_DEVICE.set_MAC]
  498.         call    eax
  499.         ret
  500.  
  501. .in_queue:
  502.         add     eax, ETH_IN_QUEUE
  503.         mov     eax, [eax + queue.size]
  504.         ret
  505.  
  506. .out_queue:
  507.         add     eax, ETH_OUT_QUEUE
  508.         mov     eax, [eax + queue.size]
  509.         ret