int lbp16_write(u16 cmd, u32 addr, void *buffer, int size) { static struct { lbp16_cmd_addr wr_packet; u8 tmp_buffer[LBP16_MAX_PACKET_DATA_SIZE*8]; } packet; int send; LBP16_INIT_PACKET4(packet.wr_packet, cmd, addr); memcpy(&packet.tmp_buffer, buffer, size); if (LBP16_SENDRECV_DEBUG) { printf("SEND: %02X %02X %02X %02X | WRITE %d bytes\n", packet.wr_packet.cmd_hi, packet.wr_packet.cmd_lo, packet.wr_packet.addr_hi, packet.wr_packet.addr_lo, size); } send = lbp16_access.send_packet(&packet, sizeof(lbp16_cmd_addr) + size); return 0; }
int lbp16_read(u16 cmd, u32 addr, void *buffer, int size) { lbp16_cmd_addr packet; int send, recv; u8 local_buff[size]; LBP16_INIT_PACKET4(packet, cmd, addr); if (LBP16_SENDRECV_DEBUG) { printf("SEND: %02X %02X %02X %02X | REQUEST %d bytes\n", packet.cmd_hi, packet.cmd_lo, packet.addr_hi, packet.addr_lo, size); } send = lbp16_access.send_packet(&packet, sizeof(packet)); recv = lbp16_access.recv_packet(&local_buff, sizeof(local_buff)); if (LBP16_SENDRECV_DEBUG) { printf("RECV: %d bytes\n", recv); } memcpy(buffer, local_buff, size); return 0; }
int lbp16_board_reload(llio_t *self, int fallback_flag) { board_t *board = self->board; int send; u32 boot_addr; u16 fw_ver; lbp16_cmd_addr_data16 packet[14]; lbp16_cmd_addr fw_packet; LBP16_INIT_PACKET4(fw_packet, CMD_READ_BOARD_INFO_ADDR16(1), offsetof(lbp_info_area, firmware_version)); lbp16_send_packet(&fw_packet, sizeof(fw_packet)); lbp16_recv_packet(&fw_ver, sizeof(fw_ver)); if ((board->type & BOARD_ETH) && (fw_ver < 15)) { printf("ERROR: FPGA reload only supported by ethernet card firmware > 14.\n"); return -1; } else if ((board->type & BOARD_SER) && (fw_ver < 2)) { printf("ERROR: FPGA reload only supported by serial card firmware > 2.\n"); return -1; } if (fallback_flag == 1) { boot_addr = 0x10000; } else { boot_addr = 0x0; } boot_addr |= 0x0B000000; // plus read command in high byte LBP16_INIT_PACKET6(packet[0], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0xFFFF); // dummy LBP16_INIT_PACKET6(packet[1], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0xFFFF); // dummy LBP16_INIT_PACKET6(packet[2], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0xAA99); // sync LBP16_INIT_PACKET6(packet[3], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x5566); // sync LBP16_INIT_PACKET6(packet[4], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x3261); // load low flash start address LBP16_INIT_PACKET6(packet[5], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, boot_addr & 0xFFFF); // start addr LBP16_INIT_PACKET6(packet[6], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x3281); // load high start address + read command LBP16_INIT_PACKET6(packet[7], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, boot_addr >> 16); // start addr (plus read command in high byte) LBP16_INIT_PACKET6(packet[8], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x30A1); // load command register LBP16_INIT_PACKET6(packet[9], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x000E); // IPROG command LBP16_INIT_PACKET6(packet[10], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x2000); // NOP LBP16_INIT_PACKET6(packet[11], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x2000); // NOP LBP16_INIT_PACKET6(packet[12], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x2000); // NOP LBP16_INIT_PACKET6(packet[13], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x2000); // NOP send = lbp16_send_packet(&packet, sizeof(packet)); }
static int fetch_hwaddr(int sockfd, unsigned char buf[6]) { lbp16_cmd_addr packet; unsigned char response[6]; LBP16_INIT_PACKET4(packet, 0x4983, 0x0002); int res = eth_socket_send(sockfd, &packet, sizeof(packet), 0); if(res < 0) return -errno; int i=0; do { res = eth_socket_recv(sockfd, &response, sizeof(response), 0); } while(++i < 10 && res < 0 && errno == EAGAIN); if(res < 0) return -errno; // eeprom order is backwards from arp AF_LOCAL order for(i=0; i<6; i++) buf[i] = response[5-i]; LL_PRINT("Hardware address: %02x:%02x:%02x:%02x:%02x:%02x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); return 0; }