⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtl8139.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            {                prom9346_decode_command(eeprom, eeprom->input & 0xff);            }            break;        case Chip9346_data_read:            eeprom->eedo = (eeprom->output & 0x8000)?1:0;            eeprom->output <<= 1;            if (eeprom->tick == 16)            {                ++eeprom->address;                eeprom->address &= EEPROM_9346_ADDR_MASK;                eeprom->output = eeprom->contents[eeprom->address];                eeprom->tick = 0;#if defined(DEBUG_RTL8139)                printf("eeprom: +++ read next address 0x%02x data=0x%04x\n",                       eeprom->address, eeprom->output);#endif            }            break;        case Chip9346_data_write:            eeprom->input = (eeprom->input << 1) | (bit & 1);            if (eeprom->tick == 16)            {#if defined(DEBUG_RTL8139)            printf("RTL8139: eeprom write to address 0x%02x data=0x%04x\n",                   eeprom->address, eeprom->input);#endif                eeprom->contents[eeprom->address] = eeprom->input;                eeprom->mode = Chip9346_none; /* waiting for next command after CS cycle */                eeprom->tick = 0;                eeprom->input = 0;            }            break;        case Chip9346_data_write_all:            eeprom->input = (eeprom->input << 1) | (bit & 1);            if (eeprom->tick == 16)            {                int i;                for (i = 0; i < EEPROM_9346_SIZE; i++)                {                    eeprom->contents[i] = eeprom->input;                }#if defined(DEBUG_RTL8139)                printf("RTL8139: eeprom filled with data=0x%04x\n",                       eeprom->input);#endif                eeprom->mode = Chip9346_enter_command_mode;                eeprom->tick = 0;                eeprom->input = 0;            }            break;        default:            break;    }}int prom9346_get_wire(RTL8139State *s){    EEprom9346 *eeprom = &s->eeprom;    if (!eeprom->eecs)        return 0;    return eeprom->eedo;}void prom9346_set_wire(RTL8139State *s, int eecs, int eesk, int eedi){    EEprom9346 *eeprom = &s->eeprom;    uint8_t old_eecs = eeprom->eecs;    uint8_t old_eesk = eeprom->eesk;    eeprom->eecs = eecs;    eeprom->eesk = eesk;    eeprom->eedi = eedi;#if defined(DEBUG_RTL8139)    printf("eeprom: +++ wires CS=%d SK=%d DI=%d DO=%d\n", eeprom->eecs, eeprom->eesk, eeprom->eedi, eeprom->eedo);#endif    if (!old_eecs && eecs)    {        /* Synchronize start */        eeprom->tick = 0;        eeprom->input = 0;        eeprom->output = 0;        eeprom->mode = Chip9346_enter_command_mode;#if defined(DEBUG_RTL8139)        printf("=== eeprom: begin access, enter command mode\n");#endif    }    if (!eecs)    {#if defined(DEBUG_RTL8139)        printf("=== eeprom: end access\n");#endif        return;    }    if (!old_eesk && eesk)    {        /* SK front rules */        prom9346_shift_clock(eeprom);    }}static void rtl8139_update_irq(RTL8139State *s){    int isr;    isr = (s->IntrStatus & s->IntrMask) & 0xffff;#if defined(DEBUG_RTL8139)    printf("RTL8139: Set IRQ line %d to %d (%04x %04x)\n",       s->irq, isr ? 1 : 0, s->IntrStatus, s->IntrMask);#endif    if (s->irq == 16) {        /* PCI irq */        pci_set_irq(s->pci_dev, 0, (isr != 0));    } else {        /* ISA irq */        pic_set_irq(s->irq, (isr != 0));    }}#define POLYNOMIAL 0x04c11db6/* From FreeBSD *//* XXX: optimize */static int compute_mcast_idx(const uint8_t *ep){    uint32_t crc;    int carry, i, j;    uint8_t b;    crc = 0xffffffff;    for (i = 0; i < 6; i++) {        b = *ep++;        for (j = 0; j < 8; j++) {            carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);            crc <<= 1;            b >>= 1;            if (carry)                crc = ((crc ^ POLYNOMIAL) | carry);        }    }    return (crc >> 26);}static int rtl8139_RxWrap(RTL8139State *s){    /* wrapping enabled; assume 1.5k more buffer space if size < 65536 */    return (s->RxConfig & (1 << 7));}static int rtl8139_receiver_enabled(RTL8139State *s){    return s->bChipCmdState & CmdRxEnb;}static int rtl8139_transmitter_enabled(RTL8139State *s){    return s->bChipCmdState & CmdTxEnb;}static int rtl8139_cp_receiver_enabled(RTL8139State *s){    return s->CpCmd & CPlusRxEnb;}static int rtl8139_cp_transmitter_enabled(RTL8139State *s){    return s->CpCmd & CPlusTxEnb;}static void rtl8139_write_buffer(RTL8139State *s, const void *buf, int size){    if (s->RxBufAddr + size > s->RxBufferSize)    {        int wrapped = MOD2(s->RxBufAddr + size, s->RxBufferSize);        /* write packet data */        if (wrapped && s->RxBufferSize < 65536 && !rtl8139_RxWrap(s))        {    #if defined(DEBUG_RTL8139)            printf(">>> RTL8139: rx packet wrapped in buffer at %d\n", size-wrapped);    #endif            if (size > wrapped)            {                cpu_physical_memory_write( s->RxBuf + s->RxBufAddr,                                           buf, size-wrapped );            }            /* reset buffer pointer */            s->RxBufAddr = 0;            cpu_physical_memory_write( s->RxBuf + s->RxBufAddr,                                       buf + (size-wrapped), wrapped );            s->RxBufAddr = wrapped;            return;        }    }    /* non-wrapping path or overwrapping enabled */    cpu_physical_memory_write( s->RxBuf + s->RxBufAddr, buf, size );    s->RxBufAddr += size;}#define MIN_BUF_SIZE 60static inline target_phys_addr_t rtl8139_addr64(uint32_t low, uint32_t high){#if TARGET_PHYS_ADDR_BITS > 32    return low | ((target_phys_addr_t)high << 32);#else    return low;#endif}static int rtl8139_can_receive(void *opaque){    RTL8139State *s = opaque;    int avail;    /* Recieve (drop) packets if card is disabled.  */    if (!s->clock_enabled)      return 1;    if (!rtl8139_receiver_enabled(s))      return 1;    if (rtl8139_cp_receiver_enabled(s)) {        /* ??? Flow control not implemented in c+ mode.           This is a hack to work around slirp deficiencies anyway.  */        return 1;    } else {        avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr,                     s->RxBufferSize);        return (avail == 0 || avail >= 1514);    }}static void rtl8139_receive(void *opaque, const uint8_t *buf, int size){    RTL8139State *s = opaque;    uint32_t packet_header = 0;    uint8_t buf1[60];    static const uint8_t broadcast_macaddr[6] =         { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };#if defined(DEBUG_RTL8139)    printf(">>> RTL8139: received len=%d\n", size);#endif    /* test if board clock is stopped */    if (!s->clock_enabled)    {#if defined(DEBUG_RTL8139)        printf("RTL8139: stopped ==========================\n");#endif        return;    }    /* first check if receiver is enabled */    if (!rtl8139_receiver_enabled(s))    {#if defined(DEBUG_RTL8139)        printf("RTL8139: receiver disabled ================\n");#endif        return;    }    /* XXX: check this */    if (s->RxConfig & AcceptAllPhys) {        /* promiscuous: receive all */#if defined(DEBUG_RTL8139)        printf(">>> RTL8139: packet received in promiscuous mode\n");#endif    } else {        if (!memcmp(buf,  broadcast_macaddr, 6)) {            /* broadcast address */            if (!(s->RxConfig & AcceptBroadcast))            {#if defined(DEBUG_RTL8139)                printf(">>> RTL8139: broadcast packet rejected\n");#endif                return;            }            packet_header |= RxBroadcast;#if defined(DEBUG_RTL8139)            printf(">>> RTL8139: broadcast packet received\n");#endif        } else if (buf[0] & 0x01) {            /* multicast */            if (!(s->RxConfig & AcceptMulticast))            {#if defined(DEBUG_RTL8139)                printf(">>> RTL8139: multicast packet rejected\n");#endif                return;            }            int mcast_idx = compute_mcast_idx(buf);            if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))            {#if defined(DEBUG_RTL8139)                printf(">>> RTL8139: multicast address mismatch\n");#endif                return;            }            packet_header |= RxMulticast;#if defined(DEBUG_RTL8139)            printf(">>> RTL8139: multicast packet received\n");#endif        } else if (s->phys[0] == buf[0] &&                   s->phys[1] == buf[1] &&                                      s->phys[2] == buf[2] &&                               s->phys[3] == buf[3] &&                               s->phys[4] == buf[4] &&                               s->phys[5] == buf[5]) {            /* match */            if (!(s->RxConfig & AcceptMyPhys))            {#if defined(DEBUG_RTL8139)                printf(">>> RTL8139: rejecting physical address matching packet\n");#endif                return;            }            packet_header |= RxPhysical;#if defined(DEBUG_RTL8139)            printf(">>> RTL8139: physical address matching packet received\n");#endif        } else {#if defined(DEBUG_RTL8139)                printf(">>> RTL8139: unknown packet\n");#endif            return;        }    }    /* if too small buffer, then expand it */    if (size < MIN_BUF_SIZE) {        memcpy(buf1, buf, size);        memset(buf1 + size, 0, MIN_BUF_SIZE - size);        buf = buf1;        size = MIN_BUF_SIZE;    }    if (rtl8139_cp_receiver_enabled(s))    {#if defined(DEBUG_RTL8139)        printf("RTL8139: in C+ Rx mode ================\n");#endif        /* begin C+ receiver mode *//* w0 ownership flag */#define CP_RX_OWN (1<<31)/* w0 end of ring flag */#define CP_RX_EOR (1<<30)/* w0 bits 0...12 : buffer size */#define CP_RX_BUFFER_SIZE_MASK ((1<<13) - 1)/* w1 tag available flag */#define CP_RX_TAVA (1<<16)/* w1 bits 0...15 : VLAN tag */#define CP_RX_VLAN_TAG_MASK ((1<<16) - 1)/* w2 low  32bit of Rx buffer ptr *//* w3 high 32bit of Rx buffer ptr */        int descriptor = s->currCPlusRxDesc;        target_phys_addr_t cplus_rx_ring_desc;        cplus_rx_ring_desc = rtl8139_addr64(s->RxRingAddrLO, s->RxRingAddrHI);        cplus_rx_ring_desc += 16 * descriptor;#ifdef DEBUG_RTL8139        printf("RTL8139: +++ C+ mode reading RX descriptor %d from host memory at %08x %08x = 0x%8lx\n",               descriptor, s->RxRingAddrHI, s->RxRingAddrLO, cplus_rx_ring_desc);#endif        uint32_t val, rxdw0,rxdw1,rxbufLO,rxbufHI;        cpu_physical_memory_read(cplus_rx_ring_desc,    (uint8_t *)&val, 4);        rxdw0 = le32_to_cpu(val);        cpu_physical_memory_read(cplus_rx_ring_desc+4,  (uint8_t *)&val, 4);        rxdw1 = le32_to_cpu(val);        cpu_physical_memory_read(cplus_rx_ring_desc+8,  (uint8_t *)&val, 4);        rxbufLO = le32_to_cpu(val);        cpu_physical_memory_read(cplus_rx_ring_desc+12, (uint8_t *)&val, 4);        rxbufHI = le32_to_cpu(val);#ifdef DEBUG_RTL8139        printf("RTL8139: +++ C+ mode RX descriptor %d %08x %08x %08x %08x\n",               descriptor,               rxdw0, rxdw1, rxbufLO, rxbufHI);#endif        if (!(rxdw0 & CP_RX_OWN))        {#if defined(DEBUG_RTL8139)            printf("RTL8139: C+ Rx mode : descriptor %d is owned by host\n", descriptor);#endif            s->IntrStatus |= RxOverflow;            ++s->RxMissed;            rtl8139_update_irq(s);            return;        }        uint32_t rx_space = rxdw0 & CP_RX_BUFFER_SIZE_MASK;        if (size+4 > rx_space)        {#if defined(DEBUG_RTL8139)            printf("RTL8139: C+ Rx mode : descriptor %d size %d received %d + 4\n",                   descriptor, rx_space, size);#endif            s->IntrStatus |= RxOverflow;            ++s->RxMissed;            rtl8139_update_irq(s);            return;        }        target_phys_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI);        /* receive/copy to target memory */        cpu_physical_memory_write( rx_addr, buf, size );        /* write checksum */#if defined (RTL8139_CALCULATE_RXCRC)        val = cpu_to_le32(crc32(~0, buf, size));#else        val = 0;#endif        cpu_physical_memory_write( rx_addr+size, (uint8_t *)&val, 4);/* first segment of received packet flag */#define CP_RX_STATUS_FS (1<<29)/* last segment of received packet flag */#define CP_RX_STATUS_LS (1<<28)/* multicast packet flag */#define CP_RX_STATUS_MAR (1<<26)/* physical-matching packet flag */#define CP_RX_STATUS_PAM (1<<25)/* broadcast packet flag */#define CP_RX_STATUS_BAR (1<<24)/* runt packet flag */#define CP_RX_STATUS_RUNT (1<<19)/* crc error flag */#define CP_RX_STATUS_CRC (1<<18)/* IP checksum error flag */#define CP_RX_STATUS_IPF (1<<15)/* UDP checksum error flag */#define CP_RX_STATUS_UDPF (1<<14)/* TCP checksum error flag */#define CP_RX_STATUS_TCPF (1<<13)        /* transfer ownership to target */        rxdw0 &= ~CP_RX_OWN;        /* set first segment bit */        rxdw0 |= CP_RX_STATUS_FS;        /* set last segment bit */        rxdw0 |= CP_RX_STATUS_LS;        /* set received packet type flags */        if (packet_header & RxBroadcast)            rxdw0 |= CP_RX_STATUS_BAR;        if (packet_header & RxMulticast)            rxdw0 |= CP_RX_STATUS_MAR;        if (packet_header & RxPhysical)            rxdw0 |= CP_RX_STATUS_PAM;        /* set received size */        rxdw0 &= ~CP_RX_BUFFER_SIZE_MASK;        rxdw0 |= (size+4);        /* reset VLAN tag flag */        rxdw1 &= ~CP_RX_TAVA;        /* update ring data */        val = cpu_to_le32(rxdw0);        cpu_physical_memory_write(cplus_rx_ring_desc,    (uint8_t *)&val, 4);        val = cpu_to_le32(rxdw1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -