diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2020-03-01 20:45:43 +0100 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2020-03-23 19:02:11 +0100 |
commit | 98ba23dee3318f62c816a5bd148f9e69ffbb4845 (patch) | |
tree | a04a4dbe2c56e576d0fdc7c71a3cd2406736fce7 | |
parent | e7d65a2a27e153f12abd50c69f67bb83123953c0 (diff) | |
download | openfirmware-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.fth | 205 | ||||
-rw-r--r-- | dev/usb2/device/net/usbnet.bth | 1 | ||||
-rw-r--r-- | dev/usb2/device/net/vendor.fth | 14 |
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 ) ; |