mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-12-23 06:29:38 +00:00
bigmac: support more registers.
This commit is contained in:
parent
9db3076a48
commit
5f48a3ab5b
@ -30,6 +30,13 @@ BigMac::BigMac(uint8_t id) {
|
|||||||
supports_types(HWCompType::MMIO_DEV | HWCompType::ETHER_MAC);
|
supports_types(HWCompType::MMIO_DEV | HWCompType::ETHER_MAC);
|
||||||
|
|
||||||
this->chip_id = id;
|
this->chip_id = id;
|
||||||
|
this->chip_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BigMac::chip_reset() {
|
||||||
|
this->event_mask = 0xFFFFU; // disable HW events causing on-chip interrupts
|
||||||
|
this->stat = 0;
|
||||||
|
|
||||||
this->phy_reset();
|
this->phy_reset();
|
||||||
this->mii_reset();
|
this->mii_reset();
|
||||||
this->srom_reset();
|
this->srom_reset();
|
||||||
@ -37,12 +44,38 @@ BigMac::BigMac(uint8_t id) {
|
|||||||
|
|
||||||
uint16_t BigMac::read(uint16_t reg_offset) {
|
uint16_t BigMac::read(uint16_t reg_offset) {
|
||||||
switch (reg_offset) {
|
switch (reg_offset) {
|
||||||
|
case BigMacReg::XIFC:
|
||||||
|
return this->tx_if_ctrl;
|
||||||
case BigMacReg::CHIP_ID:
|
case BigMacReg::CHIP_ID:
|
||||||
return this->chip_id;
|
return this->chip_id;
|
||||||
case BigMacReg::MIF_CSR:
|
case BigMacReg::MIF_CSR:
|
||||||
return (this->mif_csr_old & ~Mif_Data_In) | (this->mii_in_bit << 3);
|
return (this->mif_csr_old & ~Mif_Data_In) | (this->mii_in_bit << 3);
|
||||||
|
case BigMacReg::GLOB_STAT: {
|
||||||
|
uint16_t old_stat = this->stat;
|
||||||
|
this->stat = 0; // clear-on-read
|
||||||
|
return old_stat;
|
||||||
|
}
|
||||||
|
case BigMacReg::EVENT_MASK:
|
||||||
|
return this->event_mask;
|
||||||
case BigMacReg::SROM_CSR:
|
case BigMacReg::SROM_CSR:
|
||||||
return (this->srom_csr_old & ~Srom_Data_In) | (this->srom_in_bit << 2);
|
return (this->srom_csr_old & ~Srom_Data_In) | (this->srom_in_bit << 2);
|
||||||
|
case BigMacReg::TX_SW_RST:
|
||||||
|
return this->tx_reset;
|
||||||
|
case BigMacReg::TX_CONFIG:
|
||||||
|
return this->tx_config;
|
||||||
|
case BigMacReg::PEAK_ATT: {
|
||||||
|
uint8_t old_val = this->peak_attempts;
|
||||||
|
this->peak_attempts = 0; // clear-on-read
|
||||||
|
return old_val;
|
||||||
|
}
|
||||||
|
case BigMacReg::NC_CNT:
|
||||||
|
return this->norm_coll_cnt;
|
||||||
|
case BigMacReg::EX_CNT:
|
||||||
|
return this->excs_coll_cnt;
|
||||||
|
case BigMacReg::LT_CNT:
|
||||||
|
return this->late_coll_cnt;
|
||||||
|
case BigMacReg::RX_CONFIG:
|
||||||
|
return this->rx_config;
|
||||||
default:
|
default:
|
||||||
LOG_F(WARNING, "%s: unimplemented register at 0x%X", this->name.c_str(),
|
LOG_F(WARNING, "%s: unimplemented register at 0x%X", this->name.c_str(),
|
||||||
reg_offset);
|
reg_offset);
|
||||||
@ -53,6 +86,20 @@ uint16_t BigMac::read(uint16_t reg_offset) {
|
|||||||
|
|
||||||
void BigMac::write(uint16_t reg_offset, uint16_t value) {
|
void BigMac::write(uint16_t reg_offset, uint16_t value) {
|
||||||
switch (reg_offset) {
|
switch (reg_offset) {
|
||||||
|
case BigMacReg::XIFC:
|
||||||
|
this->tx_if_ctrl = value;
|
||||||
|
break;
|
||||||
|
case BigMacReg::TX_FIFO_CSR:
|
||||||
|
this->tx_fifo_enable = !!(value & 1);
|
||||||
|
this->tx_fifo_size = (((value >> 1) & 0xFF) + 1) << 7;
|
||||||
|
break;
|
||||||
|
case BigMacReg::TX_FIFO_TH:
|
||||||
|
this->tx_fifo_tresh = value;
|
||||||
|
break;
|
||||||
|
case BigMacReg::RX_FIFO_CSR:
|
||||||
|
this->rx_fifo_enable = !!(value & 1);
|
||||||
|
this->rx_fifo_size = (((value >> 1) & 0xFF) + 1) << 7;
|
||||||
|
break;
|
||||||
case BigMacReg::MIF_CSR:
|
case BigMacReg::MIF_CSR:
|
||||||
if (value & Mif_Data_Out_En) {
|
if (value & Mif_Data_Out_En) {
|
||||||
// send bits one by one on each low-to-high transition of Mif_Clock
|
// send bits one by one on each low-to-high transition of Mif_Clock
|
||||||
@ -64,6 +111,9 @@ void BigMac::write(uint16_t reg_offset, uint16_t value) {
|
|||||||
}
|
}
|
||||||
this->mif_csr_old = value;
|
this->mif_csr_old = value;
|
||||||
break;
|
break;
|
||||||
|
case BigMacReg::EVENT_MASK:
|
||||||
|
this->event_mask = value;
|
||||||
|
break;
|
||||||
case BigMacReg::SROM_CSR:
|
case BigMacReg::SROM_CSR:
|
||||||
if (value & Srom_Chip_Select) {
|
if (value & Srom_Chip_Select) {
|
||||||
// exchange data on each low-to-high transition of Srom_Clock
|
// exchange data on each low-to-high transition of Srom_Clock
|
||||||
@ -80,11 +130,58 @@ void BigMac::write(uint16_t reg_offset, uint16_t value) {
|
|||||||
this->tx_reset = 0; // acknowledge SW reset
|
this->tx_reset = 0; // acknowledge SW reset
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case BigMacReg::TX_CONFIG:
|
||||||
|
this->tx_config = value;
|
||||||
|
break;
|
||||||
|
case BigMacReg::NC_CNT:
|
||||||
|
this->norm_coll_cnt = value;
|
||||||
|
break;
|
||||||
|
case BigMacReg::NT_CNT:
|
||||||
|
this->net_coll_cnt = value;
|
||||||
|
break;
|
||||||
|
case BigMacReg::EX_CNT:
|
||||||
|
this->excs_coll_cnt = value;
|
||||||
|
break;
|
||||||
|
case BigMacReg::LT_CNT:
|
||||||
|
this->late_coll_cnt = value;
|
||||||
|
break;
|
||||||
|
case BigMacReg::RNG_SEED:
|
||||||
|
this->rng_seed = value;
|
||||||
|
break;
|
||||||
case BigMacReg::RX_SW_RST:
|
case BigMacReg::RX_SW_RST:
|
||||||
if (!value) {
|
if (!value) {
|
||||||
LOG_F(INFO, "%s: receiver soft reset asserted", this->name.c_str());
|
LOG_F(INFO, "%s: receiver soft reset asserted", this->name.c_str());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case BigMacReg::RX_CONFIG:
|
||||||
|
this->rx_config = value;
|
||||||
|
break;
|
||||||
|
case BigMacReg::MAC_ADDR_0:
|
||||||
|
case BigMacReg::MAC_ADDR_1:
|
||||||
|
case BigMacReg::MAC_ADDR_2:
|
||||||
|
this->mac_addr_flt[8 - ((reg_offset >> 4) & 0xF)] = value;
|
||||||
|
break;
|
||||||
|
case BigMacReg::RX_FRM_CNT:
|
||||||
|
this->rcv_frame_cnt = value;
|
||||||
|
break;
|
||||||
|
case BigMacReg::RX_LE_CNT:
|
||||||
|
this->len_err_cnt = value;
|
||||||
|
break;
|
||||||
|
case BigMacReg::RX_AE_CNT:
|
||||||
|
this->align_err_cnt = value;
|
||||||
|
break;
|
||||||
|
case BigMacReg::RX_FE_CNT:
|
||||||
|
this->fcs_err_cnt = value;
|
||||||
|
break;
|
||||||
|
case BigMacReg::RX_CVE_CNT:
|
||||||
|
this->cv_err_cnt = value;
|
||||||
|
break;
|
||||||
|
case BigMacReg::HASH_TAB_0:
|
||||||
|
case BigMacReg::HASH_TAB_1:
|
||||||
|
case BigMacReg::HASH_TAB_2:
|
||||||
|
case BigMacReg::HASH_TAB_3:
|
||||||
|
this->hash_table[(reg_offset >> 4) & 3] = value;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_F(WARNING, "%s: unimplemented register at 0x%X is written with 0x%X",
|
LOG_F(WARNING, "%s: unimplemented register at 0x%X is written with 0x%X",
|
||||||
this->name.c_str(), reg_offset, value);
|
this->name.c_str(), reg_offset, value);
|
||||||
|
@ -37,11 +37,37 @@ enum EthernetCellId : uint8_t {
|
|||||||
|
|
||||||
/* BigMac HW registers. */
|
/* BigMac HW registers. */
|
||||||
enum BigMacReg : uint16_t {
|
enum BigMacReg : uint16_t {
|
||||||
|
XIFC = 0x000, // transceiver interface control
|
||||||
|
TX_FIFO_CSR = 0x100,
|
||||||
|
TX_FIFO_TH = 0x110,
|
||||||
|
RX_FIFO_CSR = 0x120,
|
||||||
CHIP_ID = 0x170,
|
CHIP_ID = 0x170,
|
||||||
MIF_CSR = 0x180,
|
MIF_CSR = 0x180,
|
||||||
|
GLOB_STAT = 0x200, // Apple: kSTAT, Sun: Global Status Register
|
||||||
|
EVENT_MASK = 0x210, // ambiguously called INT_DISABLE in the Apple source
|
||||||
SROM_CSR = 0x190,
|
SROM_CSR = 0x190,
|
||||||
TX_SW_RST = 0x420,
|
TX_SW_RST = 0x420,
|
||||||
|
TX_CONFIG = 0x430,
|
||||||
|
PEAK_ATT = 0x4E0, // Apple: kPAREG, Sun: PeakAttempts Register
|
||||||
|
NC_CNT = 0x500, // Normal Collision Counter
|
||||||
|
NT_CNT = 0x510, // Apple: Network Collision Counter
|
||||||
|
EX_CNT = 0x520, // Excessive Collision Counter
|
||||||
|
LT_CNT = 0x530, // Late Collision Counter
|
||||||
|
RNG_SEED = 0x540,
|
||||||
RX_SW_RST = 0x620,
|
RX_SW_RST = 0x620,
|
||||||
|
RX_CONFIG = 0x630,
|
||||||
|
MAC_ADDR_2 = 0x660,
|
||||||
|
MAC_ADDR_1 = 0x670,
|
||||||
|
MAC_ADDR_0 = 0x680,
|
||||||
|
RX_FRM_CNT = 0x690, // Receive Frame Counter
|
||||||
|
RX_LE_CNT = 0x6A0, // Length Error Counter
|
||||||
|
RX_AE_CNT = 0x6B0, // Alignment Error Counter
|
||||||
|
RX_FE_CNT = 0x6C0, // FCS Error Counter
|
||||||
|
RX_CVE_CNT = 0x6E0, // Code Violation Error Counter
|
||||||
|
HASH_TAB_3 = 0x700,
|
||||||
|
HASH_TAB_2 = 0x710,
|
||||||
|
HASH_TAB_1 = 0x720,
|
||||||
|
HASH_TAB_0 = 0x730,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* MIF_CSR bit definitions. */
|
/* MIF_CSR bit definitions. */
|
||||||
@ -107,6 +133,9 @@ public:
|
|||||||
uint16_t read(uint16_t reg_offset);
|
uint16_t read(uint16_t reg_offset);
|
||||||
void write(uint16_t reg_offset, uint16_t value);
|
void write(uint16_t reg_offset, uint16_t value);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void chip_reset();
|
||||||
|
|
||||||
// MII methods
|
// MII methods
|
||||||
bool mii_rcv_value(uint16_t& var, uint8_t num_bits, uint8_t next_bit);
|
bool mii_rcv_value(uint16_t& var, uint8_t num_bits, uint8_t next_bit);
|
||||||
void mii_rcv_bit();
|
void mii_rcv_bit();
|
||||||
@ -127,7 +156,32 @@ private:
|
|||||||
uint8_t chip_id; // BigMac Chip ID
|
uint8_t chip_id; // BigMac Chip ID
|
||||||
|
|
||||||
// BigMac state
|
// BigMac state
|
||||||
uint16_t tx_reset = 0;
|
uint16_t tx_reset = 0; // self-clearing one-bit register
|
||||||
|
uint16_t tx_if_ctrl = 0;
|
||||||
|
uint16_t rng_seed;
|
||||||
|
uint16_t norm_coll_cnt = 0;
|
||||||
|
uint16_t net_coll_cnt = 0;
|
||||||
|
uint16_t excs_coll_cnt = 0;
|
||||||
|
uint16_t late_coll_cnt = 0;
|
||||||
|
uint16_t rcv_frame_cnt = 0;
|
||||||
|
uint8_t len_err_cnt = 0;
|
||||||
|
uint8_t align_err_cnt = 0;
|
||||||
|
uint8_t fcs_err_cnt = 0;
|
||||||
|
uint8_t cv_err_cnt = 0;
|
||||||
|
uint8_t peak_attempts = 0;
|
||||||
|
uint8_t tx_fifo_tresh = 0;
|
||||||
|
bool tx_fifo_enable = false;
|
||||||
|
bool rx_fifo_enable = false;
|
||||||
|
uint16_t tx_fifo_size = 0;
|
||||||
|
uint16_t rx_fifo_size = 0;
|
||||||
|
uint16_t hash_table[4] = {};
|
||||||
|
uint16_t mac_addr_flt[3] = {};
|
||||||
|
uint16_t tx_config = 0;
|
||||||
|
uint16_t rx_config = 0;
|
||||||
|
|
||||||
|
// Interrupt state
|
||||||
|
uint16_t event_mask = 0xFFFFU; // inverted mask: 0 - enabled, 1 - disabled
|
||||||
|
uint16_t stat = 0;
|
||||||
|
|
||||||
// MII state
|
// MII state
|
||||||
uint8_t mif_csr_old = 0;
|
uint8_t mif_csr_old = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user