Author: wmb Date: 2009-11-09 08:10:10 +0000 (Mon, 09 Nov 2009) New Revision: 1463
Modified: dev/usb2/device/net/ax8817x.fth dev/usb2/device/net/common.fth dev/usb2/device/net/ethernet.fth Log: OLPC trac 9638 - fixed USB Ethernet driver to work with Asix AX88772A devices. AX88772 has been working for a long time, but the A-suffix parts are a little different. The main problem was that the A parts have additional bulk I/O pipes, which was confusing the code that chose which pipes to use for Ethernet data transmission. A secondary problem was that the loopback scheme for working around the loss of the first receive packet has to be revised for the A parts.
Modified: dev/usb2/device/net/ax8817x.fth =================================================================== --- dev/usb2/device/net/ax8817x.fth 2009-11-07 09:28:16 UTC (rev 1462) +++ dev/usb2/device/net/ax8817x.fth 2009-11-09 08:10:10 UTC (rev 1463) @@ -55,6 +55,9 @@ : ax-control-get ( adr len idx value cmd -- ) DR_IN DR_VENDOR or DR_DEVICE or swap control-get 2drop ; +: control@ ( cmd -- value ) \ For the common case of reading 2 bytes + >r ax-buf 2 0 0 r> ax-control-get ax-buf le-w@ +;
\ This isn't really necessary because all the important information in the \ EEPROM (node id, phyid, descriptors) can be accessed via other commands @@ -98,7 +101,10 @@ : ax-set-ipg ( -- ) ax-buf 3 0 0 h# 11 ax-control-get \ AX_CMD_READ_IPG012 ax88772? if - ax-buf 3 0 0 h# 12 ax-control-set \ AX_CMD_WRITE_IPG0 + ax-buf 0 ( adr len ) + ax-buf 2+ c@ 0 bwjoin ( adr len idx ) + ax-buf c@ ax-buf 1+ c@ bwjoin ( adr len idx value ) + h# 12 ax-control-set \ AX_CMD_WRITE_IPG0 else ax-buf 1 0 0 h# 12 ax-control-set \ AX_CMD_WRITE_IPG0 ax-buf 1+ 1 0 0 h# 13 ax-control-set \ AX_CMD_WRITE_IPG1 @@ -205,13 +211,30 @@ ;
: rx-ctl! ( n -- ) h# 10 control! ; \ AX_CMD_WRITE_RX_CTL +: rx-ctl@ ( -- n ) h# 0f control@ ; \ AX_CMD_READ_RX_CTL + +0 value has-internal-loopback? + +h# 88 constant def-rx-ctl \ SO (MAC ON) and AB (accept broadcast) + : ax-start-nic ( -- ) ax-auto-neg-wait - h# 8c my-args " promiscuous" $= if 1 or then rx-ctl! + def-rx-ctl my-args " promiscuous" $= if 1 or then rx-ctl! ; : ax-stop-nic ( -- ) 0 rx-ctl! ;
: ax-init-nic ( -- ) \ Per ax8817x_bind + bulk-out-pipe 3 > if + \ Some versions of the AX88772A have 4 bulk endpoints, instead of the 2 + \ that are usually present. The additional ones support a command-wrapper + \ interface to a serial block for talking to an external PHY. The common + \ code that autodetects the bulk-in and bulk-out pipes from descriptor + \ information tends to lock onto the high-numbered pipes instead of the + \ low-numbered ones that are used for Ethernet data. + 2 to bulk-in-pipe + 3 to bulk-out-pipe + then + ax88772? if true to multi-packet? then
ax-toggle-gpio @@ -222,9 +245,22 @@ ax-get-mac-address 2drop ax-set-ipg ax-init-mii - ax-start-nic ;
+: ax-loopback{ ( -- ) + def-rx-ctl h# 1000 or rx-ctl! + rx-ctl@ h# 1000 and if + true to has-internal-loopback? + \ This delay is empirically necessary and must not be present in the else clause. + d# 100 ms + else + phy-loopback{ + then +; +: ax-}loopback ( -- ) + has-internal-loopback? if def-rx-ctl rx-ctl! else phy-}loopback then +; + : init-ax ( -- ) ['] ax-init-nic to init-nic ['] ax-link-up? to link-up? @@ -235,6 +271,9 @@ ['] ax-mii! to mii! ['] ax-mii-sw to mii{ ['] ax-mii-hw to }mii + ['] ax-loopback{ to loopback{ + ['] ax-}loopback to }loopback + vid h# 2001 = pid h# 1a00 = and if h# 009f.9d9f to ax-gpio then vid h# 07b8 = pid h# 420a = and if h# 001f.1d1f to ax-gpio then d# 2048 to /inbuf
Modified: dev/usb2/device/net/common.fth =================================================================== --- dev/usb2/device/net/common.fth 2009-11-07 09:28:16 UTC (rev 1462) +++ dev/usb2/device/net/common.fth 2009-11-09 08:10:10 UTC (rev 1463) @@ -26,6 +26,16 @@ defer mii@ ( reg -- val ) ' noop to mii@ defer mii! ( val reg -- ) ' drop to mii@
+: phy-loopback{ ( -- ) + mii{ 0 mii@ h# 4000 or 0 mii! }mii +; +defer loopback{ ' phy-loopback{ to loopback{ + +: phy-}loopback ( -- ) + mii{ 0 mii@ h# 4000 invert and 0 mii! }mii +; +defer }loopback ' phy-}loopback to }loopback + external defer get-mac-address ( -- adr len ) ' mac-adr$ to get-mac-address headers
Modified: dev/usb2/device/net/ethernet.fth =================================================================== --- dev/usb2/device/net/ethernet.fth 2009-11-07 09:28:16 UTC (rev 1462) +++ dev/usb2/device/net/ethernet.fth 2009-11-09 08:10:10 UTC (rev 1463) @@ -33,13 +33,6 @@ free-buf ;
-: loopback{ ( -- ) - mii{ 0 mii@ h# 4000 or 0 mii! }mii -; -: }loopback ( -- ) - mii{ 0 mii@ h# 4000 invert and 0 mii! }mii -; - external
: copy-packet ( adr len -- len' ) @@ -191,6 +184,23 @@ scratch-buf d# 2000 free-mem ;
+: do-start? ( -- error? ) + start-nic + + link-up? 0= if + ." Network not connected." cr + stop-nic + true exit + then + + init-buf + inbuf /inbuf bulk-in-pipe begin-bulk-in + + loopback-test + + false +; + external
: close ( -- ) @@ -202,25 +212,14 @@ my-args " debug" $= if debug-on then device set-target opencount @ 0= if - init-buf - inbuf /inbuf bulk-in-pipe begin-bulk-in - first-open? if false to first-open? init-nic mac-adr$ encode-bytes " local-mac-address" property ( ) ?make-mac-address-property - else - start-nic then
- link-up? 0= if - ." Network not connected." cr - stop-net - false exit - then - - loopback-test + do-start? if false exit then then opencount @ 1+ opencount ! true
openfirmware@openfirmware.info