Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | \ ========== Copyright Header Begin ========================================== |
2 | \ | |
3 | \ Hypervisor Software File: methods.fth | |
4 | \ | |
5 | \ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | \ | |
7 | \ - Do no alter or remove copyright notices | |
8 | \ | |
9 | \ - Redistribution and use of this software in source and binary forms, with | |
10 | \ or without modification, are permitted provided that the following | |
11 | \ conditions are met: | |
12 | \ | |
13 | \ - Redistribution of source code must retain the above copyright notice, | |
14 | \ this list of conditions and the following disclaimer. | |
15 | \ | |
16 | \ - Redistribution in binary form must reproduce the above copyright notice, | |
17 | \ this list of conditions and the following disclaimer in the | |
18 | \ documentation and/or other materials provided with the distribution. | |
19 | \ | |
20 | \ Neither the name of Sun Microsystems, Inc. or the names of contributors | |
21 | \ may be used to endorse or promote products derived from this software | |
22 | \ without specific prior written permission. | |
23 | \ | |
24 | \ This software is provided "AS IS," without a warranty of any kind. | |
25 | \ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
26 | \ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
27 | \ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
28 | \ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
29 | \ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
30 | \ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
31 | \ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
32 | \ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
33 | \ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
34 | \ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
35 | \ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
36 | \ | |
37 | \ You acknowledge that this software is not designed, licensed or | |
38 | \ intended for use in the design, construction, operation or maintenance of | |
39 | \ any nuclear facility. | |
40 | \ | |
41 | \ ========== Copyright Header End ============================================ | |
42 | id: @(#)methods.fth 1.5 07/06/22 | |
43 | purpose: | |
44 | copyright: Copyright 2007 Sun Microsystems, Inc. All rights reserved. | |
45 | copyright: Use is subject to license terms. | |
46 | ||
47 | headerless | |
48 | ||
49 | fload ${BP}/dev/sun4v-devices/ldc/methods.fth | |
50 | ||
51 | false value debug-vnet? | |
52 | false value debug-tcp? | |
53 | ||
54 | fload ${BP}/dev/sun4v-devices/vcommon/vio-struct.fth | |
55 | fload ${BP}/dev/sun4v-devices/vcommon/vio-methods.fth | |
56 | ||
57 | vdev-net-client to current-vio-dev | |
58 | h# 1000 value vnet-sid \ Variable to hold sequence id | |
59 | 0 value vnet-seq \ seq# for the next request | |
60 | 0 value cur-vnet-seq \ seq# of the current request | |
61 | 0 value vnet-tmpbuf | |
62 | d# 200 value vnet-retries \ Variable to hold number of retries | |
63 | 0 value vnet-opened? \ Variable to indicate if vnet has established | |
64 | \ connection with vswitch | |
65 | ||
66 | d# 1514 constant frame-size | |
67 | ||
68 | 0 value rx-buffer \ Transmit buffer | |
69 | 0 value tx-buffer \ receive buffer | |
70 | ||
71 | 8 pagesize 0 claim to rx-buffer | |
72 | 8 pagesize 0 claim to tx-buffer | |
73 | ||
74 | 0 value vnet-descr-buf \ Variable to hold Vnet descritor buffer | |
75 | ||
76 | /vnet-attr-msg /vnet-descr-msg max value /vnet-descr-buf | |
77 | 0 value obp-tftp | |
78 | 0 value ldc-up? \ flag, Set if LDC is up | |
79 | ||
80 | 6 buffer: mac-buf \ Variable to hold MAC Address | |
81 | ||
82 | 0 value vn-ldcid \ Variable to hold LDC id | |
83 | ||
84 | : inspect-vnet-port-nodes ( nptr -- ) | |
85 | dup " switch-port" ascii v md-find-prop if ( port-ptr ptr|0 ) | |
86 | " fwd" ascii a md-find-prop ( ldc-nptr|0 ) | |
87 | dup if | |
88 | md-decode-prop drop ( ldc-nptr ) | |
89 | " id" ascii v md-find-prop ( idptr|0 ) | |
90 | dup if | |
91 | md-decode-prop drop to vn-ldcid | |
92 | else | |
93 | drop | |
94 | then | |
95 | else | |
96 | drop | |
97 | then | |
98 | else | |
99 | drop | |
100 | then | |
101 | ; | |
102 | ||
103 | : look-for-vn-ldcid ( -- ) | |
104 | ['] inspect-vnet-port-nodes my-node md-applyto-fwds | |
105 | ; | |
106 | ||
107 | look-for-vn-ldcid | |
108 | ||
109 | : init-obp-tftp ( tftp-args$ -- okay? ) | |
110 | " obp-tftp" $open-package dup to obp-tftp ( pkg ) | |
111 | if | |
112 | true | |
113 | else | |
114 | cmn-warn[ " Can't open OBP standard TFTP package" ]cmn-end | |
115 | false | |
116 | then | |
117 | ; | |
118 | ||
119 | \ The service domain may be down or rebooting... Keep retrying for 5 minutes | |
120 | : open-vnet-ldc ( -- error? ) | |
121 | get-msecs d# 300.000 + \ 5 minutes later | |
122 | begin ( finish-time ) | |
123 | get-msecs over < ( finish-time keep-trying? ) | |
124 | while ( finish-time ) | |
125 | vn-ldcid ldc-mode-unreliable ldc-open if ( finish-time ) | |
126 | true to ldc-up? ( finish-time ) | |
127 | drop false exit ( false ) | |
128 | then ( finish-time ) | |
129 | cmn-warn[ | |
130 | " Timeout connecting to virtual switch... retrying" | |
131 | ]cmn-end | |
132 | d# 5000 ms ( finish-time ) | |
133 | repeat | |
134 | cmn-warn[ " Unable to connect to virtual switch" ]cmn-end | |
135 | drop true ( true ) | |
136 | ; | |
137 | ||
138 | : close-vnet-ldc ( -- ) | |
139 | ldc-close 0 to ldc-up? | |
140 | ; | |
141 | ||
142 | : receive-ready? ( -- ready? ) | |
143 | ldc-pkt-available? | |
144 | ; | |
145 | ||
146 | \ Only update seqid upon successful return because Solaris counter part | |
147 | \ doesn't like new seqid if OBP higher level module do retries | |
148 | : send-to-ldc ( buf len -- #sent ) | |
149 | debug-vnet? if | |
150 | cr ." vnet write : " 2dup swap u. u. cr | |
151 | then | |
152 | 0 vnet-retries 0 do ( buf len status ) | |
153 | drop 2dup ( buf len buf len ) | |
154 | ldc-write ( buf len #sent status ) | |
155 | dup HV-EOK <> if ( buf len #sent status ) | |
156 | dup HV-EWOULDBLOCK <> if ( buf len #sent status ) | |
157 | dup LDC-NOTUP = if ( buf len #sent status ) | |
158 | cmn-warn[ " Sending packet to LDC but LDC is Not Up!" ]cmn-end | |
159 | 2drop 2drop 0 unloop exit ( 0 ) | |
160 | then | |
161 | cmn-warn[ " Sending packet to LDC, status: %d" ]cmn-end | |
162 | 3drop 0 unloop exit | |
163 | then | |
164 | else ( buf len #sent status ) | |
165 | cur-vnet-seq 1+ to vnet-seq | |
166 | drop nip nip unloop exit ( #sent ) | |
167 | then | |
168 | nip ( buf len status ) | |
169 | \ Every 20 loops, roughly 20 seconds (ldc-write can take @ 1s), | |
170 | \ print a retrying message | |
171 | i 1+ d# 20 mod 0= if | |
172 | cmn-warn[ | |
173 | " Timeout sending package to LDC ... retrying" | |
174 | ]cmn-end | |
175 | then | |
176 | loop ( buf len status ) | |
177 | 3drop 0 | |
178 | cmn-warn[ " Sending packet to LDC timed out!" ]cmn-end | |
179 | ; | |
180 | ||
181 | : receive-from-ldc ( buf len -- #bytes ) | |
182 | 0 vnet-retries 0 do ( buf len status ) | |
183 | drop 2dup ( buf len buf len ) | |
184 | ldc-read ( buf len alen status ) | |
185 | dup HV-EOK <> if ( buf len alen status ) | |
186 | dup HV-EWOULDBLOCK <> if ( buf len alen status ) | |
187 | dup LDC-NOTUP = if ( buf len alen status ) | |
188 | cmn-warn[ | |
189 | " Receiving packet from LDC but LDC is Not Up!" | |
190 | ]cmn-end | |
191 | 2drop 2drop 0 unloop exit ( 0 ) | |
192 | then | |
193 | cmn-warn[ " Receiving packet from LDC, status: %d" ]cmn-end 3drop 0 unloop exit ( 0 ) | |
194 | then | |
195 | else ( buf len alen status ) | |
196 | \ If vnet-opened? is false and if we get EOK with Length = 0 then | |
197 | \ treat it as EWOULDBLOCK at LDC layer and just retry | |
198 | over vnet-opened? or if ( buf len alen status ) | |
199 | drop nip nip unloop exit ( alen ) | |
200 | then | |
201 | then | |
202 | nip ( buf len status ) | |
203 | \ Every 20 loops, roughly 20 seconds (ldc-read can take @ 1s), | |
204 | \ print a retrying message | |
205 | i 1+ d# 20 mod 0= if | |
206 | cmn-warn[ | |
207 | " Timeout receiving packet from LDC ... retrying" | |
208 | ]cmn-end | |
209 | then | |
210 | loop ( buf len status ) | |
211 | 3drop 0 | |
212 | cmn-warn[ " Receiving packet from LDC timed out!" ]cmn-end | |
213 | ; | |
214 | ' receive-from-ldc is retrieve-packet | |
215 | ||
216 | : receive ( -- len' ) | |
217 | rx-buffer frame-size receive-from-ldc | |
218 | ; | |
219 | ||
220 | : ldc-copy-in ( buf cookie size -- len ) | |
221 | 0 vnet-retries 0 do ( buf cookie size status ) | |
222 | drop 3dup | |
223 | ldc-copy-in ( buf cookie size len status ) | |
224 | dup HV-EOK <> if | |
225 | dup HV-EWOULDBLOCK <> if | |
226 | cmn-warn[ " Vnet-copy-in: status: %d" ]cmn-end | |
227 | 2drop 2drop 0 unloop exit | |
228 | then | |
229 | else | |
230 | drop nip nip nip unloop exit ( len ) | |
231 | then ( buf cookie size len status ) | |
232 | nip | |
233 | loop ( buf cookie size status ) | |
234 | 2drop 2drop 0 | |
235 | cmn-warn[ " ldc-copy-in timed out!" ]cmn-end | |
236 | ; | |
237 | ||
238 | : send-vnet-ver-msg ( -- ok? ) | |
239 | vnet-descr-buf /vio-ver-msg erase | |
240 | ||
241 | \ vnet session id is only updated once during version negotiation | |
242 | vnet-sid 1+ dup to vnet-sid | |
243 | vnet-descr-buf >vio-sid l! | |
244 | ||
245 | vio-msg-type-ctrl vio-subtype-info vio-ver-info | |
246 | vnet-descr-buf set-vio-msg-tag | |
247 | ||
248 | vdev-net-client vnet-minor vnet-major | |
249 | vnet-descr-buf set-vio-msg-ver | |
250 | ||
251 | vnet-descr-buf /vio-ver-msg send-to-ldc | |
252 | /vio-ver-msg = | |
253 | ; | |
254 | ||
255 | ' send-vnet-ver-msg is send-vio-ver-msg | |
256 | ||
257 | \ The ack parameter may be ack or nack | |
258 | : send-vnet-ack-msg ( buf ack -- ok? ) | |
259 | over >vio-subtype c! ( buf ) | |
260 | vnet-sid over >vio-sid l! ( buf ) | |
261 | /vio-ver-msg send-to-ldc ( rlen ) | |
262 | /vio-ver-msg = | |
263 | ; | |
264 | ||
265 | ' send-vnet-ack-msg is send-vio-ack-msg | |
266 | ||
267 | : vnet-compatible-ver? ( buf -- yes? ) | |
268 | dup >vio-ver-major w@ vnet-major = ( buf flag1 ) | |
269 | swap >vio-ver-minor w@ vnet-minor = ( flag1 flag2 ) | |
270 | and | |
271 | ; | |
272 | ||
273 | ' vnet-compatible-ver? is vio-compatible-ver? | |
274 | ||
275 | : get-vnet-mac ( -- x ) | |
276 | mac-buf x@ xlsplit swap lwsplit nip swap lwsplit -rot wljoin swap lxjoin | |
277 | ; | |
278 | ||
279 | \ Send our attributes | |
280 | : send-vnet-attr ( -- ok? ) | |
281 | vnet-descr-buf /vnet-attr-msg erase ( ) | |
282 | ||
283 | vio-msg-type-ctrl vio-subtype-info vio-attr-info | |
284 | vnet-descr-buf set-vio-msg-tag ( ) | |
285 | vnet-sid vnet-descr-buf >vio-sid l! ( ) | |
286 | ||
287 | vnet-descr-buf frame-size over >vnet-attr-mtu x! ( buf ) | |
288 | 1 over >vnet-ack-freq w! ( buf ) | |
289 | ||
290 | get-vnet-mac over >vnet-attr-addr x! ( buf ) | |
291 | addr-type-mac over >vnet-addr-type c! ( buf ) | |
292 | vio-desc-mode swap >vnet-xfer-mode c! ( ) | |
293 | ||
294 | vnet-descr-buf /vnet-attr-msg send-to-ldc ( rlen ) | |
295 | /vnet-attr-msg = | |
296 | ; | |
297 | ' send-vnet-attr is send-vio-attr | |
298 | ||
299 | : send-vnet-rdx ( buf -- ok? ) | |
300 | dup /vnet-attr-msg erase ( buf ) | |
301 | >r vio-msg-type-ctrl vio-subtype-info vio-rdx | |
302 | r@ set-vio-msg-tag ( R: buf ) | |
303 | vnet-sid r@ >vio-sid l! ( R: buf ) | |
304 | r> /vnet-attr-msg send-to-ldc ( rlen ) | |
305 | /vnet-attr-msg = | |
306 | ; | |
307 | ||
308 | ' send-vnet-rdx is send-vio-rdx | |
309 | ||
310 | \ Stages: | |
311 | \ Version negotiation -> Vnet Attr info -> Dring info -> RDX | |
312 | : init-vnet-conn ( -- ok? ) | |
313 | debug-vnet? if ." Vnet version negotiation... " cr then | |
314 | vnet-descr-buf version-negotiation if | |
315 | debug-vnet? if ." Vnet Attr Exchange..." cr then | |
316 | vnet-descr-buf /vnet-attr-msg vio-exchange-attr if | |
317 | true exit | |
318 | then | |
319 | then | |
320 | false | |
321 | ; | |
322 | ||
323 | \ Set up sid and seq | |
324 | : set-descr-req-header ( type stype env -- ) | |
325 | vnet-descr-buf /vnet-descr-msg erase ( type stype env ) | |
326 | ||
327 | vnet-descr-buf set-vio-msg-tag ( ) | |
328 | vnet-sid vnet-descr-buf >vio-sid l! ( ) | |
329 | ||
330 | vnet-seq vnet-descr-buf >vnet-seq x! ( ) | |
331 | vnet-seq to cur-vnet-seq ( ) | |
332 | ; | |
333 | ||
334 | : send-descr-req ( len -- ok? ) | |
335 | vnet-descr-buf over send-to-ldc = ( ok? ) | |
336 | ; | |
337 | ||
338 | : fill-in-vnet-args ( len cadr #ck -- ) | |
339 | 2dup 4 pick vnet-descr-buf >vnet-cookie ( len cadr #ck cadr #ck len buf ) | |
340 | fill-in-vio-cookie ( len cadr #ck ) | |
341 | nip vnet-descr-buf tuck ( len buf #ck buf ) | |
342 | >vnet-ctrl-#cookies l! ( len buf ) | |
343 | >vnet-ctrl-nbytes l! ( ) | |
344 | ; | |
345 | ||
346 | \ Fill in & send the cookie pkt, number of cookies may vary | |
347 | : vnet-xmit-msg ( len cadr #ck -- ok? ) | |
348 | vio-msg-type-data vio-subtype-info vio-desc-data | |
349 | set-descr-req-header ( len cadr #ck ) | |
350 | dup 2swap rot ( #ck len cadr #ck ) | |
351 | fill-in-vnet-args ( #ck ) | |
352 | /ldc-mem-cookie * /vnet-descr-short + ( slen ) | |
353 | send-descr-req ( ok? ) | |
354 | ; | |
355 | ||
356 | \ map-table entry should be page aligned, copy output to tx-buffer and | |
357 | \ add tx-buffer to the map table | |
358 | : vnet-xmit ( buf len -- #sent ) | |
359 | tuck tx-buffer swap move ( len ) | |
360 | debug-vnet? if | |
361 | ." vnet xmit buf: len: " tx-buffer 2dup u. u. cr over | |
362 | " dump" evaluate | |
363 | then | |
364 | tx-buffer 2dup over ( len buf len buf len ) | |
365 | ldc-add-map-table-entries ( len buf len cadr #ck ) | |
366 | vnet-xmit-msg if ( len buf ) | |
367 | drop | |
368 | else | |
369 | cmn-warn[ " Can't send vnet write request!" ]cmn-end | |
370 | 2drop 0 | |
371 | then | |
372 | ; | |
373 | ||
374 | \ Check to see if tag DATA/INFO/OBP_DATA, ctrl flag is READY | |
375 | : vnet-data-pkt? ( -- yes? ) | |
376 | vnet-descr-buf get-vio-msg-tag ( env subt type ) | |
377 | vio-desc-data vio-subtype-info vio-msg-type-data vio-tag-match? ( yes? ) | |
378 | ; | |
379 | ||
380 | ||
381 | \ If two cookies span contiguous pages the ldc framework will only give us | |
382 | \ one extra-large cookie with a size that overflows into the next page | |
383 | : supercookie? ( ck -- supercookie? ) | |
384 | dup >ldc-mem-csize x@ ( ck total-size ) | |
385 | swap >ldc-mem-caddr x@ ( total-size ck-adr ) | |
386 | dup pagesize round-up swap - ( total-size next-page ) | |
387 | dup if ( total-size next-page ) | |
388 | \ total-size spans two pages? | |
389 | > ( true|false ) | |
390 | else | |
391 | \ already page aligned | |
392 | nip ( false ) | |
393 | then | |
394 | ; | |
395 | ||
396 | \ An ethernet frame (NON-JUMBO) can span at most 2 pages | |
397 | \ so we split the cookie into hypervisor-edible cookies | |
398 | : split-supercookie ( ck -- ck0 sz0 ck1 sz1 ) | |
399 | dup >ldc-mem-csize x@ >r ( ck ) ( r: total-size ) | |
400 | >ldc-mem-caddr x@ ( ck0 ) ( r: total-size ) | |
401 | dup pagesize round-up over - ( ck0 sz0 ) ( r: total-size ) | |
402 | 2dup + ( ck0 sz0 ck1 ) ( r: total-size ) | |
403 | over r> swap - ( ck0 sz0 ck1 sz1 ) | |
404 | ; | |
405 | ||
406 | \ recreate the vnet-descr-buf with the weenie cookies | |
407 | : sort-supercookies ( ck -- ) | |
408 | dup supercookie? if | |
409 | split-supercookie 2swap ( ck1 sz1 ck0 sz0 ) | |
410 | vnet-descr-buf ( ck1 sz1 ck0 sz0 buf ) | |
411 | 2 over >vnet-ctrl-#cookies l! ( ck1 sz1 ck0 sz0 buf ) | |
412 | >vnet-cookie ( ck1 sz1 ck0 sz0 buf ) | |
413 | tuck >ldc-mem-csize x! ( ck1 sz1 ck0 buf ) | |
414 | tuck >ldc-mem-caddr x! ( ck1 sz1 buf ) | |
415 | /ldc-mem-cookie + ( ck1 sz1 buf' ) | |
416 | tuck >ldc-mem-csize x! ( ck1 buf' ) | |
417 | >ldc-mem-caddr x! | |
418 | else | |
419 | drop | |
420 | then | |
421 | ; | |
422 | ||
423 | \ Read cookies, copy in data | |
424 | \ Even though we have at most 2 cookies right now, put in a loop | |
425 | \ so that it can handle more cookies in the future | |
426 | : vnet-copy-in ( buf len -- rlen ) | |
427 | vnet-descr-buf >vnet-cookie sort-supercookies ( buf len ) | |
428 | vnet-descr-buf >vnet-ctrl-nbytes l@ ( buf len rlen ) | |
429 | \ Copy multiple cookies | |
430 | min 0 -rot ( rlen buf len' ) | |
431 | vnet-descr-buf >vnet-ctrl-#cookies l@ 0 do ( rlen buf len' ) | |
432 | vnet-descr-buf >vnet-cookie | |
433 | /ldc-mem-cookie i * + ( rlen buf len' addr ) | |
434 | dup >ldc-mem-caddr x@ ( rlen buf len' addr ck ) | |
435 | swap >ldc-mem-csize x@ ( rlen buf len' ck size ) | |
436 | ||
437 | debug-vnet? if | |
438 | dup ." Retrieved cookie size: " u. cr | |
439 | then | |
440 | ||
441 | rx-buffer -rot ldc-copy-in ( rlen buf len' clen ) | |
442 | ||
443 | debug-vnet? if | |
444 | dup ." ldc copy in cookie size: " u. cr | |
445 | rx-buffer over " dump" evaluate | |
446 | then | |
447 | ||
448 | \ For alignment, cookie size maybe bigger than requested size | |
449 | over min >r ( rlen buf len' ) ( R: clen' ) | |
450 | over rx-buffer swap r@ move ( rlen buf len' ) ( R: clen' ) | |
451 | r@ - swap r@ + rot r> + ( len'' buf' rlen' ) | |
452 | -rot swap ( rlen' buf' len'' ) | |
453 | loop | |
454 | 2drop ( rlen ) | |
455 | ; | |
456 | ||
457 | \ Send back ACK packet | |
458 | : vnet-send-ack ( idx #ck -- ) | |
459 | vio-msg-type-data vio-subtype-ack vio-desc-data ( idx #ck ) | |
460 | set-descr-req-header ( idx #ck ) | |
461 | swap vnet-descr-buf >vnet-desc-hdl x! ( #ck ) | |
462 | /ldc-mem-cookie * /vnet-descr-short + ( slen ) | |
463 | send-descr-req drop | |
464 | ; | |
465 | ||
466 | \ Read a packet if it's available, skip the ACK packets, for DATA packet, | |
467 | \ Send an ACK packet after the memory content is retrieved. | |
468 | : vnet-poll ( buf len -- #rcvd ) | |
469 | begin | |
470 | vnet-descr-buf /vnet-descr-msg retrieve-packet ( buf len rlen ) | |
471 | dup 0= if nip nip exit then ( 0 ) | |
472 | drop vnet-data-pkt? ( buf len yes? ) | |
473 | until | |
474 | ||
475 | vnet-copy-in ( #rcvd ) | |
476 | vnet-descr-buf dup >vnet-desc-hdl x@ ( #rcvd buf idx ) | |
477 | swap >vnet-ctrl-#cookies l@ ( #rcvd idx #ck ) | |
478 | vnet-send-ack ( #rcvd ) | |
479 | ; | |
480 | ||
481 | : short-send ( buf,len -- error? ) | |
482 | tuck vnet-xmit ( len #sent ) | |
483 | <> | |
484 | ; | |
485 | ||
486 | \ Dump pkts with 0x800 (IP), 0x11 (UDP) and port 0x44 (BOOTP/DHCP) | |
487 | : dump-udp-bootp ( pkt len -- pkt len ) | |
488 | dup if ( pkt len ) | |
489 | over d# 12 + w@ h# 800 = if ( pkt len ) | |
490 | over d# 23 + c@ h# 11 = if ( pkt len ) | |
491 | over d# 36 + w@ h# 44 = if | |
492 | ." udp pkt received!" cr | |
493 | 2dup " dump" evaluate cr | |
494 | then | |
495 | then | |
496 | then | |
497 | then | |
498 | ; | |
499 | ||
500 | \ offset 34: source port (2 bytes) | |
501 | \ 36: destination port (2 bytes) | |
502 | \ 38: seq number (4 bytes) | |
503 | \ 42: ack number (4 bytes) | |
504 | : dump-tcp-headers ( pkt len -- pkt len ) | |
505 | dup if ( pkt len ) | |
506 | over d# 12 + w@ h# 800 = if ( pkt len ) | |
507 | over d# 23 + c@ d# 6 = if ( pkt len ) | |
508 | over d# 34 + w@ u. over d# 36 + w@ u. | |
509 | over d# 38 + w@ >r over d# 40 + w@ r> wljoin u. | |
510 | over d# 42 + w@ >r over d# 44 + w@ r> wljoin u. cr | |
511 | then | |
512 | then | |
513 | then | |
514 | ; | |
515 | ||
516 | \ Allocate vnet descriptor buffer | |
517 | : allocate-vnet-descr-buf | |
518 | 8 /vnet-descr-buf 0 claim to vnet-descr-buf ( ) | |
519 | ; | |
520 | ||
521 | \ Release and reset vnet descriptor buffer | |
522 | : deallocate-vnet-descr-buf | |
523 | /vnet-descr-buf vnet-descr-buf release ( ) | |
524 | 0 to vnet-descr-buf | |
525 | ; | |
526 | ||
527 | external | |
528 | ||
529 | : open ( -- ok? ) | |
530 | open-vnet-ldc if ( ) | |
531 | false exit ( false ) | |
532 | then | |
533 | ||
534 | " local-mac-address" get-my-property if ( adr len | ) | |
535 | cmn-warn[ " Can not find local-mac-address property" ]cmn-end | |
536 | false exit ( false ) | |
537 | then ( adr len ) | |
538 | over mac-address comp 0= if ( adr len ) | |
539 | \ Save a copy of mac address to mac-buf, used in vnet version negotiation | |
540 | 2dup mac-buf swap cmove ( adr len ) | |
541 | " mac-address" property ( ) | |
542 | else ( adr len ) | |
543 | cmn-warn[ " MAC Address does not match local-mac-address, " cmn-append | |
544 | " Virtual Networks do not support variable local-mac-address? = false." | |
545 | ]cmn-end | |
546 | 2drop false exit ( false ) | |
547 | then | |
548 | ||
549 | allocate-vnet-descr-buf ( ) | |
550 | ||
551 | my-args init-obp-tftp 0= if | |
552 | deallocate-vnet-descr-buf ( ) | |
553 | close-vnet-ldc ( ) | |
554 | false exit ( false ) | |
555 | then | |
556 | ||
557 | init-vnet-conn 0= if ( ) | |
558 | deallocate-vnet-descr-buf ( ) | |
559 | obp-tftp ?dup if close-package then ( ) | |
560 | close-vnet-ldc ( ) | |
561 | false exit ( false ) | |
562 | then | |
563 | ||
564 | debug-vnet? if ( ) | |
565 | ." mac-address shows: " ( ) | |
566 | mac-address bounds do i c@ u. loop cr ( ) | |
567 | then | |
568 | ||
569 | true to vnet-opened? ( ) | |
570 | true ( true ) | |
571 | ; | |
572 | ||
573 | : close ( -- ) | |
574 | deallocate-vnet-descr-buf ( ) | |
575 | ||
576 | obp-tftp ?dup if close-package then | |
577 | ldc-up? if | |
578 | close-vnet-ldc | |
579 | then | |
580 | ||
581 | false to vnet-opened? | |
582 | ; | |
583 | ||
584 | : read ( buf,len -- -2|len ) | |
585 | receive-ready? 0= if 2drop -2 exit then | |
586 | ||
587 | over swap ( buf buf len ) | |
588 | vnet-poll ?dup 0= if -2 then ( buf len' ) | |
589 | ||
590 | debug-tcp? if ( buf len' ) | |
591 | dump-udp-bootp ( buf len' ) | |
592 | dump-tcp-headers ( buf len' ) | |
593 | nip ( len' ) | |
594 | else | |
595 | nip ( len' ) | |
596 | then | |
597 | ; | |
598 | ||
599 | : write ( buf,len -- len ) | |
600 | vnet-xmit | |
601 | ; | |
602 | ||
603 | : load ( adr -- len ) | |
604 | " load" obp-tftp $call-method | |
605 | ; | |
606 | ||
607 | : watch-net ( -- ) | |
608 | open 0= if exit then | |
609 | frame-size alloc-mem to vnet-tmpbuf | |
610 | ||
611 | ." Looking for Ethernet packets." cr | |
612 | ." '.' is a good packet. 'X' is a bad packet." cr | |
613 | ." Type any key to stop." cr | |
614 | ||
615 | begin | |
616 | key? 0= | |
617 | while | |
618 | receive-ready? if | |
619 | vnet-tmpbuf frame-size vnet-poll if ." ." else ." X" then | |
620 | then | |
621 | repeat | |
622 | key drop | |
623 | ||
624 | vnet-tmpbuf frame-size free-mem | |
625 | close | |
626 | ; | |
627 | ||
628 | headerless |