📄 dev_i8254x.c
字号:
{ switch(d->mii_state) { case 0: /* reset */ d->mii_phy = 0; d->mii_reg = 0; d->mii_data_pos = 15; d->mii_data = 0; case 1: /* idle */ if (!d->mii_bit) d->mii_state = 2; else d->mii_state = 1; break; case 2: /* start */ d->mii_state = d->mii_bit ? 3 : 0; break; case 3: /* opcode */ d->mii_state = d->mii_bit ? 4 : 5; break; case 4: /* read: opcode "10" */ if (!d->mii_bit) { d->mii_opcode = MII_OPCODE_READ; d->mii_state = 6; } else { d->mii_state = 0; } break; case 5: /* write: opcode "01" */ if (d->mii_bit) { d->mii_opcode = MII_OPCODE_WRITE; d->mii_state = 6; } else { d->mii_state = 0; } break; case 6 ... 10: /* phy */ d->mii_phy <<= 1; d->mii_phy |= d->mii_bit; d->mii_state++; break; case 11 ... 15: /* reg */ d->mii_reg <<= 1; d->mii_reg |= d->mii_bit; d->mii_state++; break; case 16 ... 17: /* ta */ if (d->mii_opcode == MII_OPCODE_READ) d->mii_state = 18; else d->mii_state++; break; case 18: if (d->mii_opcode == MII_OPCODE_READ) { d->mii_data = mii_reg_read(d); d->mii_state++; } case 19 ... 35: if (d->mii_opcode == MII_OPCODE_READ) { d->mii_bit = (d->mii_data >> d->mii_data_pos) & 0x1; } else { d->mii_data |= d->mii_bit << d->mii_data_pos; } if (!d->mii_data_pos) { if (d->mii_opcode == MII_OPCODE_WRITE) mii_reg_write(d); d->mii_state = 0; } else { d->mii_state++; } d->mii_data_pos--; break; default: printf("MII: impossible state %u!\n",d->mii_state); }}/* Update the interrupt status */static inline void dev_i8254x_update_irq_status(struct i8254x_data *d){ if (d->icr & d->imr) pci_dev_trigger_irq(d->vm,d->pci_dev); else pci_dev_clear_irq(d->vm,d->pci_dev);}/* Compute RX buffer size */static inline void dev_i8254x_set_rx_buf_size(struct i8254x_data *d){ m_uint32_t bsize; bsize = (d->rctl & I8254X_RCTL_BSIZE_MASK) >> I8254X_RCTL_BSIZE_SHIFT; if (!(d->rctl & I8254X_RCTL_BSEX)) { /* Standard buffer sizes */ switch(bsize) { case 0: d->rx_buf_size = 2048; break; case 1: d->rx_buf_size = 1024; break; case 2: d->rx_buf_size = 512; break; case 3: d->rx_buf_size = 256; break; } } else { /* Extended buffer sizes */ switch(bsize) { case 0: d->rx_buf_size = 0; /* invalid */ break; case 1: d->rx_buf_size = 16384; break; case 2: d->rx_buf_size = 8192; break; case 3: d->rx_buf_size = 4096; break; } }}/* * dev_i8254x_access() */void *dev_i8254x_access(cpu_gen_t *cpu,struct vdevice *dev, m_uint32_t offset,u_int op_size,u_int op_type, m_uint64_t *data){ struct i8254x_data *d = dev->priv_data; if (op_type == MTS_READ) *data = 0x0;#if DEBUG_ACCESS if (op_type == MTS_READ) { cpu_log(cpu,d->name,"read access to offset=0x%x, pc=0x%llx, size=%u\n", offset,cpu_get_pc(cpu),op_size); } else { cpu_log(cpu,d->name,"write access to offset=0x%x, pc=0x%llx, " "val=0x%llx, size=%u\n",offset,cpu_get_pc(cpu),*data,op_size); }#endif LVG_LOCK(d); switch(offset) {#if 0 /* TODO */ case 0x180: if (op_type == MTS_READ) *data = 0xFFFFFFFF; //0xDC004020; //1 << 31; break;#endif /* Link is Up and Full Duplex */ case I8254X_REG_STATUS: if (op_type == MTS_READ) *data = I8254X_STATUS_LU | I8254X_STATUS_FD; break; /* Device Control Register */ case I8254X_REG_CTRL: if (op_type == MTS_WRITE) d->ctrl = *data; else *data = d->ctrl; break; /* Extended Device Control Register */ case I8254X_REG_CTRLEXT: if (op_type == MTS_WRITE) { /* MDIO clock set ? */ if (!(d->ctrl_ext & I8254X_CTRLEXT_SDP6_DATA) && (*data & I8254X_CTRLEXT_SDP6_DATA)) { if (*data & I8254X_CTRLEXT_SDP7_IODIR) d->mii_bit = (*data & I8254X_CTRLEXT_SDP7_DATA) ? 1 : 0; mii_access(d); } d->ctrl_ext = *data; } else { *data = d->ctrl_ext; if (!(d->ctrl_ext & I8254X_CTRLEXT_SDP7_IODIR)) { if (d->mii_bit) *data |= I8254X_CTRLEXT_SDP7_DATA; else *data &= ~I8254X_CTRLEXT_SDP7_DATA; } } break; /* XXX */ case I8254X_REG_MDIC: if (op_type == MTS_READ) *data = 1 << 28; break; /* * Interrupt Cause Read Register. * * Notice: a read clears all interrupt bits. */ case I8254X_REG_ICR: if (op_type == MTS_READ) { *data = d->icr; d->icr = 0; if (d->rx_irq_cnt > 0) { d->icr |= I8254X_ICR_RXT0; d->rx_irq_cnt--; } dev_i8254x_update_irq_status(d); } break; /* Interrupt Cause Set Register */ case I8254X_REG_ICS: if (op_type == MTS_WRITE) { d->icr |= *data; dev_i8254x_update_irq_status(d); } break; /* Interrupt Mask Set/Read Register */ case I8254X_REG_IMS: if (op_type == MTS_WRITE) { d->imr |= *data; dev_i8254x_update_irq_status(d); } else { *data = d->imr; } break; /* Interrupt Mask Clear Register */ case I8254X_REG_IMC: if (op_type == MTS_WRITE) { d->imr &= ~(*data); dev_i8254x_update_irq_status(d); } break; /* Receive Control Register */ case I8254X_REG_RCTL: if (op_type == MTS_READ) { *data = d->rctl; } else { d->rctl = *data; dev_i8254x_set_rx_buf_size(d); } break; /* Transmit Control Register */ case I8254X_REG_TCTL: if (op_type == MTS_READ) *data = d->tctl; else d->tctl = *data; break; /* RX Descriptor Base Address Low */ case I8254X_REG_RDBAL: case I82542_REG_RDBAL: if (op_type == MTS_WRITE) { d->rx_addr &= 0xFFFFFFFF00000000ULL; d->rx_addr |= (m_uint32_t)(*data); } else { *data = (m_uint32_t)d->rx_addr; } break; /* RX Descriptor Base Address High */ case I8254X_REG_RDBAH: case I82542_REG_RDBAH: if (op_type == MTS_WRITE) { d->rx_addr &= 0x00000000FFFFFFFFULL; d->rx_addr |= *data << 32; } else { *data = d->rx_addr >> 32; } break; /* TX Descriptor Base Address Low */ case I8254X_REG_TDBAL: case I82542_REG_TDBAL: if (op_type == MTS_WRITE) { d->tx_addr &= 0xFFFFFFFF00000000ULL; d->tx_addr |= (m_uint32_t)(*data); } else { *data = (m_uint32_t)d->tx_addr; } break; /* TX Descriptor Base Address High */ case I8254X_REG_TDBAH: case I82542_REG_TDBAH: if (op_type == MTS_WRITE) { d->tx_addr &= 0x00000000FFFFFFFFULL; d->tx_addr |= *data << 32; } else { *data = d->tx_addr >> 32; } break; /* RX Descriptor Length */ case I8254X_REG_RDLEN: case I82542_REG_RDLEN: if (op_type == MTS_WRITE) d->rdlen = *data & 0xFFF80; else *data = d->rdlen; break; /* TX Descriptor Length */ case I8254X_REG_TDLEN: case I82542_REG_TDLEN: if (op_type == MTS_WRITE) d->tdlen = *data & 0xFFF80; else *data = d->tdlen; break; /* RX Descriptor Head */ case I82542_REG_RDH: case I8254X_REG_RDH: if (op_type == MTS_WRITE) d->rdh = *data & 0xFFFF; else *data = d->rdh; break; /* RX Descriptor Tail */ case I8254X_REG_RDT: case I82542_REG_RDT: if (op_type == MTS_WRITE) d->rdt = *data & 0xFFFF; else *data = d->rdt; break; /* TX Descriptor Head */ case I82542_REG_TDH: case I8254X_REG_TDH: if (op_type == MTS_WRITE) d->tdh = *data & 0xFFFF; else *data = d->tdh; break; /* TX Descriptor Tail */ case I82542_REG_TDT: case I8254X_REG_TDT: if (op_type == MTS_WRITE) d->tdt = *data & 0xFFFF; else *data = d->tdt; break; /* Flow Control Address Low */ case I8254X_REG_FCAL: if (op_type == MTS_WRITE) d->fcal = *data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -