void threecom3c505_device::device_reset() { LOG1(("reset 3COM 3C505")); m_rx_fifo.reset(); m_rx_data_buffer.reset(); m_tx_data_buffer.reset(); m_program_buffer.reset(); memset(m_reg, 0, sizeof(m_reg)); m_status = HCRE | DIR_; m_control = 0; m_command_index = 0; m_command_pending = 0; m_wait_for_nak = 0; m_wait_for_ack = 0; m_rx_data_index = 0; m_rx_pending = 0; m_tx_data_length = 0; m_response_length = 0; m_response_index = 0; m_microcode_running = 0; m_microcode_version = 0; m_i82586_config = 0; // these will appear in /etc/nodestat -l m_netstat.tot_recv = 0; m_netstat.tot_xmit = 0; m_netstat.err_CRC = 0; m_netstat.err_align = 0; m_netstat.err_res = 0; m_netstat.err_ovrrun = 0; memset(m_station_address, 0, sizeof(m_station_address)); memset(m_multicast_list, 0, sizeof(m_multicast_list)); set_filter_list(); set_promisc(true); }
void threecom3c505_device::device_reset() { LOG1(("reset 3COM 3C505")); m_rx_fifo.reset(); m_rx_data_buffer.reset(); m_tx_data_buffer.reset(); m_program_buffer.reset(); memset(m_reg, 0, sizeof(m_reg)); m_status = HCRE; m_control = 0; m_command_index = 0; m_command_pending = 0; m_mc_f9_pending = 0; m_wait_for_ack = 0; m_rx_data_index = 0; m_rx_pending = 0; m_tx_data_length = 0; m_response_length = 0; m_response_index = 0; m_microcode_running = 0; m_microcode_version = 0; m_i82586_config = 0; // FIXME: test data m_netstat.tot_recv = 1; m_netstat.tot_xmit = 2; m_netstat.err_CRC = 3; m_netstat.err_align = 4; m_netstat.err_res = 5; m_netstat.err_ovrrun = 6; memset(m_station_address, 0 , sizeof(m_station_address)); memset(m_multicast_list, 0 , sizeof(m_multicast_list)); set_filter_list(); set_promisc(true); }
void threecom3c505_device::do_command() { pcb_struct &command_pcp = (pcb_struct &) m_command_buffer; // default to successful completion m_response.command = command_pcp.command + CMD_RESPONSE_OFFSET; m_response.length = 1; m_response.data.failed = 0; // successful completion switch (command_pcp.command) { case CMD_RESET: // 0x00 // FIXME: should never occur break; case CMD_CONFIGURE_ADAPTER_MEMORY: // 0x01 // TODO break; case CMD_CONFIGURE_82586: // 0x02 m_i82586_config = command_pcp.data.raw[0] + (command_pcp.data.raw[1] << 8); break; case CMD_RECEIVE_PACKET: // 0x08 // preset response PCB from the Receive Command PCB m_rcv_response.command = CMD_RECEIVE_PACKET_COMPLETE; // 0x38 m_rcv_response.length = sizeof(struct Rcv_resp); m_rcv_response.data.rcv_resp.buf_ofs = command_pcp.data.rcv_pkt.buf_ofs; m_rcv_response.data.rcv_resp.buf_seg = command_pcp.data.rcv_pkt.buf_seg; m_rcv_response.data.rcv_resp.buf_len = command_pcp.data.rcv_pkt.buf_len; m_rcv_response.data.rcv_resp.pkt_len = 0; m_rcv_response.data.rcv_resp.timeout = 0; m_rcv_response.data.rcv_resp.status = 0; m_rcv_response.data.rcv_resp.timetag = 0L; // TODO m_rx_pending++; set_command_pending(0); return; // break; case CMD_TRANSMIT_PACKET_F9: m_response.command = CMD_TRANSMIT_PACKET_COMPLETE; // fall through case CMD_TRANSMIT_PACKET: // 0x09 case CMD_TRANSMIT_PACKET_18: // 0x18 m_response.length = sizeof(struct Xmit_resp); m_response.data.xmit_resp.buf_ofs = 0; m_response.data.xmit_resp.buf_seg = 0; m_response.data.xmit_resp.c_stat = 0; // successful completion m_response.data.xmit_resp.status = 0; break; case CMD_EXECUTE_PROGRAM: // 0x0e // m_response.length = 0; // FIXME: hack? m_status |= ASF_PCB_END; break; case CMD_NETWORK_STATISTICS: // 0x0a m_response.length = sizeof(struct Netstat); m_response.data.netstat.tot_recv = uint16_to_le(m_netstat.tot_recv); m_response.data.netstat.tot_xmit = uint16_to_le(m_netstat.tot_xmit); m_response.data.netstat.err_CRC = uint16_to_le(m_netstat.err_CRC); m_response.data.netstat.err_align = uint16_to_le(m_netstat.err_align); m_response.data.netstat.err_res = uint16_to_le(m_netstat.err_res); m_response.data.netstat.err_ovrrun = uint16_to_le(m_netstat.err_ovrrun); break; case CMD_ADAPTER_INFO: // 0x11 m_response.length = sizeof(struct Info); // FIXME: using demo data m_response.data.info.minor_vers = 1; m_response.data.info.major_vers = 2; m_response.data.info.ROM_cksum = uint16_to_le(3); m_response.data.info.RAM_sz = uint16_to_le(4); m_response.data.info.free_ofs = uint16_to_le(5); m_response.data.info.free_seg = uint16_to_le(6); break; case CMD_LOAD_MULTICAST_LIST:// 0x0b if (command_pcp.length > sizeof(m_multicast_list) || (command_pcp.length % ETHERNET_ADDR_SIZE) != 0) { LOG(("CMD_LOAD_MULTICAST_LIST - unexpected data size %d", command_pcp.length)); } else { memset(m_multicast_list, 0, sizeof(m_multicast_list)); memcpy(m_multicast_list, command_pcp.data.multicast, command_pcp.length- 2); set_filter_list(); } break; case CMD_SET_STATION_ADDRESS: // 0x10 if (command_pcp.length != sizeof(m_station_address)) { LOG(("CMD_SET_STATION_ADDRESS - unexpected data size %d", command_pcp.length)); memset(m_station_address, 0, sizeof(m_station_address)); } else { memcpy(m_station_address, command_pcp.data.eth_addr, command_pcp.length); } set_filter_list(); set_mac((char *) m_station_address); break; case CMD_MC_17: // 0x17 m_microcode_running = 1; break; case CMD_DOWNLOAD_PROGRAM: // 0x0d UINT16 mc_version = m_program_buffer.get_word(1); switch (mc_version) { case APOLLO_MC_VERSION_SR10_2: case APOLLO_MC_VERSION_SR10_4: m_microcode_version = mc_version; break; default: m_microcode_version = 0; LOG(("CMD_DOWNLOAD_PROGRAM - unexpected microcode version %04x", mc_version)); break; } // return microcode version as program id m_response.length = 2; m_response.data.raw[0] = m_microcode_version & 0xff; m_response.data.raw[1] = (m_microcode_version >> 8) & 0xff; break; } m_response_index = 0; m_response_length = m_response.length + 2; m_status |= ACRF; /* set adapter command register full */ if (m_control & CMDE) { set_interrupt(ASSERT_LINE); } }
void threecom3c505_device::do_command() { // default to successful completion m_response.command = m_command_buffer[0] + CMD_RESPONSE_OFFSET; m_response.length = 1; m_response.data.failed = 0; // successful completion switch (m_command_buffer[0]) { case CMD_RESET: // 0x00 // FIXME: // device_reset(); break; case CMD_CONFIGURE_ADAPTER_MEMORY: // 0x01 m_i82586_config = m_program_buffer.get_word(1); break; case CMD_RECEIVE_PACKET: // 0x08 if (m_rx_data_buffer.get_length() == 0 && !m_rx_fifo.get(&m_rx_data_buffer)) { // receive data not yet available m_rx_pending++; set_command_pending(0); } else { do_receive_command(); } return; // break; case CMD_MC_F9: m_response.command = CMD_TRANSMIT_PACKET_COMPLETE; // fall through case CMD_TRANSMIT_PACKET: // 0x09 case CMD_TRANSMIT_PACKET_18: // 0x18 m_response.length = 8; m_response.data.xmit_resp.buf_ofs = 0; m_response.data.xmit_resp.buf_seg = 0; m_response.data.xmit_resp.c_stat = 0; // successful completion m_response.data.xmit_resp.status = 0; break; case CMD_EXECUTE_PROGRAM: // 0x0e m_response.length = 0; m_microcode_running = 1; m_microcode_version = m_program_buffer.get_word(1); break; case CMD_NETWORK_STATISTICS: // 0x0a m_response.length = sizeof(struct Netstat); // response data must be LSB first! m_response.data.netstat.tot_recv = lsb_first(m_netstat.tot_recv); m_response.data.netstat.tot_xmit = lsb_first(m_netstat.tot_xmit); m_response.data.netstat.err_CRC = lsb_first(m_netstat.err_CRC); m_response.data.netstat.err_align = lsb_first(m_netstat.err_align); m_response.data.netstat.err_res = lsb_first(m_netstat.err_res); m_response.data.netstat.err_ovrrun = lsb_first(m_netstat.err_ovrrun); break; case CMD_ADAPTER_INFO: // 0x11 m_response.length = sizeof(struct Info); // FIXME: replace test data; must be LSB first! m_response.data.info.minor_vers = 1; m_response.data.info.major_vers = 2; m_response.data.info.ROM_cksum = lsb_first(3); m_response.data.info.RAM_sz = lsb_first(4); m_response.data.info.free_ofs = lsb_first(5); m_response.data.info.free_seg = lsb_first(6); break; case CMD_LOAD_MULTICAST_LIST:// 0x0b if (m_command_buffer[1] > sizeof(m_multicast_list) || (m_command_buffer[1] % ETHERNET_ADDR_SIZE) != 0) { LOG(("CMD_LOAD_MULTICAST_LIST - !!! unexpected data size %d !!!", m_command_buffer[1])); } else { memset(m_multicast_list, 0 , sizeof(m_multicast_list)); memcpy(m_multicast_list, m_command_buffer+2 , m_command_buffer[1]-2); set_filter_list(); } break; case CMD_SET_STATION_ADDRESS: // 0x10 if (m_command_buffer[1] != sizeof(m_station_address)) { LOG(("CMD_SET_STATION_ADDRESS - !!! unexpected data size %d !!!", m_command_buffer[1])); memset(m_station_address, 0 , sizeof(m_station_address)); } else { memcpy(m_station_address, m_command_buffer+2 , m_command_buffer[1]); } set_filter_list(); set_mac((char *)m_station_address); break; case CMD_CONFIGURE_82586: // 0x02 case CMD_DOWNLOAD_PROGRAM: // 0x0d case CMD_MC_17: // 0x17 default: break; } m_response_index = 0; m_response_length = m_response.length + 2; m_status |= ACRF; /* adapter command register full */ if (m_control & CMDE) { switch (m_command_buffer[0]) { case CMD_NETWORK_STATISTICS: // 0x0a case CMD_DOWNLOAD_PROGRAM: // 0xd case CMD_EXECUTE_PROGRAM: // 0x0e case CMD_ADAPTER_INFO: // 0x11 // interrupt later m_timer->adjust( attotime::from_msec(5)); break; default: // interrupt at once set_interrupt(ASSERT_LINE); break; } } }