static void hfa_statline_before(char *buf, size_t bufsiz, struct cgpu_info *hashfast) { struct hashfast_info *info = hashfast->device_data; double max_temp, max_volt; struct hf_g1_die_data *d; int i; max_temp = max_volt = 0.0; for (i = 0; i < info->asic_count; i++) { double temp; int j; d = &info->die_status[i]; temp = GN_DIE_TEMPERATURE(d->die.die_temperature); if (temp > max_temp) max_temp = temp; for (j = 0; j < 6; j++) { double volt = GN_CORE_VOLTAGE(d->die.core_voltage[j]); if (volt > max_volt) max_volt = volt; } } tailsprintf(buf, bufsiz, " max%3.0fC %3.2fV | ", max_temp, max_volt); }
static void hfa_update_die_status(struct cgpu_info *hashfast, struct hashfast_info *info, struct hf_header *h) { struct hf_g1_die_data *d = (struct hf_g1_die_data *)(h + 1), *ds; int num_included = (h->data_length * 4) / sizeof(struct hf_g1_die_data); int i, j; float die_temperature; float core_voltage[6]; if (info->device_type == HFD_G1) { // Copy in the data. They're numbered sequentially from the starting point ds = info->die_status + h->chip_address; for (i = 0; i < num_included; i++) memcpy(ds++, d++, sizeof(struct hf_g1_die_data)); for (i = 0, d = &info->die_status[h->chip_address]; i < num_included; i++, d++) { die_temperature = GN_DIE_TEMPERATURE(d->die.die_temperature); for (j = 0; j < 6; j++) core_voltage[j] = GN_CORE_VOLTAGE(d->die.core_voltage[j]); applog(LOG_DEBUG, "HFA %d: die %2d: OP_DIE_STATUS Die temp %.2fC vdd's %.2f %.2f %.2f %.2f %.2f %.2f", hashfast->device_id, h->chip_address + i, die_temperature, core_voltage[0], core_voltage[1], core_voltage[2], core_voltage[3], core_voltage[4], core_voltage[5]); // XXX Convert board phase currents, voltage, temperature } } }
static void packetRx(void *user, hfPacketT *packet) { switch (packet->h.h.operation_code) { case OP_STATUS: printf("op_status die %u\n", (unsigned int) packet->h.h.chip_address); printf(" temperature %5.1f voltage %5.3f\n", (double) GN_DIE_TEMPERATURE( packet->d.opStatus.monitor.die_temperature), (double) GN_CORE_VOLTAGE( packet->d.opStatus.monitor.core_voltage[0])); break; case OP_CONFIG: printf("op_config\n"); break; case OP_USB_INIT: printf("op_usb_init\n"); break; case OP_GWQ_STATUS: printf("op_gwq_status\n"); break; case OP_DIE_STATUS: printf("op_die_status: die %2u\n", (unsigned int) packet->h.h.chip_address); printf(" temperature %5.1f voltage %5.3f\n", (double) GN_DIE_TEMPERATURE( packet->d.opDieStatus.die.die_temperature), (double) GN_CORE_VOLTAGE( packet->d.opDieStatus.die.core_voltage[0])); break; case OP_USB_NOTICE: packet->d.b[packet->h.h.data_length * 4] = '\0'; printf("op_usb_notice: \"%s\"\n", &packet->d.b[4]); break; default: puts("packet rx:"); dumpBytes(&packet->h.b[0], 8 + packet->h.h.data_length * 4); break; } }
static void hfa_update_die_status(struct cgpu_info *hashfast, struct hashfast_info *info, struct hf_header *h) { struct hf_g1_die_data *d = (struct hf_g1_die_data *)(h + 1), *ds; int num_included = (h->data_length * 4) / sizeof(struct hf_g1_die_data); int i, j, die = h->chip_address; float die_temperature; float core_voltage[6]; // Copy in the data. They're numbered sequentially from the starting point ds = info->die_status + h->chip_address; for (i = 0; i < num_included; i++) memcpy(ds++, d++, sizeof(struct hf_g1_die_data)); for (i = 0, d = &info->die_status[h->chip_address]; i < num_included; i++, d++) { die += i; die_temperature = GN_DIE_TEMPERATURE(d->die.die_temperature); /* Sanity checking */ if (unlikely(die_temperature > 255)) die_temperature = info->die_data[die].temp; info->die_data[die].temp = die_temperature; for (j = 0; j < 6; j++) core_voltage[j] = GN_CORE_VOLTAGE(d->die.core_voltage[j]); applog(LOG_DEBUG, "%s %d: die %2d: OP_DIE_STATUS Temps die %.1fC board %.1fC vdd's %.2f %.2f %.2f %.2f %.2f %.2f", hashfast->drv->name, hashfast->device_id, die, die_temperature, board_temperature(d->temperature), core_voltage[0], core_voltage[1], core_voltage[2], core_voltage[3], core_voltage[4], core_voltage[5]); // XXX Convert board phase currents, voltage, temperature } if (die == info->asic_count - 1) { info->temp_updates++; /* We have a full set of die temperatures, find the highest * current die temp. */ die_temperature = 0; for (die = 0; die < info->asic_count; die++) { if (info->die_data[die].temp > die_temperature) die_temperature = info->die_data[die].temp; } /* Exponentially change the max_temp to smooth out troughs. */ info->max_temp = info->max_temp * 0.63 + die_temperature * 0.37; } if (unlikely(info->max_temp >= opt_hfa_overheat)) { /* -1 means new overheat condition */ if (!info->overheat) info->overheat = -1; } else if (unlikely(info->overheat && info->max_temp < opt_hfa_overheat - HFA_TEMP_HYSTERESIS)) info->overheat = 0; }
static void hfa_statline_before(char *buf, size_t bufsiz, struct cgpu_info *hashfast) { struct hashfast_info *info = hashfast->device_data; double max_temp, max_volt; struct hf_g1_die_data *d; int i; max_temp = max_volt = 0.0; for (i = 0; i < info->asic_count; i++) { double temp; int j; d = &info->die_status[i]; temp = GN_DIE_TEMPERATURE(d->die.die_temperature); /* Sanity check on temp since we change it lockless it can * rarely read a massive value */ if (temp > max_temp && temp < 200) max_temp = temp; for (j = 0; j < 6; j++) { double volt = GN_CORE_VOLTAGE(d->die.core_voltage[j]); if (volt > max_volt) max_volt = volt; } } tailsprintf(buf, bufsiz, " max%3.0fC %3.2fV | ", max_temp, max_volt); if (unlikely(max_temp >= opt_hfa_overheat)) { /* -1 means new overheat condition */ if (!info->overheat) info->overheat = -1; } else if (unlikely(info->overheat)) info->overheat = 0; }
static struct api_data *hfa_api_stats(struct cgpu_info *cgpu) { struct hashfast_info *info = cgpu->device_data; struct hf_long_usb_stats1 *s1; struct api_data *root = NULL; struct hf_usb_init_base *db; int varint, i; char buf[64]; root = api_add_int(root, "asic count", &info->asic_count, false); root = api_add_int(root, "core count", &info->core_count, false); db = &info->usb_init_base; sprintf(buf, "%d.%d", (db->firmware_rev >> 8) & 0xff, db->firmware_rev & 0xff); root = api_add_string(root, "firmware rev", buf, true); sprintf(buf, "%d.%d", (db->hardware_rev >> 8) & 0xff, db->hardware_rev & 0xff); root = api_add_string(root, "hardware rev", buf, true); varint = db->serial_number; root = api_add_int(root, "serial number", &varint, true); varint = db->hash_clockrate; root = api_add_int(root, "hash clockrate", &varint, true); varint = db->inflight_target; root = api_add_int(root, "inflight target", &varint, true); varint = db->sequence_modulus; root = api_add_int(root, "sequence modules", &varint, true); s1 = &info->stats1; root = api_add_uint64(root, "rx preambles", &s1->usb_rx_preambles, false); root = api_add_uint64(root, "rx rcv byte err", &s1->usb_rx_receive_byte_errors, false); root = api_add_uint64(root, "rx bad hcrc", &s1->usb_rx_bad_hcrc, false); root = api_add_uint64(root, "tx attempts", &s1->usb_tx_attempts, false); root = api_add_uint64(root, "tx packets", &s1->usb_tx_packets, false); root = api_add_uint64(root, "tx incompletes", &s1->usb_tx_incompletes, false); root = api_add_uint64(root, "tx ep stalled", &s1->usb_tx_endpointstalled, false); root = api_add_uint64(root, "tx disconnect", &s1->usb_tx_disconnected, false); root = api_add_uint64(root, "tx suspend", &s1->usb_tx_suspended, false); varint = s1->max_tx_buffers; root = api_add_int(root, "max tx buf", &varint, true); varint = s1->max_rx_buffers; root = api_add_int(root, "max rx buf", &varint, true); for (i = 0; i < info->asic_count; i++) { struct hf_long_statistics *l = &info->die_statistics[i]; struct hf_g1_die_data *d = &info->die_status[i]; double die_temp, core_voltage; int j; root = api_add_int(root, "Core", &i, true); die_temp = GN_DIE_TEMPERATURE(d->die.die_temperature); root = api_add_double(root, "die temperature", &die_temp, true); for (j = 0; j < 6; j++) { core_voltage = GN_CORE_VOLTAGE(d->die.core_voltage[j]); sprintf(buf, "%d: %.2f", j, core_voltage); root = api_add_string(root, "core voltage", buf, true); } root = api_add_uint64(root, "rx header crc", &l->rx_header_crc, false); root = api_add_uint64(root, "rx body crc", &l->rx_body_crc, false); root = api_add_uint64(root, "rx header to", &l->rx_header_timeouts, false); root = api_add_uint64(root, "rx body to", &l->rx_body_timeouts, false); root = api_add_uint64(root, "cn fifo full", &l->core_nonce_fifo_full, false); root = api_add_uint64(root, "an fifo full", &l->array_nonce_fifo_full, false); root = api_add_uint64(root, "stats overrun", &l->stats_overrun, false); } return root; }