@@ 104,6 104,7 @@ enum {
/* MediaStatus bits */
JabberEna = 0x0040, /* Jabber Enabled (writeable) */
LinkBeatEna = 0x0080, /* Link Beat Enabled (writeable) */
+ LinkBeatOk = 0x0800, /* Valid link beat detected (ro) */
};
#define COMMAND(port, cmd, a) outs(port+Command, ((cmd)<<11)|(a))
@@ 10,11 10,17 @@
#include "etherif.h"
enum {
+ GlobalReset = 0x00, /* Global Reset */
SelectWindow = 0x01, /* SelectWindow command */
Command = 0x0E, /* all windows */
Status = 0x0E,
+ XcvrTypeMask = 0xC000, /* Transceiver Type Select */
+ Xcvr10BaseT = 0x0000,
+ XcvrAUI = 0x4000,
+ XcvrBNC = 0xC000,
+
ManufacturerID = 0x00, /* window 0 */
ProductID = 0x02,
ConfigControl = 0x04,
@@ 22,6 28,14 @@ enum {
ResourceConfig = 0x08,
EEPROMcmd = 0x0A,
EEPROMdata = 0x0C,
+
+ FIFOdiag = 0x04, /* window 4 */
+ MediaStatus = 0x0A,
+
+ /* MediaStatus bits */
+ JabberEna = 0x0040, /* Jabber Enabled (writeable) */
+ LinkBeatEna = 0x0080, /* Link Beat Enabled (writeable) */
+ LinkBeatOk = 0x0800, /* Valid link beat detected (ro) */
};
#define COMMAND(port, cmd, a) outs(port+Command, ((cmd)<<11)|(a))
@@ 29,29 43,17 @@ enum {
extern int ether509reset(Ether*);
static int
-reset(Ether *ether)
+configASIC(Ether *ether, int port, int xcvr)
{
- int slot;
- int port;
ushort x;
- if(ether->irq == 0)
- ether->irq = 10;
- if(ether->port == 0)
- ether->port = 0x240;
- port = ether->port;
-
- slot = pcmspecial("3C589", ether);
- if(slot < 0)
- return -1;
-
/* set Window 0 configuration registers */
COMMAND(port, SelectWindow, 0);
/* ROM size & base - must be set before we can access ROM */
- /* transceiver type (for now always 10baseT) */
+ /* transceiver type is 2 for 'figure it out' */
x = ins(port + AddressConfig);
- outs(port + AddressConfig, x & 0x20);
+ outs(port + AddressConfig, (x & 0x20) | xcvr);
/* IRQ must be 3 on 3C589 */
x = ins(port + ResourceConfig);
@@ 66,10 68,46 @@ reset(Ether *ether)
x = ins(port+EEPROMdata);
outs(port + ProductID, x);
- if(ether509reset(ether) < 0){
+ return ether509reset(ether);
+}
+
+static int
+reset(Ether *ether)
+{
+ int slot;
+ int port;
+
+ if(ether->irq == 0)
+ ether->irq = 10;
+ if(ether->port == 0)
+ ether->port = 0x240;
+ port = ether->port;
+
+ slot = pcmspecial("3C589", ether);
+ if(slot < 0)
+ return -1;
+
+ /* try configuring as a 10baseT */
+ if(configASIC(ether, port, Xcvr10BaseT) < 0){
+ pcmspecialclose(slot);
+ return -1;
+ }
+ delay(100);
+ COMMAND(port, SelectWindow, 4);
+ if(ins(port+MediaStatus) & LinkBeatOk){
+ /* reselect window 1 for normal operation */
+ COMMAND(port, SelectWindow, 1);
+ print("10baseT 3C589\n");
+ return 0;
+ }
+
+ /* try configuring as a 10base2 */
+ COMMAND(port, GlobalReset, 0);
+ if(configASIC(ether, port, XcvrBNC) < 0){
pcmspecialclose(slot);
return -1;
}
+ print("BNC 3C589\n");
return 0;
}