Subversion Repositories Kolibri OS

Rev

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

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