Subversion Repositories Kolibri OS

Rev

Rev 1241 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2009. 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: 1249 $
  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. iglobal
  50.  
  51.         ETH_BROADCAST   dp  0xffffffffffff
  52. endg
  53.  
  54. align 4
  55. uglobal
  56.  
  57.         ETH_RUNNING     dd  ?
  58.         ETH_DRV_LIST    rd  MAX_ETH_DEVICES
  59.         ETH_IN_QUEUE    rd  3*ETH_QUEUE_SIZE+3
  60.         ETH_OUT_QUEUE   rd  3*ETH_QUEUE_SIZE+3
  61. endg
  62.  
  63.  
  64. ;-----------------------------------------------
  65. ;
  66. ; ETH_init
  67. ;
  68. ;  This function resets all ethernet variables
  69. ;
  70. ;  IN:  /
  71. ;  OUT: /
  72. ;
  73. ;-----------------------------------------------
  74.  
  75. align 4
  76. ETH_init:
  77.  
  78.         xor     eax, eax
  79.         mov     edi, ETH_RUNNING
  80.         mov     ecx, (1+MAX_ETH_DEVICES)
  81.         rep     stosd
  82.  
  83.         init_queue ETH_IN_QUEUE
  84.         init_queue ETH_OUT_QUEUE
  85.  
  86.         ret
  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 ", ebx
  105.  
  106.         mov     eax, [ETH_RUNNING]
  107.         cmp     eax, MAX_ETH_DEVICES
  108.         jge     .error
  109.  
  110.         test    eax, eax
  111.         jnz     .notfirst
  112.         mov     dword [ETH_IN_QUEUE], eax
  113.         mov     dword [ETH_OUT_QUEUE], eax
  114.       .notfirst:
  115.  
  116.         mov     eax, ebx
  117.         mov     ecx, MAX_ETH_DEVICES      ; We need to check whole list because a device may be removed without re-organizing list
  118.         mov     edi, ETH_DRV_LIST
  119.  
  120.         repne   scasd                     ; See if device is already in the list
  121.         jz      .error
  122.  
  123.         xor     eax, eax
  124.         mov     ecx, MAX_ETH_DEVICES
  125.         mov     edi, ETH_DRV_LIST
  126.  
  127.         repne   scasd                     ; Find empty spot in the list
  128.         jnz     .error
  129.  
  130.         sub     edi, 4
  131.         mov     [edi], ebx                ; add device to list
  132.  
  133.         sub     edi, ETH_DRV_LIST         ; edi = 4*device num       Calculate device number in eax
  134.         mov     eax, edi                  ; edx = 4*device num
  135.         shr     eax, 2
  136.  
  137.         inc     [ETH_RUNNING]             ; Indicate that one more ethernet device is up and running
  138.  
  139.         DEBUGF  1,"- succes: %u\n",eax
  140.         ret
  141.  
  142.        .error:
  143.         or      eax, -1
  144.         DEBUGF  1,"- fail\n"
  145.  
  146.         ret
  147.  
  148.  
  149.  
  150.  
  151. ;--------------------------------
  152. ;
  153. ; ETH_Remove_Device:
  154. ;
  155. ;  This function is called by ethernet drivers,
  156. ;  to unregister ethernet devices from the kernel
  157. ;
  158. ;  IN:  Pointer to device structure in ebx
  159. ;  OUT: eax: -1 on error
  160. ;
  161. ;--------------------------------
  162.  
  163. align 4
  164. ETH_remove_device:
  165.  
  166.         cmp     [ETH_RUNNING], 0
  167.         je      .error
  168.  
  169.         mov     eax, ebx
  170.         mov     ecx, MAX_ETH_DEVICES
  171.         mov     edi, ETH_DRV_LIST
  172.  
  173.         repne   scasd
  174.         jnz     .error
  175.  
  176.         xor     eax, eax
  177.         mov     dword [edi-4], eax
  178.  
  179.         dec     [ETH_RUNNING]
  180.         jnz     .notlast
  181.  
  182.         mov     dword [ETH_IN_QUEUE], ETH_QUEUE_SIZE
  183.         mov     dword [ETH_OUT_QUEUE], ETH_QUEUE_SIZE
  184.  
  185.        .notlast:
  186.  
  187.         ret
  188.  
  189.        .error:
  190.         or      eax, -1
  191.  
  192.         ret
  193.  
  194.  
  195.  
  196. ;-------------------------------------------------------------
  197. ;
  198. ; ETH_Receiver:
  199. ;
  200. ;  This function is called by ethernet drivers,
  201. ;  It pushes the received ethernet packets onto the eth_in_queue
  202. ;
  203. ;  IN:  Pointer to buffer in [esp], size of buffer in [esp-4], pointer to eth_device in ebx
  204. ;  OUT: /
  205. ;
  206. ;-------------------------------------------------------------
  207.  
  208. align 4
  209. ETH_receiver:
  210.         DEBUGF  1,"ETH_Receiver: "
  211.  
  212.         push    ebx
  213.         mov     esi, esp
  214.         add_to_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .fail
  215.         DEBUGF  1,"Queued packet successfully\n"
  216.         add     esp, 4*3
  217.         ret
  218.  
  219.   .fail:
  220.         DEBUGF  1,"ETH_IN_QUEUE is full!\n"
  221.         add     esp, 4
  222.         call    kernel_free
  223.         add     esp, 4
  224.         ret
  225.  
  226.  
  227.  
  228.  
  229.  
  230. ;-------------------------------------------------------------
  231. ;
  232. ; ETH_Handler:
  233. ;
  234. ;  Handles all queued eth packets (called from kernel's main_loop)
  235. ;
  236. ;  IN:  /
  237. ;  OUT: /
  238. ;
  239. ;-------------------------------------------------------------
  240.  
  241. align 4
  242. ETH_handler:
  243.  
  244.         get_from_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .gohome
  245.  
  246.         push    ETH_handler
  247.  
  248.         lodsd
  249.         mov     ebx, eax
  250.         lodsd
  251.         mov     ecx, eax
  252.         lodsd
  253.         xchg    eax, ecx
  254.         push    ecx
  255.         push    eax
  256.  
  257.         DEBUGF  1,"ETH_Handler - size: %u\n", ecx
  258.         cmp     ecx, 60    ; check packet length
  259.         jl      .dump
  260.         sub     ecx, ETH_FRAME.Data
  261.  
  262.         lea     edx, [eax + ETH_FRAME.Data]
  263.         mov     ax , [eax + ETH_FRAME.Type]
  264.  
  265.         cmp     ax, ETHER_IPv4
  266.         je      IPv4_handler
  267.  
  268.         cmp     ax, ETHER_ARP
  269.         je      ARP_handler
  270.  
  271.         DEBUGF  1,"Unknown ethernet packet type %x\n", ax
  272.  
  273.   .dump:
  274.         DEBUGF  1,"Dumping packet\n"
  275.         call    kernel_free
  276.         add     esp, 4
  277.  
  278.   .gohome:
  279.         ret                             ; return to get more from queue / to caller
  280.  
  281.  
  282.  
  283. ;-----------------------------------------------------------------
  284. ;
  285. ; ETH_sender:
  286. ;
  287. ;  This function sends an ethernet packet to the correct driver.
  288. ;
  289. ;  IN:  Pointer to buffer in [esp]
  290. ;       size of buffer in [esp+4]
  291. ;       pointer to device struct in ebx
  292. ;  OUT: /
  293. ;
  294. ;-----------------------------------------------------------------
  295.  
  296. align 4
  297. ETH_sender:
  298.         DEBUGF  1,"ETH_Sender: queuing for device: %x, %u bytes\n", [esp], [esp + 4]
  299.  
  300.         push    ebx
  301.         mov     esi, esp
  302.         add_to_queue ETH_OUT_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .fail
  303.         DEBUGF  1,"Queued packet successfully\n"
  304.         add     esp, 3*4
  305.         ret
  306.  
  307.   .fail:
  308.         DEBUGF  1,"ETH_OUT_QUEUE is full!\n"
  309.         add     esp, 4
  310.         call    kernel_free
  311.         add     esp, 4
  312.         ret
  313.  
  314.  
  315.  
  316. ;-----------------------------------------------------------------
  317. ;
  318. ; ETH_send_queued:
  319. ;
  320. ;  IN:  /
  321. ;  OUT: /
  322. ;
  323. ;-----------------------------------------------------------------
  324.  
  325. align 4
  326. ETH_send_queued:
  327.  
  328.         get_from_queue ETH_OUT_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .gohome
  329.  
  330.         push    ETH_send_queued
  331.  
  332.         lodsd
  333.         mov     ebx, eax
  334.  
  335.         sub     esp, 8
  336.         mov     edi, esp
  337.         movsd
  338.         movsd
  339.  
  340.         DEBUGF  1,"dequeued packet for device %x\n", ebx
  341.  
  342.         call    ETH_struc2dev                   ; convert struct ptr to device num (this way we know if driver is still mounted)
  343.         cmp     edi, -1
  344.         je      .fail
  345.  
  346.         jmp     [ebx+ETH_DEVICE.transmit]       ; we will return to get_from_queue macro after transmitting packet
  347.  
  348.      .fail:
  349.         call    kernel_free
  350.         add     esp, 4 ; pop (balance stack)
  351.         DEBUGF 1,"ETH_Sender - fail\n"
  352.  
  353.      .gohome:
  354.         ret
  355.  
  356.  
  357. ;---------------------------------------------------------------------------
  358. ;
  359. ; ETH_struc2dev
  360. ;
  361. ; IN: pointer to device struct in ebx
  362. ;
  363. ; OUT: edi is -1 on error, device number otherwise
  364. ;
  365. ;---------------------------------------------------------------------------
  366.  
  367. align 4
  368. ETH_struc2dev:
  369.         push    eax ecx
  370.  
  371.         mov     eax, ebx
  372.         mov     ecx, MAX_ETH_DEVICES
  373.         mov     edi, ETH_DRV_LIST
  374.  
  375.         repne   scasd
  376.         jnz     .error
  377.  
  378.         sub     edi, ETH_DRV_LIST+4
  379.         shr     edi, 2
  380.  
  381.         pop     ecx eax
  382.         ret
  383.   .error:
  384.         or      edi, -1
  385.         pop     ecx eax
  386.  
  387.         ret
  388.  
  389.  
  390. ;---------------------------------------------------------------------------
  391. ;
  392. ; ETH_create_Packet
  393. ;
  394. ; IN: pointer to source mac in eax
  395. ;     pointer to destination mac in ebx
  396. ;     packet size in ecx
  397. ;     device number in edx
  398. ;     protocol in di
  399. ;
  400. ; OUT: edi is -1 on error, pointer to buffer otherwise
  401. ;      eax points to buffer start
  402. ;      ebx is pointer to device structure
  403. ;      ecx is unchanged (packet size of embedded data)
  404. ;      edx is size of complete buffer
  405. ;      esi points to procedure wich needs to be called to send packet
  406. ;
  407. ;---------------------------------------------------------------------------
  408.  
  409. align 4
  410. ETH_create_packet:
  411.  
  412.         DEBUGF 1,"Creating Ethernet Packet (size=%u): \n", ecx
  413.  
  414.         cmp     ecx, 1500
  415.         jg      .exit
  416.  
  417.         push    ecx di eax ebx edx
  418.  
  419.         add     ecx, ETH_FRAME.Data
  420.         push    ecx
  421.         push    ecx
  422.         call    kernel_alloc
  423.         test    eax, eax
  424.         jz      .pop_exit
  425.  
  426.         pop     ecx
  427.         pop     edx
  428.  
  429.         mov     edi, eax
  430.         pop     esi
  431.         movsd
  432.         movsw
  433.         pop     esi
  434.         movsd
  435.         movsw
  436.         pop     ax
  437.         stosw
  438.  
  439.         lea     eax, [edi - ETH_FRAME.Data]  ; Set eax to buffer start
  440.         mov     edx, ecx                     ; Set ebx to complete buffer size
  441.         pop     ecx
  442.         mov     esi, ETH_sender
  443.  
  444.         xor     ebx, ebx                        ;;;; TODO: Fixme
  445.         mov     ebx, [ETH_DRV_LIST + ebx]
  446.  
  447.         cmp     edx, 46 + ETH_FRAME.Data    ; If data size is less then 46, add padding bytes
  448.         jg      .continue
  449.         mov     edx, 46 + ETH_FRAME.Data
  450.        .continue:
  451.  
  452.         DEBUGF 1,"done: %x size:%u device:%x\n", eax, edx, ebx
  453.         ret
  454.  
  455.   .pop_exit:
  456.         DEBUGF 1,"Out of ram space!!\n"
  457.         add     esp, 18
  458.         or      edi,-1
  459.         ret
  460.  
  461.   .exit:
  462.         DEBUGF 1,"Packet too large!\n"
  463.         or      edi, -1
  464.         ret
  465.  
  466.  
  467.  
  468. ;---------------------------------------------------------------------------
  469. ;
  470. ; ETH_API
  471. ;
  472. ; This function is called by system function 75
  473. ;
  474. ; IN:  subfunction number in bl
  475. ;      device number in bh
  476. ;      ecx, edx, .. depends on subfunction
  477. ;
  478. ; OUT:
  479. ;
  480. ;---------------------------------------------------------------------------
  481.  
  482. align 4
  483. ETH_API:
  484.  
  485.         movzx   eax, bh
  486.         shl     eax, 2
  487.  
  488.         test    bl, bl
  489.         jz      .packets_tx     ; 0
  490.         dec     bl
  491.         jz      .packets_rx     ; 1
  492.         dec     bl
  493.         jz      .bytes_tx       ; 2
  494.         dec     bl
  495.         jz      .bytes_rx       ; 3
  496.         dec     bl
  497.         jz      .read_mac       ; 4
  498.         dec     bl
  499.         jz      .write_mac      ; 5
  500.         dec     bl
  501.         jz      .in_queue       ; 6
  502.         dec     bl
  503.         jz      .out_queue      ; 7
  504.  
  505. .error:
  506.         mov     eax, -1
  507.         ret
  508.  
  509. .packets_tx:
  510.         add     eax, ETH_DRV_LIST
  511.         mov     eax, dword [eax]
  512.         mov     eax, dword [eax + ETH_DEVICE.packets_tx]
  513.  
  514.         ret
  515.  
  516. .packets_rx:
  517.         add     eax, ETH_DRV_LIST
  518.         mov     eax, dword [eax]
  519.         mov     eax, dword [eax + ETH_DEVICE.packets_rx]
  520.         ret
  521.  
  522. .bytes_tx:
  523.         add     eax, ETH_DRV_LIST
  524.         mov     eax, dword [eax]
  525.         mov     ebx, dword [eax + ETH_DEVICE.bytes_tx + 4]
  526.         mov     eax, dword [eax + ETH_DEVICE.bytes_tx]
  527.         mov     [esp+20+4], ebx                         ; TODO: fix this ugly code
  528.         ret
  529.  
  530. .bytes_rx:
  531.         add     eax, ETH_DRV_LIST
  532.         mov     eax, dword [eax]
  533.         mov     ebx, dword [eax + ETH_DEVICE.bytes_rx + 4]
  534.         mov     eax, dword [eax + ETH_DEVICE.bytes_rx]
  535.         mov     [esp+20+4], ebx                         ; TODO: fix this ugly code
  536.         ret
  537.  
  538.  
  539. .read_mac:
  540.         add     eax, ETH_DRV_LIST
  541.         mov     eax, [eax]
  542. ;        push    eax
  543. ;        call    dword [eax + ETH_DEVICE.get_MAC]
  544. ;        pop     eax
  545.         movzx   ebx, word [eax + ETH_DEVICE.mac]
  546.         mov     eax, dword [eax + ETH_DEVICE.mac + 2]
  547.         mov     [esp+20+4], ebx                         ; TODO: fix this ugly code
  548.         ret
  549.  
  550. .write_mac:
  551.         push    ecx
  552.         push    dx
  553.         add     eax, ETH_DRV_LIST
  554.         mov     eax, [eax]
  555.         mov     eax, dword [eax + ETH_DEVICE.set_MAC]
  556.         call    eax
  557.         ret
  558.  
  559. .in_queue:
  560.         add     eax, ETH_IN_QUEUE
  561.         mov     eax, [eax + queue.size]
  562.         ret
  563.  
  564. .out_queue:
  565.         add     eax, ETH_OUT_QUEUE
  566.         mov     eax, [eax + queue.size]
  567.         ret