Subversion Repositories Kolibri OS

Rev

Rev 5565 | 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. ;;  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: 5522 $
  18.  
  19. ETH_FRAME_MINIMUM       = 60
  20. ETH_QUEUE_SIZE          = 255
  21.  
  22. struct  ETH_header
  23.  
  24.         DstMAC          dp  ?  ; destination MAC-address
  25.         SrcMAC          dp  ?  ; source MAC-address
  26.         Type            dw  ?  ; type of the upper-layer protocol
  27.  
  28. ends
  29.  
  30. struct  ETH_DEVICE      NET_DEVICE
  31.  
  32.         mac             dp ?
  33.  
  34. ends
  35.  
  36. iglobal
  37. align 4
  38.  
  39.         ETH_BROADCAST   dp 0xffffffffffff
  40.  
  41.         ETH_frame_queued        dd 0    ; Number of queued frames
  42.  
  43.         ETH_frame_head          dd ETH_frame_head       ; Pointer to next frame in the linked list
  44.         ETH_frame_tail          dd ETH_frame_head       ; Pointer to last frame in the linked list
  45.  
  46. endg
  47.  
  48. uglobal
  49. align 4
  50.         ETH_input_event dd ?
  51. endg
  52.  
  53. macro   ETH_init {
  54.  
  55.         movi    ebx, 1
  56.         mov     ecx, ETH_process_input
  57.         call    new_sys_threads
  58.         test    eax, eax
  59.         jns     @f
  60.         DEBUGF  DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for ethernet, error %d\n', eax
  61.   @@:
  62.  
  63. }
  64.  
  65. ;-----------------------------------------------------------------
  66. ;
  67. ; ETH_input
  68. ;
  69. ;  This function is called by ethernet drivers,
  70. ;  It pushes the received ethernet packets onto the ethernet input queue
  71. ;
  72. ;  IN:  [esp] = Pointer to buffer
  73. ;
  74. ;  OUT: /
  75. ;
  76. ;-----------------------------------------------------------------
  77. align 4
  78. ETH_input:
  79.  
  80.         pop     eax
  81.         pushf
  82.         cli
  83.  
  84.         cmp     [ETH_frame_queued], ETH_QUEUE_SIZE
  85.         jae     .full
  86.         inc     [ETH_frame_queued]
  87.  
  88. ; Add frame to the end of the linked list
  89.         mov     [eax + NET_BUFF.NextPtr], ETH_frame_head
  90.  
  91.         mov     ebx, [ETH_frame_tail]
  92.         mov     [eax + NET_BUFF.PrevPtr], ebx
  93.  
  94.         mov     [ETH_frame_tail], eax
  95.         mov     [ebx + NET_BUFF.NextPtr], eax
  96.  
  97.         popf
  98.  
  99. ; Now queue an event to process it
  100.         xor     edx, edx
  101.         mov     eax, [ETH_input_event]
  102.         mov     ebx, [eax + EVENT.id]
  103.         xor     esi, esi
  104.         call    raise_event
  105.  
  106.         ret
  107.  
  108.   .full:
  109.         DEBUGF  DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n"
  110.         popf
  111.         push    eax
  112.         call    NET_BUFF_free
  113.         ret
  114.  
  115.  
  116.  
  117.  
  118. align 4
  119. ETH_process_input:
  120.  
  121.         xor     esi, esi
  122.         mov     ecx, MANUAL_DESTROY
  123.         call    create_event
  124.         mov     [ETH_input_event], eax
  125.         pushf
  126.   .wait:
  127.         popf
  128.         mov     eax, [ETH_input_event]
  129.         mov     ebx, [eax + EVENT.id]
  130.         call    wait_event
  131.  
  132.   .loop:
  133.         pushf
  134.         cli
  135.         cmp     [ETH_frame_queued], 0
  136.         je      .wait
  137.  
  138.         dec     [ETH_frame_queued]
  139.  
  140.         mov     esi, [ETH_frame_head]
  141.         mov     ebx, [esi + NET_BUFF.NextPtr]
  142.  
  143.         mov     [ETH_frame_head], ebx
  144.         mov     [ebx + NET_BUFF.PrevPtr], ETH_frame_head
  145.  
  146.         popf
  147.  
  148.         mov     eax, [esi + NET_BUFF.offset]
  149.         add     eax, esi
  150.         mov     ecx, [esi + NET_BUFF.length]
  151.         mov     ebx, [esi + NET_BUFF.device]
  152.  
  153.         pushd   .loop           ; return address for protocol handler
  154.         push    esi             ; keep pointer to NET_BUFF on stack
  155.  
  156.         DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx
  157.         sub     ecx, sizeof.ETH_header
  158.         jb      .dump
  159.  
  160. ; Set registers for protocol handlers
  161.         lea     edx, [eax + sizeof.ETH_header]
  162.         mov     ax, [eax + ETH_header.Type]
  163.  
  164. ; Place protocol handlers here
  165.         cmp     ax, ETHER_PROTO_IPv4
  166.         je      IPv4_input
  167.  
  168.         cmp     ax, ETHER_PROTO_ARP
  169.         je      ARP_input
  170.  
  171. ;        cmp     ax, ETHER_PROTO_IPv6
  172. ;        je      IPv6_input
  173.  
  174. ;        cmp     ax, ETHER_PROTO_PPP_DISCOVERY
  175. ;        je      PPPoE_discovery_input
  176.  
  177. ;        cmp     ax, ETHER_PROTO_PPP_SESSION
  178. ;        je      PPPoE_session_input
  179.  
  180.         DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax
  181.  
  182.   .dump:
  183.         DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: dumping\n"
  184.         call    NET_BUFF_free
  185.         ret
  186.  
  187. ;-----------------------------------------------------------------
  188. ;
  189. ; ETH_output
  190. ;
  191. ; IN:  ax = protocol
  192. ;     ebx = device ptr
  193. ;     ecx = payload size
  194. ;     edx = pointer to destination mac
  195. ;
  196. ; OUT: eax = start of net frame / 0 on error
  197. ;      ebx = device ptr
  198. ;      ecx = payload size
  199. ;      edi = start of payload
  200. ;
  201. ;-----------------------------------------------------------------
  202. align 4
  203. ETH_output:
  204.  
  205.         DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx
  206.  
  207.         cmp     ecx, [ebx + ETH_DEVICE.mtu]
  208.         ja      .exit
  209.  
  210.         push    ecx
  211.         push    ax edx
  212.  
  213.         add     ecx, sizeof.ETH_header + NET_BUFF.data
  214.         stdcall NET_BUFF_alloc, ecx
  215.         test    eax, eax
  216.         jz      .out_of_ram
  217.         mov     [eax + NET_BUFF.type], NET_BUFF_ETH
  218.         mov     [eax + NET_BUFF.device], ebx
  219.         mov     [eax + NET_BUFF.offset], NET_BUFF.data
  220.         lea     edi, [eax + NET_BUFF.data]
  221.  
  222.         pop     esi
  223.         movsd
  224.         movsw
  225.         lea     esi, [ebx + ETH_DEVICE.mac]
  226.         movsd
  227.         movsw
  228.         pop     ax
  229.         stosw
  230.  
  231.         lea     eax, [edi - sizeof.ETH_header - NET_BUFF.data]  ; Set eax to buffer start
  232.         pop     ecx
  233.  
  234.         lea     edx, [ecx + sizeof.ETH_header]  ; Set edx to complete buffer size
  235.         cmp     edx, ETH_FRAME_MINIMUM
  236.         jbe     .adjust_size
  237.   .done:
  238.         mov     [eax + NET_BUFF.length], edx
  239.         DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: ptr=%x size=%u\n", eax, edx
  240.         ret
  241.  
  242.   .adjust_size:
  243.         mov     edx, ETH_FRAME_MINIMUM
  244.         test    edx, edx                        ; clear zero flag
  245.         jmp     .done
  246.  
  247.   .out_of_ram:
  248.         DEBUGF  DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n"
  249.         add     esp, 4+2+4
  250.         xor     eax, eax
  251.         ret
  252.  
  253.   .exit:
  254.         DEBUGF  DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n"
  255.         xor     eax, eax
  256.         ret
  257.  
  258.  
  259.  
  260. ;-----------------------------------------------------------------
  261. ;
  262. ; ETH_API
  263. ;
  264. ; This function is called by system function 76
  265. ;
  266. ; IN:  subfunction number in bl
  267. ;      device number in bh
  268. ;      ecx, edx, .. depends on subfunction
  269. ;
  270. ; OUT:
  271. ;
  272. ;-----------------------------------------------------------------
  273. align 4
  274. ETH_api:
  275.  
  276.         cmp     bh, NET_DEVICES_MAX
  277.         ja      .error
  278.         movzx   eax, bh
  279.         mov     eax, dword [NET_DRV_LIST + 4*eax]
  280.         cmp     [eax + NET_DEVICE.device_type], NET_DEVICE_ETH
  281.         jne     .error
  282.  
  283.         and     ebx, 0xff
  284.         cmp     ebx, .number
  285.         ja      .error
  286.         jmp     dword [.table + 4*ebx]
  287.  
  288.   .table:
  289.         dd      .read_mac       ; 0
  290.   .number = ($ - .table) / 4 - 1
  291.  
  292.   .error:
  293.         or      eax, -1
  294.         ret
  295.  
  296.  
  297.   .read_mac:
  298.         movzx   ebx, word [eax + ETH_DEVICE.mac]
  299.         mov     eax, dword [eax + ETH_DEVICE.mac + 2]
  300.         mov     [esp+20+4], ebx                         ; FIXME
  301.         ret
  302.  
  303.  
  304.