Fix PCNet driver for real hardware usage

Align memory buffers
Delay enabling interrupts until config is complete
Adds functions to Read/Write BCR registers
Configures link related BCR registers
This commit is contained in:
tinkeros 2022-12-20 12:35:22 -06:00
parent 777203d952
commit aa1066c5bb

View file

@ -23,8 +23,12 @@
#define PCNET_DW_RDP 0x10 #define PCNET_DW_RDP 0x10
#define PCNET_DW_RAP 0x14 #define PCNET_DW_RAP 0x14
#define PCNET_DW_BDP 0x1c
#define PCNET_DW_RESET 0x18 // reset reg location when card is in 32-bit mode #define PCNET_DW_RESET 0x18 // reset reg location when card is in 32-bit mode
#define PCNET_BCR_MISC_CONFIG 2
#define PCNET_BCR_FULL_DUPLEX_CTRL 9
#define PCNET_CSR_CTRLSTATUS 0 #define PCNET_CSR_CTRLSTATUS 0
#define PCNET_CSR_INTERRUPTS 3 #define PCNET_CSR_INTERRUPTS 3
#define PCNET_CSR_FEATURECTRL 4 #define PCNET_CSR_FEATURECTRL 4
@ -57,6 +61,11 @@
#define PCNET_FEATURE_APADXMT 11 #define PCNET_FEATURE_APADXMT 11
#define PCNET_BCR_MISC_CONFIG_ASEL 1
#define PCNET_BCR_FULL_DUPLEX_CTRL_FDEN 0
#define PCNET_BCR_FULL_DUPLEX_CTRL_AUIFD 1
#define PCNET_CTRL_INIT 0 #define PCNET_CTRL_INIT 0
#define PCNET_CTRL_STRT 1 #define PCNET_CTRL_STRT 1
#define PCNET_CTRL_STOP 2 #define PCNET_CTRL_STOP 2
@ -159,6 +168,28 @@ U0 PCNetRAPWrite(U32 value)
OutU32(PCNetIOBaseGet + PCNET_DW_RAP, value); OutU32(PCNetIOBaseGet + PCNET_DW_RAP, value);
} }
U0 PCNetBCRWrite(U32 bcr, U32 value)
{/* AMD PCNet datasheet p. 1-952
Summary: Bus Control Registers are
accessed via the BDP (Bus Data Port).
Which BCR is selected is based on the value
in the RAP. */
PCNetRAPWrite(bcr);
OutU32(PCNetIOBaseGet + PCNET_DW_BDP, value);
}
U32 PCNetBCRRead(U32 bcr)
{/* AMD PCNet datasheet p. 1-952
Summary: Bus Control Registers are
accessed via the BDP (Bus Data Port).
Which BCR is selected is based on the value
in the RAP. */
PCNetRAPWrite(bcr);
return InU32(PCNetIOBaseGet + PCNET_DW_BDP);
}
U0 PCNetCSRWrite(U32 csr, U32 value) U0 PCNetCSRWrite(U32 csr, U32 value)
{/* AMD PCNet datasheet p. 1-952 {/* AMD PCNet datasheet p. 1-952
Summary: Control and Status Registers are Summary: Control and Status Registers are
@ -181,6 +212,22 @@ U32 PCNetCSRRead(U32 csr)
return InU32(PCNetIOBaseGet + PCNET_DW_RDP); return InU32(PCNetIOBaseGet + PCNET_DW_RDP);
} }
U0 PCNetAutoLinkSelect()
{
U32 bcr = PCNetCSRRead(PCNET_BCR_FULL_DUPLEX_CTRL);
Bts(&bcr,PCNET_BCR_FULL_DUPLEX_CTRL_FDEN);
Bts(&bcr,PCNET_BCR_FULL_DUPLEX_CTRL_AUIFD);
PCNetBCRWrite(PCNET_BCR_FULL_DUPLEX_CTRL,bcr);
}
U0 PCNetEnableFullDuplex()
{
U32 bcr = PCNetCSRRead(PCNET_BCR_MISC_CONFIG);
Bts(&bcr,PCNET_BCR_MISC_CONFIG_ASEL);
PCNetBCRWrite(PCNET_BCR_MISC_CONFIG,bcr);
}
U0 PCNetSWStyleSet() U0 PCNetSWStyleSet()
{/* AMD PCNet datasheet p. 1-968 {/* AMD PCNet datasheet p. 1-968
In CSR58 (Software Style), the 8-bit In CSR58 (Software Style), the 8-bit
@ -260,9 +307,9 @@ U0 PCNetBuffersAllocate()
pcnet.rx_de_buffer = dev.uncached_alias + pcnet.rx_de_buffer_phys; // we want uncached pcnet.rx_de_buffer = dev.uncached_alias + pcnet.rx_de_buffer_phys; // we want uncached
pcnet.tx_de_buffer = dev.uncached_alias + pcnet.tx_de_buffer_phys; // access to these. pcnet.tx_de_buffer = dev.uncached_alias + pcnet.tx_de_buffer_phys; // access to these.
pcnet.rx_buffer_addr_phys = CAlloc(ETHERNET_FRAME_SIZE * PCNET_RX_BUFF_COUNT, Fs->code_heap); pcnet.rx_buffer_addr_phys = CAllocAligned(ETHERNET_FRAME_SIZE * PCNET_RX_BUFF_COUNT, 16, Fs->code_heap);
pcnet.tx_buffer_addr_phys = CAlloc(ETHERNET_FRAME_SIZE * PCNET_TX_BUFF_COUNT, Fs->code_heap); pcnet.tx_buffer_addr_phys = CAllocAligned(ETHERNET_FRAME_SIZE * PCNET_TX_BUFF_COUNT, 16, Fs->code_heap);
//Shrine does a check and returns -1 here, if the end of either buffer exceeds 0x100000000 //Shrine does a check and returns -1 here, if the end of either buffer exceeds 0x100000000
@ -361,7 +408,7 @@ U0 PCNetDirectInit()
U8 *PCNetInitBlockSetup() U8 *PCNetInitBlockSetup()
{ {
U8 *setup = CAlloc(sizeof(CPCNetBufferSetup), Fs->code_heap); U8 *setup = CAllocAligned(sizeof(CPCNetBufferSetup), 16, Fs->code_heap);
CPCNetBufferSetup *u_setup = setup + dev.uncached_alias; CPCNetBufferSetup *u_setup = setup + dev.uncached_alias;
U32 p_setup; U32 p_setup;
@ -426,6 +473,7 @@ U0 PCNetConfigModeExit()
Btr(&csr, PCNET_CTRL_INIT); Btr(&csr, PCNET_CTRL_INIT);
Btr(&csr, PCNET_CTRL_STOP); Btr(&csr, PCNET_CTRL_STOP);
Bts(&csr, PCNET_CTRL_IENA);
Bts(&csr, PCNET_CTRL_STRT); Bts(&csr, PCNET_CTRL_STRT);
PCNetCSRWrite(PCNET_CSR_CTRLSTATUS, csr); PCNetCSRWrite(PCNET_CSR_CTRLSTATUS, csr);
@ -433,10 +481,9 @@ U0 PCNetConfigModeExit()
U0 PCNetUploadConfig() U0 PCNetUploadConfig()
{/* Upload new config and wait for card to acknowlege */ {/* Upload new config and wait for card to acknowlege */
U32 csr = PCNetCSRRead(PCNET_CSR_CTRLSTATUS); U32 csr = 0;
Bts(&csr, PCNET_CTRL_INIT); Bts(&csr, PCNET_CTRL_INIT);
Bts(&csr, PCNET_CTRL_IENA);
PCNetCSRWrite(PCNET_CSR_CTRLSTATUS, csr); PCNetCSRWrite(PCNET_CSR_CTRLSTATUS, csr);
@ -449,7 +496,6 @@ U0 PCNetUploadConfig()
} }
} }
I64 PCNetDriverOwns(CPCNetDescriptorEntry* entry) I64 PCNetDriverOwns(CPCNetDescriptorEntry* entry)
{/* Returns whether the value of the OWN bit of the {/* Returns whether the value of the OWN bit of the
Descriptor Entry is zero. If 0, driver owns, Descriptor Entry is zero. If 0, driver owns,
@ -681,6 +727,10 @@ U0 PCNetInit()
PCNetTXAutoPadEnable; PCNetTXAutoPadEnable;
PCNetAutoLinkSelect;
PCNetEnableFullDuplex;
PCNetUploadConfig; PCNetUploadConfig;
csr = PCNetCSRRead(PCNET_CSR_CTRLSTATUS); csr = PCNetCSRRead(PCNET_CSR_CTRLSTATUS);