static void hfa_parse_nonce(struct thr_info *thr, struct cgpu_info *hashfast, struct hashfast_info *info, struct hf_header *h) { struct hf_candidate_nonce *n = (struct hf_candidate_nonce *)(h + 1); int i, num_nonces = h->data_length / U32SIZE(sizeof(struct hf_candidate_nonce)); applog(LOG_DEBUG, "%s %d: OP_NONCE: %2d/%2d:, num_nonces %d hdata 0x%04x", hashfast->drv->name, hashfast->device_id, h->chip_address, h->core_address, num_nonces, h->hdata); for (i = 0; i < num_nonces; i++, n++) { struct work *work = NULL; applog(LOG_DEBUG, "%s %d: OP_NONCE: %2d: %2d: ntime %2d sequence %4d nonce 0x%08x", hashfast->drv->name, hashfast->device_id, h->chip_address, i, n->ntime & HF_NTIME_MASK, n->sequence, n->nonce); if (n->sequence < info->usb_init_base.sequence_modulus) { // Find the job from the sequence number mutex_lock(&info->lock); work = info->works[n->sequence]; mutex_unlock(&info->lock); } else { applog(LOG_INFO, "%s %d: OP_NONCE: Sequence out of range %4d max %4d", hashfast->drv->name, hashfast->device_id, n->sequence, info->usb_init_base.sequence_modulus); } if (unlikely(!work)) { info->no_matching_work++; applog(LOG_INFO, "%s %d: No matching work!", hashfast->drv->name, hashfast->device_id); } else { applog(LOG_DEBUG, "%s %d: OP_NONCE: sequence %d: submitting nonce 0x%08x ntime %d", hashfast->drv->name, hashfast->device_id, n->sequence, n->nonce, n->ntime & HF_NTIME_MASK); if (submit_noffset_nonce(thr, work, n->nonce, n->ntime & HF_NTIME_MASK)) { mutex_lock(&info->lock); info->hash_count += 0xffffffffull * work->device_diff; mutex_unlock(&info->lock); } #if 0 /* Not used */ if (unlikely(n->ntime & HF_NONCE_SEARCH)) { /* This tells us there is another share in the * next 128 nonces */ applog(LOG_DEBUG, "%s %d: OP_NONCE: SEARCH PROXIMITY EVENT FOUND", hashfast->drv->name, hashfast->device_id); } #endif } } }
static void hfa_parse_nonce(struct thr_info *thr, struct cgpu_info *hashfast, struct hashfast_info *info, struct hf_header *h) { struct hf_candidate_nonce *n = (struct hf_candidate_nonce *)(h + 1); int i, num_nonces = h->data_length / U32SIZE(sizeof(struct hf_candidate_nonce)); applog(LOG_DEBUG, "HFA %d: OP_NONCE: %2d:, num_nonces %d hdata 0x%04x", hashfast->device_id, h->chip_address, num_nonces, h->hdata); for (i = 0; i < num_nonces; i++, n++) { struct work *work = NULL; applog(LOG_DEBUG, "HFA %d: OP_NONCE: %2d: %2d: ntime %2d sequence %4d nonce 0x%08x", hashfast->device_id, h->chip_address, i, n->ntime & HF_NTIME_MASK, n->sequence, n->nonce); if (n->sequence < info->usb_init_base.sequence_modulus) { // Find the job from the sequence number mutex_lock(&info->lock); work = info->works[n->sequence]; mutex_unlock(&info->lock); } else { applog(LOG_INFO, "HFA %d: OP_NONCE: Sequence out of range %4d max %4d", hashfast->device_id, n->sequence, info->usb_init_base.sequence_modulus); } if (unlikely(!work)) { info->no_matching_work++; applog(LOG_INFO, "HFA %d: No matching work!", hashfast->device_id); } else { applog(LOG_DEBUG, "HFA %d: OP_NONCE: sequence %d: submitting nonce 0x%08x ntime %d", hashfast->device_id, n->sequence, n->nonce, n->ntime & HF_NTIME_MASK); if ((n->nonce & 0xffff0000) == 0x42420000) // XXX REMOVE THIS break; // XXX PHONEY EMULATOR NONCE submit_noffset_nonce(thr, work, n->nonce, n->ntime & HF_NTIME_MASK); // XXX Return value from submit_nonce is error if set if (unlikely(n->ntime & HF_NONCE_SEARCH)) { /* This tells us there is another share in the * next 128 nonces */ applog(LOG_DEBUG, "HFA %d: OP_NONCE: SEARCH PROXIMITY EVENT FOUND", hashfast->device_id); search_for_extra_nonce(thr, work, n); } } } }
static bool hfa_reset(struct cgpu_info *hashfast, struct hashfast_info *info) { struct hf_usb_init_header usb_init[2], *hu = usb_init; struct hf_usb_init_base *db; struct hf_usb_init_options *ho; int retries = 0, i; char buf[1024]; struct hf_header *h = (struct hf_header *)buf; uint8_t hcrc; bool ret; /* Hash clock rate in Mhz */ info->hash_clock_rate = opt_hfa_hash_clock ? opt_hfa_hash_clock : 550; info->group_ntime_roll = opt_hfa_ntime_roll ? opt_hfa_ntime_roll : 1; info->core_ntime_roll = 1; // Assemble the USB_INIT request memset(hu, 0, sizeof(*hu)); hu->preamble = HF_PREAMBLE; hu->operation_code = OP_USB_INIT; hu->protocol = PROTOCOL_GLOBAL_WORK_QUEUE; // Protocol to use // Force PLL bypass hu->pll_bypass = opt_hfa_pll_bypass; hu->hash_clock = info->hash_clock_rate; // Hash clock rate in Mhz if (info->group_ntime_roll > 1 && info->core_ntime_roll) { ho = (struct hf_usb_init_options *)(hu + 1); memset(ho, 0, sizeof(*ho)); ho->group_ntime_roll = info->group_ntime_roll; ho->core_ntime_roll = info->core_ntime_roll; hu->data_length = sizeof(*ho) / 4; } hu->crc8 = hfa_crc8((uint8_t *)hu); applog(LOG_INFO, "HFA%d: Sending OP_USB_INIT with GWQ protocol specified", hashfast->device_id); if (!hfa_send_packet(hashfast, (struct hf_header *)hu, HF_USB_CMD(OP_USB_INIT))) return false; // Check for the correct response. // We extend the normal timeout - a complete device initialization, including // bringing power supplies up from standby, etc., can take over a second. tryagain: for (i = 0; i < 30; i++) { ret = hfa_get_header(hashfast, h, &hcrc); if (ret) break; } if (!ret) { applog(LOG_WARNING, "HFA %d: OP_USB_INIT failed!", hashfast->device_id); return false; } if (h->crc8 != hcrc) { applog(LOG_WARNING, "HFA %d: OP_USB_INIT failed! CRC mismatch", hashfast->device_id); return false; } if (h->operation_code != OP_USB_INIT) { // This can happen if valid packet(s) were in transit *before* the OP_USB_INIT arrived // at the device, so we just toss the packets and keep looking for the response. applog(LOG_WARNING, "HFA %d: OP_USB_INIT: Tossing packet, valid but unexpected type %d", hashfast->device_id, h->operation_code); hfa_get_data(hashfast, buf, h->data_length); if (retries++ < 3) goto tryagain; return false; } applog(LOG_DEBUG, "HFA %d: Good reply to OP_USB_INIT", hashfast->device_id); applog(LOG_DEBUG, "HFA %d: OP_USB_INIT: %d die in chain, %d cores, device_type %d, refclk %d Mhz", hashfast->device_id, h->chip_address, h->core_address, h->hdata & 0xff, (h->hdata >> 8) & 0xff); // Save device configuration info->asic_count = h->chip_address; info->core_count = h->core_address; info->device_type = (uint8_t)h->hdata; info->ref_frequency = (uint8_t)(h->hdata >> 8); info->hash_sequence_head = 0; info->hash_sequence_tail = 0; info->device_sequence_tail = 0; // Size in bytes of the core bitmap in bytes info->core_bitmap_size = (((info->asic_count * info->core_count) + 31) / 32) * 4; // Get the usb_init_base structure if (!hfa_get_data(hashfast, (char *)&info->usb_init_base, U32SIZE(info->usb_init_base))) { applog(LOG_WARNING, "HFA %d: OP_USB_INIT failed! Failure to get usb_init_base data", hashfast->device_id); return false; } db = &info->usb_init_base; applog(LOG_INFO, "HFA %d: firmware_rev: %d.%d", hashfast->device_id, (db->firmware_rev >> 8) & 0xff, db->firmware_rev & 0xff); applog(LOG_INFO, "HFA %d: hardware_rev: %d.%d", hashfast->device_id, (db->hardware_rev >> 8) & 0xff, db->hardware_rev & 0xff); applog(LOG_INFO, "HFA %d: serial number: %d", hashfast->device_id, db->serial_number); applog(LOG_INFO, "HFA %d: hash clockrate: %d Mhz", hashfast->device_id, db->hash_clockrate); applog(LOG_INFO, "HFA %d: inflight_target: %d", hashfast->device_id, db->inflight_target); applog(LOG_INFO, "HFA %d: sequence_modulus: %d", hashfast->device_id, db->sequence_modulus); info->num_sequence = db->sequence_modulus; // Now a copy of the config data used if (!hfa_get_data(hashfast, (char *)&info->config_data, U32SIZE(info->config_data))) { applog(LOG_WARNING, "HFA %d: OP_USB_INIT failed! Failure to get config_data", hashfast->device_id); return false; } // Now the core bitmap info->core_bitmap = malloc(info->core_bitmap_size); if (!info->core_bitmap) quit(1, "Failed to malloc info core bitmap in hfa_reset"); if (!hfa_get_data(hashfast, (char *)info->core_bitmap, info->core_bitmap_size / 4)) { applog(LOG_WARNING, "HFA %d: OP_USB_INIT failed! Failure to get core_bitmap", hashfast->device_id); return false; } // See if the initialization suceeded if (db->operation_status) { applog(LOG_WARNING, "HFA %d: OP_USB_INIT failed! Operation status %d (%s)", hashfast->device_id, db->operation_status, (db->operation_status < sizeof(hf_usb_init_errors)/sizeof(hf_usb_init_errors[0])) ? hf_usb_init_errors[db->operation_status] : "Unknown error code"); return false; } return true; }