Subversion Repositories Kolibri OS

Rev

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