Subversion Repositories Kolibri OS

Rev

Rev 4587 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4429 Serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
5116 serge 3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved.    ;;
4429 Serge 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
 
5116 serge 17
$Revision: 5015 $
4429 Serge 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
struct  ETH_queue_entry
37
 
38
        device          dd ?
39
        packet          dd ?
40
        size            dd ?
41
 
42
ends
43
 
44
iglobal
45
align 4
46
 
47
        ETH_BROADCAST   dp  0xffffffffffff
48
endg
49
 
50
uglobal
51
align 4
52
        ETH_input_event dd ?
53
        ETH_queue       rd (ETH_QUEUE_SIZE*sizeof.ETH_queue_entry + sizeof.queue)/4
54
endg
55
 
56
macro   ETH_init {
57
 
58
        init_queue ETH_queue
59
 
60
        movi    ebx, 1
61
        mov     ecx, ETH_process_input
62
        call    new_sys_threads
63
        test    eax, eax
64
        jns     @f
65
        DEBUGF  DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for ethernet, error %d\n', eax
66
  @@:
67
 
68
}
69
 
70
;-----------------------------------------------------------------
71
;
72
; ETH_input
73
;
74
;  This function is called by ethernet drivers,
75
;  It pushes the received ethernet packets onto the eth_in_queue
76
;
77
;  IN:   [esp]  = Pointer to buffer
78
;       [esp+4] = size of buffer
79
;         ebx   = pointer to eth_device
80
;  OUT: /
81
;
82
;-----------------------------------------------------------------
83
align 4
84
ETH_input:
85
 
86
        push    ebx
87
        mov     esi, esp
88
 
89
        add_to_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .fail
90
        add     esp, sizeof.ETH_queue_entry
91
 
92
        xor     edx, edx
93
        mov     eax, [ETH_input_event]
94
        mov     ebx, [eax + EVENT.id]
95
        xor     esi, esi
96
        call    raise_event
97
 
98
        ret
99
 
100
  .fail:
4587 Serge 101
        DEBUGF  DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n"
4429 Serge 102
 
4587 Serge 103
        pop     ebx
4429 Serge 104
        call    NET_packet_free
105
        add     esp, 4
106
 
107
        ret
108
 
109
 
110
 
111
 
112
align 4
113
ETH_process_input:
114
 
115
        xor     esi, esi
116
        mov     ecx, MANUAL_DESTROY
117
        call    create_event
118
        mov     [ETH_input_event], eax
119
 
120
  .wait:
121
        mov     eax, [ETH_input_event]
122
        mov     ebx, [eax + EVENT.id]
123
        call    wait_event
124
 
125
  .loop:
126
        get_from_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .wait
127
 
128
        mov     eax, [esi + ETH_queue_entry.packet]
129
        mov     ecx, [esi + ETH_queue_entry.size]
130
        mov     ebx, [esi + ETH_queue_entry.device]
131
 
132
        pushd   .loop   ; return address
133
        push    ecx eax
134
 
135
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx
136
        sub     ecx, sizeof.ETH_header
137
        jb      .dump
138
 
139
        lea     edx, [eax + sizeof.ETH_header]
140
        mov     ax, [eax + ETH_header.Type]
141
 
142
        cmp     ax, ETHER_PROTO_IPv4
143
        je      IPv4_input
144
 
145
        cmp     ax, ETHER_PROTO_ARP
146
        je      ARP_input
147
 
5116 serge 148
;        cmp     ax, ETHER_PROTO_IPv6
149
;        je      IPv6_input
4429 Serge 150
 
5116 serge 151
;        cmp     ax, ETHER_PROTO_PPP_DISCOVERY
152
;        je      PPPoE_discovery_input
4429 Serge 153
 
5116 serge 154
;        cmp     ax, ETHER_PROTO_PPP_SESSION
155
;        je      PPPoE_session_input
4429 Serge 156
 
157
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax
158
 
159
  .dump:
160
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: dumping\n"
161
        call    NET_packet_free
162
        add     esp, 4
163
        ret
164
 
165
;-----------------------------------------------------------------
166
;
167
; ETH_output
168
;
5116 serge 169
; IN:  ax = protocol
4429 Serge 170
;     ebx = device ptr
5116 serge 171
;     ecx = payload size
4429 Serge 172
;     edx = pointer to destination mac
173
;
5116 serge 174
; OUT: eax = start of ethernet frame / 0 on error
175
;      ebx = device ptr
176
;      ecx = payload size
177
;      edx = ethernet frame size
178
;      edi = start of ethernet payload
4429 Serge 179
;
180
;-----------------------------------------------------------------
181
align 4
182
ETH_output:
183
 
184
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx
185
 
5116 serge 186
        cmp     ecx, [ebx + ETH_DEVICE.mtu]
4429 Serge 187
        ja      .exit
188
 
189
        push    ecx
5116 serge 190
        push    ax edx
4429 Serge 191
 
192
        add     ecx, sizeof.ETH_header
193
        stdcall kernel_alloc, ecx
194
        test    eax, eax
195
        jz      .out_of_ram
196
        mov     edi, eax
197
 
198
        pop     esi
199
        movsd
200
        movsw
5116 serge 201
        lea     esi, [ebx + ETH_DEVICE.mac]
4429 Serge 202
        movsd
203
        movsw
204
        pop     ax
205
        stosw
206
 
207
        lea     eax, [edi - sizeof.ETH_header]  ; Set eax to buffer start
208
        pop     ecx
209
        lea     edx, [ecx + sizeof.ETH_header]  ; Set edx to complete buffer size
210
 
211
        cmp     edx, ETH_FRAME_MINIMUM
212
        jbe     .adjust_size
213
  .done:
214
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: ptr=%x size=%u\n", eax, edx
215
        ret
216
 
217
  .adjust_size:
218
        mov     edx, ETH_FRAME_MINIMUM
5116 serge 219
        test    edx, edx                        ; clear zero flag
4429 Serge 220
        jmp     .done
221
 
222
  .out_of_ram:
223
        DEBUGF  DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n"
5116 serge 224
        add     esp, 4+2+4
225
        xor     eax, eax
4429 Serge 226
        ret
227
 
228
  .exit:
229
        DEBUGF  DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n"
5116 serge 230
        xor     eax, eax
4429 Serge 231
        ret
232
 
233
 
234
 
235
;-----------------------------------------------------------------
236
;
237
; ETH_API
238
;
239
; This function is called by system function 76
240
;
241
; IN:  subfunction number in bl
242
;      device number in bh
243
;      ecx, edx, .. depends on subfunction
244
;
245
; OUT:
246
;
247
;-----------------------------------------------------------------
248
align 4
249
ETH_api:
250
 
251
        cmp     bh, NET_DEVICES_MAX
252
        ja      .error
253
        movzx   eax, bh
254
        mov     eax, dword [NET_DRV_LIST + 4*eax]
255
        cmp     [eax + NET_DEVICE.device_type], NET_DEVICE_ETH
256
        jne     .error
257
 
258
        and     ebx, 0xff
259
        cmp     ebx, .number
260
        ja      .error
261
        jmp     dword [.table + 4*ebx]
262
 
263
  .table:
264
        dd      .read_mac       ; 0
265
  .number = ($ - .table) / 4 - 1
266
 
267
  .error:
268
        or      eax, -1
269
        ret
270
 
271
 
272
  .read_mac:
273
        movzx   ebx, word [eax + ETH_DEVICE.mac]
274
        mov     eax, dword [eax + ETH_DEVICE.mac + 2]
275
        mov     [esp+20+4], ebx                         ; TODO: fix this ugly code
276
        ret
277