blob: c905b6894a7648dc3e6fe37f61f47c656cd007ca [file] [log] [blame]
purpose: Ethernet driver
\ See license at end of file
hex
headers
" ethernet" device-name
" network" device-type
variable opencount 0 opencount !
true value first-open?
headers
: ?make-mac-address-property ( -- )
" mac-address" get-my-property if
mac-address encode-bytes " mac-address" property
else
2drop
then
;
: set-frame-size ( -- )
" max-frame-size" get-my-property if ( )
max-frame-size encode-int " max-frame-size" property
else ( prop$ )
2drop
then
;
: stop-net ( -- )
stop-mac
end-bulk-in
free-buf
;
external
: copy-packet ( adr len -- len' )
dup multi-packet? if 4 + then ( adr len len' )
/outbuf > if ." USB Ethernet write packet too long" cr stop-mac abort then ( adr len )
multi-packet? if ( adr len )
dup wbsplit ( adr len len.low len.high )
dup outbuf 1+ c! invert outbuf 3 + c! ( adr len len.low )
dup outbuf c! invert outbuf 2 + c! ( adr len )
tuck outbuf 4 + swap move ( len )
4 + ( len' )
else
outbuf over length-header ( adr len hdrlen )
2dup + ( adr len hdrlen len' )
swap 2swap rot ( len' adr len hdrlen )
outbuf + ( len' adr len adr' )
swap move ( len' )
then
;
: write ( adr len -- actual )
tuck copy-packet ( len len' )
outbuf swap bulk-out-pipe bulk-out ( len usberr )
if drop -1 then ( actual )
;
: even ( n -- n' ) 1+ -2 and ;
\ The data format is:
\ length.leword ~length.leword data [ pad-to-even ]
: extract-packet ( -- data-adr len )
residue 4 < if ." Short residue from USB Ethernet" cr stop-mac abort then
pkt-adr dup 4 + swap >r
r@ c@ r@ 1+ c@ bwjoin ( data-adr length )
r@ 2+ c@ r> 3 + c@ bwjoin ( data-adr length ~length )
over + h# ffff <> if ( data-adr length )
\ ." Bad length in USB Ethernet" cr
\ We got out of sync so we must discard the entire buffer
\ Return data-adr 0
drop 0
0 to residue 0 to pkt-adr
exit
then ( data-adr length )
2dup even ( data-adr length data-adr padded-len )
tuck + to pkt-adr ( data-adr length padded-len )
residue swap - 4 - to residue ( data-adr actual )
;
: packet-data ( -- data-adr data-len )
\ In multi-packet mode, the device can return multiple packets in
\ a single USB transaction. Each packet is preceded by a 32-bit
\ header containing the packet length and its one's complement.
multi-packet? if \ Extract packet from buffer
extract-packet ( in-adr actual )
else \ Buffer contains entire packet
pkt-adr residue ( in-adr actual' )
0 to residue
then ( in-adr actual' )
unwrap-msg ( data-adr data-len )
;
: read ( adr len -- actual )
\ If a good receive packet is ready, copy it out and return actual length
\ If a bad packet came in, discard it and return -1
\ If no packet is currently available, return -2
residue 0= if ( adr len )
bulk-in? if restart-bulk-in then ( adr len actual ) \ USB error; restart
to residue ( adr len )
residue 0= if 2drop -2 exit then ( adr len )
inbuf to pkt-adr
then
\ At this point we can be sure that residue is nonzero
packet-data ( adr len data-adr data-len )
rot min >r ( adr in-adr R: actual )
swap r@ move r> ( actual )
residue 0= if restart-bulk-in then \ Release buffer
;
: load ( adr -- len )
" obp-tftp" find-package if ( adr phandle )
my-args rot open-package ( adr ihandle|0 )
else ( adr )
0 ( adr 0 )
then ( adr ihandle|0 )
dup 0= if ." Can't open obp-tftp support package" stop-mac abort then
( adr ihandle )
>r
" load" r@ ['] $call-method catch ( len false | x x x true )
r> close-package
throw
;
: selftest ( -- flag )
false
;
: reset ( -- flag ) reset-nic ;
headers
\ This loopback code is here just in case it might be useful later.
\ It was originally written as a workaround for a first-packet lossage
\ problem, but the problem was eventually tracked down to a data toggle
\ issue in the EHCI layer.
0 value scratch-buf
: clear-rx ( -- )
d# 200 0 do
scratch-buf d# 2000 read -2 = ?leave
loop
;
create test-packet
h# ff c, h# ff c, h# ff c, h# ff c, h# ff c, h# ff c, \ Dst - broadcast
h# 01 c, h# 02 c, h# 03 c, h# 04 c, h# 05 c, h# 06 c, \ Src - junk
h# 00 c, h# 00 c, \ Type - junk
here h# 40 dup allot erase \ Junk data
here test-packet - constant /tp
: try-loopback? ( -- okay? )
test-packet /tp write /tp <> if false exit then
2 ms
scratch-buf d# 2000 read /tp =
;
: loopback-test ( -- )
d# 2000 alloc-mem to scratch-buf
loopback{
clear-rx
5 0 do try-loopback? ?leave loop
}loopback
scratch-buf d# 2000 free-mem
;
: do-start? ( -- error? )
start-phy
link-up? 0= if
." Network not connected." cr
true exit
then
init-buf
inbuf /inbuf bulk-in-pipe begin-bulk-in
start-mac
false
;
: parse-args ( -- )
false to use-promiscuous?
false to use-multicast?
my-args
begin ?dup while
ascii , left-parse-string
2dup " debug" $= if debug-on then
2dup " promiscuous" $= if true to use-promiscuous? then
2dup " multicast" $= if true to use-multicast? then
2drop
repeat drop
;
external
: close ( -- )
opencount @ 1- 0 max opencount !
opencount @ 0= if stop-net then
;
: open ( -- ok? )
parse-args
set-device? if false exit then
device set-target
opencount @ 0= if
reset? if
configuration set-config if
." Failed to set configuration" cr
false exit
then
bulk-in-pipe bulk-out-pipe reset-bulk-toggles
init-nic
then
first-open? if
false to first-open?
mac-adr$ encode-bytes " local-mac-address" property ( )
?make-mac-address-property
then
do-start? if false exit then
then
opencount @ 1+ opencount !
true
;
headers
init
\ LICENSE_BEGIN
\ Copyright (c) 2006 FirmWorks
\
\ Permission is hereby granted, free of charge, to any person obtaining
\ a copy of this software and associated documentation files (the
\ "Software"), to deal in the Software without restriction, including
\ without limitation the rights to use, copy, modify, merge, publish,
\ distribute, sublicense, and/or sell copies of the Software, and to
\ permit persons to whom the Software is furnished to do so, subject to
\ the following conditions:
\
\ The above copyright notice and this permission notice shall be
\ included in all copies or substantial portions of the Software.
\
\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\
\ LICENSE_END