Subversion Repositories Kolibri OS

Rev

Rev 5596 | 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
 
6078 serge 17
$Revision: 6011 $
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
 
6078 serge 53
macro   eth_init {
4265 Serge 54
 
55
        movi    ebx, 1
6078 serge 56
        mov     ecx, eth_process_input
4265 Serge 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
 
6078 serge 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
;-----------------------------------------------------------------;
3555 Serge 75
align 4
6078 serge 76
eth_input:
3555 Serge 77
 
5565 serge 78
        pop     eax
79
        pushf
80
        cli
4265 Serge 81
 
5565 serge 82
        cmp     [ETH_frame_queued], ETH_QUEUE_SIZE
83
        jae     .full
84
        inc     [ETH_frame_queued]
4265 Serge 85
 
5565 serge 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
 
97
; Now queue an event to process it
4265 Serge 98
        xor     edx, edx
99
        mov     eax, [ETH_input_event]
100
        mov     ebx, [eax + EVENT.id]
101
        xor     esi, esi
102
        call    raise_event
103
 
104
        ret
105
 
5565 serge 106
  .full:
5201 serge 107
        DEBUGF  DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n"
5565 serge 108
        popf
109
        push    eax
6078 serge 110
        call    net_buff_free
4265 Serge 111
        ret
112
 
113
 
114
 
6078 serge 115
;-----------------------------------------------------------------;
116
;                                                                 ;
117
; eth_process_input: Process packets from ethernet input queue.   ;
118
;                                                                 ;
119
;  IN:  /                                                         ;
120
;                                                                 ;
121
;  OUT: /                                                         ;
122
;                                                                 ;
123
;-----------------------------------------------------------------;
4265 Serge 124
align 4
6078 serge 125
eth_process_input:
4265 Serge 126
 
127
        xor     esi, esi
128
        mov     ecx, MANUAL_DESTROY
129
        call    create_event
130
        mov     [ETH_input_event], eax
5565 serge 131
        pushf
4265 Serge 132
  .wait:
5565 serge 133
        popf
4265 Serge 134
        mov     eax, [ETH_input_event]
135
        mov     ebx, [eax + EVENT.id]
136
        call    wait_event
137
 
138
  .loop:
5565 serge 139
        pushf
140
        cli
141
        cmp     [ETH_frame_queued], 0
142
        je      .wait
4265 Serge 143
 
5565 serge 144
        dec     [ETH_frame_queued]
4265 Serge 145
 
5565 serge 146
        mov     esi, [ETH_frame_head]
147
        mov     ebx, [esi + NET_BUFF.NextPtr]
4265 Serge 148
 
5565 serge 149
        mov     [ETH_frame_head], ebx
150
        mov     [ebx + NET_BUFF.PrevPtr], ETH_frame_head
151
 
152
        popf
153
 
154
        mov     eax, [esi + NET_BUFF.offset]
155
        add     eax, esi
156
        mov     ecx, [esi + NET_BUFF.length]
157
        mov     ebx, [esi + NET_BUFF.device]
158
 
159
        pushd   .loop           ; return address for protocol handler
160
        push    esi             ; keep pointer to NET_BUFF on stack
161
 
4265 Serge 162
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx
3725 Serge 163
        sub     ecx, sizeof.ETH_header
3555 Serge 164
        jb      .dump
165
 
5565 serge 166
; Set registers for protocol handlers
3555 Serge 167
        lea     edx, [eax + sizeof.ETH_header]
168
        mov     ax, [eax + ETH_header.Type]
169
 
5565 serge 170
; Place protocol handlers here
3626 Serge 171
        cmp     ax, ETHER_PROTO_IPv4
6078 serge 172
        je      ipv4_input
3555 Serge 173
 
3626 Serge 174
        cmp     ax, ETHER_PROTO_ARP
6078 serge 175
        je      arp_input
3555 Serge 176
 
5201 serge 177
;        cmp     ax, ETHER_PROTO_IPv6
6078 serge 178
;        je      ipv6_input
3555 Serge 179
 
5201 serge 180
;        cmp     ax, ETHER_PROTO_PPP_DISCOVERY
6078 serge 181
;        je      pppoe_discovery_input
3555 Serge 182
 
5201 serge 183
;        cmp     ax, ETHER_PROTO_PPP_SESSION
6078 serge 184
;        je      pppoe_session_input
3555 Serge 185
 
4265 Serge 186
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax
3555 Serge 187
 
188
  .dump:
4265 Serge 189
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: dumping\n"
6078 serge 190
        call    net_buff_free
3555 Serge 191
        ret
192
 
6078 serge 193
 
194
 
195
;-----------------------------------------------------------------;
196
;                                                                 ;
197
; eth_output                                                      ;
198
;                                                                 ;
199
;  IN:  ax = protocol                                             ;
200
;       ebx = device ptr                                          ;
201
;       ecx = payload size                                        ;
202
;       edx = pointer to destination mac                          ;
203
;                                                                 ;
204
;  OUT: eax = start of net frame / 0 on error                     ;
205
;       ebx = device ptr                                          ;
206
;       ecx = payload size                                        ;
207
;       edi = start of payload                                    ;
208
;                                                                 ;
209
;-----------------------------------------------------------------;
3555 Serge 210
align 4
6078 serge 211
eth_output:
3555 Serge 212
 
3589 Serge 213
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx
3555 Serge 214
 
5201 serge 215
        cmp     ecx, [ebx + ETH_DEVICE.mtu]
3555 Serge 216
        ja      .exit
217
 
218
        push    ecx
5201 serge 219
        push    ax edx
3555 Serge 220
 
5565 serge 221
        add     ecx, sizeof.ETH_header + NET_BUFF.data
6078 serge 222
        stdcall net_buff_alloc, ecx
3555 Serge 223
        test    eax, eax
224
        jz      .out_of_ram
5565 serge 225
        mov     [eax + NET_BUFF.type], NET_BUFF_ETH
226
        mov     [eax + NET_BUFF.device], ebx
227
        mov     [eax + NET_BUFF.offset], NET_BUFF.data
228
        lea     edi, [eax + NET_BUFF.data]
3555 Serge 229
 
230
        pop     esi
231
        movsd
232
        movsw
5201 serge 233
        lea     esi, [ebx + ETH_DEVICE.mac]
3555 Serge 234
        movsd
235
        movsw
236
        pop     ax
237
        stosw
238
 
5565 serge 239
        lea     eax, [edi - sizeof.ETH_header - NET_BUFF.data]  ; Set eax to buffer start
3555 Serge 240
        pop     ecx
5565 serge 241
 
3555 Serge 242
        lea     edx, [ecx + sizeof.ETH_header]  ; Set edx to complete buffer size
243
        cmp     edx, ETH_FRAME_MINIMUM
244
        jbe     .adjust_size
245
  .done:
5565 serge 246
        mov     [eax + NET_BUFF.length], edx
3589 Serge 247
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: ptr=%x size=%u\n", eax, edx
3555 Serge 248
        ret
249
 
250
  .adjust_size:
251
        mov     edx, ETH_FRAME_MINIMUM
5596 serge 252
        test    edx, edx                        ; clear zero flag
3555 Serge 253
        jmp     .done
254
 
255
  .out_of_ram:
3589 Serge 256
        DEBUGF  DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n"
5201 serge 257
        add     esp, 4+2+4
258
        xor     eax, eax
3555 Serge 259
        ret
260
 
261
  .exit:
3589 Serge 262
        DEBUGF  DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n"
5201 serge 263
        xor     eax, eax
3555 Serge 264
        ret
265
 
266
 
267
 
6078 serge 268
;-----------------------------------------------------------------;
269
;                                                                 ;
270
; eth_api: Part of system function 76.                            ;
271
;                                                                 ;
272
;  IN:  bl = subfunction number                                   ;
273
;       bh = device number                                        ;
274
;       ecx, edx, .. depends on subfunction                       ;
275
;                                                                 ;
276
; OUT:  depends on subfunction                                    ;
277
;                                                                 ;
278
;-----------------------------------------------------------------;
3555 Serge 279
align 4
6078 serge 280
eth_api:
3555 Serge 281
 
3626 Serge 282
        cmp     bh, NET_DEVICES_MAX
3555 Serge 283
        ja      .error
284
        movzx   eax, bh
285
        mov     eax, dword [NET_DRV_LIST + 4*eax]
3626 Serge 286
        cmp     [eax + NET_DEVICE.device_type], NET_DEVICE_ETH
3555 Serge 287
        jne     .error
288
 
289
        and     ebx, 0xff
290
        cmp     ebx, .number
291
        ja      .error
292
        jmp     dword [.table + 4*ebx]
293
 
294
  .table:
3626 Serge 295
        dd      .read_mac       ; 0
3555 Serge 296
  .number = ($ - .table) / 4 - 1
297
 
298
  .error:
299
        or      eax, -1
300
        ret
301
 
302
 
303
  .read_mac:
304
        movzx   ebx, word [eax + ETH_DEVICE.mac]
305
        mov     eax, dword [eax + ETH_DEVICE.mac + 2]
5565 serge 306
        mov     [esp+20+4], ebx                         ; FIXME
3555 Serge 307
        ret
308