Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2019. 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: 7679 $
  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: This function is called by ethernet drivers.         ;
  68. ; Push the received ethernet packet onto the ethernet input queue.;
  69. ;                                                                 ;
  70. ;  IN:  [esp] = Pointer to buffer                                 ;
  71. ;                                                                 ;
  72. ;  OUT: /                                                         ;
  73. ;                                                                 ;
  74. ;-----------------------------------------------------------------;
  75. align 4
  76. eth_input:
  77.  
  78.         pop     eax
  79.         pushf
  80.         cli
  81.  
  82.         cmp     [ETH_frame_queued], ETH_QUEUE_SIZE
  83.         jae     .full
  84.         inc     [ETH_frame_queued]
  85.  
  86. ; Add frame to the end of the linked list
  87.         mov     [eax + NET_BUFF.NextPtr], ETH_frame_head
  88.  
  89.         mov     ebx, [ETH_frame_tail]
  90.         mov     [eax + NET_BUFF.PrevPtr], ebx
  91.  
  92.         mov     [ETH_frame_tail], eax
  93.         mov     [ebx + NET_BUFF.NextPtr], eax
  94.  
  95.         popf
  96.  
  97. ; Mark it as being an Ethernet Frame
  98.         mov     [eax + NET_BUFF.type], NET_BUFF_ETH
  99.  
  100. ; Now queue an event to process it
  101.         xor     edx, edx
  102.         mov     eax, [ETH_input_event]
  103.         mov     ebx, [eax + EVENT.id]
  104.         xor     esi, esi
  105.         call    raise_event
  106.  
  107.         ret
  108.  
  109.   .full:
  110.         DEBUGF  DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n"
  111.         popf
  112.         push    eax
  113.         call    net_buff_free
  114.         ret
  115.  
  116.  
  117.  
  118. ;-----------------------------------------------------------------;
  119. ;                                                                 ;
  120. ; eth_process_input: Process packets from ethernet input queue.   ;
  121. ;                                                                 ;
  122. ;  IN:  /                                                         ;
  123. ;                                                                 ;
  124. ;  OUT: /                                                         ;
  125. ;                                                                 ;
  126. ;-----------------------------------------------------------------;
  127. align 4
  128. eth_process_input:
  129.  
  130.         xor     esi, esi
  131.         mov     ecx, MANUAL_DESTROY
  132.         call    create_event
  133.         mov     [ETH_input_event], eax
  134.         pushf
  135.   .wait:
  136.         popf
  137.         mov     eax, [ETH_input_event]
  138.         mov     ebx, [eax + EVENT.id]
  139.         call    wait_event
  140.  
  141.   .loop:
  142.         pushf
  143.         cli
  144.         cmp     [ETH_frame_queued], 0
  145.         je      .wait
  146.  
  147.         dec     [ETH_frame_queued]
  148.  
  149.         mov     esi, [ETH_frame_head]
  150.         mov     ebx, [esi + NET_BUFF.NextPtr]
  151.  
  152.         mov     [ETH_frame_head], ebx
  153.         mov     [ebx + NET_BUFF.PrevPtr], ETH_frame_head
  154.  
  155.         popf
  156.  
  157.         mov     eax, [esi + NET_BUFF.offset]
  158.         add     eax, esi
  159.         mov     ecx, [esi + NET_BUFF.length]
  160.         mov     ebx, [esi + NET_BUFF.device]
  161.  
  162.         pushd   .loop           ; return address for protocol handler
  163.         push    esi             ; keep pointer to NET_BUFF on stack
  164.  
  165.         DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx
  166.         sub     ecx, sizeof.ETH_header
  167.         jb      .dump
  168.  
  169. ; Set registers for protocol handlers
  170.         lea     edx, [eax + sizeof.ETH_header]
  171.         mov     ax, [eax + ETH_header.Type]
  172.  
  173. ; Place protocol handlers here
  174.         cmp     ax, ETHER_PROTO_IPv4
  175.         je      ipv4_input
  176.  
  177.         cmp     ax, ETHER_PROTO_ARP
  178.         je      arp_input
  179.  
  180. ;        cmp     ax, ETHER_PROTO_IPv6
  181. ;        je      ipv6_input
  182.  
  183. ;        cmp     ax, ETHER_PROTO_PPP_DISCOVERY
  184. ;        je      pppoe_discovery_input
  185.  
  186. ;        cmp     ax, ETHER_PROTO_PPP_SESSION
  187. ;        je      pppoe_session_input
  188.  
  189.         DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax
  190.  
  191.   .dump:
  192.         DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: dumping\n"
  193.         call    net_buff_free
  194.         ret
  195.  
  196.  
  197.  
  198. ;-----------------------------------------------------------------;
  199. ;                                                                 ;
  200. ; eth_output                                                      ;
  201. ;                                                                 ;
  202. ;  IN:  ax = protocol                                             ;
  203. ;       ebx = device ptr                                          ;
  204. ;       ecx = payload size                                        ;
  205. ;       edx = pointer to destination mac                          ;
  206. ;                                                                 ;
  207. ;  OUT: eax = start of net frame / 0 on error                     ;
  208. ;       ebx = device ptr                                          ;
  209. ;       ecx = payload size                                        ;
  210. ;       edi = start of payload                                    ;
  211. ;                                                                 ;
  212. ;-----------------------------------------------------------------;
  213. align 4
  214. eth_output:
  215.  
  216.         DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx
  217.  
  218.         cmp     ecx, [ebx + ETH_DEVICE.mtu]
  219.         ja      .exit
  220.  
  221.         push    ecx
  222.         push    ax edx
  223.  
  224.         add     ecx, sizeof.ETH_header + NET_BUFF.data
  225.         stdcall net_buff_alloc, ecx
  226.         test    eax, eax
  227.         jz      .out_of_ram
  228.         mov     [eax + NET_BUFF.type], NET_BUFF_ETH
  229.         mov     [eax + NET_BUFF.device], ebx
  230.         mov     [eax + NET_BUFF.offset], NET_BUFF.data
  231.         lea     edi, [eax + NET_BUFF.data]
  232.  
  233.         pop     esi
  234.         movsd
  235.         movsw
  236.         lea     esi, [ebx + ETH_DEVICE.mac]
  237.         movsd
  238.         movsw
  239.         pop     ax
  240.         stosw
  241.  
  242.         lea     eax, [edi - sizeof.ETH_header - NET_BUFF.data]  ; Set eax to buffer start
  243.         pop     ecx
  244.  
  245.         lea     edx, [ecx + sizeof.ETH_header]  ; Set edx to complete buffer size
  246.         cmp     edx, ETH_FRAME_MINIMUM
  247.         jbe     .adjust_size
  248.   .done:
  249.         mov     [eax + NET_BUFF.length], edx
  250.         DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: ptr=%x size=%u\n", eax, edx
  251.         ret
  252.  
  253.   .adjust_size:
  254.         mov     edx, ETH_FRAME_MINIMUM
  255.         test    edx, edx                        ; clear zero flag
  256.         jmp     .done
  257.  
  258.   .out_of_ram:
  259.         DEBUGF  DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n"
  260.         add     esp, 4+2+4
  261.         xor     eax, eax
  262.         ret
  263.  
  264.   .exit:
  265.         DEBUGF  DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n"
  266.         xor     eax, eax
  267.         ret
  268.  
  269.  
  270.  
  271. ;-----------------------------------------------------------------;
  272. ;                                                                 ;
  273. ; eth_api: Part of system function 76.                            ;
  274. ;                                                                 ;
  275. ;  IN:  bl = subfunction number                                   ;
  276. ;       bh = device number                                        ;
  277. ;       ecx, edx, .. depends on subfunction                       ;
  278. ;                                                                 ;
  279. ; OUT:  depends on subfunction                                    ;
  280. ;                                                                 ;
  281. ;-----------------------------------------------------------------;
  282. align 4
  283. eth_api:
  284.  
  285.         cmp     bh, NET_DEVICES_MAX
  286.         ja      .error
  287.         movzx   eax, bh
  288.         mov     eax, dword [net_device_list + 4*eax]
  289.         cmp     [eax + NET_DEVICE.device_type], NET_DEVICE_ETH
  290.         jne     .error
  291.  
  292.         and     ebx, 0xff
  293.         cmp     ebx, .number
  294.         ja      .error
  295.         jmp     dword [.table + 4*ebx]
  296.  
  297.   .table:
  298.         dd      .read_mac       ; 0
  299.   .number = ($ - .table) / 4 - 1
  300.  
  301.   .error:
  302.         or      eax, -1
  303.         ret
  304.  
  305.  
  306.   .read_mac:
  307.         movzx   ebx, word [eax + ETH_DEVICE.mac]
  308.         mov     eax, dword [eax + ETH_DEVICE.mac + 2]
  309.         mov     [esp+20+4], ebx                         ; FIXME
  310.         ret
  311.  
  312.  
  313.