MODULE RTL8139;
IMPORT
SYSTEM, Kernel, Machine, PCI, Objects, Modules, Plugins, Network, KernelLog
, Files;
CONST
Name = "RTL8139#";
Desc = "RealTek 8139 ethernet driver";
Model8139 = 0; Model8139CB = 1; ModelSMC1211TX = 2; ModelDELTA8139 = 3; ModelADDTRON8139 = 4; ModelDFE528TX = 5;
Model8129 = 7; MaxModel = 8;
Chipset8139 = 0; Chipset8139K = 1; Chipset8139A = 2; Chipset8139B = 3; Chipset8130 = 4; Chipset8139C = 5;
NofChipsets = 6;
HasPwrDn = 0; HasLWake = 1;
DebugFind = TRUE; DebugInit = TRUE; DebugCleanup = TRUE; DebugTransmit = FALSE; DebugReceive = FALSE;
RegisterInNetwork = TRUE; CallNetworkReceiver = TRUE; Min60BytePacket = TRUE;
ReceiveAll = FALSE;
RxBufLenIdx = 2;
RxBufLen = ASH(8192, RxBufLenIdx) ;
RxBufPad = 16;
RxBufWrapPad = 2048;
RxBufSize = RxBufLen + RxBufPad + RxBufWrapPad;
MaxETHFrameSize = 1514;
MaxPacketsPerIRQ = 10;
VAR
installed: LONGINT;
logtime: Kernel.MilliTimer;
TYPE
ChipsetSpecific = RECORD
name: ARRAY 32 OF CHAR;
version: LONGINT;
configSet, flags: SET;
END;
VAR
chipsetInfo: ARRAY MaxModel OF ChipsetSpecific;
nPCIError, nTimeOut, nCableLengthChg, nFifoOverflow, nPUnOrLnkChg,
nRxBufferOverflow, nTxError, nTxOk, nRxError, nRxOk :LONGINT;
logging : BOOLEAN;
log :Files.Rider;
TYPE
LinkDevice = OBJECT (Network.LinkDevice)
VAR ctrl: Controller;
PROCEDURE Linked*(): LONGINT;
BEGIN
IF ctrl.Linked() THEN
RETURN Network.LinkLinked;
ELSE
RETURN Network.LinkNotLinked;
END;
END Linked;
PROCEDURE DoSend*(dst: Network.LinkAdr; type: LONGINT; VAR l3hdr, l4hdr, data: ARRAY OF CHAR; h3len, h4len, dofs, dlen: LONGINT);
VAR i: LONGINT; bufAdr: SYSTEM.ADDRESS; txState:LONGINT; txs:SET; t, totlen:LONGINT;
BEGIN {EXCLUSIVE}
SYSTEM.PUT16(ctrl.base + 3CH, SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LONG(SYSTEM.GET16(ctrl.base + 3CH)))-{0..6, 13..15}));
bufAdr:=SYSTEM.ADR(ctrl.txBuffers[ctrl.nextTxBuffer]^[0]);
SYSTEM.MOVE(SYSTEM.ADR(dst[0]), bufAdr, 6);
SYSTEM.MOVE(SYSTEM.ADR(local[0]), bufAdr+6, 6);
SYSTEM.PUT16(bufAdr+12, SYSTEM.ROT(SYSTEM.VAL(INTEGER, SHORT(type)), 8));
i:=14;
IF h3len > 0 THEN SYSTEM.MOVE(SYSTEM.ADR(l3hdr[0]), bufAdr+i, h3len); INC(i, h3len) END;
IF h4len > 0 THEN SYSTEM.MOVE(SYSTEM.ADR(l4hdr[0]), bufAdr+i, h4len); INC(i, h4len) END;
IF i + dlen < MaxETHFrameSize THEN
SYSTEM.MOVE(SYSTEM.ADR(data[0]) + dofs, bufAdr + i, dlen); INC(i, dlen);
END;
IF Min60BytePacket THEN WHILE i<60 DO ctrl.txBuffers[ctrl.nextTxBuffer]^[i] := CHR(0); INC(i) END END;
totlen := i;
IF DebugTransmit THEN
KernelLog.Enter; KernelLog.String("[TRANSMIT] Packet length:"); KernelLog.Int(i, 5); KernelLog.String(" data ..."); KernelLog.Ln;
KernelLog.Buffer(ctrl.txBuffers[ctrl.nextTxBuffer]^, 0, i);
KernelLog.Exit;
END;
IF i <= MaxETHFrameSize THEN
SYSTEM.PUT32(ctrl.base + 20H+4*ctrl.nextTxBuffer, bufAdr);
txState:=8*32*2048;
txState:=txState+i;
SYSTEM.PUT32(ctrl.base + 10H+4*ctrl.nextTxBuffer, txState);
i:=0; WHILE (i<10000000) & (SYSTEM.VAL(SET, SYSTEM.GET32(ctrl.base+10H+4*ctrl.nextTxBuffer)) * {14, 15, 30} = {}) DO
INC(i)
END;
IF i=10000000 THEN KernelLog.Enter; KernelLog.String("MegaError !!!"); KernelLog.Exit; ctrl.Reset END;
IF DebugTransmit THEN
KernelLog.Enter;
IF i<10000000 THEN
txs:=SYSTEM.VAL(SET, SYSTEM.GET32(ctrl.base+10H+4*ctrl.nextTxBuffer));
IF 13 IN txs THEN KernelLog.String(" DMA Completed ") END;
IF 14 IN txs THEN KernelLog.String(" Fifo underrun ") END;
IF 15 IN txs THEN KernelLog.String(" Transmit OK ") END;
IF 30 IN txs THEN KernelLog.String(" Transmit ABORTED ") END
ELSE KernelLog.String("Transmit timed out ");
KernelLog.Bits(SYSTEM.VAL(SET, SYSTEM.GET32(ctrl.base+10H+4*ctrl.nextTxBuffer)), 0, 32)
END;
KernelLog.Exit
END;
INC(sendCount);
ctrl.nextTxBuffer := (ctrl.nextTxBuffer + 1) MOD 4
END
;
SYSTEM.PUT16(ctrl.base + 3CH, SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LONG(SYSTEM.GET16(ctrl.base + 3CH)))+{0..6, 13..15}));
IF logging THEN
t := Kernel.Elapsed(logtime);
Files.WriteLInt(log, t DIV 1000);
Files.WriteLInt(log, (t MOD 1000)*1000+1);
Files.WriteLInt(log, totlen); Files.WriteLInt(log, totlen);
log.file.WriteBytes(log, ctrl.txBuffers[ctrl.nextTxBuffer]^, 0, totlen)
END
END DoSend;
PROCEDURE Finalize(connected: BOOLEAN);
BEGIN
ctrl.Finalize;
Finalize^(connected);
END Finalize;
END LinkDevice;
Controller = OBJECT
VAR
next: Controller;
base: SYSTEM.ADDRESS; irq: LONGINT;
dev: LinkDevice;
model, chipset: LONGINT;
media: SET;
rxBufPos: LONGINT;
timer: Kernel.Timer;
eepromAdrLen:LONGINT;
devAdr:ARRAY 3 OF LONGINT;
rxBuffer: POINTER TO ARRAY OF CHAR;
rxAdr: LONGINT;
nextTxBuffer: LONGINT;
txBuffers: ARRAY 4 OF POINTER TO ARRAY OF CHAR;
rcvAdr, rcvSize:LONGINT;
PROCEDURE FlushWrite8(reg, val:LONGINT);
BEGIN
SYSTEM.PUT8(base + reg, val); val := SYSTEM.GET8(base + reg)
END FlushWrite8;
PROCEDURE Reset;
VAR dp, dummy:LONGINT; val:SET;
BEGIN nextTxBuffer:=0;
KernelLog.Enter; KernelLog.String("Softreset"); KernelLog.Exit;
SYSTEM.PUT8(base + 37H, SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LONG(LONG(SYSTEM.GET8(base + 37H)))) + {4}));
dp:=0;
LOOP INC(dp); timer.Sleep(1); IF (SYSTEM.VAL(SET, LONG(LONG(SYSTEM.GET8(base + 37H)))) * {4} = {}) OR (dp=100) THEN EXIT END END;
val := SYSTEM.VAL(SET, SYSTEM.GET8(base + 52H));
IF val * {3} = {} THEN KernelLog.String("MMIO is disabled."); HALT(1000) END;
IF val * {2} = {} THEN KernelLog.String("IO mapping is disabled."); HALT(1000) END;
FlushWrite8(37H, SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LONG(LONG(SYSTEM.GET8(base + 37H))))* {1, 5, 6, 7} + {2 , 3}));
SYSTEM.PUT32(base + 30H, SYSTEM.ADR(rxBuffer[0]));
rxBufPos:=0; SYSTEM.PUT16(base+38H, rxBufPos-16); dummy:=SYSTEM.GET16(base + 38H);
IF ReceiveAll THEN
SYSTEM.PUT32(base + 44H,
SYSTEM.VAL(SET, SYSTEM.GET32(base + 44H)) * chipsetInfo[chipset].configSet + {, 12, 8..10, 7, 0..4})
ELSE
SYSTEM.PUT32(base + 44H,
SYSTEM.VAL(SET, SYSTEM.GET32(base + 44H)) * chipsetInfo[chipset].configSet + {, 12, 8..10, 7, 1..4})
END;
dummy:=SYSTEM.GET32(base + 44H);
SYSTEM.PUT32(base, Network.Get4(dev.local, 0)); dummy:=SYSTEM.GET32(base);
SYSTEM.PUT32(base + 4, Network.Get4(dev.local, 4));dummy:=SYSTEM.GET32(base + 4);
SYSTEM.PUT16(base + 3CH, SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LONG(SYSTEM.GET16(base + 3CH)))+{0..6, 13..15}));
SYSTEM.PUT32(base + 40H, SYSTEM.VAL(SET, SYSTEM.GET32(base + 40H))+{9, 10});
END Reset;
PROCEDURE &Init*(dev: LinkDevice; base: SYSTEM.ADDRESS; irq, model: LONGINT);
VAR res, dp, ver, i, dummy: LONGINT; val, nval: SET;
BEGIN
SELF.next:=installedControllers; installedControllers:=SELF;
NEW(timer);
SELF.base := base; SELF.dev := dev; SELF.model := model; SELF.media := media; SELF.irq := irq;
dev.ctrl := SELF;
IF HasPwrDn IN chipsetInfo[chipset].flags THEN
FlushWrite8(50H, SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LONG(LONG(SYSTEM.GET8(base + 50H)))) + {7, 6}));
SYSTEM.PUT8(base + 52H, SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LONG(LONG(SYSTEM.GET8(base + 52H)))) - {0, 1}));
FlushWrite8(50H, SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LONG(LONG(SYSTEM.GET8(base + 50H)))) - {7, 6}));
ELSE
val := SYSTEM.VAL(SET, SYSTEM.GET8(base + 52H)); nval := val;
IF (HasLWake IN chipsetInfo[chipset].flags) & (1 IN val) THEN nval:=nval - {1} END;
nval := nval + {0};
IF nval # val THEN
FlushWrite8(50H, SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LONG(LONG(SYSTEM.GET8(base + 50H)))) + {7, 6}));
SYSTEM.PUT8(base + 52H, SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LONG(LONG(SYSTEM.GET8(base + 52H)))) - {0, 1}));
FlushWrite8(50H, SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LONG(LONG(SYSTEM.GET8(base + 50H)))) - {7, 6}))
END;
IF (HasLWake IN chipsetInfo[chipset].flags) THEN
SYSTEM.PUT8(base + 5AH, SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LONG(LONG(SYSTEM.GET8(base + 5AH)))) - {2}))
END
END;
SYSTEM.PUT8(base + 37H, SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LONG(LONG(SYSTEM.GET8(base + 37H)))) + {4}));
dp:=0;
LOOP INC(dp); timer.Sleep(1); IF (SYSTEM.VAL(SET, LONG(LONG(SYSTEM.GET8(base + 37H)))) * {4} = {}) OR (dp=100) THEN EXIT END END;
val := SYSTEM.VAL(SET, SYSTEM.GET8(base + 52H));
IF val * {3} = {} THEN KernelLog.String("MMIO is disabled."); HALT(1000) END;
IF val * {2} = {} THEN KernelLog.String("IO mapping is disabled."); HALT(1000) END;
chipset:=-1;
ver := SYSTEM.GET8(base + 43H);
i := 0; WHILE i < NofChipsets DO IF chipsetInfo[i].version = ver THEN chipset := i; i:=NofChipsets ELSE INC(i) END END;
IF chipset = -1 THEN chipset:=Chipset8139; KernelLog.Enter; KernelLog.String("chipset version unknown... assuming RTL-8139"); KernelLog.Exit END;
IF DebugInit THEN KernelLog.String("Chip version is: "); KernelLog.Hex(ver, 2); KernelLog.String(" "); KernelLog.String(chipsetInfo[chipset].name); KernelLog.Ln END;
IF DebugInit THEN KernelLog.String("Install IRQ Handler: "); KernelLog.Int(irq, 5); KernelLog.Ln END;
IF (irq >= 1) & (irq <= 15) THEN Objects.InstallHandler(SELF.HandleInterrupt, Machine.IRQ0+irq) END;
NEW(rxBuffer, RxBufSize);
FlushWrite8(37H, SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LONG(LONG(SYSTEM.GET8(base + 37H))))* {1, 5, 6, 7} + {2 , 3}));
SYSTEM.PUT32(base + 30H, SYSTEM.ADR(rxBuffer[0]));
rxBufPos:=0; SYSTEM.PUT16(base+38H, rxBufPos-16); dummy:=SYSTEM.GET16(base + 38H);
IF ReceiveAll THEN
SYSTEM.PUT32(base + 44H,
SYSTEM.VAL(SET, SYSTEM.GET32(base + 44H)) * chipsetInfo[chipset].configSet + {, 12, 8..10, 7, 0..4})
ELSE
SYSTEM.PUT32(base + 44H,
SYSTEM.VAL(SET, SYSTEM.GET32(base + 44H)) * chipsetInfo[chipset].configSet + {, 12, 8..10, 7, 1..4})
END;
dummy:=SYSTEM.GET32(base + 44H);
FOR i:=0 TO 3 DO NEW(txBuffers[i], MaxETHFrameSize) END;
FOR i := 0 TO 5 DO dev.broadcast[i] := 0FFX END;
eepromAdrLen:=8; IF ReadEEPROM(0)#8129H THEN eepromAdrLen:=6 END;
FOR i:=0 TO 2 DO devAdr[i]:=ReadEEPROM(7+i);
dev.local[i*2]:=CHR(devAdr[i] MOD 256);dev.local[i*2+1]:=CHR(devAdr[i] DIV 256 MOD 256)
END;
dev.adrSize := 6;
SYSTEM.PUT32(base, Network.Get4(dev.local, 0)); dummy:=SYSTEM.GET32(base);
SYSTEM.PUT32(base + 4, Network.Get4(dev.local, 4));dummy:=SYSTEM.GET32(base + 4);
SYSTEM.PUT32(base + 8H, 0FFFF3333H);
SYSTEM.PUT32(base + 0CH, 0FFFFFFFFH);
SYSTEM.PUT16(base + 3CH, SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LONG(SYSTEM.GET16(base + 3CH)))+{1..6, 13..15}));
SYSTEM.PUT32(base + 40H, SYSTEM.VAL(SET, SYSTEM.GET32(base + 40H))+{9, 10});
IF RegisterInNetwork THEN
Network.registry.Add(dev, res);
ASSERT(res = Plugins.Ok);
INC(installed)
END
END Init;
PROCEDURE ReadEEPROM(loc:LONGINT):LONGINT;
VAR readCMD, data:SET; dummy, i:LONGINT;
BEGIN
readCMD := SYSTEM.VAL(SET, loc);
IF eepromAdrLen = 6 THEN readCMD:=readCMD+{1+6, 2+6} ELSE readCMD:=readCMD+{1+8, 2+8} END;
SYSTEM.PUT8(base+50H, SYSTEM.VAL(CHAR, {7})); SYSTEM.PUT8(base+50H, SYSTEM.VAL(CHAR, {7, 3}));
dummy:=SYSTEM.GET32(base+50H);
i := 4 + eepromAdrLen;
WHILE i >= 0 DO
IF i IN readCMD THEN SYSTEM.PUT8(base+50H, SYSTEM.VAL(CHAR, {7, 3, 1})) ELSE SYSTEM.PUT8(base+50H, SYSTEM.VAL(CHAR,{7, 3})) END;
dummy:=SYSTEM.GET32(base+50H);
IF i IN readCMD THEN SYSTEM.PUT8(base+50H, SYSTEM.VAL(CHAR,{7, 3, 2, 1})) ELSE SYSTEM.PUT8(base+50H, SYSTEM.VAL(CHAR,{7, 3, 2})) END;
dummy:=SYSTEM.GET32(base+50H);
DEC(i)
END;
SYSTEM.PUT8(base+50H, SYSTEM.VAL(CHAR, {7, 3}));
dummy:=SYSTEM.GET32(base+50H);
data:={};
FOR i:=15 TO 0 BY -1 DO
SYSTEM.PUT8(base+50H, SYSTEM.VAL(CHAR,{7, 3, 2}));
dummy:=SYSTEM.GET32(base+50H);
IF SYSTEM.VAL(SET, LONG(LONG(SYSTEM.GET8(base + 50H)))) * {0} = {0} THEN INCL(data, i) END;
SYSTEM.PUT8(base+50H, SYSTEM.VAL(CHAR, {7, 3}));
dummy:=SYSTEM.GET32(base+50H)
END;
SYSTEM.PUT8(base+50H, SYSTEM.VAL(CHAR, -{3}));
dummy:=SYSTEM.GET32(base+50H);
RETURN SYSTEM.VAL(LONGINT, data)
END ReadEEPROM;
PROCEDURE ReadPacket;
VAR rxInfo, pSize, pStart, dummy, i, type: LONGINT; t: LONGINT;
buf : Network.Buffer;
BEGIN
i:=0;
WHILE (i<MaxPacketsPerIRQ) & ~(0 IN SYSTEM.VAL(SET, SYSTEM.GET8(base + 37H))) DO
rxInfo := Network.Get4(rxBuffer^, rxBufPos);
pSize := (rxInfo DIV 65536) MOD 65536 - 4;
pStart := rxBufPos + 4;
IF DebugReceive THEN KernelLog.Enter; KernelLog.String("[RECEIVE] PSize is:"); KernelLog.Int(pSize, 4); KernelLog.Exit END;
IF pSize # 0FFF0H THEN
IF pSize < MaxETHFrameSize THEN
IF DebugReceive THEN
KernelLog.Enter;
KernelLog.String("Read Packet ("); KernelLog.Int(pSize, 4); KernelLog.String(")"); KernelLog.Ln;
KernelLog.Buffer(rxBuffer^, rxBufPos + 4, pSize);
KernelLog.Exit
END;
IF logging THEN
t := Kernel.Elapsed(logtime);
Files.WriteLInt(log, t DIV 1000);
Files.WriteLInt(log, (t MOD 1000)*1000+1);
Files.WriteLInt(log, pSize); Files.WriteLInt(log, pSize);
log.file.WriteBytes(log, rxBuffer^, rxBufPos + 4, pSize);
END;
type := Network.GetNet2(rxBuffer^, pStart + 6 + 6);
IF DebugReceive THEN KernelLog.Enter; KernelLog.String("packet type:"); KernelLog.Hex(type, 2); KernelLog.Exit END;
buf := Network.GetNewBuffer();
IF buf # NIL THEN
buf.ofs := 0;
buf.len := pSize - 14;
buf.src := SYSTEM.VAL(Network.LinkAdr, rxBuffer[pStart + 6]);
buf.calcChecksum := {};
Network.Copy(rxBuffer^, buf.data, pStart + 14, 0, pSize - 14);
dev.QueueBuffer(buf, type);
ELSE
END
END
END;
rxBufPos:=(rxBufPos+pSize+8+3); rxBufPos:=(rxBufPos - (rxBufPos MOD 4)) MOD RxBufLen;
SYSTEM.PUT16(base+38H, rxBufPos-16); dummy:=SYSTEM.GET16(base + 38H);
INC(i)
END;
END ReadPacket;
PROCEDURE HandleInterrupt;
VAR status, ack:SET; dummy:LONGINT;
BEGIN
ack:={0};
status:=SYSTEM.VAL(SET, LONG(SYSTEM.GET16(base + 3EH)));
IF 15 IN status THEN
Machine.AtomicInc(nPCIError)
END;
IF 14 IN status THEN
Machine.AtomicInc(nTimeOut); INCL(ack, 14);
END;
IF 13 IN status THEN
Machine.AtomicInc(nCableLengthChg); INCL(ack, 13)
END;
IF 6 IN status THEN
INCL(ack, 4); INCL(ack, 6); INCL(ack, 0);
Machine.AtomicInc(nFifoOverflow);
END;
IF 5 IN status THEN Reset;
Machine.AtomicInc(nPUnOrLnkChg); INCL(ack, 5)
END;
IF 4 IN status THEN
Machine.AtomicInc(nRxBufferOverflow);
INCL(ack, 0); INCL(ack, 4);
END;
IF 3 IN status THEN
Machine.AtomicInc(nTxError); INCL(ack, 3)
END;
IF 2 IN status THEN
Machine.AtomicInc(nTxOk);
INCL(ack, 2)
END;
IF 1 IN status THEN
Machine.AtomicInc(nRxError); INCL(ack, 1)
END;
IF 0 IN status THEN
Machine.AtomicInc(nRxOk);
ReadPacket;
INCL(ack, 0);
END;
SYSTEM.PUT16(base + 3EH, SYSTEM.VAL(LONGINT, ack));
dummy:=SYSTEM.GET16(base + 3EH);
END HandleInterrupt;
PROCEDURE Finalize;
BEGIN
SYSTEM.PUT16(base + 3CH, 0);
timer.Sleep(1000);
IF DebugCleanup THEN KernelLog.String("Remove IRQ Handler."); KernelLog.Ln END;
Objects.RemoveHandler(SELF.HandleInterrupt, Machine.IRQ0+irq);
IF RegisterInNetwork THEN Network.registry.Remove(dev) END
END Finalize;
PROCEDURE Linked(): BOOLEAN;
BEGIN
RETURN ~(2 IN SYSTEM.VAL(SET, SYSTEM.GET8(base + 58H)));
END Linked;
END Controller;
VAR
installedControllers: Controller;
PROCEDURE ScanPCI(vendor, device, model: LONGINT);
VAR index, bus, dev, fct, res, irq, i: LONGINT; base: SYSTEM.ADDRESS; d: LinkDevice; c: Controller; name: Plugins.Name;
BEGIN
index := 0;
WHILE (PCI.FindPCIDevice(device, vendor, index, bus, dev, fct) = PCI.Done) & (installed < 10) DO
res := PCI.ReadConfigDword(bus, dev, fct, PCI.Adr1Reg, i); ASSERT(res = PCI.Done);
base := i; ASSERT(~ODD(base));
DEC(base, base MOD 16);
Machine.MapPhysical(base, 0FFH, base);
res := PCI.ReadConfigByte(bus, dev, fct, PCI.IntlReg, irq); ASSERT(res = PCI.Done);
NEW(d, Network.TypeEthernet, MaxETHFrameSize - 14, 6);
name := Name;
i := 0; WHILE name[i] # 0X DO INC(i) END;
name[i] := CHR(ORD("0") + installed);
name[i+1] := 0X;
d.SetName(name);
d.desc := Desc;
IF DebugFind THEN KernelLog.String("Found model nr :"); KernelLog.Int(model, 4); KernelLog.Ln END;
NEW(c, d, base, irq, model);
INC(index)
END
END ScanPCI;
PROCEDURE Install*;
BEGIN {EXCLUSIVE}
IF installed = 0 THEN
IF DebugFind THEN KernelLog.String("Searching devices..."); KernelLog.Ln END;
ScanPCI(10ECH, 8139H, Model8139);
ScanPCI(10ECH, 8138H, Model8139CB);
ScanPCI(1113H, 1211H, ModelSMC1211TX);
ScanPCI(1500H, 1360H, ModelDELTA8139);
ScanPCI(4033H, 1360H, ModelADDTRON8139);
ScanPCI(1186H, 1300H, ModelDFE528TX);
ScanPCI(10ECH, 8129H, Model8129);
IF DebugFind THEN KernelLog.String("Find finished."); KernelLog.Ln END;
END;
END Install;
PROCEDURE StartLog*;
VAR f: Files.File;
BEGIN
Kernel.SetTimer(logtime, 0);
f := Files.New("EtherNet.Log"); f.Set(log, 0); Files.Register(f);
Files.WriteLInt(log, SHORT(0A1B2C3D4H)); Files.WriteInt(log, 2);
Files.WriteInt(log, 4); Files.WriteLInt(log, 0); Files.WriteLInt(log, 0);
Files.WriteLInt(log, 1514); Files.WriteLInt(log, 1);
logging := TRUE;
KernelLog.Enter; KernelLog.String("EtherNet log started --> dumping to EtherNet.Log."); KernelLog.Exit
END StartLog;
PROCEDURE StopLog*;
BEGIN
logging:=FALSE;
KernelLog.Enter; KernelLog.String("EtherNet log stopped."); KernelLog.Exit
END StopLog;
PROCEDURE Cleanup;
BEGIN
WHILE installedControllers # NIL DO installedControllers.Finalize; installedControllers:=installedControllers.next END
END Cleanup;
BEGIN
Modules.InstallTermHandler(Cleanup);
chipsetInfo[Chipset8139].name := "RTL-8139"; chipsetInfo[Chipset8139].version := 40H;
chipsetInfo[Chipset8139].flags := {HasPwrDn}; chipsetInfo[Chipset8139].configSet:={28..31, 17..23, 6};
chipsetInfo[Chipset8139B].name := "RTL-8139B"; chipsetInfo[Chipset8139B].version := 78H;
chipsetInfo[Chipset8139B].flags := {HasLWake}; chipsetInfo[Chipset8139B].configSet:={28..31, 17..22, 6};
chipsetInfo[Chipset8139A].name := "RTL-8139A"; chipsetInfo[Chipset8139A].version := 70H;
chipsetInfo[Chipset8139A].flags := {}; chipsetInfo[Chipset8139A].configSet:={28..31, 17..26, 6};
chipsetInfo[Chipset8139C].name := "RTL-8139C"; chipsetInfo[Chipset8139C].version := 74H;
chipsetInfo[Chipset8139C].flags := {HasLWake}; chipsetInfo[Chipset8139C].configSet:={28..31, 17..22, 6};
END RTL8139.
SystemTools.Free RTL8139 ~
RTL8139.Install
System.OpenKernelLog
TestNet.Mod
TestNet.SetDevice "RTL8139#0"