aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2020-03-01 20:45:43 +0100
committerLubomir Rintel <lkundrak@v3.sk>2020-03-23 19:02:11 +0100
commit98ba23dee3318f62c816a5bd148f9e69ffbb4845 (patch)
treea04a4dbe2c56e576d0fdc7c71a3cd2406736fce7
parente7d65a2a27e153f12abd50c69f67bb83123953c0 (diff)
downloadopenfirmware-98ba23dee3318f62c816a5bd148f9e69ffbb4845.tar.gz
usb2/net: add a driver for SMSC LAN7500
This is a driver for the USB 2.0 to 10/100/1000 Mbps Ethernet driver. At the time it is pretty basic, it accepts all packets and makes no attempt at filtering in hardware but works well enough.
-rw-r--r--dev/usb2/device/net/lan7500.fth205
-rw-r--r--dev/usb2/device/net/usbnet.bth1
-rw-r--r--dev/usb2/device/net/vendor.fth14
3 files changed, 218 insertions, 2 deletions
diff --git a/dev/usb2/device/net/lan7500.fth b/dev/usb2/device/net/lan7500.fth
new file mode 100644
index 00000000..3b9f74a8
--- /dev/null
+++ b/dev/usb2/device/net/lan7500.fth
@@ -0,0 +1,205 @@
+purpose: SMSC LAN7500 USB Ethernet Driver
+\ See license at end of file
+
+headers
+
+\ Register I/O
+
+variable usb-val
+
+: error? ( flag -- ) ?dup if ." usb error: " . cr abort then ;
+
+h# a0 constant SET_REG
+h# a1 constant GET_REG
+
+: lan7500@ ( index -- u )
+ usb-val 4 rot 0 DR_IN DR_VENDOR DR_DEVICE or or GET_REG control-get
+ error? drop
+ usb-val l@
+;
+
+: lan7500! ( u index -- )
+ swap usb-val l! ( index )
+ usb-val 4 rot 0 DR_OUT DR_VENDOR DR_DEVICE or or SET_REG control-set
+ error?
+;
+
+\ Interface to the configuration EEPROM
+
+h# 040 constant e2p-cmd
+: epc-busy+ h# 8000.0000 or ;
+: epc-timeout+ h# 0000.0400 or ;
+: epc-read+ h# 0000.0000 or ;
+h# 044 constant e2p-data
+
+: lan7500-eeprom-ready ( -- )
+ begin
+ e2p-cmd lan7500@
+ 0 epc-busy+ epc-timeout+
+ and 0= until
+;
+
+: lan7500-eeprom@ ( index -- u )
+ lan7500-eeprom-ready
+ epc-busy+ epc-read+ e2p-cmd lan7500!
+ lan7500-eeprom-ready
+ e2p-data lan7500@
+;
+
+: lan7500-get-mac-address ( -- adr len )
+ h# a5 0 lan7500-eeprom@ = if
+ 6 0 do
+ i 1+ lan7500-eeprom@
+ mac-adr i + !
+ loop
+ else
+ ." Serial EEPROM with MAC address is not present." cr
+ then
+ mac-adr /mac-adr
+;
+
+\ MII interface to the PHY
+
+1 value phyid
+
+h# 120 constant mii-acc
+: mii-busy+ h# 0000.0001 or ;
+: mii-read+ h# 0000.0000 or ;
+: mii-write+ h# 0000.0002 or ;
+h# 124 constant mii-data
+
+: lan7500-phy-ready ( -- )
+ begin
+ mii-acc lan7500@
+ 0 mii-busy+ and 0= until
+;
+
+: lan7500-mii@ ( index -- u )
+ lan7500-phy-ready
+ d# 6 << phyid d# 11 << or
+ mii-busy+ mii-read+ mii-acc lan7500!
+ lan7500-phy-ready
+ mii-data lan7500@
+;
+
+: lan7500-mii! ( u index -- )
+ lan7500-phy-ready ( index u )
+ swap ( index u )
+ mii-data lan7500! ( index )
+ lan7500-phy-ready
+ d# 6 << phyid d# 11 << or
+ mii-busy+ mii-write+ mii-acc lan7500!
+;
+
+: lan7500-link-up? ( -- flag )
+ 1 lan7500-mii@ 4 and 0<>
+;
+
+: lan7500-sync-link-status ( -- )
+ \ Delayed loop until link-up is detected.
+ d# 500 0 do lan7500-link-up? if unloop exit then d# 10 ms loop
+;
+
+: lan7500-start-phy ( -- )
+ lan7500-sync-link-status
+;
+
+\ MAC interface
+
+h# 090 constant rx-fifo
+: rx-fifo-enable+ h# 8000.0000 or ;
+
+h# 094 constant tx-fifo
+: tx-fifo-enable+ h# 8000.0000 or ;
+
+h# 104 constant mac-rx
+: mac-rx-enable+ h# 0000.0001 or ;
+: strip-fcs+ h# 0000.0010 or ;
+
+h# 108 constant mac-tx
+: mac-tx-enable+ h# 0000.0001 or ;
+
+: lan7500-start-mac ( -- )
+ 0 mac-tx-enable+ mac-tx lan7500!
+ 0 tx-fifo-enable+ tx-fifo lan7500!
+
+ max-frame-size 16 <<
+ strip-fcs+ mac-rx-enable+ mac-rx lan7500!
+ 0 rx-fifo-enable+ rx-fifo lan7500!
+;
+
+\ Packet data wrapping and unwrapping
+
+: tx-fcs+ h# 0040.0000 or ;
+
+: lan7500-length-header ( adr len -- hdrlen )
+ tx-fcs+ over l! ( adr )
+ 4 + 0 swap l! ( )
+ 8 ( hdrlen )
+;
+
+: lan7500-unwrap-msg ( adr len -- adr' len' )
+ d# 10 < if ." Short read" 0 0 exit then ( adr )
+ dup @ h# 3fff and 2- ( adr len' )
+ swap d# 10 + swap ( adr' len' )
+;
+
+\ Initialization
+
+h# 0010 constant hw-cfg
+: nak-empty-in+ h# 0000.0080 or ;
+h# 0060 constant rfe-ctl
+: accept-bcast+ h# 0000.0400 or ;
+: accept-mcast+ h# 0000.0200 or ;
+: accept-ucast+ h# 0000.0100 or ;
+
+: lan7500-init-nic ( -- )
+ 0 nak-empty-in+ hw-cfg lan7500!
+ 0 accept-bcast+ accept-mcast+ accept-ucast+ rfe-ctl lan7500!
+
+ lan7500-get-mac-address 2drop
+ lan7500-sync-link-status
+;
+
+: init-lan7500 ( -- )
+ ['] lan7500-get-mac-address to get-mac-address
+ ['] lan7500-mii@ to mii@
+ ['] lan7500-mii! to mii!
+ ['] lan7500-link-up? to link-up?
+ ['] lan7500-start-phy to start-phy
+ ['] lan7500-start-mac to start-mac
+ ['] lan7500-length-header to length-header
+ ['] lan7500-unwrap-msg to unwrap-msg
+ ['] lan7500-init-nic to init-nic
+;
+
+: init ( -- )
+ init
+ vid pid net-lan7500? if
+ init-lan7500
+ then
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2020 Lubomir Rintel <lkundrak@v3.sk>
+\
+\ 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
diff --git a/dev/usb2/device/net/usbnet.bth b/dev/usb2/device/net/usbnet.bth
index d2467329..c624843a 100644
--- a/dev/usb2/device/net/usbnet.bth
+++ b/dev/usb2/device/net/usbnet.bth
@@ -15,6 +15,7 @@ fload ${BP}/dev/usb2/vendor.fth \ Vendor/product id table search routines
fload ${BP}/dev/usb2/device/net/vendor.fth \ Ethernet vendor/product id table
fload ${BP}/dev/usb2/device/net/common.fth \ Ethernet common variables and routines
fload ${BP}/dev/usb2/device/net/ax8817x.fth \ AX8817X device routines
+fload ${BP}/dev/usb2/device/net/lan7500.fth \ SMSC LAN7500 device routines
fload ${BP}/dev/usb2/device/net/pegasus.fth \ PegasusII device routines
fload ${BP}/dev/usb2/device/net/ethernet.fth \ USB ethernet driver
diff --git a/dev/usb2/device/net/vendor.fth b/dev/usb2/device/net/vendor.fth
index c40fab36..6a54846c 100644
--- a/dev/usb2/device/net/vendor.fth
+++ b/dev/usb2/device/net/vendor.fth
@@ -20,6 +20,10 @@ create net-ax8817x-list here
05ac w, 1402 w, \ Apple
here swap - constant /net-ax8817x-list
+create net-lan7500-list here
+ 0424 w, 7500 w, \ SMSC LAN7500
+here swap - constant /net-lan7500-list
+
create net-pegasus-list here
050d w, 0121 w, \ Belkin F5D5050
07a6 w, 8515 w, \ ADMtek 8515
@@ -30,11 +34,17 @@ here swap - constant /net-pegasus-list
net-ax8817x-list /net-ax8817x-list find-vendor-product?
;
+: net-lan7500? ( vid pid -- flag )
+ net-lan7500-list /net-lan7500-list find-vendor-product?
+;
+
: pegasus? ( vid pid -- flag )
net-pegasus-list /net-pegasus-list find-vendor-product?
;
: usb-net? ( vid pid -- flag )
- 2dup net-ax8817x? ( vid pid flag )
- -rot pegasus? or ( flag )
+ 2dup net-ax8817x? -rot ( flag vid pid )
+ 2dup net-lan7500? -rot ( flag flag vid pid )
+ pegasus? ( flag flag flag )
+ or or ( flag )
;