void SocketConnection::handle_error() { got_error_ = true; read_listener_.stop(); write_listener_.stop(); packet_received( PacketPtr() ); }
void SocketConnection::handle_line(const std::string& line) { DH_LOG(Info) << "received packet: \"" << line << "\""; PacketPtr packet; try { packet = Packet::create(line); } catch (const std::exception& e) { DH_LOG(Error) << "packet parse error: " << e.what(); return; } packet_received(packet); }
void inmate_main(void) { enum { ROLE_UNDEFINED, ROLE_CONTROLLER, ROLE_TARGET } role; unsigned long min = -1, max = 0, rtt; struct eth_header *rx_packet; unsigned long long start; bool first_round = true; unsigned int n; u32 eerd, val; u8 mac[6]; u64 bar; int bdf; printk_uart_base = UART_BASE; bdf = pci_find_device(PCI_ID_ANY, PCI_ID_ANY, 0); if (bdf < 0) { printk("No device found!\n"); return; } printk("Found %04x:%04x at %02x:%02x.%x\n", pci_read_config(bdf, PCI_CFG_VENDOR_ID, 2), pci_read_config(bdf, PCI_CFG_DEVICE_ID, 2), bdf >> 8, (bdf >> 3) & 0x1f, bdf & 0x3); bar = pci_read_config(bdf, PCI_CFG_BAR, 4); if ((bar & 0x6) == 0x4) bar |= (u64)pci_read_config(bdf, PCI_CFG_BAR + 4, 4) << 32; mmiobar = (void *)(bar & ~0xfUL); map_range(mmiobar, 128 * 1024, MAP_UNCACHED); printk("MMIO register BAR at %p\n", mmiobar); pci_write_config(bdf, PCI_CFG_COMMAND, PCI_CMD_MEM | PCI_CMD_MASTER, 2); mmio_write32(mmiobar + E1000_REG_CTRL, E1000_CTRL_RST); delay_us(20000); val = mmio_read32(mmiobar + E1000_REG_CTRL); val &= ~(E1000_CTRL_LRST | E1000_CTRL_FRCSPD); val |= E1000_CTRL_ASDE | E1000_CTRL_SLU; mmio_write32(mmiobar + E1000_REG_CTRL, val); printk("Reset done, waiting for link..."); while (!(mmio_read32(mmiobar + E1000_REG_STATUS) & E1000_STATUS_LU)) cpu_relax(); printk(" ok\n"); if (mmio_read32(mmiobar + E1000_REG_RAH) & E1000_RAH_AV) { *(u32 *)mac = mmio_read32(mmiobar + E1000_REG_RAL); *(u16 *)&mac[4] = mmio_read32(mmiobar + E1000_REG_RAH); } else { for (n = 0; n < 3; n++) { mmio_write32(mmiobar + E1000_REG_EERD, E1000_EERD_START | (n << E1000_EERD_ADDR_SHIFT)); do { eerd = mmio_read32(mmiobar + E1000_REG_EERD); cpu_relax(); } while (!(eerd & E1000_EERD_DONE)); mac[n * 2] = (u8)(eerd >> E1000_EERD_DATA_SHIFT); mac[n * 2 + 1] = (u8)(eerd >> (E1000_EERD_DATA_SHIFT + 8)); } } printk("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); mmio_write32(mmiobar + E1000_REG_RAL, *(u32 *)mac); mmio_write32(mmiobar + E1000_REG_RAH, *(u16 *)&mac[4] | E1000_RAH_AV); for (n = 0; n < RX_DESCRIPTORS; n++) rx_ring[n].addr = (unsigned long)&buffer[n * RX_BUFFER_SIZE]; mmio_write32(mmiobar + E1000_REG_RDBAL, (unsigned long)&rx_ring); mmio_write32(mmiobar + E1000_REG_RDBAH, 0); mmio_write32(mmiobar + E1000_REG_RDLEN, sizeof(rx_ring)); mmio_write32(mmiobar + E1000_REG_RDH, 0); mmio_write32(mmiobar + E1000_REG_RDT, RX_DESCRIPTORS - 1); val = mmio_read32(mmiobar + E1000_REG_RCTL); val |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_BSIZE_2048 | E1000_RCTL_SECRC; mmio_write32(mmiobar + E1000_REG_RCTL, val); mmio_write32(mmiobar + E1000_REG_TDBAL, (unsigned long)&tx_ring); mmio_write32(mmiobar + E1000_REG_TDBAH, 0); mmio_write32(mmiobar + E1000_REG_TDLEN, sizeof(tx_ring)); mmio_write32(mmiobar + E1000_REG_TDH, 0); mmio_write32(mmiobar + E1000_REG_TDT, 0); val = mmio_read32(mmiobar + E1000_REG_TCTL); val |= E1000_TCTL_EN | E1000_TCTL_PSP | E1000_TCTL_CT_DEF | E1000_TCTL_COLD_DEF; mmio_write32(mmiobar + E1000_REG_TCTL, val); mmio_write32(mmiobar + E1000_REG_TIPG, E1000_TIPG_IPGT_DEF | E1000_TIPG_IPGR1_DEF | E1000_TIPG_IPGR2_DEF); role = ROLE_UNDEFINED; memcpy(tx_packet.src, mac, sizeof(tx_packet.src)); memset(tx_packet.dst, 0xff, sizeof(tx_packet.dst)); tx_packet.type = FRAME_TYPE_ANNOUNCE; send_packet(&tx_packet, sizeof(tx_packet)); start = pm_timer_read(); while (pm_timer_read() - start < NS_PER_MSEC && role == ROLE_UNDEFINED) { rx_packet = packet_received(); if (!rx_packet) continue; if (rx_packet->type == FRAME_TYPE_TARGET_ROLE) { role = ROLE_TARGET; memcpy(tx_packet.dst, rx_packet->src, sizeof(tx_packet.dst)); } packet_reception_done(); } if (role == ROLE_UNDEFINED) { role = ROLE_CONTROLLER; printk("Waiting for peer\n"); while (1) { rx_packet = packet_received(); if (!rx_packet) continue; if (rx_packet->type == FRAME_TYPE_ANNOUNCE) { memcpy(tx_packet.dst, rx_packet->src, sizeof(tx_packet.dst)); packet_reception_done(); tx_packet.type = FRAME_TYPE_TARGET_ROLE; send_packet(&tx_packet, sizeof(tx_packet)); break; } else { packet_reception_done(); } } } mmio_write32(mmiobar + E1000_REG_RCTL, mmio_read32(mmiobar + E1000_REG_RCTL) & ~E1000_RCTL_BAM); if (role == ROLE_CONTROLLER) { printk("Running as controller\n"); tx_packet.type = FRAME_TYPE_PING; while (1) { start = pm_timer_read(); send_packet(&tx_packet, sizeof(tx_packet)); do rx_packet = packet_received(); while (!rx_packet || rx_packet->type != FRAME_TYPE_PONG); packet_reception_done(); if (!first_round) { rtt = pm_timer_read() - start; if (rtt < min) min = rtt; if (rtt > max) max = rtt; printk("Received pong, RTT: %6ld ns, " "min: %6ld ns, max: %6ld ns\n", rtt, min, max); } first_round = false; delay_us(100000); } } else { printk("Running as target\n"); tx_packet.type = FRAME_TYPE_PONG; while (1) { rx_packet = packet_received(); if (!rx_packet || rx_packet->type != FRAME_TYPE_PING) continue; packet_reception_done(); send_packet(&tx_packet, sizeof(tx_packet)); } } }