Subversion Repositories Kolibri OS

Rev

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

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