Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3555 Serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2013. 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: 3346 $
18
 
19
ETH_FRAME_MINIMUM       = 60
4265 Serge 20
ETH_QUEUE_SIZE          = 255
3555 Serge 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
 
4265 Serge 36
struct  ETH_queue_entry
37
 
38
        device          dd ?
39
        packet          dd ?
40
        size            dd ?
41
 
42
ends
43
 
3725 Serge 44
iglobal
3555 Serge 45
align 4
46
 
47
        ETH_BROADCAST   dp  0xffffffffffff
48
endg
49
 
4265 Serge 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
 
3555 Serge 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
 
4265 Serge 86
        push    ebx
87
        mov     esi, esp
88
 
89
        pushf
90
        cli
91
        add_to_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .fail
92
        popf
93
 
94
        add     esp, sizeof.ETH_queue_entry
95
 
96
        xor     edx, edx
97
        mov     eax, [ETH_input_event]
98
        mov     ebx, [eax + EVENT.id]
99
        xor     esi, esi
100
        call    raise_event
101
 
102
        ret
103
 
104
  .fail:
105
        popf
106
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH incoming queue is full, discarding packet!\n"
107
 
108
        add     esp, sizeof.ETH_queue_entry - 8
109
        call    NET_packet_free
110
        add     esp, 4
111
 
112
        ret
113
 
114
 
115
 
116
 
117
align 4
118
ETH_process_input:
119
 
120
        xor     esi, esi
121
        mov     ecx, MANUAL_DESTROY
122
        call    create_event
123
        mov     [ETH_input_event], eax
124
 
125
  .wait:
126
        mov     eax, [ETH_input_event]
127
        mov     ebx, [eax + EVENT.id]
128
        call    wait_event
129
 
130
  .loop:
131
        get_from_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .wait
132
 
133
        mov     eax, [esi + ETH_queue_entry.packet]
134
        mov     ecx, [esi + ETH_queue_entry.size]
135
        mov     ebx, [esi + ETH_queue_entry.device]
136
 
137
        pushd   .loop   ; return address
138
        push    ecx eax
139
 
140
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx
3725 Serge 141
        sub     ecx, sizeof.ETH_header
3555 Serge 142
        jb      .dump
143
 
144
        lea     edx, [eax + sizeof.ETH_header]
145
        mov     ax, [eax + ETH_header.Type]
146
 
3626 Serge 147
        cmp     ax, ETHER_PROTO_IPv4
3555 Serge 148
        je      IPv4_input
149
 
3626 Serge 150
        cmp     ax, ETHER_PROTO_ARP
3555 Serge 151
        je      ARP_input
152
 
3626 Serge 153
        cmp     ax, ETHER_PROTO_IPv6
3555 Serge 154
        je      IPv6_input
155
 
3626 Serge 156
        cmp     ax, ETHER_PROTO_PPP_DISCOVERY
3555 Serge 157
        je      PPPoE_discovery_input
158
 
3626 Serge 159
        cmp     ax, ETHER_PROTO_PPP_SESSION
3555 Serge 160
        je      PPPoE_session_input
161
 
4265 Serge 162
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax
3555 Serge 163
 
164
  .dump:
4265 Serge 165
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: dumping\n"
3908 Serge 166
        call    NET_packet_free
3555 Serge 167
        add     esp, 4
168
        ret
169
 
170
;-----------------------------------------------------------------
171
;
172
; ETH_output
173
;
174
; IN: eax = pointer to source mac
175
;     ebx = device ptr
176
;     ecx = packet size
177
;     edx = pointer to destination mac
178
;      di = protocol
179
;
180
; OUT: edi = 0 on error, pointer to buffer otherwise
181
;      eax = buffer start
182
;      ebx = to device structure
183
;      ecx = unchanged (packet size of embedded data)
184
;      edx = size of complete buffer
185
;
186
;-----------------------------------------------------------------
187
align 4
188
ETH_output:
189
 
3589 Serge 190
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx
3555 Serge 191
 
192
        cmp     ecx, [ebx + NET_DEVICE.mtu]
193
        ja      .exit
194
 
195
        push    ecx
196
        push    di eax edx
197
 
198
        add     ecx, sizeof.ETH_header
199
        stdcall kernel_alloc, ecx
200
        test    eax, eax
201
        jz      .out_of_ram
202
        mov     edi, eax
203
 
204
        pop     esi
205
        movsd
206
        movsw
207
        pop     esi
208
        movsd
209
        movsw
210
        pop     ax
211
        stosw
212
 
213
        lea     eax, [edi - sizeof.ETH_header]  ; Set eax to buffer start
214
        pop     ecx
215
        lea     edx, [ecx + sizeof.ETH_header]  ; Set edx to complete buffer size
216
 
217
        cmp     edx, ETH_FRAME_MINIMUM
218
        jbe     .adjust_size
219
  .done:
3589 Serge 220
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: ptr=%x size=%u\n", eax, edx
3555 Serge 221
        ret
222
 
223
  .adjust_size:
224
        mov     edx, ETH_FRAME_MINIMUM
225
        test    edx, edx        ; clear zero flag
226
        jmp     .done
227
 
228
  .out_of_ram:
3589 Serge 229
        DEBUGF  DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n"
3555 Serge 230
        add     esp, 4+4+2+4
231
        sub     edi, edi
232
        ret
233
 
234
  .exit:
3589 Serge 235
        DEBUGF  DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n"
3555 Serge 236
        sub     edi, edi
237
        ret
238
 
239
 
240
 
241
;-----------------------------------------------------------------
242
;
243
; ETH_API
244
;
3626 Serge 245
; This function is called by system function 76
3555 Serge 246
;
247
; IN:  subfunction number in bl
248
;      device number in bh
249
;      ecx, edx, .. depends on subfunction
250
;
251
; OUT:
252
;
253
;-----------------------------------------------------------------
254
align 4
255
ETH_api:
256
 
3626 Serge 257
        cmp     bh, NET_DEVICES_MAX
3555 Serge 258
        ja      .error
259
        movzx   eax, bh
260
        mov     eax, dword [NET_DRV_LIST + 4*eax]
3626 Serge 261
        cmp     [eax + NET_DEVICE.device_type], NET_DEVICE_ETH
3555 Serge 262
        jne     .error
263
 
264
        and     ebx, 0xff
265
        cmp     ebx, .number
266
        ja      .error
267
        jmp     dword [.table + 4*ebx]
268
 
269
  .table:
3626 Serge 270
        dd      .read_mac       ; 0
3555 Serge 271
  .number = ($ - .table) / 4 - 1
272
 
273
  .error:
274
        or      eax, -1
275
        ret
276
 
277
 
278
  .read_mac:
279
        movzx   ebx, word [eax + ETH_DEVICE.mac]
280
        mov     eax, dword [eax + ETH_DEVICE.mac + 2]
281
        mov     [esp+20+4], ebx                         ; TODO: fix this ugly code
282
        ret
283