📄 rtl8139.c
字号:
cpu_physical_memory_write(cplus_rx_ring_desc+4, (uint8_t *)&val, 4); /* seek to next Rx descriptor */ if (rxdw0 & CP_RX_EOR) { s->currCPlusRxDesc = 0; } else { ++s->currCPlusRxDesc; }#if defined(DEBUG_RTL8139) printf("RTL8139: done C+ Rx mode ----------------\n");#endif } else {#if defined(DEBUG_RTL8139) printf("RTL8139: in ring Rx mode ================\n");#endif /* begin ring receiver mode */ int avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr, s->RxBufferSize); /* if receiver buffer is empty then avail == 0 */ if (avail != 0 && size + 8 >= avail) {#if defined(DEBUG_RTL8139) printf("rx overflow: rx buffer length %d head 0x%04x read 0x%04x === available 0x%04x need 0x%04x\n", s->RxBufferSize, s->RxBufAddr, s->RxBufPtr, avail, size + 8);#endif s->IntrStatus |= RxOverflow; ++s->RxMissed; rtl8139_update_irq(s); return; } packet_header |= RxStatusOK; packet_header |= (((size+4) << 16) & 0xffff0000); /* write header */ uint32_t val = cpu_to_le32(packet_header); rtl8139_write_buffer(s, (uint8_t *)&val, 4); rtl8139_write_buffer(s, buf, size); /* write checksum */#if defined (RTL8139_CALCULATE_RXCRC) val = cpu_to_le32(crc32(~0, buf, size));#else val = 0;#endif rtl8139_write_buffer(s, (uint8_t *)&val, 4); /* correct buffer write pointer */ s->RxBufAddr = MOD2((s->RxBufAddr + 3) & ~0x3, s->RxBufferSize); /* now we can signal we have received something */#if defined(DEBUG_RTL8139) printf(" received: rx buffer length %d head 0x%04x read 0x%04x\n", s->RxBufferSize, s->RxBufAddr, s->RxBufPtr);#endif } s->IntrStatus |= RxOK; rtl8139_update_irq(s);}static void rtl8139_reset_rxring(RTL8139State *s, uint32_t bufferSize){ s->RxBufferSize = bufferSize; s->RxBufPtr = 0; s->RxBufAddr = 0;}static void rtl8139_reset(RTL8139State *s){ int i; /* restore MAC address */ memcpy(s->phys, s->macaddr, 6); /* reset interrupt mask */ s->IntrStatus = 0; s->IntrMask = 0; rtl8139_update_irq(s); /* prepare eeprom */ s->eeprom.contents[0] = 0x8129; memcpy(&s->eeprom.contents[7], s->macaddr, 6); /* mark all status registers as owned by host */ for (i = 0; i < 4; ++i) { s->TxStatus[i] = TxHostOwns; } s->currTxDesc = 0; s->currCPlusRxDesc = 0; s->currCPlusTxDesc = 0; s->RxRingAddrLO = 0; s->RxRingAddrHI = 0; s->RxBuf = 0; rtl8139_reset_rxring(s, 8192); /* ACK the reset */ s->TxConfig = 0;#if 0// s->TxConfig |= HW_REVID(1, 0, 0, 0, 0, 0, 0); // RTL-8139 HasHltClk s->clock_enabled = 0;#else s->TxConfig |= HW_REVID(1, 1, 1, 0, 1, 0, 0); // RTL-8139C HasLWake s->clock_enabled = 1;#endif s->bChipCmdState = CmdReset; /* RxBufEmpty bit is calculated on read from ChipCmd */; /* set initial state data */ s->Config0 = 0x0; /* No boot ROM */ s->Config1 = 0xC; /* IO mapped and MEM mapped registers available */ s->Config3 = 0x1; /* fast back-to-back compatible */ s->Config5 = 0x0; s->CSCR = CSCR_F_LINK_100 | CSCR_HEART_BIT | CSCR_LD; s->CpCmd = 0x0; /* reset C+ mode */// s->BasicModeCtrl = 0x3100; // 100Mbps, full duplex, autonegotiation// s->BasicModeCtrl = 0x2100; // 100Mbps, full duplex s->BasicModeCtrl = 0x1000; // autonegotiation s->BasicModeStatus = 0x7809; //s->BasicModeStatus |= 0x0040; /* UTP medium */ s->BasicModeStatus |= 0x0020; /* autonegotiation completed */ s->BasicModeStatus |= 0x0004; /* link is up */ s->NWayAdvert = 0x05e1; /* all modes, full duplex */ s->NWayLPAR = 0x05e1; /* all modes, full duplex */ s->NWayExpansion = 0x0001; /* autonegotiation supported */}static void rtl8139_ChipCmd_write(RTL8139State *s, uint32_t val){ val &= 0xff;#ifdef DEBUG_RTL8139 printf("RTL8139: ChipCmd write val=0x%08x\n", val);#endif if (val & CmdReset) {#ifdef DEBUG_RTL8139 printf("RTL8139: ChipCmd reset\n");#endif rtl8139_reset(s); } if (val & CmdRxEnb) {#ifdef DEBUG_RTL8139 printf("RTL8139: ChipCmd enable receiver\n");#endif } if (val & CmdTxEnb) {#ifdef DEBUG_RTL8139 printf("RTL8139: ChipCmd enable transmitter\n");#endif } /* mask unwriteable bits */ val = SET_MASKED(val, 0xe3, s->bChipCmdState); /* Deassert reset pin before next read */ val &= ~CmdReset; s->bChipCmdState = val;}static int rtl8139_RxBufferEmpty(RTL8139State *s){ int unread = MOD2(s->RxBufferSize + s->RxBufAddr - s->RxBufPtr, s->RxBufferSize); if (unread != 0) {#ifdef DEBUG_RTL8139 printf("RTL8139: receiver buffer data available 0x%04x\n", unread);#endif return 0; }#ifdef DEBUG_RTL8139 printf("RTL8139: receiver buffer is empty\n");#endif return 1;}static uint32_t rtl8139_ChipCmd_read(RTL8139State *s){ uint32_t ret = s->bChipCmdState; if (rtl8139_RxBufferEmpty(s)) ret |= RxBufEmpty;#ifdef DEBUG_RTL8139 printf("RTL8139: ChipCmd read val=0x%04x\n", ret);#endif return ret;}static void rtl8139_CpCmd_write(RTL8139State *s, uint32_t val){ val &= 0xffff;#ifdef DEBUG_RTL8139 printf("RTL8139C+ command register write(w) val=0x%04x\n", val);#endif /* mask unwriteable bits */ val = SET_MASKED(val, 0xff84, s->CpCmd); s->CpCmd = val;}static uint32_t rtl8139_CpCmd_read(RTL8139State *s){ uint32_t ret = s->CpCmd;#ifdef DEBUG_RTL8139 printf("RTL8139C+ command register read(w) val=0x%04x\n", ret);#endif return ret;}int rtl8139_config_writeable(RTL8139State *s){ if (s->Cfg9346 & Cfg9346_Unlock) { return 1; }#ifdef DEBUG_RTL8139 printf("RTL8139: Configuration registers are write-protected\n");#endif return 0;}static void rtl8139_BasicModeCtrl_write(RTL8139State *s, uint32_t val){ val &= 0xffff;#ifdef DEBUG_RTL8139 printf("RTL8139: BasicModeCtrl register write(w) val=0x%04x\n", val);#endif /* mask unwriteable bits */ uint32 mask = 0x4cff; if (1 || !rtl8139_config_writeable(s)) { /* Speed setting and autonegotiation enable bits are read-only */ mask |= 0x3000; /* Duplex mode setting is read-only */ mask |= 0x0100; } val = SET_MASKED(val, mask, s->BasicModeCtrl); s->BasicModeCtrl = val;}static uint32_t rtl8139_BasicModeCtrl_read(RTL8139State *s){ uint32_t ret = s->BasicModeCtrl;#ifdef DEBUG_RTL8139 printf("RTL8139: BasicModeCtrl register read(w) val=0x%04x\n", ret);#endif return ret;}static void rtl8139_BasicModeStatus_write(RTL8139State *s, uint32_t val){ val &= 0xffff;#ifdef DEBUG_RTL8139 printf("RTL8139: BasicModeStatus register write(w) val=0x%04x\n", val);#endif /* mask unwriteable bits */ val = SET_MASKED(val, 0xff3f, s->BasicModeStatus); s->BasicModeStatus = val;}static uint32_t rtl8139_BasicModeStatus_read(RTL8139State *s){ uint32_t ret = s->BasicModeStatus;#ifdef DEBUG_RTL8139 printf("RTL8139: BasicModeStatus register read(w) val=0x%04x\n", ret);#endif return ret;}static void rtl8139_Cfg9346_write(RTL8139State *s, uint32_t val){ val &= 0xff;#ifdef DEBUG_RTL8139 printf("RTL8139: Cfg9346 write val=0x%02x\n", val);#endif /* mask unwriteable bits */ val = SET_MASKED(val, 0x31, s->Cfg9346); uint32_t opmode = val & 0xc0; uint32_t eeprom_val = val & 0xf; if (opmode == 0x80) { /* eeprom access */ int eecs = (eeprom_val & 0x08)?1:0; int eesk = (eeprom_val & 0x04)?1:0; int eedi = (eeprom_val & 0x02)?1:0; prom9346_set_wire(s, eecs, eesk, eedi); } else if (opmode == 0x40) { /* Reset. */ val = 0; rtl8139_reset(s); } s->Cfg9346 = val;}static uint32_t rtl8139_Cfg9346_read(RTL8139State *s){ uint32_t ret = s->Cfg9346; uint32_t opmode = ret & 0xc0; if (opmode == 0x80) { /* eeprom access */ int eedo = prom9346_get_wire(s); if (eedo) { ret |= 0x01; } else { ret &= ~0x01; } }#ifdef DEBUG_RTL8139 printf("RTL8139: Cfg9346 read val=0x%02x\n", ret);#endif return ret;}static void rtl8139_Config0_write(RTL8139State *s, uint32_t val){ val &= 0xff;#ifdef DEBUG_RTL8139 printf("RTL8139: Config0 write val=0x%02x\n", val);#endif if (!rtl8139_config_writeable(s)) return; /* mask unwriteable bits */ val = SET_MASKED(val, 0xf8, s->Config0); s->Config0 = val;}static uint32_t rtl8139_Config0_read(RTL8139State *s){ uint32_t ret = s->Config0;#ifdef DEBUG_RTL8139 printf("RTL8139: Config0 read val=0x%02x\n", ret);#endif return ret;}static void rtl8139_Config1_write(RTL8139State *s, uint32_t val){ val &= 0xff;#ifdef DEBUG_RTL8139 printf("RTL8139: Config1 write val=0x%02x\n", val);#endif if (!rtl8139_config_writeable(s)) return; /* mask unwriteable bits */ val = SET_MASKED(val, 0xC, s->Config1); s->Config1 = val;}static uint32_t rtl8139_Config1_read(RTL8139State *s){ uint32_t ret = s->Config1;#ifdef DEBUG_RTL8139 printf("RTL8139: Config1 read val=0x%02x\n", ret);#endif return ret;}static void rtl8139_Config3_write(RTL8139State *s, uint32_t val){ val &= 0xff;#ifdef DEBUG_RTL8139 printf("RTL8139: Config3 write val=0x%02x\n", val);#endif if (!rtl8139_config_writeable(s)) return; /* mask unwriteable bits */ val = SET_MASKED(val, 0x8F, s->Config3); s->Config3 = val;}static uint32_t rtl8139_Config3_read(RTL8139State *s){ uint32_t ret = s->Config3;#ifdef DEBUG_RTL8139 printf("RTL8139: Config3 read val=0x%02x\n", ret);#endif return ret;}static void rtl8139_Config4_write(RTL8139State *s, uint32_t val){ val &= 0xff;#ifdef DEBUG_RTL8139 printf("RTL8139: Config4 write val=0x%02x\n", val);#endif if (!rtl8139_config_writeable(s)) return; /* mask unwriteable bits */ val = SET_MASKED(val, 0x0a, s->Config4); s->Config4 = val;}static uint32_t rtl8139_Config4_read(RTL8139State *s){ uint32_t ret = s->Config4;#ifdef DEBUG_RTL8139 printf("RTL8139: Config4 read val=0x%02x\n", ret);#endif return ret;}static void rtl8139_Config5_write(RTL8139State *s, uint32_t val){ val &= 0xff;#ifdef DEBUG_RTL8139 printf("RTL8139: Config5 write val=0x%02x\n", val);#endif /* mask unwriteable bits */ val = SET_MASKED(val, 0x80, s->Config5); s->Config5 = val;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -