Subversion Repositories Kolibri OS

Rev

Rev 5363 | Rev 7536 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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