Subversion Repositories Kolibri OS

Rev

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

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