Author: wmb
Date: 2010-01-28 03:44:36 +0100 (Thu, 28 Jan 2010)
New Revision: 1715
Modified:
cpu/x86/pc/olpc/nandcastui.fth
dev/usb2/device/net/ax8817x.fth
ofw/inet/ip.fth
ofw/inet/netload.fth
Log:
Multicast improvements.
Modified: cpu/x86/pc/olpc/nandcastui.fth
===================================================================
--- cpu/x86/pc/olpc/nandcastui.fth 2010-01-27 06:21:04 UTC (rev 1714)
+++ cpu/x86/pc/olpc/nandcastui.fth 2010-01-28 02:44:36 UTC (rev 1715)
@@ -100,12 +100,18 @@
" boot rom:nb_rx ,,239.255.1.2" eval
;
-: nb-rx
+: nb-xx
false to already-go?
boot-as-call(
" boot rom:nb_rx ,,239.255.1.2" eval
)boot-as-call
;
+: nb-rx
+ false to already-go?
+ boot-as-call(
+ " boot rom:nb_rx ,,0.0.0.1" eval
+ )boot-as-call
+;
: ucastnand
false to already-go?
" boot rom:nb_rx 10.20.0.16,,10.20.0.44" eval
Modified: dev/usb2/device/net/ax8817x.fth
===================================================================
--- dev/usb2/device/net/ax8817x.fth 2010-01-27 06:21:04 UTC (rev 1714)
+++ dev/usb2/device/net/ax8817x.fth 2010-01-28 02:44:36 UTC (rev 1715)
@@ -135,6 +135,12 @@
ax-mii-hw
;
+8 buffer: multicast-filter
+
+: ax-multi-filter! ( -- )
+ multicast-filter 8 0 0 h# 16 ax-control-set
+;
+
: ax-init-mii ( -- )
ax-mii-sw
\ ax88772? if
@@ -233,7 +239,39 @@
ax-auto-neg-wait
;
: ax-promiscuous ( -- ) rx-ctl@ 1 or rx-ctl! ;
-: ax-set-multicast ( adr len -- ) 2drop rx-ctl@ 2 or rx-ctl! ;
+
+: crc32-le ( adr len crc0 -- crc1 )
+ -rot bounds ?do ( crc )
+ i c@ xor ( crc' )
+ 8 0 do ( crc )
+ dup 1 and 0<> h# edb88320 and ( crc poly )
+ swap u2/ xor ( crc' )
+ loop ( crc )
+ loop ( crc )
+;
+
+\ index 000 001 010 011 100 101 110 111
+\ bitrev 000 100 010 110 001 101 011 111
+create bitrev3 0 c, 4 c, 2 c, 6 c, 1 c, 5 c, 3 c, 7 c,
+
+: add-multicast-address ( adr len -- )
+ h# ffffffff crc32-le ( crc )
+ \ The low 3 bits - reversed - are the byte index and
+ \ the next 3 bits - reversed - are the bit number
+ dup 3 rshift 7 and bitrev3 + c@ ( crc bit# )
+ 1 swap lshift ( crc bitmask )
+ swap 7 and bitrev3 + c@ ( bitmask byte# )
+ multicast-filter + tuck ( adr bitmask adr )
+ c@ or swap c! ( )
+;
+
+\ : ax-set-multicast ( adr len -- ) 2drop rx-ctl@ 2 or rx-ctl! ;
+: ax-set-multicast ( adr len -- )
+ multicast-filter 8 erase ( adr len )
+ add-multicast-address ( )
+ ax-multi-filter! ( )
+ rx-ctl@ h# 10 or rx-ctl!
+;
: ax-stop-mac ( -- ) 0 rx-ctl! ;
: ax-init-nic ( -- ) \ Per ax8817x_bind
Modified: ofw/inet/ip.fth
===================================================================
--- ofw/inet/ip.fth 2010-01-27 06:21:04 UTC (rev 1714)
+++ ofw/inet/ip.fth 2010-01-28 02:44:36 UTC (rev 1715)
@@ -84,6 +84,10 @@
swap unknown-ip-addr? or ( flag )
;
+: multicast-ip-addr? ( adr-buf -- flag )
+ c@ h# f0 and h# e0 =
+;
+
: netmask ( -- 'ip )
subnetmask unknown-ip-addr? if default-netmask else subnetmask then
;
@@ -185,6 +189,8 @@
drop ip-length xw@ ip-version c@ h# f and /l* payload
;
+0 instance value multicast-rx?
+
: ip-addr-match? ( -- flag )
\ If we know the server's IP address (e.g. the user specified one, or
\ we chose one from a RARP or BOOTP reply, or we locked onto one that
@@ -200,6 +206,10 @@
\ If we don't know our own IP address yet, we accept every IP packet
my-ip-addr unknown-ip-addr? if true exit then
+ multicast-rx? if
+ ip-dest-addr multicast-ip-addr? if true exit then
+ then
+
\ Otherwise, we know our IP address, so we filter out packets addressed
\ to other destinations.
my-ip-addr ip-dest-addr ip=
Modified: ofw/inet/netload.fth
===================================================================
--- ofw/inet/netload.fth 2010-01-27 06:21:04 UTC (rev 1714)
+++ ofw/inet/netload.fth 2010-01-28 02:44:36 UTC (rev 1715)
@@ -434,24 +434,45 @@
." Can't enable multicast reception in network driver" cr
;
+: set-multicast-en-addr ( 'ip -- )
+ " "(01 00 5e)" his-en-addr swap move ( 'ip )
+ 1+ his-en-addr 3 + 3 move ( )
+ his-en-addr 3 + c@ h# 7f and his-en-addr 3 + c! ( )
+;
+
: send-multicast ( -- )
server-ip-addr his-ip-addr copy-ip-addr
- " "(01 00 5e)" his-en-addr swap move ( acf )
- his-ip-addr 1+ his-en-addr 3 + 3 move ( acf )
- his-en-addr 3 + c@ h# 7f and his-en-addr 3 + c! ( )
+ his-ip-addr set-multicast-en-addr
;
-: receive-multicast ( -- )
-\ server-ip-addr my-ip-addr copy-ip-addr
+0 value igmp-packet
+: send-igmp-v1-report ( 'ip -- )
+ 8 allocate-ip to igmp-packet ( 'ip )
+ 0 igmp-packet l! ( 'ip )
+ h# 12 igmp-packet c! ( 'ip )
+ dup igmp-packet 4 + copy-ip-addr ( 'ip )
+ 0 igmp-packet 8 oc-checksum igmp-packet 2+ be-w! ( 'ip )
+
+ his-ip-addr copy-ip-addr \ Send to the group we are registering for
+ 1 ttl !
+ igmp-packet 8 2 send-ip-packet
+ igmp-packet 8 free-ip
+ broadcast-ip-addr his-ip-addr copy-ip-addr \ Don't filter on the server IP address
+;
+
+: join-multicast-group ( 'ip -- )
+ dup set-multicast-en-addr ( 'ip )
+ send-igmp-v1-report ( )
+ true to multicast-rx? ( )
" set-multicast" my-parent ihandle>phandle find-method if ( acf )
- " "(01 00 5e)" his-en-addr swap move ( acf )
- my-ip-addr 1+ his-en-addr 3 + 3 move ( acf )
- his-en-addr 3 + c@ h# 7f and his-en-addr 3 + c! ( )
his-en-addr /e rot my-parent call-package ( )
exit
then
try-promiscuous
;
+: receive-multicast ( 'ip -- )
+ my-ip-addr join-multicast-group
+;
defer configured ' noop to configured
: configure ( -- )