static int decode_pkg(struct thr_info *thr, struct avalon2_ret *ar, uint8_t *pkg) { struct cgpu_info *avalon2; struct avalon2_info *info; struct pool *pool; unsigned int expected_crc; unsigned int actual_crc; uint32_t nonce, nonce2, miner, modular_id; int pool_no; uint8_t job_id[5]; int tmp; int type = AVA2_GETS_ERROR; if (thr) { avalon2 = thr->cgpu; info = avalon2->device_data; } memcpy((uint8_t *)ar, pkg, AVA2_READ_SIZE); if (ar->head[0] == AVA2_H1 && ar->head[1] == AVA2_H2) { expected_crc = crc16(ar->data, AVA2_P_DATA_LEN); actual_crc = (ar->crc[0] & 0xff) | ((ar->crc[1] & 0xff) << 8); type = ar->type; applog(LOG_DEBUG, "Avalon2: %d: expected crc(%04x), actural_crc(%04x)", type, expected_crc, actual_crc); if (expected_crc != actual_crc) goto out; memcpy(&modular_id, ar->data + 28, 4); modular_id = be32toh(modular_id); if (modular_id == 3) modular_id = 0; switch(type) { case AVA2_P_NONCE: memcpy(&miner, ar->data + 0, 4); memcpy(&pool_no, ar->data + 4, 4); memcpy(&nonce2, ar->data + 8, 4); /* Calc time ar->data + 12 */ memcpy(&nonce, ar->data + 16, 4); memset(job_id, 0, 5); memcpy(job_id, ar->data + 20, 4); miner = be32toh(miner); pool_no = be32toh(pool_no); if (miner >= AVA2_DEFAULT_MINERS || modular_id >= AVA2_DEFAULT_MINERS || pool_no >= total_pools || pool_no < 0) { applog(LOG_DEBUG, "Avalon2: Wrong miner/pool/id no %d,%d,%d", miner, pool_no, modular_id); break; } else info->matching_work[modular_id * AVA2_DEFAULT_MINERS + miner]++; nonce2 = bswap_32(nonce2); nonce = be32toh(nonce); nonce -= 0x180; applog(LOG_DEBUG, "Avalon2: Found! [%s] %d:(%08x) (%08x)", job_id, pool_no, nonce2, nonce); /* FIXME: * We need remember the pre_pool. then submit the stale work */ pool = pools[pool_no]; if (job_idcmp(job_id, pool->swork.job_id)) break; if (thr && !info->new_stratum) submit_nonce2_nonce(thr, pool_no, nonce2, nonce); break; case AVA2_P_STATUS: memcpy(&tmp, ar->data, 4); tmp = be32toh(tmp); info->temp[0 + modular_id * 2] = tmp >> 16; info->temp[1 + modular_id * 2] = tmp & 0xffff; memcpy(&tmp, ar->data + 4, 4); tmp = be32toh(tmp); info->fan[0 + modular_id * 2] = tmp >> 16; info->fan[1 + modular_id * 2] = tmp & 0xffff; memcpy(&(info->get_frequency[modular_id]), ar->data + 8, 4); memcpy(&(info->get_voltage[modular_id]), ar->data + 12, 4); memcpy(&(info->local_work[modular_id]), ar->data + 16, 4); memcpy(&(info->hw_work[modular_id]), ar->data + 20, 4); info->get_frequency[modular_id] = be32toh(info->get_frequency[modular_id]); info->get_voltage[modular_id] = be32toh(info->get_voltage[modular_id]); info->local_work[modular_id] = be32toh(info->local_work[modular_id]); info->hw_work[modular_id] = be32toh(info->hw_work[modular_id]); info->local_works[modular_id] += info->local_work[modular_id]; info->hw_works[modular_id] += info->hw_work[modular_id]; info->get_voltage[modular_id] = decode_voltage(info->get_voltage[modular_id]); avalon2->temp = get_temp_max(info); break; case AVA2_P_ACKDETECT: break; case AVA2_P_ACK: break; case AVA2_P_NAK: break; default: type = AVA2_GETS_ERROR; break; } }
static int decode_pkg(struct thr_info *thr, struct hashratio_ret *ar, uint8_t *pkg) { struct cgpu_info *hashratio = thr->cgpu; struct hashratio_info *info = hashratio->device_data; struct pool *pool, *real_pool, *pool_stratum = &info->pool; unsigned int expected_crc; unsigned int actual_crc; uint32_t nonce, nonce2, miner; int pool_no; uint8_t job_id[4]; int tmp; int type = HRTO_GETS_ERROR; memcpy((uint8_t *)ar, pkg, HRTO_READ_SIZE); // applog(LOG_DEBUG, "pkg.type, hex: %02x, dec: %d", ar->type, ar->type); if (ar->head[0] == HRTO_H1 && ar->head[1] == HRTO_H2) { expected_crc = crc16(ar->data, HRTO_P_DATA_LEN); actual_crc = (ar->crc[0] & 0xff) | ((ar->crc[1] & 0xff) << 8); type = ar->type; applog(LOG_DEBUG, "hashratio: %d: expected crc(%04x), actual_crc(%04x)", type, expected_crc, actual_crc); if (expected_crc != actual_crc) goto out; switch(type) { case HRTO_P_NONCE: applog(LOG_DEBUG, "Hashratio: HRTO_P_NONCE"); memcpy(&miner, ar->data + 0, 4); memcpy(&pool_no, ar->data + 4, 4); memcpy(&nonce2, ar->data + 8, 4); /* Calc time ar->data + 12 */ memcpy(&nonce, ar->data + 12, 4); memcpy(job_id, ar->data + 16, 4); miner = be32toh(miner); pool_no = be32toh(pool_no); if (miner >= HRTO_DEFAULT_MINERS || pool_no >= total_pools || pool_no < 0) { applog(LOG_DEBUG, "hashratio: Wrong miner/pool/id no %d,%d", miner, pool_no); break; } else info->matching_work[miner]++; nonce2 = be32toh(nonce2); nonce = be32toh(nonce); applog(LOG_DEBUG, "hashratio: Found! [%s] %d:(%08x) (%08x)", job_id, pool_no, nonce2, nonce); real_pool = pool = pools[pool_no]; if (job_idcmp(job_id, pool->swork.job_id)) { if (!job_idcmp(job_id, pool_stratum->swork.job_id)) { applog(LOG_DEBUG, "Hashratio: Match to previous stratum! (%s)", pool_stratum->swork.job_id); pool = pool_stratum; } else { applog(LOG_DEBUG, "Hashratio Cannot match to any stratum! (%s)", pool->swork.job_id); break; } } submit_nonce2_nonce(thr, pool, real_pool, nonce2, nonce, 0); break; case HRTO_P_STATUS: applog(LOG_DEBUG, "Hashratio: HRTO_P_STATUS"); memcpy(&tmp, ar->data, 4); tmp = be32toh(tmp); info->temp = (tmp & 0x00f0) >> 8; if (info->temp_max < info->temp) { info->temp_max = info->temp; } // info->temp[1] = tmp & 0xffff; memcpy(&tmp, ar->data + 4, 4); tmp = be32toh(tmp); info->fan[0] = tmp >> 16; info->fan[1] = tmp & 0xffff; // local_work memcpy(&tmp, ar->data + 8, 4); tmp = be32toh(tmp); info->local_work = tmp; info->local_works += tmp; // hw_work memcpy(&tmp, ar->data + 12, 4); tmp = be32toh(tmp); info->hw_works += tmp; hashratio->temp = info->temp; break; case HRTO_P_ACKDETECT: applog(LOG_DEBUG, "Hashratio: HRTO_P_ACKDETECT"); break; case HRTO_P_ACK: applog(LOG_DEBUG, "Hashratio: HRTO_P_ACK"); break; case HRTO_P_NAK: applog(LOG_DEBUG, "Hashratio: HRTO_P_NAK"); break; default: applog(LOG_DEBUG, "Hashratio: HRTO_GETS_ERROR"); type = HRTO_GETS_ERROR; break; } }
static int polling_and_return_number_of_wins(struct thr_info *thr) { struct cgpu_info *spondoolies = thr->cgpu; struct spond_adapter *device = spondoolies->device_data; /* * send request to miner gateway to get wins results */ pxgate_gen_packet req_rsp; req_rsp.header.message_type = pxgate_MESSAGE_TYPE_RSP_REQ; req_rsp.header.message_size = sizeof(req_rsp)-sizeof(req_rsp.header); req_rsp.header.protocol_version = pxgate_PROTOCOL_VERSION; do_write(device->socket_fd, &req_rsp, sizeof(req_rsp)); /* * read result */ // OK, since we don't know message size, lets take biggest void *message = calloc(1, sizeof(pxgate_rsp_packet)); int size = do_read_packet(device->socket_fd, message, sizeof(pxgate_rsp_packet)); if (size == 0) { quit(1, "%s: Ooops returned bad packet from cgminer", sp50_drv.dname); free(message); return 0; } // lets check the header pxgate_packet_header *header = (pxgate_packet_header*) message; switch (header->message_type) { case pxgate_MESSAGE_TYPE_RSP_NODATA: { free(message); return 0; } case pxgate_MESSAGE_TYPE_RSP_DATA: { int i; int j; pxgate_rsp_packet *rsp = (pxgate_rsp_packet*) message; // TODO: handle rsp->gh_div_10_rate int results = rsp->rsp_count; for (i = 0; i < results; ++i) { // get work object that requested mining struct pool *real_pool = NULL; struct pool *pool = NULL; int job_id = get_array_id(rsp->rsp[i].work_id_in_sw); // lets check that we can work with sw job_id and pool we cached // CHECKING JOB VALIDITY if (job_id < 0 || rsp->rsp[i].work_id_in_sw > MAX_SW_JOB_INDEX_IN_MINERGATE) { free(message); return 0; } cg_rlock(&(device->my_jobs[job_id].data_lock)); if (device->my_jobs[job_id].pool.swork.job_id == NULL) { // it is stale job, we drop result // it happens due to flush work, right before we received results from asic SPONDLOG(LOG_ERR, "droping wins enonce2[0x%016llx] nonce[0x%08x] gate_job_id[%d] cgminer_job_id[%d], stale job", rsp->rsp[i].nonce2, rsp->rsp[i].winner_nonce, rsp->rsp[i].work_id_in_sw, device->my_jobs[job_id].sw_job_id ); free(message); cg_runlock(&(device->my_jobs[job_id].data_lock)); return 0; } if (device->my_jobs[job_id].sw_job_id != rsp->rsp[i].work_id_in_sw) { // it is stale job, we drop result SPONDLOG(LOG_ERR, "droping wins enonce2[0x%016llx] nonce[0x%08x] gate_job_id[%d] cgminer_job_id[%d], stale job", rsp->rsp[i].nonce2, rsp->rsp[i].winner_nonce, rsp->rsp[i].work_id_in_sw, device->my_jobs[job_id].sw_job_id ); free(message); cg_runlock(&(device->my_jobs[job_id].data_lock)); return 0; } pool = &device->my_jobs[job_id].pool; real_pool = pools[device->my_jobs[job_id].pool.pool_no]; if (submit_nonce2_nonce( thr, pool, real_pool, rsp->rsp[i].nonce2, ntohl(rsp->rsp[i].winner_nonce), rsp->rsp[i].ntime_offset)){ SPONDLOG(LOG_ERR, "nonce::: %s: win [%d/%d] enonce[%016llx] nonce [%08x], ntime_offset %x", sp50_drv.dname, i+1, results, rsp->rsp[i].nonce2, rsp->rsp[i].winner_nonce, rsp->rsp[i].ntime_offset ); } cg_runlock(&(device->my_jobs[job_id].data_lock)); } free(message); return results; }; default: { SPONDLOG(LOG_ERR, "Ooops returned un expected message type [%08x]", header->message_type); free(message); return 0; } } return 0; }
static int decode_pkg(struct thr_info *thr, struct hashratio_ret *ar, uint8_t *pkg) { struct cgpu_info *hashratio; struct hashratio_info *info; struct pool *pool; unsigned int expected_crc; unsigned int actual_crc; uint32_t nonce, nonce2, miner; int pool_no; uint8_t job_id[5]; int tmp; int type = HRTO_GETS_ERROR; if (thr) { hashratio = thr->cgpu; info = hashratio->device_data; } // else // FIXME: Should this happen at all!? // return 0; memcpy((uint8_t *)ar, pkg, HRTO_READ_SIZE); // applog(LOG_DEBUG, "pkg.type, hex: %02x, dec: %d", ar->type, ar->type); if (ar->head[0] == HRTO_H1 && ar->head[1] == HRTO_H2) { expected_crc = crc16(ar->data, HRTO_P_DATA_LEN); actual_crc = (ar->crc[0] & 0xff) | ((ar->crc[1] & 0xff) << 8); type = ar->type; applog(LOG_DEBUG, "hashratio: %d: expected crc(%04x), actural_crc(%04x)", type, expected_crc, actual_crc); if (expected_crc != actual_crc) goto out; switch(type) { case HRTO_P_NONCE: memcpy(&miner, ar->data + 0, 4); memcpy(&pool_no, ar->data + 4, 4); memcpy(&nonce2, ar->data + 8, 4); /* Calc time ar->data + 12 */ memcpy(&nonce, ar->data + 12, 4); memset(job_id, 0, 5); memcpy(job_id, ar->data + 16, 4); miner = be32toh(miner); pool_no = be32toh(pool_no); if (miner >= HRTO_DEFAULT_MINERS || pool_no >= total_pools || pool_no < 0) { applog(LOG_DEBUG, "hashratio: Wrong miner/pool/id no %d,%d", miner, pool_no); break; } else info->matching_work[miner]++; nonce2 = be32toh(nonce2); nonce = be32toh(nonce); applog(LOG_DEBUG, "hashratio: Found! [%s] %d:(%08x) (%08x)", job_id, pool_no, nonce2, nonce); /* FIXME: * We need remember the pre_pool. then submit the stale work */ // pool = pools[pool_no]; // if (job_idcmp(job_id, pool->swork.job_id)) // break; if (thr && !info->new_stratum) submit_nonce2_nonce(thr, pool_no, nonce2, nonce); break; case HRTO_P_STATUS: memcpy(&tmp, ar->data, 4); tmp = be32toh(tmp); info->temp = (tmp & 0x000000ff); if (info->temp_max < info->temp) { info->temp_max = info->temp; } // info->temp[1] = tmp & 0xffff; memcpy(&tmp, ar->data + 4, 4); tmp = be32toh(tmp); info->fan[0] = tmp >> 16; info->fan[1] = tmp & 0xffff; // local_work memcpy(&tmp, ar->data + 8, 4); tmp = be32toh(tmp); info->local_work = tmp; info->local_works += tmp; // hw_work memcpy(&tmp, ar->data + 12, 4); tmp = be32toh(tmp); info->hw_works += tmp; hashratio->temp = info->temp; break; case HRTO_P_ACKDETECT: break; case HRTO_P_ACK: break; case HRTO_P_NAK: break; default: type = HRTO_GETS_ERROR; break; } }