Subversion Repositories Kolibri OS

Rev

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