Subversion Repositories Kolibri OS

Rev

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