/ driver-bitfury16.c
driver-bitfury16.c
1 #include "config.h" 2 3 #include "math.h" 4 #include "miner.h" 5 6 #include "bf16-communication.h" 7 #include "bf16-ctrldevice.h" 8 #include "bf16-mspcontrol.h" 9 #include "bf16-spidevice.h" 10 #include "bf16-uartdevice.h" 11 #include "driver-bitfury16.h" 12 13 #ifdef FILELOG 14 #define LOGFILE "/var/log/cgminer.log" 15 #endif 16 17 #define DISABLE_SEND_CMD_ERROR 18 19 #define POWER_WAIT_INTERVAL 100000 20 #define RENONCE_SEND 5 21 #define RENONCE_STAGE2_LIMIT 80 22 #define RENONCE_STAGE3_LIMIT 60 23 #define RENONCE_QUEUE_LEN 100 24 25 #define RENONCE_COUNT 29 26 27 /* chip nonce queue len */ 28 #define NONCE_CHIP_QUEUE_LEN 7 29 #define RENONCE_CHIP_QUEUE_LEN 40 30 31 #define WORK_TIMEOUT 2.0 32 33 /* statistics intervals */ 34 #define AVG_TIME_DELTA 5.0 35 #define AVG_TIME_INTERVAL 5.0 36 37 /* power chain alarm interval */ 38 #define ICHAIN_ALARM_INTERVAL 60 39 #define U_LOSS 0.2 40 41 /* power chain reenable timeout */ 42 #define CHAIN_REENABLE_INTERVAL 10 43 #define CHAIN_WORK_INTERVAL 1200 44 45 /* disable chip if no good nonces received during CHIP_FAILING_INTERVAL */ 46 #define RENONCE_CHIP_FAILING_INTERVAL 15.0 47 #define CHIP_FAILING_INTERVAL 30.0 48 #define CHIP_RECOVERY_INTERVAL 5.0 49 50 /* chip is considered to be failed after CHIP_ERROR_FAIL_LIMIT recovery attempts */ 51 #define CHIP_ERROR_FAIL_LIMIT 10 52 /* this value should be less than CHIP_ERROR_FAIL_LIMIT */ 53 #define RENONCE_CHIP_ERROR_FAIL_LIMIT 8 54 #define CHIP_ERROR_LIMIT 5 55 56 #define CHIP_TASK_STATUS_INTERVAL 7000 57 #define CHIP_TASK_SWITCH_INTERVAL 5000000 58 59 #define CHIP_RESTART_LIMIT 120 60 61 /* alarm intervals */ 62 #define LED_GREEN_INTERVAL 1000000 63 #define LED_RED_INTERVAL 1000000 64 #define LED_RED_NET_INTERVAL 500000 65 #define BUZZER_INTERVAL 1000000 66 67 /* threads delay */ 68 #define CHIPWORKER_DELAY 1000000 69 #define NONCEWORKER_DELAY 30000 70 #define RENONCEWORKER_DELAY 30000 71 #define HWMONITOR_DELAY 1000000 72 #define STATISTICS_DELAY 400000 73 #define ALARM_DELAY 500000 74 75 /* hold 3 works for each chip */ 76 #define WORK_QUEUE_LEN 3 * CHIPS_NUM 77 78 /* set clock to all chips and exit */ 79 bool opt_bf16_set_clock = false; 80 81 /* enable board mining statistics output */ 82 bool opt_bf16_stats_enabled = false; 83 84 /* disable automatic power management */ 85 bool opt_bf16_power_management_disabled = false; 86 87 /* renonce configuration */ 88 int opt_bf16_renonce = RENONCE_ONE_CHIP; 89 90 /* chip clock value */ 91 char* opt_bf16_clock = NULL; 92 uint8_t bf16_chip_clock = 0x32; 93 94 /* renonce chip clock value */ 95 char* opt_bf16_renonce_clock = NULL; 96 uint8_t bf16_renonce_chip_clock = 0x2d; 97 98 /* fan speed */ 99 int opt_bf16_fan_speed = -1; 100 101 /* target temp */ 102 int opt_bf16_target_temp = -1; 103 104 /* alarm temp */ 105 int opt_bf16_alarm_temp = -1; 106 107 /* test chip communication */ 108 char* opt_bf16_test_chip = NULL; 109 110 /* number of bits to fixate */ 111 static uint32_t mask_bits = 10; 112 113 /* default chip mask */ 114 static uint32_t mask = 0x00000000; 115 116 /* initial pid state */ 117 static bf_pid_t pid = { 118 .i_state = 0, 119 .i_max = 300, 120 .i_min = -10, 121 }; 122 123 #ifdef MINER_X5 124 bool opt_bf16_manual_pid_enabled = false; 125 bool manual_pid_enabled = false; 126 127 static bf_bcm250_map_t bcm250_map[CHIPBOARD_NUM][BCM250_NUM] = { 128 { 129 { 130 .channel_path = { BF250_LOCAL, BF250_NONE }, 131 .first_good_chip = 0, 132 .last_good_chip = BF16_NUM, 133 .chips_num = BF16_NUM 134 }, 135 { 136 .channel_path = { BF250_CHAN1, BF250_LOCAL }, 137 .first_good_chip = 7, 138 .last_good_chip = BF16_NUM, 139 .chips_num = 4 140 }, 141 { 142 .channel_path = { BF250_CHAN2, BF250_LOCAL }, 143 .first_good_chip = 0, 144 .last_good_chip = BF16_NUM, 145 .chips_num = BF16_NUM 146 } 147 }, 148 { 149 { 150 .channel_path = { BF250_LOCAL, BF250_NONE }, 151 .first_good_chip = 0, 152 .last_good_chip = BF16_NUM, 153 .chips_num = BF16_NUM 154 }, 155 { 156 .channel_path = { BF250_CHAN1, BF250_LOCAL }, 157 .first_good_chip = 7, 158 .last_good_chip = BF16_NUM, 159 .chips_num = 4 160 }, 161 { 162 .channel_path = { BF250_CHAN2, BF250_LOCAL }, 163 .first_good_chip = 0, 164 .last_good_chip = BF16_NUM, 165 .chips_num = BF16_NUM 166 } 167 } 168 }; 169 #endif 170 171 #ifdef MINER_X6 172 bool opt_bf16_manual_pid_disabled = false; 173 bool manual_pid_enabled = false; 174 175 static bf_bcm250_map_t bcm250_map[CHIPBOARD_NUM][BCM250_NUM] = { 176 { 177 { 178 .channel_path = { BF250_LOCAL, BF250_NONE, BF250_NONE, BF250_NONE }, 179 .first_good_chip = 0, 180 .last_good_chip = BF16_NUM, 181 .chips_num = BF16_NUM 182 }, 183 { 184 .channel_path = { BF250_CHAN1, BF250_LOCAL, BF250_NONE, BF250_NONE }, 185 .first_good_chip = 0, 186 .last_good_chip = BF16_NUM, 187 .chips_num = BF16_NUM 188 }, 189 { 190 .channel_path = { BF250_CHAN2, BF250_LOCAL, BF250_NONE, BF250_NONE }, 191 .first_good_chip = 0, 192 .last_good_chip = 4, 193 .chips_num = 4 194 }, 195 { 196 .channel_path = { BF250_CHAN2, BF250_CHAN2, BF250_LOCAL, BF250_NONE }, 197 .first_good_chip = 0, 198 .last_good_chip = BF16_NUM, 199 .chips_num = BF16_NUM 200 }, 201 { 202 .channel_path = { BF250_CHAN2, BF250_CHAN2, BF250_CHAN1, BF250_LOCAL }, 203 .first_good_chip = 0, 204 .last_good_chip = BF16_NUM, 205 .chips_num = BF16_NUM 206 }, 207 { 208 .channel_path = { BF250_CHAN2, BF250_CHAN2, BF250_CHAN2, BF250_LOCAL }, 209 .first_good_chip = 0, 210 .last_good_chip = 4, 211 .chips_num = 4 212 } 213 }, 214 { 215 { 216 .channel_path = { BF250_LOCAL, BF250_NONE, BF250_NONE, BF250_NONE }, 217 .first_good_chip = 0, 218 .last_good_chip = BF16_NUM, 219 .chips_num = BF16_NUM 220 }, 221 { 222 .channel_path = { BF250_CHAN1, BF250_LOCAL, BF250_NONE, BF250_NONE }, 223 .first_good_chip = 0, 224 .last_good_chip = BF16_NUM, 225 .chips_num = BF16_NUM 226 }, 227 { 228 .channel_path = { BF250_CHAN2, BF250_LOCAL, BF250_NONE, BF250_NONE }, 229 .first_good_chip = 0, 230 .last_good_chip = 4, 231 .chips_num = 4 232 }, 233 { 234 .channel_path = { BF250_CHAN2, BF250_CHAN2, BF250_LOCAL, BF250_NONE }, 235 .first_good_chip = 0, 236 .last_good_chip = BF16_NUM, 237 .chips_num = BF16_NUM 238 }, 239 { 240 .channel_path = { BF250_CHAN2, BF250_CHAN2, BF250_CHAN1, BF250_LOCAL }, 241 .first_good_chip = 0, 242 .last_good_chip = BF16_NUM, 243 .chips_num = BF16_NUM 244 }, 245 { 246 .channel_path = { BF250_CHAN2, BF250_CHAN2, BF250_CHAN2, BF250_LOCAL }, 247 .first_good_chip = 0, 248 .last_good_chip = 4, 249 .chips_num = 4 250 } 251 } 252 }; 253 #endif 254 255 /* each array element contains chip address assosiated to corresponting chipboard * 256 * e.g. first array element - renonce chip address for the first chipboard and so * 257 * on */ 258 static bf_chip_address_t renonce_chip_address[CHIPBOARD_NUM] = { 259 { 260 .board_id = 0, 261 .bcm250_id = 0, 262 .chip_id = 0 263 }, 264 { 265 .board_id = 1, 266 .bcm250_id = 0, 267 .chip_id = 0 268 } 269 }; 270 271 #ifdef FILELOG 272 static int filelog(struct bitfury16_info *info, const char* format, ...) 273 { 274 char fmt[1024]; 275 char datetime[64]; 276 struct timeval tv = {0, 0}; 277 struct tm *tm; 278 279 if (info->logfile == NULL) 280 return -1; 281 282 gettimeofday(&tv, NULL); 283 284 const time_t tmp_time = tv.tv_sec; 285 int ms = (int)(tv.tv_usec / 1000); 286 tm = localtime(&tmp_time); 287 288 snprintf(datetime, sizeof(datetime), " [%d-%02d-%02d %02d:%02d:%02d.%03d] ", 289 tm->tm_year + 1900, 290 tm->tm_mon + 1, 291 tm->tm_mday, 292 tm->tm_hour, 293 tm->tm_min, 294 tm->tm_sec, ms); 295 296 memset(fmt, 0, sizeof(fmt)); 297 sprintf(fmt, "%s%s\n", datetime, format); 298 299 va_list args; 300 va_start(args, format); 301 302 mutex_lock(&info->logfile_mutex); 303 vfprintf(info->logfile, fmt, args); 304 fflush(info->logfile); 305 mutex_unlock(&info->logfile_mutex); 306 307 va_end(args); 308 309 return 0; 310 } 311 #endif 312 313 static double timediff(struct timeval time1, struct timeval time2) 314 { 315 double time1_val = 1000000 * time1.tv_sec + time1.tv_usec; 316 double time2_val = 1000000 * time2.tv_sec + time2.tv_usec; 317 318 return (double)(time2_val - time1_val) / 1000000.0; 319 } 320 321 static uint32_t timediff_us(struct timeval time1, struct timeval time2) 322 { 323 uint32_t time1_val = 1000000 * time1.tv_sec + time1.tv_usec; 324 uint32_t time2_val = 1000000 * time2.tv_sec + time2.tv_usec; 325 326 return (time2_val - time1_val); 327 } 328 329 static void get_average(float* average, float delta, float time_diff, float interval) 330 { 331 float ftotal, fprop; 332 333 fprop = 1.0 - 1 / (exp((float)time_diff/(float)interval)); 334 ftotal = 1.0 + fprop; 335 *average += (delta / time_diff * fprop); 336 *average /= ftotal; 337 } 338 339 static uint8_t renonce_chip(bf_chip_address_t chip_address) 340 { 341 uint8_t board_id = chip_address.board_id; 342 343 if ((renonce_chip_address[board_id].bcm250_id == chip_address.bcm250_id) && 344 (renonce_chip_address[board_id].chip_id == chip_address.chip_id)) 345 return 1; 346 347 return 0; 348 } 349 350 static void get_next_chip_address(struct bitfury16_info *info, bf_chip_address_t* chip_address) 351 { 352 uint8_t board_id = chip_address->board_id; 353 uint8_t bcm250_id = chip_address->bcm250_id; 354 uint8_t chip_id = chip_address->chip_id; 355 356 uint8_t last_good_chip = info->chipboard[board_id].bcm250[bcm250_id].last_good_chip - 1; 357 if (last_good_chip == chip_id) { 358 #ifdef MINER_X5 359 bcm250_id = (bcm250_id + 1) % BCM250_NUM; 360 chip_id = info->chipboard[board_id].bcm250[bcm250_id].first_good_chip; 361 #endif 362 363 #ifdef MINER_X6 364 if (opt_bf16_power_management_disabled == false) { 365 bcm250_id = (bcm250_id + 1) % BCM250_NUM; 366 367 /* do not set bcm250_id to disabled chain */ 368 /* second power chain disabled */ 369 if ((info->chipboard[board_id].p_chain2_enabled == 0) && 370 (info->chipboard[board_id].power2_disabled == true) && 371 (bcm250_id >= BCM250_NUM / 2) && (bcm250_id < BCM250_NUM)) { 372 bcm250_id = 0; 373 } 374 375 chip_id = info->chipboard[board_id].bcm250[bcm250_id].first_good_chip; 376 } else { 377 chip_id = info->chipboard[board_id].bcm250[bcm250_id].first_good_chip; 378 } 379 #endif 380 } else 381 chip_id++; 382 383 chip_address->bcm250_id = bcm250_id; 384 chip_address->chip_id = chip_id; 385 } 386 387 static int8_t change_renonce_chip_address(struct cgpu_info *bitfury, bf_chip_address_t chip_address) 388 { 389 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 390 391 uint8_t board_id = chip_address.board_id; 392 uint8_t bcm250_id = chip_address.bcm250_id; 393 uint8_t chip_id = chip_address.chip_id; 394 395 bf_chip_address_t new_chip_address = { board_id, bcm250_id, chip_id }; 396 397 bool found = false; 398 uint8_t chip_count = 0; 399 while (true) { 400 get_next_chip_address(info, &new_chip_address); 401 chip_count++; 402 403 uint8_t new_board_id = new_chip_address.board_id; 404 uint8_t new_bcm250_id = new_chip_address.bcm250_id; 405 uint8_t new_chip_id = new_chip_address.chip_id; 406 407 /* enabled chip found */ 408 if (info->chipboard[new_board_id].bcm250[new_bcm250_id].chips[new_chip_id].status != DISABLED) { 409 found = true; 410 break; 411 } 412 413 /* we have run full loop chipboard */ 414 #ifdef MINER_X5 415 if (chip_count == info->chipboard[board_id].chips_num) 416 break; 417 #endif 418 419 #ifdef MINER_X6 420 if (opt_bf16_power_management_disabled == false) { 421 if ((info->chipboard[board_id].p_chain2_enabled == 0) && 422 (info->chipboard[board_id].power2_disabled == true)) { 423 if (chip_count == info->chipboard[board_id].chips_num / 2) 424 break; 425 } else { 426 if (chip_count == info->chipboard[board_id].chips_num) 427 break; 428 } 429 } else { 430 if (chip_count == info->chipboard[board_id].chips_num) 431 break; 432 } 433 #endif 434 } 435 436 if ((found == true) && 437 (memcmp(&new_chip_address, &renonce_chip_address[board_id], sizeof(bf_chip_address_t)) != 0)) { 438 board_id = new_chip_address.board_id; 439 bcm250_id = new_chip_address.bcm250_id; 440 chip_id = new_chip_address.chip_id; 441 442 renonce_chip_address[board_id].bcm250_id = bcm250_id; 443 renonce_chip_address[board_id].chip_id = chip_id; 444 445 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = UNINITIALIZED; 446 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_nonce_time = time(NULL); 447 gettimeofday(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_time, NULL); 448 449 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count = 0; 450 451 applog(LOG_NOTICE, "%s: changed renonce chip address to: [%d:%d:%2d]", 452 bitfury->drv->name, 453 board_id, bcm250_id, chip_id); 454 455 #ifdef FILELOG 456 filelog(info, "%s: changed renonce chip address to: [%d:%d:%2d]", 457 bitfury->drv->name, 458 board_id, bcm250_id, chip_id); 459 #endif 460 461 return 0; 462 } else { 463 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = DISABLED; 464 465 applog(LOG_NOTICE, "%s: failed to find working renonce chip. disabling...", 466 bitfury->drv->name); 467 468 #ifdef FILELOG 469 filelog(info, "%s: failed to find working renonce chip. disabling...", 470 bitfury->drv->name); 471 #endif 472 473 return -1; 474 } 475 } 476 477 static void increase_good_nonces(struct bitfury16_info *info, bf_chip_address_t chip_address) 478 { 479 uint8_t board_id = chip_address.board_id; 480 uint8_t bcm250_id = chip_address.bcm250_id; 481 uint8_t chip_id = chip_address.chip_id; 482 483 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_good_dx++; 484 info->chipboard[board_id].bcm250[bcm250_id].nonces_good_dx++; 485 info->chipboard[board_id].nonces_good_dx++; 486 info->nonces_good_dx++; 487 } 488 489 static void increase_bad_nonces(struct bitfury16_info *info, bf_chip_address_t chip_address) 490 { 491 uint8_t board_id = chip_address.board_id; 492 uint8_t bcm250_id = chip_address.bcm250_id; 493 uint8_t chip_id = chip_address.chip_id; 494 495 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_bad_dx++; 496 info->chipboard[board_id].bcm250[bcm250_id].nonces_bad_dx++; 497 info->chipboard[board_id].nonces_bad_dx++; 498 info->nonces_bad_dx++; 499 } 500 501 static void increase_re_nonces(struct bitfury16_info *info, bf_chip_address_t chip_address) 502 { 503 uint8_t board_id = chip_address.board_id; 504 uint8_t bcm250_id = chip_address.bcm250_id; 505 uint8_t chip_id = chip_address.chip_id; 506 507 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_re_dx++; 508 info->chipboard[board_id].bcm250[bcm250_id].nonces_re_dx++; 509 info->chipboard[board_id].nonces_re_dx++; 510 info->nonces_re_dx++; 511 } 512 513 static void increase_re_good_nonces(struct bitfury16_info *info, bf_chip_address_t chip_address) 514 { 515 uint8_t board_id = chip_address.board_id; 516 uint8_t bcm250_id = chip_address.bcm250_id; 517 uint8_t chip_id = chip_address.chip_id; 518 519 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_re_good_dx++; 520 521 if (renonce_chip(chip_address) == 0) { 522 info->chipboard[board_id].bcm250[bcm250_id].nonces_re_good_dx++; 523 info->chipboard[board_id].nonces_re_good_dx++; 524 info->nonces_re_good_dx++; 525 } 526 } 527 528 static void increase_re_bad_nonces(struct bitfury16_info *info, bf_chip_address_t chip_address) 529 { 530 uint8_t board_id = chip_address.board_id; 531 uint8_t bcm250_id = chip_address.bcm250_id; 532 uint8_t chip_id = chip_address.chip_id; 533 534 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_re_bad_dx++; 535 536 if (renonce_chip(chip_address) == 0) { 537 info->chipboard[board_id].bcm250[bcm250_id].nonces_re_bad_dx++; 538 info->chipboard[board_id].nonces_re_bad_dx++; 539 info->nonces_re_bad_dx++; 540 } 541 } 542 543 static void increase_total_nonces(struct bitfury16_info *info, bf_chip_address_t chip_address) 544 { 545 uint8_t board_id = chip_address.board_id; 546 uint8_t bcm250_id = chip_address.bcm250_id; 547 uint8_t chip_id = chip_address.chip_id; 548 549 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_dx++; 550 551 if ((renonce_chip(chip_address) == 0) || 552 (opt_bf16_renonce == RENONCE_DISABLED)) { 553 info->chipboard[board_id].bcm250[bcm250_id].nonces_dx++; 554 info->chipboard[board_id].nonces_dx++; 555 info->nonces_dx++; 556 } 557 } 558 559 static void increase_task_switch(struct bitfury16_info *info, bf_chip_address_t chip_address) 560 { 561 uint8_t board_id = chip_address.board_id; 562 uint8_t bcm250_id = chip_address.bcm250_id; 563 uint8_t chip_id = chip_address.chip_id; 564 565 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].task_switch_dx++; 566 info->chipboard[board_id].bcm250[bcm250_id].task_switch_dx++; 567 info->chipboard[board_id].task_switch_dx++; 568 info->task_switch_dx++; 569 } 570 571 static void increase_errors(struct bitfury16_info *info, bf_chip_address_t chip_address) 572 { 573 uint8_t board_id = chip_address.board_id; 574 uint8_t bcm250_id = chip_address.bcm250_id; 575 uint8_t chip_id = chip_address.chip_id; 576 577 /* update timing interval */ 578 time_t curr_time = time(NULL); 579 if (curr_time - info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_error_time <= 1) 580 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate++; 581 else 582 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate = 0; 583 584 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_error_time = curr_time; 585 586 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].errors++; 587 588 if ((renonce_chip(chip_address) == 0) || 589 (opt_bf16_renonce == RENONCE_DISABLED)) 590 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = UNINITIALIZED; 591 592 /* mark chip as FAILING if error rate too high*/ 593 if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate >= CHIP_ERROR_LIMIT) { 594 #ifdef FILELOG 595 filelog(info, "BF16: chip [%d:%d:%2d] error rate too high: [%d], " 596 "marked as failing, recovery_count: [%d]", 597 board_id, bcm250_id, chip_id, 598 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate, 599 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count); 600 #endif 601 602 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = FAILING; 603 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate = 0; 604 } 605 } 606 607 static uint8_t* init_channel_path(uint8_t board_id, uint8_t btc250_num, uint8_t* channel_depth, uint8_t channel_length) 608 { 609 uint8_t i, j; 610 uint8_t* channel_path = cgcalloc(channel_length, sizeof(uint8_t)); 611 612 for (i = 0, j = 0; i < CHANNEL_DEPTH; i++) { 613 if (bcm250_map[board_id][btc250_num].channel_path[i] != BF250_NONE) 614 (*channel_depth)++; 615 616 int8_t shift = 8*(j + 1) - 3*(i + 1); 617 if (shift < 0) { 618 channel_path[j] |= bcm250_map[board_id][btc250_num].channel_path[i] >> abs(shift); 619 channel_path[j + 1] |= bcm250_map[board_id][btc250_num].channel_path[i] << (8 - abs(shift)); 620 j++; 621 } else 622 channel_path[j] |= bcm250_map[board_id][btc250_num].channel_path[i] << shift; 623 } 624 625 return channel_path; 626 } 627 628 static int8_t parse_chip_address(struct cgpu_info *bitfury, char* address, bf_chip_address_t* chip_address) 629 { 630 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 631 632 int8_t board_id = 0; 633 int8_t bcm250_id = 0; 634 int8_t chip_id = 0; 635 636 char buff[16]; 637 638 if (address == NULL) 639 return -1; 640 641 /* board_id */ 642 char* start = strchr(address, '['); 643 char* end = strchr(address, ':'); 644 if ((start == NULL) || (end == NULL)) 645 return -1; 646 uint8_t len = end - start; 647 648 memset(buff, 0, sizeof(buff)); 649 cg_memcpy(buff, start + 1, len); 650 board_id = atoi(buff); 651 652 /* bcm250_id */ 653 start = end; 654 end = strchr(start + 1, ':'); 655 if (end == NULL) 656 return -1; 657 len = end - start; 658 659 memset(buff, 0, sizeof(buff)); 660 cg_memcpy(buff, start + 1, len); 661 bcm250_id = atoi(buff); 662 663 /* chip_id */ 664 start = end; 665 end = strchr(start + 1, ']'); 666 if (end == NULL) 667 return -1; 668 len = end - start; 669 670 memset(buff, 0, sizeof(buff)); 671 cg_memcpy(buff, start + 1, len); 672 chip_id = atoi(buff); 673 674 if ((board_id < 0) || (board_id >= CHIPBOARD_NUM)) { 675 applog(LOG_ERR, "%s: invalid board_id %d: [0 - %d] specified", 676 bitfury->drv->name, 677 board_id, CHIPBOARD_NUM); 678 return -1; 679 } 680 681 if ((bcm250_id < 0) || (bcm250_id >= BCM250_NUM)) { 682 applog(LOG_ERR, "%s: invalid bcm250_id %d: [0 - %d] specified", 683 bitfury->drv->name, 684 bcm250_id, BCM250_NUM); 685 return -1; 686 } 687 688 689 uint8_t first_good_chip = info->chipboard[board_id].bcm250[bcm250_id].first_good_chip; 690 uint8_t last_good_chip = info->chipboard[board_id].bcm250[bcm250_id].last_good_chip; 691 692 if ((chip_id >= first_good_chip) && (chip_id < last_good_chip)) { 693 chip_address->board_id = board_id; 694 chip_address->bcm250_id = bcm250_id; 695 chip_address->chip_id = chip_id; 696 } else { 697 applog(LOG_ERR, "%s: invalid chip_id %d: [%d - %d] specified", 698 bitfury->drv->name, 699 chip_id, first_good_chip, last_good_chip); 700 return -1; 701 } 702 703 applog(LOG_NOTICE, "%s: parsed chip address: [%d:%d:%2d]", 704 bitfury->drv->name, 705 chip_address->board_id, 706 chip_address->bcm250_id, 707 chip_address->chip_id); 708 709 return 0; 710 } 711 712 static void update_bcm250_map(struct cgpu_info *bitfury, uint8_t board_id) 713 { 714 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 715 716 #ifdef MINER_X5 717 info->chipboard[board_id].board_type = CHIPBOARD_X5; 718 719 switch (info->chipboard[board_id].board_ver) { 720 /* 23 chip board version */ 721 case 5: 722 info->chipboard[board_id].board_rev = CHIPBOARD_REV2; 723 724 bcm250_map[board_id][0].last_good_chip = BF16_NUM - 2; 725 bcm250_map[board_id][0].chips_num = BF16_NUM - 2; 726 727 bcm250_map[board_id][1].first_good_chip = 6; 728 bcm250_map[board_id][1].chips_num = 5; 729 730 bcm250_map[board_id][2].last_good_chip = BF16_NUM - 2; 731 bcm250_map[board_id][2].chips_num = BF16_NUM - 2; 732 break; 733 734 /* 24 chip board version */ 735 case 7: 736 info->chipboard[board_id].board_rev = CHIPBOARD_REV2; 737 738 bcm250_map[board_id][0].last_good_chip = BF16_NUM - 2; 739 bcm250_map[board_id][0].chips_num = BF16_NUM - 2; 740 741 bcm250_map[board_id][1].first_good_chip = 6; 742 bcm250_map[board_id][1].chips_num = 5; 743 744 bcm250_map[board_id][2].last_good_chip = BF16_NUM - 1; 745 bcm250_map[board_id][2].chips_num = BF16_NUM - 1; 746 break; 747 748 /* 25 chip board version */ 749 case 9: 750 info->chipboard[board_id].board_rev = CHIPBOARD_REV2; 751 752 bcm250_map[board_id][0].last_good_chip = BF16_NUM - 1; 753 bcm250_map[board_id][0].chips_num = BF16_NUM - 1; 754 755 bcm250_map[board_id][1].first_good_chip = 6; 756 bcm250_map[board_id][1].chips_num = 5; 757 758 bcm250_map[board_id][2].last_good_chip = BF16_NUM - 1; 759 bcm250_map[board_id][2].chips_num = BF16_NUM - 1; 760 break; 761 762 /* 26 chip board version */ 763 case 11: 764 info->chipboard[board_id].board_rev = CHIPBOARD_REV2; 765 766 bcm250_map[board_id][0].last_good_chip = BF16_NUM - 1; 767 bcm250_map[board_id][0].chips_num = BF16_NUM - 1; 768 769 bcm250_map[board_id][1].first_good_chip = 6; 770 bcm250_map[board_id][1].chips_num = 5; 771 break; 772 773 /* 27 chip board version */ 774 case 13: 775 info->chipboard[board_id].board_rev = CHIPBOARD_REV2; 776 777 bcm250_map[board_id][1].first_good_chip = 6; 778 bcm250_map[board_id][1].chips_num = 5; 779 break; 780 781 /* 26 chip board version - default */ 782 case 1: 783 case 2: 784 info->chipboard[board_id].board_rev = CHIPBOARD_REV1; 785 default: 786 break; 787 } 788 #endif 789 790 #ifdef MINER_X6 791 info->chipboard[board_id].board_type = CHIPBOARD_X6; 792 793 switch (info->chipboard[board_id].board_ver) { 794 /* 46 chip board version */ 795 case 4: 796 info->chipboard[board_id].board_rev = CHIPBOARD_REV2; 797 798 bcm250_map[board_id][0].last_good_chip = BF16_NUM - 2; 799 bcm250_map[board_id][0].chips_num = BF16_NUM - 2; 800 801 bcm250_map[board_id][1].first_good_chip = 1; 802 bcm250_map[board_id][1].last_good_chip = BF16_NUM - 1; 803 bcm250_map[board_id][1].chips_num = BF16_NUM - 2; 804 805 bcm250_map[board_id][2].last_good_chip = 5; 806 bcm250_map[board_id][2].chips_num = 5; 807 808 bcm250_map[board_id][3].last_good_chip = BF16_NUM - 2; 809 bcm250_map[board_id][3].chips_num = BF16_NUM - 2; 810 811 bcm250_map[board_id][4].first_good_chip = 1; 812 bcm250_map[board_id][4].last_good_chip = BF16_NUM - 1; 813 bcm250_map[board_id][4].chips_num = BF16_NUM - 1; 814 815 bcm250_map[board_id][5].last_good_chip = 5; 816 bcm250_map[board_id][5].chips_num = 5; 817 break; 818 819 /* 48 chip board version */ 820 case 6: 821 info->chipboard[board_id].board_rev = CHIPBOARD_REV2; 822 823 bcm250_map[board_id][0].last_good_chip = BF16_NUM - 1; 824 bcm250_map[board_id][0].chips_num = BF16_NUM - 1; 825 826 bcm250_map[board_id][1].first_good_chip = 1; 827 bcm250_map[board_id][1].last_good_chip = BF16_NUM - 1; 828 bcm250_map[board_id][1].chips_num = BF16_NUM - 2; 829 830 bcm250_map[board_id][2].last_good_chip = 5; 831 bcm250_map[board_id][2].chips_num = 5; 832 833 bcm250_map[board_id][3].last_good_chip = BF16_NUM - 1; 834 bcm250_map[board_id][3].chips_num = BF16_NUM - 1; 835 836 bcm250_map[board_id][4].first_good_chip = 1; 837 bcm250_map[board_id][4].last_good_chip = BF16_NUM - 1; 838 bcm250_map[board_id][4].chips_num = BF16_NUM - 1; 839 840 bcm250_map[board_id][5].last_good_chip = 5; 841 bcm250_map[board_id][5].chips_num = 5; 842 break; 843 844 /* 50 chip board version */ 845 case 8: 846 info->chipboard[board_id].board_rev = CHIPBOARD_REV2; 847 848 bcm250_map[board_id][0].last_good_chip = BF16_NUM - 1; 849 bcm250_map[board_id][0].chips_num = BF16_NUM - 1; 850 851 bcm250_map[board_id][1].last_good_chip = BF16_NUM - 1; 852 bcm250_map[board_id][1].chips_num = BF16_NUM - 1; 853 854 bcm250_map[board_id][2].last_good_chip = 5; 855 bcm250_map[board_id][2].chips_num = 5; 856 857 bcm250_map[board_id][3].last_good_chip = BF16_NUM - 1; 858 bcm250_map[board_id][3].chips_num = BF16_NUM - 1; 859 860 bcm250_map[board_id][4].last_good_chip = BF16_NUM - 1; 861 bcm250_map[board_id][4].chips_num = BF16_NUM - 1; 862 863 bcm250_map[board_id][5].last_good_chip = 5; 864 bcm250_map[board_id][5].chips_num = 5; 865 break; 866 867 /* 52 chip board version */ 868 case 10: 869 info->chipboard[board_id].board_rev = CHIPBOARD_REV2; 870 871 bcm250_map[board_id][1].last_good_chip = BF16_NUM - 1; 872 bcm250_map[board_id][1].chips_num = BF16_NUM - 1; 873 874 bcm250_map[board_id][2].last_good_chip = 5; 875 bcm250_map[board_id][2].chips_num = 5; 876 877 bcm250_map[board_id][4].last_good_chip = BF16_NUM - 1; 878 bcm250_map[board_id][4].chips_num = BF16_NUM - 1; 879 880 bcm250_map[board_id][5].last_good_chip = 5; 881 bcm250_map[board_id][5].chips_num = 5; 882 break; 883 884 /* 54 chip board version */ 885 case 12: 886 info->chipboard[board_id].board_rev = CHIPBOARD_REV2; 887 888 bcm250_map[board_id][2].last_good_chip = 5; 889 bcm250_map[board_id][2].chips_num = 5; 890 891 bcm250_map[board_id][5].last_good_chip = 5; 892 bcm250_map[board_id][5].chips_num = 5; 893 break; 894 895 /* 46 chip board version */ 896 case 14:; 897 info->chipboard[board_id].board_rev = CHIPBOARD_REV3; 898 899 uint8_t bcm250_channel_path[3][CHANNEL_DEPTH] = { 900 { BF250_CHAN1, BF250_CHAN1, BF250_LOCAL, BF250_NONE }, 901 { BF250_CHAN1, BF250_CHAN1, BF250_CHAN1, BF250_LOCAL }, 902 { BF250_CHAN1, BF250_CHAN1, BF250_CHAN2, BF250_LOCAL }, 903 }; 904 905 bcm250_map[board_id][0].first_good_chip = 0; 906 bcm250_map[board_id][0].last_good_chip = 1; 907 bcm250_map[board_id][0].chips_num = 1; 908 909 bcm250_map[board_id][2].first_good_chip = 0; 910 bcm250_map[board_id][2].last_good_chip = BF16_NUM; 911 bcm250_map[board_id][2].chips_num = BF16_NUM; 912 913 bcm250_map[board_id][3].first_good_chip = 0; 914 bcm250_map[board_id][3].last_good_chip = 1; 915 bcm250_map[board_id][3].chips_num = 1; 916 cg_memcpy(bcm250_map[board_id][3].channel_path, bcm250_channel_path[0], sizeof(bcm250_map[board_id][3].channel_path)); 917 918 cg_memcpy(bcm250_map[board_id][4].channel_path, bcm250_channel_path[1], sizeof(bcm250_map[board_id][4].channel_path)); 919 920 bcm250_map[board_id][5].first_good_chip = 0; 921 bcm250_map[board_id][5].last_good_chip = BF16_NUM; 922 bcm250_map[board_id][5].chips_num = BF16_NUM; 923 cg_memcpy(bcm250_map[board_id][5].channel_path, bcm250_channel_path[2], sizeof(bcm250_map[board_id][5].channel_path)); 924 break; 925 926 /* 52 chip board version - default */ 927 case 3: 928 info->chipboard[board_id].board_rev = CHIPBOARD_REV1; 929 default: 930 break; 931 } 932 #endif 933 } 934 935 static void reinit_x5(struct bitfury16_info *info, bool chip_reinit) 936 { 937 uint8_t board_id, bcm250_id, chip_id; 938 939 /* reinit board chips */ 940 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 941 for (bcm250_id = 0; bcm250_id < BCM250_NUM; bcm250_id++) { 942 uint8_t first_good_chip = info->chipboard[board_id].bcm250[bcm250_id].first_good_chip; 943 uint8_t last_good_chip = info->chipboard[board_id].bcm250[bcm250_id].last_good_chip; 944 945 for (chip_id = first_good_chip; chip_id < last_good_chip; chip_id++) { 946 if (chip_reinit == true) { 947 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count = 0; 948 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate = 0; 949 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = UNINITIALIZED; 950 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_nonce_time = time(NULL); 951 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_error_time = time(NULL); 952 gettimeofday(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_time, NULL); 953 gettimeofday(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].switch_time, NULL); 954 } else { 955 if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count < CHIP_ERROR_FAIL_LIMIT) 956 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = UNINITIALIZED; 957 } 958 959 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_nonce_time = time(NULL); 960 gettimeofday(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_time, NULL); 961 gettimeofday(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].switch_time, NULL); 962 } 963 } 964 } 965 966 /* send reset to all boards */ 967 spi_emit_reset(SPI_CHANNEL1); 968 spi_emit_reset(SPI_CHANNEL2); 969 } 970 971 static void init_x5(struct cgpu_info *bitfury) 972 { 973 uint8_t board_id, bcm250_id, chip_id; 974 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 975 976 info->chipboard = cgcalloc(CHIPBOARD_NUM, sizeof(bf_chipboard_t)); 977 978 /* channel size in bytes */ 979 info->channel_length = (CHANNEL_DEPTH * 3) / 8 + 1; 980 info->ialarm_count = 1; 981 982 info->work_list = workd_list_init(); 983 info->stale_work_list = workd_list_init(); 984 985 info->noncework_list = noncework_list_init(); 986 987 if (opt_bf16_renonce != RENONCE_DISABLED) { 988 info->renoncework_list = renoncework_list_init(); 989 info->renonce_id = 1; 990 info->renonce_list = renonce_list_init(); 991 } 992 993 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 994 /* detect board */ 995 char buff[256]; 996 memset(buff, 0, sizeof(buff)); 997 998 device_ctrl_txrx(board_id + 1, 0, F_BDET, buff); 999 parse_board_detect(bitfury, board_id, buff); 1000 1001 if (info->chipboard[board_id].detected == true) { 1002 applog(LOG_NOTICE, "%s: BOARD%d detected", bitfury->drv->name, board_id + 1); 1003 1004 info->chipboard[board_id].bcm250 = cgcalloc(BCM250_NUM, sizeof(bf_bcm250_t)); 1005 cmd_buffer_init(&info->chipboard[board_id].cmd_buffer); 1006 1007 get_board_info(bitfury, board_id); 1008 update_bcm250_map(bitfury, board_id); 1009 1010 info->chipboard_num++; 1011 info->chipboard[board_id].bcm250_num = BCM250_NUM; 1012 1013 cg_memcpy(&info->chipboard[board_id].pid, &pid, sizeof(bf_pid_t)); 1014 1015 uint8_t chips_num = 0; 1016 for (bcm250_id = 0; bcm250_id < BCM250_NUM; bcm250_id++) { 1017 info->chipboard[board_id].bcm250[bcm250_id].channel_path = init_channel_path(board_id, bcm250_id, 1018 &info->chipboard[board_id].bcm250[bcm250_id].channel_depth, info->channel_length); 1019 info->chipboard[board_id].bcm250[bcm250_id].first_good_chip = bcm250_map[board_id][bcm250_id].first_good_chip; 1020 info->chipboard[board_id].bcm250[bcm250_id].last_good_chip = bcm250_map[board_id][bcm250_id].last_good_chip; 1021 info->chipboard[board_id].bcm250[bcm250_id].chips_num = bcm250_map[board_id][bcm250_id].chips_num; 1022 chips_num += bcm250_map[board_id][bcm250_id].chips_num; 1023 1024 uint8_t first_good_chip = info->chipboard[board_id].bcm250[bcm250_id].first_good_chip; 1025 uint8_t last_good_chip = info->chipboard[board_id].bcm250[bcm250_id].last_good_chip; 1026 1027 for (chip_id = first_good_chip; chip_id < last_good_chip; chip_id++) { 1028 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = UNINITIALIZED; 1029 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_nonce_time = time(NULL); 1030 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonce_list = nonce_list_init(); 1031 gettimeofday(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_time, NULL); 1032 gettimeofday(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].switch_time, NULL); 1033 } 1034 } 1035 1036 info->chipboard[board_id].chips_num = chips_num; 1037 info->chips_num += info->chipboard[board_id].chips_num; 1038 } else 1039 applog(LOG_NOTICE, "%s: BOARD%d not found", bitfury->drv->name, board_id + 1); 1040 1041 applog(LOG_INFO, "%s: initialized board X5.%d", bitfury->drv->name, board_id); 1042 } 1043 1044 applog(LOG_INFO, "%s: initialized X5", bitfury->drv->name); 1045 } 1046 1047 static void deinit_x5(struct cgpu_info *bitfury) 1048 { 1049 uint8_t board_id, bcm250_id, chip_id; 1050 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 1051 1052 workd_list_deinit(info->work_list, bitfury); 1053 workd_list_deinit(info->stale_work_list, bitfury); 1054 1055 noncework_list_deinit(info->noncework_list); 1056 1057 if (opt_bf16_renonce != RENONCE_DISABLED) { 1058 renoncework_list_deinit(info->renoncework_list); 1059 info->renonce_id = 1; 1060 renonce_list_deinit(info->renonce_list); 1061 } 1062 1063 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 1064 for (bcm250_id = 0; bcm250_id < BCM250_NUM; bcm250_id++) { 1065 free(info->chipboard[board_id].bcm250[bcm250_id].channel_path); 1066 1067 uint8_t first_good_chip = info->chipboard[board_id].bcm250[bcm250_id].first_good_chip; 1068 uint8_t last_good_chip = info->chipboard[board_id].bcm250[bcm250_id].last_good_chip; 1069 1070 for (chip_id = first_good_chip; chip_id < last_good_chip; chip_id++) 1071 nonce_list_deinit(info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonce_list); 1072 } 1073 free(info->chipboard[board_id].bcm250); 1074 1075 cmd_buffer_deinit(&info->chipboard[board_id].cmd_buffer); 1076 } 1077 1078 free(info->chipboard); 1079 } 1080 1081 static void bitfury16_set_clock(struct cgpu_info *bitfury) 1082 { 1083 uint8_t board_id, bcm250_id, chip_id; 1084 struct bitfury16_info *info = (struct bitfury16_info *)bitfury->device_data; 1085 1086 /* send reset to all boards */ 1087 spi_emit_reset(SPI_CHANNEL1); 1088 spi_emit_reset(SPI_CHANNEL2); 1089 1090 /* board loop */ 1091 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 1092 applog(LOG_NOTICE, "%s: CHIPBOARD [%d]:", bitfury->drv->name, board_id); 1093 /* concentrator loop */ 1094 for (bcm250_id = 0; bcm250_id < BCM250_NUM; bcm250_id++) { 1095 applog(LOG_NOTICE, "%s: BCM250 [%d]:", bitfury->drv->name, bcm250_id); 1096 1097 spi_emit_reset(board_id + 1); 1098 1099 /* build channel */ 1100 create_channel(board_id + 1, info->chipboard[board_id].bcm250[bcm250_id].channel_path, info->channel_length); 1101 1102 uint8_t channel_depth = info->chipboard[board_id].bcm250[bcm250_id].channel_depth; 1103 uint8_t first_good_chip = info->chipboard[board_id].bcm250[bcm250_id].first_good_chip; 1104 uint8_t last_good_chip = info->chipboard[board_id].bcm250[bcm250_id].last_good_chip; 1105 1106 uint8_t result; 1107 bool fail; 1108 /* chips loop */ 1109 for (chip_id = first_good_chip; chip_id < last_good_chip; chip_id++) { 1110 fail = false; 1111 bf_chip_address_t chip_address = { board_id, bcm250_id, chip_id }; 1112 1113 result = send_toggle(board_id + 1, channel_depth, chip_address); 1114 if (result != 0) 1115 fail = true; 1116 1117 result = set_clock(board_id + 1, channel_depth, chip_address, bf16_chip_clock); 1118 if ((result != 0) && (fail != true)) 1119 fail = true; 1120 1121 if (fail == false) 1122 applog(LOG_NOTICE, "%s: CHIP [%2d]: OK", bitfury->drv->name, chip_id); 1123 else 1124 applog(LOG_NOTICE, "%s: CHIP [%2d]: FAIL", bitfury->drv->name, chip_id); 1125 } 1126 1127 /* destroy channel */ 1128 destroy_channel(board_id + 1, info->chipboard[board_id].bcm250[bcm250_id].channel_depth); 1129 } 1130 } 1131 1132 deinit_x5(bitfury); 1133 } 1134 1135 static void bitfury16_test_chip(struct cgpu_info *bitfury, bf_chip_address_t chip_address) 1136 { 1137 struct bitfury16_info *info = (struct bitfury16_info *)bitfury->device_data; 1138 1139 uint8_t board_id = chip_address.board_id; 1140 uint8_t bcm250_id = chip_address.bcm250_id; 1141 uint8_t chip_id = chip_address.chip_id; 1142 1143 /* send reset to board */ 1144 spi_emit_reset(board_id + 1); 1145 1146 /* build channel */ 1147 create_channel(board_id + 1, info->chipboard[board_id].bcm250[bcm250_id].channel_path, info->channel_length); 1148 1149 uint8_t channel_depth = info->chipboard[board_id].bcm250[bcm250_id].channel_depth; 1150 1151 uint8_t result; 1152 bool fail = false; 1153 1154 result = send_toggle(board_id + 1, channel_depth, chip_address); 1155 if (result != 0) 1156 fail = true; 1157 1158 result = set_clock(board_id + 1, channel_depth, chip_address, bf16_chip_clock); 1159 if ((result != 0) && (fail != true)) 1160 fail = true; 1161 1162 if (fail == false) 1163 applog(LOG_NOTICE, "%s: CHIP [%2d]: OK", bitfury->drv->name, chip_id); 1164 else 1165 applog(LOG_NOTICE, "%s: CHIP [%2d]: FAIL", bitfury->drv->name, chip_id); 1166 1167 /* destroy channel */ 1168 destroy_channel(board_id + 1, info->chipboard[board_id].bcm250[bcm250_id].channel_depth); 1169 1170 deinit_x5(bitfury); 1171 } 1172 1173 static void bitfury16_identify(__maybe_unused struct cgpu_info *bitfury) 1174 { 1175 } 1176 1177 static void set_fan_speed(struct cgpu_info *bitfury) 1178 { 1179 struct bitfury16_info *info = (struct bitfury16_info *)bitfury->device_data; 1180 uint8_t board_id; 1181 1182 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 1183 if (info->chipboard[board_id].detected == true) { 1184 if (opt_bf16_fan_speed == -1) { 1185 if (device_uart_transfer(board_id + 1, "F") < 0) 1186 quit(1, "%s: %s() failed to set BOARD%d fan speed", 1187 bitfury->drv->name, __func__, board_id + 1); 1188 1189 applog(LOG_INFO, "%s: set BOARD%d fan speed to auto mode", 1190 bitfury->drv->name, board_id + 1); 1191 } else { 1192 char uart_cmd[8]; 1193 sprintf(uart_cmd, "F:%d", opt_bf16_fan_speed); 1194 1195 if (device_uart_transfer(board_id + 1, uart_cmd) < 0) 1196 quit(1, "%s: %s() failed to set BOARD%d fan speed", 1197 bitfury->drv->name, __func__, board_id + 1); 1198 1199 applog(LOG_INFO, "%s: set BOARD%d fan speed to [%d]", 1200 bitfury->drv->name, board_id + 1, opt_bf16_fan_speed); 1201 } 1202 } 1203 } 1204 } 1205 1206 static void bitfury16_detect(bool hotplug) 1207 { 1208 struct cgpu_info *bitfury = NULL; 1209 struct bitfury16_info *info = NULL; 1210 uint8_t board_id, bcm250_id, chip_id; 1211 1212 if (hotplug) 1213 return; 1214 1215 bitfury = cgmalloc(sizeof(struct cgpu_info)); 1216 if (unlikely(!bitfury)) 1217 quit(1, "%s: %s() failed to malloc bitfury", 1218 bitfury->drv->name, __func__); 1219 1220 bitfury->drv = &bitfury16_drv; 1221 bitfury->deven = DEV_ENABLED; 1222 bitfury->threads = 1; 1223 1224 info = cgmalloc(sizeof(struct bitfury16_info)); 1225 if (unlikely(!info)) 1226 quit(1, "%s: %s() failed to malloc info", 1227 bitfury->drv->name, __func__); 1228 1229 bitfury->device_data = info; 1230 1231 /* manual PID option */ 1232 #ifdef MINER_X5 1233 manual_pid_enabled = opt_bf16_manual_pid_enabled; 1234 #endif 1235 1236 #ifdef MINER_X6 1237 manual_pid_enabled = !opt_bf16_manual_pid_disabled; 1238 #endif 1239 1240 /* renonce chip address and renonce chip clock */ 1241 if (opt_bf16_renonce != RENONCE_DISABLED) { 1242 if (opt_bf16_renonce_clock != NULL) 1243 bf16_renonce_chip_clock = strtol(opt_bf16_renonce_clock, NULL, 16); 1244 } else 1245 /* default chip clock if renonce is disabled */ 1246 bf16_chip_clock = 0x2d; 1247 1248 /* general chip clock */ 1249 if (opt_bf16_clock != NULL) 1250 bf16_chip_clock = strtol(opt_bf16_clock, NULL, 16); 1251 else if ((opt_bf16_set_clock == true) || (opt_bf16_test_chip != NULL)) 1252 /* default chip clock if set_clock option is set */ 1253 bf16_chip_clock = 0x20; 1254 1255 /* open devices */ 1256 if (open_spi_device(SPI_CHANNEL1) < 0) 1257 quit(1, "%s: %s() failed to open [%s] device", 1258 bitfury->drv->name, __func__, spi0_device_name); 1259 1260 applog(LOG_INFO, "%s: opened [%s] device", bitfury->drv->name, spi0_device_name); 1261 1262 if (open_spi_device(SPI_CHANNEL2) < 0) 1263 quit(1, "%s: %s() failed to open [%s] device", 1264 bitfury->drv->name, __func__, spi1_device_name); 1265 1266 applog(LOG_INFO, "%s: opened [%s] device", bitfury->drv->name, spi1_device_name); 1267 1268 if (open_ctrl_device() < 0) 1269 quit(1, "%s: %s() failed to open [%s] device", 1270 bitfury->drv->name, __func__, ctrl_device_name); 1271 1272 applog(LOG_INFO, "%s: opened [%s] device", bitfury->drv->name, ctrl_device_name); 1273 1274 if (open_uart_device(UART_CHANNEL1) < 0) 1275 quit(1, "%s: %s() failed to open [%s] device", 1276 bitfury->drv->name, __func__, uart1_device_name); 1277 1278 applog(LOG_INFO, "%s: opened [%s] device", bitfury->drv->name, uart1_device_name); 1279 1280 if (open_uart_device(UART_CHANNEL2) < 0) 1281 quit(1, "%s: %s() failed to open [%s] device", 1282 bitfury->drv->name, __func__, uart2_device_name); 1283 1284 applog(LOG_INFO, "%s: opened [%s] device", bitfury->drv->name, uart2_device_name); 1285 1286 init_x5(bitfury); 1287 1288 /* send reset to boards */ 1289 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 1290 if (info->chipboard[board_id].detected == true) { 1291 device_ctrl_transfer(board_id + 1, 1, F_BRST); 1292 cgsleep_us(POWER_WAIT_INTERVAL); 1293 device_ctrl_transfer(board_id + 1, 0, F_BRST); 1294 cgsleep_us(POWER_WAIT_INTERVAL); 1295 1296 applog(LOG_INFO, "%s: sent reset to BOARD%d", 1297 bitfury->drv->name, board_id + 1); 1298 } 1299 } 1300 1301 /* check if board power is present */ 1302 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 1303 /* read hw sensor data */ 1304 char buff[256]; 1305 1306 if (info->chipboard[board_id].detected == true) { 1307 memset(buff, 0, sizeof(buff)); 1308 if (device_uart_txrx(board_id + 1, "S", buff) < 0) 1309 quit(1, "%s: %s() failed to get BOARD%d status", 1310 bitfury->drv->name, __func__, board_id + 1); 1311 1312 if (parse_hwstats(info, board_id, buff) < 0) 1313 applog(LOG_ERR, "%s: failed to parse hw stats", 1314 bitfury->drv->name); 1315 1316 /* disable board if power voltage is incorrect */ 1317 if ((info->chipboard[board_id].u_board < 10.0) || 1318 (info->chipboard[board_id].u_board > 15.0)) { 1319 1320 /* concentrator loop */ 1321 for (bcm250_id = 0; bcm250_id < BCM250_NUM; bcm250_id++) { 1322 uint8_t first_good_chip = info->chipboard[board_id].bcm250[bcm250_id].first_good_chip; 1323 uint8_t last_good_chip = info->chipboard[board_id].bcm250[bcm250_id].last_good_chip; 1324 1325 /* chips loop */ 1326 for (chip_id = first_good_chip; chip_id < last_good_chip; chip_id++) 1327 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = DISABLED; 1328 } 1329 1330 applog(LOG_ERR, "%s: incorrect U board detected [%.1f] on BOARD%d, " 1331 "disabling board...", 1332 bitfury->drv->name, 1333 info->chipboard[board_id].u_board, 1334 board_id + 1); 1335 } else { 1336 info->chipboard[board_id].active = true; 1337 info->active_chipboard_num++; 1338 } 1339 } 1340 } 1341 1342 /* enable power chain */ 1343 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 1344 if (enable_power_chain(bitfury, board_id, 0) < 0) 1345 info->chipboard[board_id].detected = false; 1346 else { 1347 #ifdef MINER_X5 1348 info->chipboard[board_id].power_enable_time = time(NULL); 1349 info->chipboard[board_id].power_disable_count = 1; 1350 #endif 1351 1352 #ifdef MINER_X6 1353 info->chipboard[board_id].power1_enable_time = time(NULL); 1354 info->chipboard[board_id].power2_enable_time = time(NULL); 1355 info->chipboard[board_id].power1_disable_count = 1; 1356 info->chipboard[board_id].power2_disable_count = 1; 1357 #endif 1358 } 1359 } 1360 1361 /* wait for power chain to enable */ 1362 cgsleep_us(POWER_WAIT_INTERVAL); 1363 1364 if (opt_bf16_set_clock == true) { 1365 applog(LOG_INFO, "%s: setting clock [%02x] to all chips", 1366 bitfury->drv->name, bf16_chip_clock); 1367 1368 bitfury16_set_clock(bitfury); 1369 1370 quit(0, "Done."); 1371 } 1372 1373 if (opt_bf16_test_chip != NULL) { 1374 bf_chip_address_t chip_address = { 0, 0, 0 }; 1375 1376 if (parse_chip_address(bitfury, opt_bf16_test_chip, &chip_address) < 0) { 1377 quit(1, "%s: %s() error parsing chip address...", 1378 bitfury->drv->name, __func__); 1379 } 1380 1381 applog(LOG_INFO, "%s: testing communicaton with chip [%d:%d:%2d]", 1382 bitfury->drv->name, 1383 chip_address.board_id, 1384 chip_address.bcm250_id, 1385 chip_address.chip_id); 1386 1387 bitfury16_test_chip(bitfury, chip_address); 1388 1389 quit(0, "Done."); 1390 } 1391 1392 /* fan speed */ 1393 if ((opt_bf16_fan_speed != -1) && 1394 (manual_pid_enabled == true)) { 1395 manual_pid_enabled = false; 1396 } 1397 1398 set_fan_speed(bitfury); 1399 1400 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 1401 if (info->chipboard[board_id].detected == true) { 1402 /* target temp */ 1403 if (opt_bf16_target_temp == -1) { 1404 if (device_uart_transfer(board_id + 1, "T") < 0) 1405 quit(1, "%s: %s() failed to set BOARD%d target temp", 1406 bitfury->drv->name, __func__, board_id + 1); 1407 1408 applog(LOG_INFO, "%s: set BOARD%d target temp to default value", 1409 bitfury->drv->name, board_id + 1); 1410 } else { 1411 char uart_cmd[8]; 1412 sprintf(uart_cmd, "T:%d", opt_bf16_target_temp); 1413 1414 if (device_uart_transfer(board_id + 1, uart_cmd) < 0) 1415 quit(1, "%s: %s() failed to set BOARD%d target temp", 1416 bitfury->drv->name, __func__, board_id + 1); 1417 1418 applog(LOG_INFO, "%s: set BOARD%d target temp to [%d]", 1419 bitfury->drv->name, board_id + 1, opt_bf16_target_temp); 1420 } 1421 1422 /* alarm temp */ 1423 if (opt_bf16_alarm_temp == -1) { 1424 if (device_uart_transfer(board_id + 1, "C") < 0) 1425 quit(1, "%s: %s() failed to set BOARD%d alarm temp", 1426 bitfury->drv->name, __func__, board_id + 1); 1427 1428 applog(LOG_INFO, "%s: set BOARD%d alarm temp to default value", 1429 bitfury->drv->name, board_id + 1); 1430 } else { 1431 char uart_cmd[8]; 1432 sprintf(uart_cmd, "C:%d", opt_bf16_alarm_temp); 1433 1434 if (device_uart_transfer(board_id + 1, uart_cmd) < 0) 1435 quit(1, "%s: %s() failed to set BOARD%d alarm temp", 1436 bitfury->drv->name, __func__, board_id + 1); 1437 1438 applog(LOG_INFO, "%s: set BOARD%d alarm temp to [%d]", 1439 bitfury->drv->name, board_id + 1, opt_bf16_alarm_temp); 1440 } 1441 } 1442 } 1443 1444 /* count number of renonce chips */ 1445 if (opt_bf16_renonce != RENONCE_DISABLED) { 1446 info->renonce_chips = opt_bf16_renonce; 1447 1448 uint8_t renonce_chips = 0; 1449 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 1450 if ((info->chipboard[board_id].detected == true) && 1451 (info->chipboard[board_id].active == true)) { 1452 if (opt_bf16_renonce == RENONCE_ONE_CHIP) { 1453 if (renonce_chips != info->renonce_chips) 1454 renonce_chips++; 1455 else { 1456 renonce_chip_address[board_id].board_id = -1; 1457 renonce_chip_address[board_id].bcm250_id = -1; 1458 renonce_chip_address[board_id].chip_id = -1; 1459 } 1460 } else 1461 renonce_chips++; 1462 } else { 1463 renonce_chip_address[board_id].board_id = -1; 1464 renonce_chip_address[board_id].bcm250_id = -1; 1465 renonce_chip_address[board_id].chip_id = -1; 1466 } 1467 } 1468 1469 if (renonce_chips != info->renonce_chips) { 1470 applog(LOG_ERR, "%s: expected to find [%d] renonce chips, but found only [%d]", 1471 bitfury->drv->name, opt_bf16_renonce, renonce_chips); 1472 1473 info->renonce_chips = renonce_chips; 1474 } 1475 } else { 1476 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 1477 renonce_chip_address[board_id].board_id = -1; 1478 renonce_chip_address[board_id].bcm250_id = -1; 1479 renonce_chip_address[board_id].chip_id = -1; 1480 } 1481 } 1482 1483 /* correct renonce chip address */ 1484 if (opt_bf16_renonce != RENONCE_DISABLED) { 1485 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 1486 if ((info->chipboard[board_id].detected == true) && 1487 (info->chipboard[board_id].active == true) && 1488 (renonce_chip_address[board_id].board_id != -1)) { 1489 bcm250_id = renonce_chip_address[board_id].bcm250_id; 1490 1491 uint8_t first_good_chip = info->chipboard[board_id].bcm250[bcm250_id].first_good_chip; 1492 uint8_t last_good_chip = info->chipboard[board_id].bcm250[bcm250_id].last_good_chip; 1493 1494 if (renonce_chip_address[board_id].chip_id >= last_good_chip) 1495 renonce_chip_address[board_id].chip_id = last_good_chip - 1; 1496 else if (renonce_chip_address[board_id].chip_id < first_good_chip) 1497 renonce_chip_address[board_id].chip_id = first_good_chip; 1498 } 1499 } 1500 } 1501 1502 #ifdef FILELOG 1503 info->logfile = fopen(LOGFILE, "a"); 1504 if (info->logfile == NULL) 1505 applog(LOG_ERR, "%s: failed to open logfile [%s]: %s", 1506 bitfury->drv->name, LOGFILE, strerror(errno)); 1507 else 1508 mutex_init(&info->logfile_mutex); 1509 #endif 1510 1511 /* exit if no boards present */ 1512 if ((info->chipboard_num == 0) || 1513 (info->active_chipboard_num == 0)) { 1514 deinit_x5(bitfury); 1515 1516 /* close devices */ 1517 close_spi_device(SPI_CHANNEL1); 1518 close_spi_device(SPI_CHANNEL2); 1519 close_ctrl_device(); 1520 close_uart_device(UART_CHANNEL1); 1521 close_uart_device(UART_CHANNEL2); 1522 1523 #ifdef FILELOG 1524 fclose(info->logfile); 1525 #endif 1526 1527 applog(LOG_ERR, "%s: no boards present. exiting...", 1528 bitfury->drv->name); 1529 1530 free(info); 1531 free(bitfury); 1532 1533 return; 1534 } 1535 1536 mutex_init(&info->nonces_good_lock); 1537 1538 if (!add_cgpu(bitfury)) 1539 quit(1, "%s: %s() failed to add_cgpu", 1540 bitfury->drv->name, __func__); 1541 1542 info->initialised = true; 1543 1544 applog(LOG_INFO, "%s: chip driver initialized", bitfury->drv->name); 1545 #ifdef FILELOG 1546 filelog(info, "%s: cgminer started", bitfury->drv->name); 1547 #endif 1548 } 1549 1550 static uint8_t chip_task_update(struct cgpu_info *bitfury, bf_chip_address_t chip_address) 1551 { 1552 uint8_t i; 1553 int8_t ret = 0; 1554 bf_works_t work; 1555 time_t curr_time_t; 1556 struct timeval curr_time; 1557 1558 uint8_t board_id = chip_address.board_id; 1559 uint8_t bcm250_id = chip_address.bcm250_id; 1560 uint8_t chip_id = chip_address.chip_id; 1561 1562 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 1563 bf_cmd_buffer_t* cmd_buffer = &info->chipboard[board_id].cmd_buffer; 1564 1565 if (cmd_buffer->status != EMPTY) 1566 return -1; 1567 1568 switch (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status) { 1569 1570 /* fill chip buffer with toggle task */ 1571 case UNINITIALIZED: 1572 applog(LOG_DEBUG, "%s: chipworker_thr: chip [%d:%d:%2d], prepare toggle_cmd", 1573 bitfury->drv->name, 1574 board_id, bcm250_id, chip_id); 1575 1576 uint8_t toggle[4] = { 0xa5, 0x00, 0x00, 0x02 }; 1577 1578 ret = cmd_buffer_push(cmd_buffer, 1579 info->chipboard[board_id].bcm250[bcm250_id].channel_depth, chip_address, chip_address, 1580 work, 0, CHIP_CMD_TOGGLE, 3, toggle); 1581 1582 if (ret < 0) 1583 applog(LOG_ERR, "%s: chipworker_thr: chip [%d:%d:%2d], error prepare toggle_cmd", 1584 bitfury->drv->name, 1585 board_id, bcm250_id, chip_id); 1586 break; 1587 1588 /* fill chip buffer with set clock task */ 1589 case TOGGLE_SET: 1590 applog(LOG_DEBUG, "%s: chipworker_thr: chip [%d:%d:%2d], prepare set_clock_cmd", 1591 bitfury->drv->name, 1592 board_id, bcm250_id, chip_id); 1593 1594 uint8_t clock_buf[4]; 1595 memset(clock_buf, 0, sizeof(clock_buf)); 1596 1597 /* init renonce chip with lower clock */ 1598 if ((renonce_chip(chip_address) == 1) && 1599 (opt_bf16_renonce != RENONCE_DISABLED)) { 1600 gen_clock_data(bf16_renonce_chip_clock, 1, clock_buf); 1601 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].clock = bf16_renonce_chip_clock; 1602 } else { 1603 gen_clock_data(bf16_chip_clock, 1, clock_buf); 1604 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].clock = bf16_chip_clock; 1605 } 1606 1607 ret = cmd_buffer_push(cmd_buffer, 1608 info->chipboard[board_id].bcm250[bcm250_id].channel_depth, chip_address, chip_address, 1609 work, 0, CHIP_CMD_SET_CLOCK, 3, clock_buf); 1610 1611 if (ret < 0) 1612 applog(LOG_ERR, "%s: chipworker_thr: chip [%d:%d:%2d], error prepare set_clock_cmd", 1613 bitfury->drv->name, 1614 board_id, bcm250_id, chip_id); 1615 break; 1616 1617 /* fill chip buffer with chip mask */ 1618 case CLOCK_SET: 1619 applog(LOG_DEBUG, "%s: chipworker_thr: chip [%d:%d:%2d], prepare set_mask_cmd", 1620 bitfury->drv->name, 1621 board_id, bcm250_id, chip_id); 1622 1623 uint8_t noncemask[4]; 1624 memset(noncemask, 0, sizeof(noncemask)); 1625 1626 for (i = 0; i < 4; i++) 1627 noncemask[i] = (mask >> (8*(4 - i - 1))) & 0xff; 1628 1629 ret = cmd_buffer_push(cmd_buffer, 1630 info->chipboard[board_id].bcm250[bcm250_id].channel_depth, chip_address, chip_address, 1631 work, 0, CHIP_CMD_SET_MASK, 3, noncemask); 1632 1633 if (ret < 0) 1634 applog(LOG_ERR, "%s: chipworker_thr: chip [%d:%d:%2d], error prepare set_mask_cmd", 1635 bitfury->drv->name, 1636 board_id, bcm250_id, chip_id); 1637 break; 1638 1639 /* fill chip buffer with new task */ 1640 case MASK_SET: 1641 if ((renonce_chip(chip_address) == 0) || 1642 (opt_bf16_renonce == RENONCE_DISABLED)) { 1643 applog(LOG_DEBUG, "%s: chipworker_thr: chip [%d:%d:%2d], prepare send_task_cmd", 1644 bitfury->drv->name, 1645 board_id, bcm250_id, chip_id); 1646 1647 L_LOCK(info->work_list); 1648 L_LOCK(info->stale_work_list); 1649 if (info->work_list->count > 0) { 1650 memset(info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].cwork.task, 0, 1651 sizeof(info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].cwork.task)); 1652 1653 bf_data_t* wdata = info->work_list->head; 1654 1655 workd_list_push(info->stale_work_list, WORKD(wdata)); 1656 workd_list_remove(info->work_list, &info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].cwork); 1657 1658 gen_task_data(info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].cwork.payload.midstate, 1659 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].cwork.payload.m7, 1660 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].cwork.payload.ntime, 1661 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].cwork.payload.nbits, mask, 1662 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].cwork.task); 1663 1664 ret = cmd_buffer_push(cmd_buffer, 1665 info->chipboard[board_id].bcm250[bcm250_id].channel_depth, chip_address, chip_address, 1666 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].cwork, 0, 1667 CHIP_CMD_TASK_WRITE, 79, 1668 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].cwork.task); 1669 1670 if (ret < 0) 1671 applog(LOG_ERR, "%s: chipworker_thr: chip [%d:%d:%2d], error prepare send_task_cmd", 1672 bitfury->drv->name, 1673 board_id, bcm250_id, chip_id); 1674 } 1675 #if 0 1676 else 1677 applog(LOG_ERR, "%s: chipworker_thr: chip [%d:%d:%2d], error prepare send_task_cmd: no works available", 1678 bitfury->drv->name, 1679 board_id, bcm250_id, chip_id); 1680 #endif 1681 L_UNLOCK(info->stale_work_list); 1682 L_UNLOCK(info->work_list); 1683 } 1684 1685 break; 1686 1687 /* fill chip buffer with check status task */ 1688 case TASK_SENT: 1689 gettimeofday(&curr_time, NULL); 1690 1691 if (((renonce_chip(chip_address) == 0) || 1692 (opt_bf16_renonce == RENONCE_DISABLED)) && 1693 (timediff_us(info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_time, curr_time) > CHIP_TASK_STATUS_INTERVAL)) { 1694 applog(LOG_DEBUG, "%s: chipworker_thr: chip [%d:%d:%2d], prepare task_status_cmd", 1695 bitfury->drv->name, 1696 board_id, bcm250_id, chip_id); 1697 1698 ret = cmd_buffer_push(cmd_buffer, 1699 info->chipboard[board_id].bcm250[bcm250_id].channel_depth, chip_address, chip_address, 1700 work, 0, CHIP_CMD_TASK_STATUS, 0, NULL); 1701 1702 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_time.tv_sec = curr_time.tv_sec; 1703 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_time.tv_usec = curr_time.tv_usec; 1704 1705 if (ret < 0) 1706 applog(LOG_ERR, "%s: chipworker_thr: chip [%d:%d:%2d], error prepare task_status_cmd", 1707 bitfury->drv->name, 1708 board_id, bcm250_id, chip_id); 1709 } 1710 break; 1711 1712 /* fill chip buffer with read nonces task */ 1713 case TASK_SWITCHED: 1714 if ((renonce_chip(chip_address) == 0) || 1715 (opt_bf16_renonce == RENONCE_DISABLED)) { 1716 applog(LOG_DEBUG, "%s: chipworker_thr: chip [%d:%d:%2d], prepare read_nonce_cmd", 1717 bitfury->drv->name, 1718 board_id, bcm250_id, chip_id); 1719 1720 ret = cmd_buffer_push(cmd_buffer, 1721 info->chipboard[board_id].bcm250[bcm250_id].channel_depth, chip_address, chip_address, 1722 work, 0, CHIP_CMD_READ_NONCE, 0, NULL); 1723 1724 if (ret < 0) 1725 applog(LOG_ERR, "%s: chipworker_thr: chip [%d:%d:%2d], error prepare read_nonce_cmd", 1726 bitfury->drv->name, 1727 board_id, bcm250_id, chip_id); 1728 } 1729 1730 break; 1731 1732 /* mark chip as UNINITIALIZED and start all over again */ 1733 case FAILING: 1734 curr_time_t = time(NULL); 1735 time_t time_diff = curr_time_t - info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_error_time; 1736 1737 if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count < CHIP_ERROR_FAIL_LIMIT) { 1738 if (time_diff >= info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count * CHIP_RECOVERY_INTERVAL) { 1739 1740 /* change renonce chip address if RENONCE_CHIP_ERROR_FAIL_LIMIT reached */ 1741 if ((renonce_chip(chip_address) == 1) && 1742 (opt_bf16_renonce != RENONCE_DISABLED)) { 1743 if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count == RENONCE_CHIP_ERROR_FAIL_LIMIT) { 1744 applog(LOG_ERR, "%s: chipworker_thr: renonce chip [%d:%d:%2d] failed. trying to switch to another one...", 1745 bitfury->drv->name, 1746 chip_address.board_id, 1747 chip_address.bcm250_id, 1748 chip_address.chip_id); 1749 1750 if (change_renonce_chip_address(bitfury, chip_address) == 0) { 1751 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = UNINITIALIZED; 1752 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_nonce_time = curr_time_t; 1753 gettimeofday(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_time, NULL); 1754 } 1755 } else { 1756 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = UNINITIALIZED; 1757 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_nonce_time = curr_time_t; 1758 gettimeofday(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_time, NULL); 1759 1760 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count++; 1761 } 1762 } else { 1763 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = UNINITIALIZED; 1764 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_nonce_time = curr_time_t; 1765 gettimeofday(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_time, NULL); 1766 gettimeofday(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].switch_time, NULL); 1767 1768 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count++; 1769 1770 #ifdef FILELOG 1771 filelog(info, "BF16: chip [%d:%d:%2d] recovered time_diff: [%d], " 1772 "recovery_count: [%d], error_rate: [%d]", 1773 board_id, bcm250_id, chip_id, 1774 time_diff, 1775 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count, 1776 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate); 1777 #endif 1778 } 1779 } 1780 } 1781 /* mark chip as DISABLED and never communicate to it again */ 1782 else if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status != DISABLED) { 1783 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = DISABLED; 1784 1785 #ifdef FILELOG 1786 filelog(info, "BF16: disabling chip [%d:%d:%2d] recovery_count: [%d], error_rate: [%d]", 1787 board_id, bcm250_id, chip_id, 1788 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count, 1789 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate); 1790 #endif 1791 } 1792 break; 1793 1794 case DISABLED: 1795 default: 1796 break; 1797 } 1798 1799 return ret; 1800 } 1801 1802 static uint8_t renonce_task_update_loop(struct cgpu_info *bitfury, uint8_t board_id, 1803 bf_renonce_stage_t stage, uint8_t renonce_count) 1804 { 1805 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 1806 bf_cmd_buffer_t* cmd_buffer = &info->chipboard[board_id].cmd_buffer; 1807 1808 uint8_t bcm250_id = renonce_chip_address[board_id].bcm250_id; 1809 uint8_t chip_id = renonce_chip_address[board_id].chip_id; 1810 1811 uint8_t nonces = 0; 1812 1813 if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status < FAILING) { 1814 L_LOCK(info->renonce_list); 1815 bf_data_t* rdata = info->renonce_list->head; 1816 while ((rdata != NULL) && (nonces < renonce_count)) { 1817 uint8_t ret = 1; 1818 1819 if ((RENONCE(rdata)->sent == false) && 1820 (RENONCE(rdata)->stage == stage)) { 1821 /* generate work mask */ 1822 uint32_t nonce_mask = gen_mask(RENONCE(rdata)->nonce, mask_bits); 1823 nonce_mask = ntohl(nonce_mask); 1824 1825 switch (RENONCE(rdata)->stage) { 1826 case RENONCE_STAGE0: 1827 case RENONCE_STAGE2: 1828 /* generate chip work with new mask */ 1829 cg_memcpy(RENONCE(rdata)->owork.task + 19*4, 1830 &nonce_mask, sizeof(nonce_mask)); 1831 1832 /* send task and read nonces at the same time */ 1833 ret = cmd_buffer_push(cmd_buffer, 1834 info->chipboard[board_id].bcm250[bcm250_id].channel_depth, 1835 renonce_chip_address[board_id], RENONCE(rdata)->src_address, 1836 RENONCE(rdata)->owork, RENONCE(rdata)->id, 1837 (CHIP_CMD_TASK_WRITE | CHIP_CMD_TASK_SWITCH | CHIP_CMD_READ_NONCE), 79, 1838 RENONCE(rdata)->owork.task); 1839 break; 1840 case RENONCE_STAGE1: 1841 case RENONCE_STAGE3: 1842 /* generate chip work with new mask */ 1843 cg_memcpy(RENONCE(rdata)->cwork.task + 19*4, 1844 &nonce_mask, sizeof(nonce_mask)); 1845 1846 /* send task and read nonces at the same time */ 1847 ret = cmd_buffer_push(cmd_buffer, 1848 info->chipboard[board_id].bcm250[bcm250_id].channel_depth, 1849 renonce_chip_address[board_id], RENONCE(rdata)->src_address, 1850 RENONCE(rdata)->cwork, RENONCE(rdata)->id, 1851 (CHIP_CMD_TASK_WRITE | CHIP_CMD_TASK_SWITCH | CHIP_CMD_READ_NONCE), 79, 1852 RENONCE(rdata)->cwork.task); 1853 break; 1854 case RENONCE_STAGE_FINISHED: 1855 default: 1856 break; 1857 } 1858 } 1859 1860 if (ret == 0) { 1861 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = TASK_SWITCHED; 1862 RENONCE(rdata)->sent = true; 1863 RENONCE(rdata)->received = false; 1864 nonces++; 1865 } 1866 1867 rdata = rdata->next; 1868 } 1869 L_UNLOCK(info->renonce_list); 1870 } 1871 1872 return nonces; 1873 } 1874 1875 static void renonce_task_update(struct cgpu_info *bitfury, uint8_t board_id, uint8_t renonce_count) 1876 { 1877 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 1878 bf_cmd_buffer_t* cmd_buffer = &info->chipboard[board_id].cmd_buffer; 1879 1880 bf_works_t work; 1881 uint8_t i; 1882 1883 uint8_t bcm250_id = renonce_chip_address[board_id].bcm250_id; 1884 uint8_t chip_id = renonce_chip_address[board_id].chip_id; 1885 1886 cmd_buffer_push_create_channel(cmd_buffer, 1887 info->chipboard[board_id].bcm250[bcm250_id].channel_path, 1888 info->channel_length); 1889 1890 if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status < FAILING) { 1891 uint8_t toggle[4] = { 0xa5, 0x00, 0x00, 0x02 }; 1892 1893 cmd_buffer_push(cmd_buffer, 1894 info->chipboard[board_id].bcm250[bcm250_id].channel_depth, 1895 renonce_chip_address[board_id], renonce_chip_address[board_id], 1896 work, 0, CHIP_CMD_TOGGLE, 3, toggle); 1897 1898 uint8_t clock_buf[4]; 1899 memset(clock_buf, 0, sizeof(clock_buf)); 1900 gen_clock_data(bf16_renonce_chip_clock, 1, clock_buf); 1901 1902 cmd_buffer_push(cmd_buffer, 1903 info->chipboard[board_id].bcm250[bcm250_id].channel_depth, 1904 renonce_chip_address[board_id], renonce_chip_address[board_id], 1905 work, 0, CHIP_CMD_SET_CLOCK, 3, clock_buf); 1906 1907 uint8_t noncemask[4]; 1908 memset(noncemask, 0, sizeof(noncemask)); 1909 1910 for (i = 0; i < 4; i++) 1911 noncemask[i] = (mask >> (8*(4 - i - 1))) & 0xff; 1912 1913 cmd_buffer_push(cmd_buffer, 1914 info->chipboard[board_id].bcm250[bcm250_id].channel_depth, 1915 renonce_chip_address[board_id], renonce_chip_address[board_id], 1916 work, 0, CHIP_CMD_SET_MASK, 3, noncemask); 1917 1918 bf_renonce_stage_t stage = RENONCE_STAGE0; 1919 while ((renonce_count > 0) && (stage != RENONCE_STAGE_FINISHED)) { 1920 renonce_count -= renonce_task_update_loop(bitfury, board_id, stage++, renonce_count); 1921 } 1922 } 1923 1924 cmd_buffer_push_destroy_channel(cmd_buffer, 1925 info->chipboard[board_id]. 1926 bcm250[renonce_chip_address[board_id].bcm250_id].channel_depth); 1927 } 1928 1929 static void fill_cmd_buffer_loop(struct cgpu_info *bitfury, uint8_t board_id, bool do_renonce, uint16_t renonce_count) 1930 { 1931 uint8_t bcm250_id, chip_id; 1932 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 1933 bf_cmd_buffer_t* cmd_buffer = &info->chipboard[board_id].cmd_buffer; 1934 1935 /* concentrator loop */ 1936 for (bcm250_id = 0; bcm250_id < BCM250_NUM; bcm250_id++) { 1937 uint8_t first_good_chip = info->chipboard[board_id].bcm250[bcm250_id].first_good_chip; 1938 uint8_t last_good_chip = info->chipboard[board_id].bcm250[bcm250_id].last_good_chip; 1939 1940 cmd_buffer_push_create_channel(cmd_buffer, 1941 info->chipboard[board_id].bcm250[bcm250_id].channel_path, 1942 info->channel_length); 1943 1944 /* chips loop */ 1945 for (chip_id = first_good_chip; chip_id < last_good_chip; chip_id++) { 1946 bf_chip_address_t chip_address = { board_id, bcm250_id, chip_id }; 1947 chip_task_update(bitfury, chip_address); 1948 } 1949 1950 cmd_buffer_push_destroy_channel(cmd_buffer, 1951 info->chipboard[board_id].bcm250[bcm250_id].channel_depth); 1952 } 1953 1954 if (do_renonce == true) { 1955 uint8_t count = (cmd_buffer->free_bytes - (2 + 11 + 11 + 11 + 8)) / 136; 1956 if (count < renonce_count) { 1957 if (count > 0) 1958 renonce_task_update(bitfury, board_id, count); 1959 } else if (renonce_count > 0) 1960 renonce_task_update(bitfury, board_id, renonce_count); 1961 } 1962 1963 cmd_buffer->status = TX_READY; 1964 } 1965 1966 static void fill_cmd_buffer(struct cgpu_info *bitfury, uint8_t board_id) 1967 { 1968 static uint8_t do_renonce[CHIPBOARD_NUM]; 1969 uint16_t renonce_count = 0; 1970 1971 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 1972 bf_cmd_buffer_t* cmd_buffer = &info->chipboard[board_id].cmd_buffer; 1973 1974 if (cmd_buffer->status == EMPTY) { 1975 if ((opt_bf16_renonce == RENONCE_DISABLED) || 1976 (renonce_chip_address[board_id].board_id == -1)) { 1977 1978 fill_cmd_buffer_loop(bitfury, board_id, false, 0); 1979 } else { 1980 L_LOCK(info->renonce_list); 1981 bf_data_t* rdata = info->renonce_list->head; 1982 while (rdata != NULL) { 1983 if (RENONCE(rdata)->sent == false) 1984 renonce_count++; 1985 rdata = rdata->next; 1986 } 1987 L_UNLOCK(info->renonce_list); 1988 1989 if (do_renonce[board_id] < RENONCE_SEND) { 1990 fill_cmd_buffer_loop(bitfury, board_id, true, renonce_count); 1991 1992 do_renonce[board_id]++; 1993 } else { 1994 if (renonce_count >= RENONCE_COUNT) { 1995 renonce_task_update(bitfury, board_id, RENONCE_COUNT); 1996 1997 do_renonce[board_id] = 0; 1998 cmd_buffer->status = TX_READY; 1999 } else { 2000 fill_cmd_buffer_loop(bitfury, board_id, true, renonce_count); 2001 2002 do_renonce[board_id]++; 2003 } 2004 } 2005 } 2006 } 2007 } 2008 2009 static uint8_t update_chip_status(struct cgpu_info *bitfury, bf_cmd_status_t cmd_status) 2010 { 2011 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 2012 uint8_t board_id = cmd_status.chip_address.board_id; 2013 uint8_t bcm250_id = cmd_status.chip_address.bcm250_id; 2014 uint8_t chip_id = cmd_status.chip_address.chip_id; 2015 2016 switch (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status) { 2017 2018 case UNINITIALIZED: 2019 case TOGGLE_SET: 2020 case CLOCK_SET: 2021 case MASK_SET: 2022 applog(LOG_DEBUG, "%s: chipworker_thr: chip [%d:%d:%2d], send_cmd [%s]", 2023 bitfury->drv->name, 2024 board_id, bcm250_id, chip_id, 2025 get_cmd_description(cmd_status.cmd_code)); 2026 2027 /* update chip status */ 2028 if (cmd_status.checksum_error == false) 2029 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status++; 2030 2031 else { 2032 #ifndef DISABLE_SEND_CMD_ERROR 2033 applog(LOG_ERR, "%s: chipworker_thr: chip [%d:%d:%2d]: error send_cmd [%s]. " 2034 "checksum: expected: [%02x]; received: [%02x]", 2035 bitfury->drv->name, 2036 board_id, bcm250_id, chip_id, 2037 get_cmd_description(cmd_status.cmd_code), 2038 cmd_status.checksum_expected, 2039 cmd_status.checksum_received); 2040 #endif 2041 2042 /* increase error counters */ 2043 increase_errors(info, cmd_status.chip_address); 2044 } 2045 break; 2046 2047 case TASK_SENT: 2048 applog(LOG_DEBUG, "%s: chipworker_thr: chip [%d:%d:%2d], send_cmd [%s]", 2049 bitfury->drv->name, 2050 board_id, bcm250_id, chip_id, 2051 get_cmd_description(cmd_status.cmd_code)); 2052 2053 /* read task status from chip*/ 2054 if (cmd_status.checksum_error == false) { 2055 uint8_t new_buff = ((cmd_status.status & 0x0f) == 0x0f) ? 1 : 0; 2056 2057 /* status cmd counter */ 2058 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_cmd_dx++; 2059 info->chipboard[board_id].bcm250[bcm250_id].status_cmd_dx++; 2060 info->chipboard[board_id].status_cmd_dx++; 2061 info->status_cmd_dx++; 2062 2063 /* check if chip task has switched */ 2064 if (new_buff != info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].curr_buff) { 2065 gettimeofday(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].switch_time, NULL); 2066 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].curr_buff = new_buff; 2067 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status++; 2068 2069 /* task switch counter */ 2070 increase_task_switch(info, cmd_status.chip_address); 2071 2072 } else { 2073 /* task not switched */ 2074 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_cmd_none_dx++; 2075 info->chipboard[board_id].bcm250[bcm250_id].status_cmd_none_dx++; 2076 info->chipboard[board_id].status_cmd_none_dx++; 2077 info->status_cmd_none_dx++; 2078 2079 /* check if chip hang */ 2080 struct timeval curr_time; 2081 gettimeofday(&curr_time, NULL); 2082 2083 if ((timediff_us(info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].switch_time, curr_time) > CHIP_TASK_SWITCH_INTERVAL) && 2084 (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status < FAILING)) { 2085 increase_errors(info, cmd_status.chip_address); 2086 2087 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = FAILING; 2088 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_error_time = time(NULL); 2089 2090 applog(LOG_ERR, "%s: nonceworker_thr: chip [%d:%d:%2d], " 2091 "failed: no task switch during last [%.3f] seconds", 2092 bitfury->drv->name, 2093 board_id, bcm250_id, chip_id, CHIP_TASK_SWITCH_INTERVAL / 1000000.0); 2094 2095 #ifdef FILELOG 2096 filelog(info, "BF16: no task switch for chip [%d:%d:%2d], " 2097 "error count: [%d], recovery_count: [%d], error_rate: [%d]", 2098 board_id, bcm250_id, chip_id, 2099 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].errors, 2100 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count, 2101 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate); 2102 #endif 2103 } 2104 } 2105 } else { 2106 #ifndef DISABLE_SEND_CMD_ERROR 2107 applog(LOG_ERR, "%s: chipworker_thr: chip [%d:%d:%2d]: error send_cmd [%s]. " 2108 "checksum: expected: [%02x]; received: [%02x]", 2109 bitfury->drv->name, 2110 board_id, bcm250_id, chip_id, 2111 get_cmd_description(cmd_status.cmd_code), 2112 cmd_status.checksum_expected, 2113 cmd_status.checksum_received); 2114 #endif 2115 2116 /* increase error counters */ 2117 increase_errors(info, cmd_status.chip_address); 2118 } 2119 break; 2120 2121 case TASK_SWITCHED: 2122 applog(LOG_DEBUG, "%s: chipworker_thr: chip [%d:%d:%2d], send_cmd [%s]", 2123 bitfury->drv->name, 2124 board_id, bcm250_id, chip_id, 2125 get_cmd_description(cmd_status.cmd_code)); 2126 2127 if (cmd_status.checksum_error == false) { 2128 if ((renonce_chip(cmd_status.chip_address) == 1) && 2129 (opt_bf16_renonce != RENONCE_DISABLED)) { 2130 2131 /* task switch counter */ 2132 if (cmd_status.cmd_code & CHIP_CMD_READ_NONCE) 2133 increase_task_switch(info, cmd_status.chip_address); 2134 } else if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status < FAILING) { 2135 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].task_processed++; 2136 2137 if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].task_processed >= CHIP_RESTART_LIMIT) { 2138 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = UNINITIALIZED; 2139 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].task_processed = 0; 2140 } else 2141 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = MASK_SET; 2142 } 2143 2144 return 1; 2145 } else { 2146 #ifndef DISABLE_SEND_CMD_ERROR 2147 applog(LOG_ERR, "%s: chipworker_thr: chip [%d:%d:%2d]: error send_cmd [%s]. " 2148 "checksum: expected: [%02x]; received: [%02x]", 2149 bitfury->drv->name, 2150 board_id, bcm250_id, chip_id, 2151 get_cmd_description(cmd_status.cmd_code), 2152 cmd_status.checksum_expected, 2153 cmd_status.checksum_received); 2154 #endif 2155 2156 /* increase error counters */ 2157 increase_errors(info, cmd_status.chip_address); 2158 } 2159 2160 break; 2161 2162 case FAILING: 2163 case DISABLED: 2164 default: 2165 break; 2166 } 2167 2168 return 0; 2169 } 2170 2171 static uint8_t process_nonces(struct cgpu_info *bitfury, bf_cmd_status_t cmd_status, uint32_t* nonces) 2172 { 2173 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 2174 2175 uint8_t i; 2176 uint32_t found_nonces[12]; 2177 2178 uint8_t board_id = cmd_status.chip_address.board_id; 2179 uint8_t bcm250_id = cmd_status.chip_address.bcm250_id; 2180 uint8_t chip_id = cmd_status.chip_address.chip_id; 2181 2182 if ((cmd_status.checksum_error == false) && 2183 (cmd_status.nonce_checksum_error == false)) { 2184 cg_memcpy(info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].rx, nonces, sizeof(found_nonces)); 2185 2186 uint8_t found = find_nonces(info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].rx, 2187 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].rx_prev, 2188 found_nonces); 2189 2190 /* check if chip is still mining */ 2191 if (found == 0) { 2192 time_t curr_time = time(NULL); 2193 time_t time_diff = curr_time - info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_nonce_time; 2194 2195 if ((renonce_chip(cmd_status.chip_address) == 1) && 2196 (opt_bf16_renonce != RENONCE_DISABLED)) { 2197 if ((time_diff >= RENONCE_CHIP_FAILING_INTERVAL) && 2198 (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status < FAILING)) { 2199 increase_errors(info, cmd_status.chip_address); 2200 2201 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = FAILING; 2202 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_error_time = curr_time; 2203 2204 applog(LOG_ERR, "%s: nonceworker_thr: renonce chip [%d:%d:%2d] " 2205 "failed: no good nonces during last [%.1f] seconds", 2206 bitfury->drv->name, 2207 board_id, bcm250_id, chip_id, RENONCE_CHIP_FAILING_INTERVAL); 2208 2209 #ifdef FILELOG 2210 filelog(info, "BF16: no good nonces from renonce chip [%d:%d:%2d], " 2211 "error count: [%d] recovery_count: [%d], error_rate: [%d]", 2212 board_id, bcm250_id, chip_id, 2213 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].errors, 2214 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count, 2215 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate); 2216 #endif 2217 } 2218 } else { 2219 if ((time_diff >= CHIP_FAILING_INTERVAL) && 2220 (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status < FAILING)) { 2221 increase_errors(info, cmd_status.chip_address); 2222 2223 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = FAILING; 2224 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_error_time = curr_time; 2225 2226 applog(LOG_ERR, "%s: nonceworker_thr: chip [%d:%d:%2d], " 2227 "failed: no good nonces during last [%.1f] seconds", 2228 bitfury->drv->name, 2229 board_id, bcm250_id, chip_id, CHIP_FAILING_INTERVAL); 2230 2231 #ifdef FILELOG 2232 filelog(info, "BF16: no good nonces from chip [%d:%d:%2d], " 2233 "error count: [%d], recovery_count: [%d], error_rate: [%d]", 2234 board_id, bcm250_id, chip_id, 2235 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].errors, 2236 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count, 2237 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate); 2238 #endif 2239 } 2240 } 2241 } 2242 2243 /* increase stage if no nonces received */ 2244 if ((renonce_chip(cmd_status.chip_address) == 1) && 2245 (opt_bf16_renonce != RENONCE_DISABLED)) { 2246 L_LOCK(info->renonce_list); 2247 bf_data_t* rdata = info->renonce_list->head; 2248 while (rdata != NULL) { 2249 if (RENONCE(rdata)->id == cmd_status.id) { 2250 if (found == 0) { 2251 RENONCE(rdata)->stage++; 2252 RENONCE(rdata)->sent = false; 2253 2254 /* clear renonces list if we are running too slow */ 2255 if ((RENONCE(rdata)->stage >= RENONCE_STAGE2) && 2256 (info->renonce_list->count > RENONCE_STAGE2_LIMIT)) { 2257 info->unmatched++; 2258 increase_re_bad_nonces(info, RENONCE(rdata)->src_address); 2259 bf_data_t* rndata = rdata->next; 2260 renonce_list_remove(info->renonce_list, rdata); 2261 rdata = rndata; 2262 continue; 2263 } 2264 2265 if ((RENONCE(rdata)->stage >= RENONCE_STAGE3) && 2266 (info->renonce_list->count > RENONCE_STAGE3_LIMIT)) { 2267 info->unmatched++; 2268 increase_re_bad_nonces(info, RENONCE(rdata)->src_address); 2269 bf_data_t* rndata = rdata->next; 2270 renonce_list_remove(info->renonce_list, rdata); 2271 rdata = rndata; 2272 continue; 2273 } 2274 2275 /* remove expired renonce */ 2276 if (RENONCE(rdata)->stage == RENONCE_STAGE_FINISHED) { 2277 info->unmatched++; 2278 increase_re_bad_nonces(info, RENONCE(rdata)->src_address); 2279 bf_data_t* rndata = rdata->next; 2280 renonce_list_remove(info->renonce_list, rdata); 2281 rdata = rndata; 2282 continue; 2283 } 2284 } 2285 2286 RENONCE(rdata)->received = true; 2287 break; 2288 } 2289 rdata = rdata->next; 2290 } 2291 L_UNLOCK(info->renonce_list); 2292 } 2293 2294 bf_list_t* nonce_list = info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonce_list; 2295 for (i = 0; i < found; i++) { 2296 L_LOCK(nonce_list); 2297 int8_t res = nonce_list_push(nonce_list, found_nonces[i]); 2298 L_UNLOCK(nonce_list); 2299 if (res < 0) 2300 continue; 2301 2302 increase_total_nonces(info, cmd_status.chip_address); 2303 2304 /* check if nonce has errors and add it to renonce list */ 2305 if ((opt_bf16_renonce != RENONCE_DISABLED) && 2306 (renonce_chip(cmd_status.chip_address) == 0) && 2307 (found_nonces[i] & 0xfff00000) == 0xaaa00000) { 2308 increase_re_nonces(info, cmd_status.src_address); 2309 2310 L_LOCK(info->renonce_list); 2311 if (info->renonce_list->count < RENONCE_QUEUE_LEN) { 2312 renonce_list_push(info->renonce_list, 2313 info->renonce_id++, 2314 found_nonces[i], 2315 cmd_status.chip_address, 2316 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].cwork, 2317 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].owork); 2318 } else 2319 increase_re_bad_nonces(info, cmd_status.chip_address); 2320 L_UNLOCK(info->renonce_list); 2321 2322 applog(LOG_DEBUG, "%s: chipworker_thr: pushing renonce task: nonce: [%08x]", 2323 bitfury->drv->name, 2324 found_nonces[i]); 2325 continue; 2326 } 2327 2328 /* add nonces to noncework list */ 2329 if ((renonce_chip(cmd_status.chip_address) == 1) && 2330 (opt_bf16_renonce != RENONCE_DISABLED)) { 2331 L_LOCK(info->renoncework_list); 2332 renoncework_list_push(info->renoncework_list, cmd_status.chip_address, found_nonces[i]); 2333 L_UNLOCK(info->renoncework_list); 2334 } else { 2335 L_LOCK(info->noncework_list); 2336 noncework_list_push(info->noncework_list, 2337 cmd_status.chip_address, cmd_status.src_address, 2338 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].cwork, 2339 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].owork, 2340 found_nonces[i]); 2341 L_UNLOCK(info->noncework_list); 2342 } 2343 2344 applog(LOG_DEBUG, "%s: chipworker_thr: pushing nonce task: nonce: [%08x]", 2345 bitfury->drv->name, 2346 found_nonces[i]); 2347 } 2348 2349 /* rotate works and buffers */ 2350 cg_memcpy(info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].rx_prev, 2351 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].rx, sizeof(found_nonces)); 2352 2353 cg_memcpy(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].owork, 2354 &info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].cwork, sizeof(bf_works_t)); 2355 2356 /* remove old nonces from nonce list */ 2357 L_LOCK(nonce_list); 2358 if ((renonce_chip(cmd_status.chip_address) == 1) && 2359 (opt_bf16_renonce != RENONCE_DISABLED)) { 2360 while (nonce_list->count > RENONCE_CHIP_QUEUE_LEN) 2361 nonce_list_pop(nonce_list); 2362 } else { 2363 while (nonce_list->count > NONCE_CHIP_QUEUE_LEN) 2364 nonce_list_pop(nonce_list); 2365 } 2366 L_UNLOCK(nonce_list); 2367 } else { 2368 if (cmd_status.checksum_error != 0) { 2369 #ifndef DISABLE_SEND_CMD_ERROR 2370 applog(LOG_ERR, "%s: chipworker_thr: chip [%d:%d:%2d]: error send_cmd [%s]. " 2371 "checksum: expected: [%02x]; received: [%02x]", 2372 bitfury->drv->name, 2373 board_id, bcm250_id, chip_id, 2374 get_cmd_description(cmd_status.cmd_code), 2375 cmd_status.checksum_expected, 2376 cmd_status.checksum_received); 2377 #endif 2378 2379 /* increase error counters */ 2380 increase_errors(info, cmd_status.chip_address); 2381 } 2382 2383 if (cmd_status.nonce_checksum_error != 0) { 2384 if ((renonce_chip(cmd_status.chip_address) == 0) || 2385 (opt_bf16_renonce == RENONCE_DISABLED)) { 2386 applog(LOG_ERR, "%s: chipworker_thr: chip [%d:%d:%2d]: error receiving data. " 2387 "nonce checksum: expected: [%02x]; received: [%02x]", 2388 bitfury->drv->name, 2389 board_id, bcm250_id, chip_id, 2390 cmd_status.checksum_expected, 2391 cmd_status.checksum_received); 2392 2393 /* increase error counters */ 2394 increase_errors(info, cmd_status.chip_address); 2395 } 2396 } 2397 } 2398 2399 return 0; 2400 } 2401 2402 /* routine sending-receiving data to chipboard */ 2403 static void process_cmd_buffer(struct cgpu_info *bitfury, uint8_t board_id) 2404 { 2405 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 2406 uint8_t i; 2407 bf_cmd_status_t cmd_status; 2408 bf_cmd_buffer_t* cmd_buffer = &info->chipboard[board_id].cmd_buffer; 2409 2410 if (cmd_buffer->status == EXECUTED) { 2411 /* process extracted data */ 2412 uint16_t cmd_number = cmd_buffer->cmd_list->count; 2413 for (i = 0; i < cmd_number; i++) { 2414 uint32_t nonces[12]; 2415 2416 cmd_buffer_pop(cmd_buffer, &cmd_status, nonces); 2417 if ((cmd_status.cmd_code == CHIP_CMD_CREATE_CHANNEL) || 2418 (cmd_status.cmd_code == CHIP_CMD_TASK_SWITCH)) 2419 continue; 2420 2421 uint8_t task_switch = update_chip_status(bitfury, cmd_status); 2422 2423 /* analyze nonces */ 2424 if ((cmd_status.cmd_code & CHIP_CMD_READ_NONCE) && 2425 (task_switch == 1)) { 2426 process_nonces(bitfury, cmd_status, nonces); 2427 } 2428 } 2429 2430 cmd_buffer_clear(cmd_buffer); 2431 } 2432 } 2433 2434 static void *bitfury_chipworker(void *userdata) 2435 { 2436 struct cgpu_info *bitfury = (struct cgpu_info *)userdata; 2437 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 2438 uint8_t board_id; 2439 2440 applog(LOG_INFO, "%s: started chipworker thread", bitfury->drv->name); 2441 2442 while (bitfury->shutdown == false) { 2443 if (info->initialised) { 2444 break; 2445 } 2446 cgsleep_us(30); 2447 } 2448 2449 /* send reset sequence to boards */ 2450 spi_emit_reset(SPI_CHANNEL1); 2451 spi_emit_reset(SPI_CHANNEL2); 2452 2453 while (bitfury->shutdown == false) { 2454 if ((info->a_temp == false) && 2455 (info->a_ichain == false)) { 2456 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 2457 if (info->chipboard[board_id].detected == true) { 2458 /* prepare send buffer */ 2459 struct timeval start_time, stop_time; 2460 gettimeofday(&start_time, NULL); 2461 2462 if (info->chipboard[board_id].cmd_buffer.status == EMPTY) 2463 fill_cmd_buffer(bitfury, board_id); 2464 2465 gettimeofday(&stop_time, NULL); 2466 2467 #if 0 2468 applog(LOG_ERR, "%s: chipworker_thr: board %d buffer prepare: time elapsed: [%.6f]", 2469 bitfury->drv->name, board_id, timediff(start_time, stop_time)); 2470 #endif 2471 2472 gettimeofday(&start_time, NULL); 2473 2474 /* send buffer to chipboard */ 2475 if (info->chipboard[board_id].cmd_buffer.status == TX_READY) { 2476 spi_emit_reset(board_id + 1); 2477 2478 cmd_buffer_exec(board_id + 1, &info->chipboard[board_id].cmd_buffer); 2479 info->chipboard[board_id].bytes_transmitted_dx += info->chipboard[board_id].cmd_buffer.tx_offset; 2480 info->chipboard[board_id].bytes_transmitted += info->chipboard[board_id].cmd_buffer.tx_offset; 2481 } 2482 2483 gettimeofday(&stop_time, NULL); 2484 2485 #if 0 2486 applog(LOG_ERR, "%s: chipworker_thr: board %d TX/RX time: [%.6f]", 2487 bitfury->drv->name, board_id, timediff(start_time, stop_time)); 2488 #endif 2489 2490 gettimeofday(&start_time, NULL); 2491 2492 /* analyze received data */ 2493 if (info->chipboard[board_id].cmd_buffer.status == EXECUTED) { 2494 process_cmd_buffer(bitfury, board_id); 2495 } 2496 2497 gettimeofday(&stop_time, NULL); 2498 2499 #if 0 2500 applog(LOG_ERR, "%s: chipworker_thr: board %d buffer processing: time elapsed: [%.6f]", 2501 bitfury->drv->name, board_id, timediff(start_time, stop_time)); 2502 #endif 2503 } 2504 } 2505 } else 2506 cgsleep_us(CHIPWORKER_DELAY); 2507 } 2508 2509 applog(LOG_INFO, "%s: chipworker_thr: exiting...", bitfury->drv->name); 2510 return NULL; 2511 } 2512 2513 static int16_t cleanup_older(struct cgpu_info *bitfury) 2514 { 2515 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 2516 time_t curr_time = time(NULL); 2517 uint16_t released = 0; 2518 2519 /* clear stale work list */ 2520 L_LOCK(info->stale_work_list); 2521 bf_data_t* wdata = info->stale_work_list->head; 2522 while (wdata != NULL) { 2523 if (curr_time - WORKD(wdata)->generated >= WORK_TIMEOUT) { 2524 workd_list_pop(info->stale_work_list, bitfury); 2525 released++; 2526 } else 2527 break; 2528 wdata = info->stale_work_list->head; 2529 } 2530 L_UNLOCK(info->stale_work_list); 2531 2532 applog(LOG_INFO, "%s: released %d works", bitfury->drv->name, released); 2533 return released; 2534 } 2535 2536 static void *bitfury_nonceworker(void *userdata) 2537 { 2538 struct cgpu_info *bitfury = (struct cgpu_info *)userdata; 2539 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 2540 2541 applog(LOG_INFO, "%s: started nonceworker thread", bitfury->drv->name); 2542 2543 while (bitfury->shutdown == false) { 2544 if (info->initialised) { 2545 break; 2546 } 2547 cgsleep_us(30); 2548 } 2549 2550 applog(LOG_INFO, "%s: nonceworker loop started", bitfury->drv->name); 2551 2552 while (bitfury->shutdown == false) { 2553 struct timeval start_time, stop_time; 2554 gettimeofday(&start_time, NULL); 2555 2556 uint32_t nonce_cnt = 0; 2557 2558 /* general nonces processing */ 2559 L_LOCK(info->noncework_list); 2560 bf_data_t* nwdata = info->noncework_list->head; 2561 while (nwdata != NULL) { 2562 uint8_t board_id = NONCEWORK(nwdata)->chip_address.board_id; 2563 uint8_t bcm250_id = NONCEWORK(nwdata)->chip_address.bcm250_id; 2564 uint8_t chip_id = NONCEWORK(nwdata)->chip_address.chip_id; 2565 2566 nonce_cnt++; 2567 2568 /* general chip results processing */ 2569 if (test_nonce(&NONCEWORK(nwdata)->owork.work, NONCEWORK(nwdata)->nonce)) { 2570 applog(LOG_DEBUG, "%s: nonceworker_thr: chip [%d:%d:%2d], valid nonce [%08x]", 2571 bitfury->drv->name, 2572 board_id, bcm250_id, chip_id, NONCEWORK(nwdata)->nonce); 2573 2574 submit_tested_work(info->thr, &NONCEWORK(nwdata)->owork.work); 2575 2576 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_nonce_time = time(NULL); 2577 2578 if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count > 0) { 2579 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count = 0; 2580 2581 #ifdef FILELOG 2582 filelog(info, "BF16: good nonce for chip [%d:%d:%2d] " 2583 "setting recovery_count to [0], error_rate: [%d]", 2584 board_id, bcm250_id, chip_id, 2585 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate); 2586 #endif 2587 } 2588 2589 increase_good_nonces(info, NONCEWORK(nwdata)->chip_address); 2590 2591 mutex_lock(&info->nonces_good_lock); 2592 info->nonces_good_cg++; 2593 mutex_unlock(&info->nonces_good_lock); 2594 } else if (test_nonce(&NONCEWORK(nwdata)->cwork.work, NONCEWORK(nwdata)->nonce)) { 2595 applog(LOG_DEBUG, "%s: nonceworker_thr: chip [%d:%d:%2d], valid nonce [%08x]", 2596 bitfury->drv->name, 2597 board_id, bcm250_id, chip_id, NONCEWORK(nwdata)->nonce); 2598 2599 submit_tested_work(info->thr, &NONCEWORK(nwdata)->cwork.work); 2600 2601 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_nonce_time = time(NULL); 2602 2603 if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count > 0) { 2604 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count = 0; 2605 2606 #ifdef FILELOG 2607 filelog(info, "BF16: good nonce for chip [%d:%d:%2d] " 2608 "setting recovery_count to 0, error_rate: [%d]", 2609 board_id, bcm250_id, chip_id, 2610 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate); 2611 #endif 2612 } 2613 2614 increase_good_nonces(info, NONCEWORK(nwdata)->chip_address); 2615 2616 mutex_lock(&info->nonces_good_lock); 2617 info->nonces_good_cg++; 2618 mutex_unlock(&info->nonces_good_lock); 2619 } else { 2620 time_t curr_time = time(NULL); 2621 time_t time_diff = curr_time - info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_nonce_time; 2622 2623 if ((time_diff >= CHIP_FAILING_INTERVAL) && 2624 (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status < FAILING)) { 2625 increase_errors(info, NONCEWORK(nwdata)->chip_address); 2626 2627 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = FAILING; 2628 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_error_time = curr_time; 2629 2630 applog(LOG_ERR, "%s: nonceworker_thr: chip [%d:%d:%2d], " 2631 "failed: no good nonces during last [%.1f] seconds", 2632 bitfury->drv->name, 2633 board_id, bcm250_id, chip_id, CHIP_FAILING_INTERVAL); 2634 2635 #ifdef FILELOG 2636 filelog(info, "BF16: no good nonces from chip [%d:%d:%2d], " 2637 "error count: [%d], recovery_count: [%d], error_rate: [%d]", 2638 board_id, bcm250_id, chip_id, 2639 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].errors, 2640 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count, 2641 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate); 2642 #endif 2643 } 2644 2645 if (opt_bf16_renonce != RENONCE_DISABLED) { 2646 /* add failed nonce to renonce list */ 2647 increase_bad_nonces(info, NONCEWORK(nwdata)->chip_address); 2648 2649 L_LOCK(info->renonce_list); 2650 if (info->renonce_list->count < RENONCE_QUEUE_LEN) { 2651 renonce_list_push(info->renonce_list, 2652 info->renonce_id++, 2653 NONCEWORK(nwdata)->nonce, 2654 NONCEWORK(nwdata)->chip_address, 2655 NONCEWORK(nwdata)->cwork, 2656 NONCEWORK(nwdata)->owork); 2657 } else 2658 increase_re_bad_nonces(info, NONCEWORK(nwdata)->chip_address); 2659 L_UNLOCK(info->renonce_list); 2660 2661 applog(LOG_DEBUG, "%s: nonceworker_thr: pushing renonce task: nonce: [%08x]", 2662 bitfury->drv->name, 2663 NONCEWORK(nwdata)->nonce); 2664 } else 2665 increase_bad_nonces(info, NONCEWORK(nwdata)->chip_address); 2666 } 2667 2668 /* remove nonce from list */ 2669 noncework_list_pop(info->noncework_list); 2670 nwdata = info->noncework_list->head; 2671 } 2672 L_UNLOCK(info->noncework_list); 2673 2674 /* cleanup older works */ 2675 cleanup_older(bitfury); 2676 2677 gettimeofday(&stop_time, NULL); 2678 2679 #if 0 2680 applog(LOG_DEBUG, "%s: nonceworker_thr: nonces processed [%d]: time elapsed: [%.6f]", 2681 bitfury->drv->name, 2682 nonce_cnt, timediff(start_time, stop_time)); 2683 #endif 2684 2685 cgsleep_us(NONCEWORKER_DELAY); 2686 } 2687 2688 applog(LOG_INFO, "%s: nonceworker_thr: exiting...", bitfury->drv->name); 2689 return NULL; 2690 } 2691 2692 static bool test_renonce(struct cgpu_info *bitfury, bf_data_t* rdata, bf_data_t* rnwdata, bool owork) 2693 { 2694 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 2695 2696 uint8_t board_id = RENONCEWORK(rnwdata)->src_address.board_id; 2697 uint8_t bcm250_id = renonce_chip_address[board_id].bcm250_id; 2698 uint8_t chip_id = renonce_chip_address[board_id].chip_id; 2699 2700 if (owork == true) { 2701 if (test_nonce(&RENONCE(rdata)->owork.work, RENONCEWORK(rnwdata)->nonce)) { 2702 applog(LOG_DEBUG, "%s: renonceworker_thr: restored renonce: nonce: [%08x]", 2703 bitfury->drv->name, 2704 RENONCEWORK(rnwdata)->nonce); 2705 2706 submit_tested_work(info->thr, &RENONCE(rdata)->owork.work); 2707 2708 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_nonce_time = time(NULL); 2709 2710 if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count > 0) { 2711 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count = 0; 2712 2713 #ifdef FILELOG 2714 filelog(info, "BF16: good nonce for renonce chip [%d:%d:%2d] " 2715 "setting recovery_count to 0, error_rate: [%d]", 2716 board_id, bcm250_id, chip_id, 2717 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate); 2718 #endif 2719 } 2720 2721 increase_re_good_nonces(info, RENONCE(rdata)->src_address); 2722 increase_re_good_nonces(info, renonce_chip_address[board_id]); 2723 2724 mutex_lock(&info->nonces_good_lock); 2725 info->nonces_good_cg++; 2726 mutex_unlock(&info->nonces_good_lock); 2727 2728 RENONCE(rdata)->match = true; 2729 } else { 2730 time_t curr_time = time(NULL); 2731 time_t time_diff = curr_time - info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_nonce_time; 2732 2733 if ((time_diff >= RENONCE_CHIP_FAILING_INTERVAL) && 2734 (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status < FAILING)) { 2735 increase_errors(info, renonce_chip_address[board_id]); 2736 2737 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = FAILING; 2738 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_error_time = curr_time; 2739 2740 applog(LOG_ERR, "%s: nonceworker_thr: renonce chip [%d:%d:%2d] " 2741 "failed: no good nonces during last [%.1f] seconds", 2742 bitfury->drv->name, 2743 board_id, bcm250_id, chip_id, RENONCE_CHIP_FAILING_INTERVAL); 2744 2745 #ifdef FILELOG 2746 filelog(info, "BF16: no good nonces from renonce chip [%d:%d:%2d], " 2747 "error count: [%d] recovery_count: [%d], error_rate: [%d]", 2748 board_id, bcm250_id, chip_id, 2749 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].errors, 2750 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count, 2751 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate); 2752 #endif 2753 } 2754 } 2755 } else { 2756 if (test_nonce(&RENONCE(rdata)->cwork.work, RENONCEWORK(rnwdata)->nonce)) { 2757 applog(LOG_DEBUG, "%s: renonceworker_thr: restored renonce: nonce: [%08x]", 2758 bitfury->drv->name, 2759 RENONCEWORK(rnwdata)->nonce); 2760 2761 submit_tested_work(info->thr, &RENONCE(rdata)->cwork.work); 2762 2763 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_nonce_time = time(NULL); 2764 2765 if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count > 0) { 2766 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count = 0; 2767 2768 #ifdef FILELOG 2769 filelog(info, "BF16: good nonce for renonce chip [%d:%d:%2d] " 2770 "setting recovery_count to 0, error_rate: [%d]", 2771 board_id, bcm250_id, chip_id, 2772 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate); 2773 #endif 2774 } 2775 2776 increase_re_good_nonces(info, RENONCE(rdata)->src_address); 2777 increase_re_good_nonces(info, renonce_chip_address[board_id]); 2778 2779 mutex_lock(&info->nonces_good_lock); 2780 info->nonces_good_cg++; 2781 mutex_unlock(&info->nonces_good_lock); 2782 2783 RENONCE(rdata)->match = true; 2784 } else { 2785 time_t curr_time = time(NULL); 2786 time_t time_diff = curr_time - info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_nonce_time; 2787 2788 if ((time_diff >= RENONCE_CHIP_FAILING_INTERVAL) && 2789 (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status < FAILING)) { 2790 increase_errors(info, renonce_chip_address[board_id]); 2791 2792 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status = FAILING; 2793 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].last_error_time = curr_time; 2794 2795 applog(LOG_ERR, "%s: nonceworker_thr: renonce chip [%d:%d:%2d] " 2796 "failed: no good nonces during last [%.1f] seconds", 2797 bitfury->drv->name, 2798 board_id, bcm250_id, chip_id, RENONCE_CHIP_FAILING_INTERVAL); 2799 2800 #ifdef FILELOG 2801 filelog(info, "BF16: no good nonces from renonce chip [%d:%d:%2d], " 2802 "error count: [%d] recovery_count: [%d], error_rate: [%d]", 2803 board_id, bcm250_id, chip_id, 2804 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].errors, 2805 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].recovery_count, 2806 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].error_rate); 2807 #endif 2808 } 2809 } 2810 } 2811 2812 return RENONCE(rdata)->match; 2813 } 2814 2815 static void *bitfury_renonceworker(void *userdata) 2816 { 2817 struct cgpu_info *bitfury = (struct cgpu_info *)userdata; 2818 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 2819 bf_list_t* id_list = nonce_list_init(); 2820 2821 applog(LOG_INFO, "%s: started renonceworker thread", bitfury->drv->name); 2822 2823 while (bitfury->shutdown == false) { 2824 if (info->initialised) { 2825 break; 2826 } 2827 cgsleep_us(30); 2828 } 2829 2830 applog(LOG_INFO, "%s: renonceworker loop started", bitfury->drv->name); 2831 2832 while (bitfury->shutdown == false) { 2833 struct timeval start_time, stop_time; 2834 gettimeofday(&start_time, NULL); 2835 2836 uint32_t nonce_cnt = 0; 2837 2838 /* renonce chip results processing */ 2839 L_LOCK(info->renoncework_list); 2840 bf_data_t* rnwdata = info->renoncework_list->head; 2841 while (rnwdata != NULL) { 2842 nonce_cnt++; 2843 2844 /* find nonce by id */ 2845 L_LOCK(info->renonce_list); 2846 bf_data_t* rdata = info->renonce_list->head; 2847 while (rdata != NULL) { 2848 if (match_nonce(RENONCEWORK(rnwdata)->nonce, RENONCE(rdata)->nonce, mask_bits)) { 2849 if (RENONCE(rdata)->match == false) { 2850 switch (RENONCE(rdata)->stage) { 2851 case RENONCE_STAGE0: 2852 if (test_renonce(bitfury, rdata, rnwdata, true) == true) 2853 info->stage0_match++; 2854 else 2855 info->stage0_mismatch++; 2856 break; 2857 case RENONCE_STAGE1: 2858 case RENONCE_STAGE2: 2859 case RENONCE_STAGE3: 2860 /* test old work first */ 2861 if (test_renonce(bitfury, rdata, rnwdata, true) == true) { 2862 if (RENONCE(rdata)->stage == RENONCE_STAGE1) 2863 info->stage1_mismatch++; 2864 2865 if (RENONCE(rdata)->stage == RENONCE_STAGE2) 2866 info->stage2_match++; 2867 2868 if (RENONCE(rdata)->stage == RENONCE_STAGE3) 2869 info->stage3_mismatch++; 2870 } else { 2871 if (test_renonce(bitfury, rdata, rnwdata, false) == true) { 2872 if (RENONCE(rdata)->stage == RENONCE_STAGE1) 2873 info->stage1_match++; 2874 2875 if (RENONCE(rdata)->stage == RENONCE_STAGE2) 2876 info->stage2_mismatch++; 2877 2878 if (RENONCE(rdata)->stage == RENONCE_STAGE3) 2879 info->stage3_match++; 2880 } 2881 } 2882 break; 2883 default: 2884 applog(LOG_ERR, "%s: renonceworker_thr: invalid renonce stage arrived: [%d]", 2885 bitfury->drv->name, 2886 RENONCE(rdata)->stage); 2887 } 2888 } 2889 nonce_list_push(id_list, RENONCE(rdata)->id); 2890 2891 if (RENONCE(rdata)->match == true) 2892 break; 2893 } 2894 2895 rdata = rdata->next; 2896 } 2897 L_UNLOCK(info->renonce_list); 2898 2899 /* remove nonce from list */ 2900 renoncework_list_pop(info->renoncework_list); 2901 rnwdata = info->renoncework_list->head; 2902 } 2903 L_UNLOCK(info->renoncework_list); 2904 2905 L_LOCK(info->renonce_list); 2906 bf_data_t* rdata = info->renonce_list->head; 2907 while (rdata != NULL) { 2908 if (RENONCE(rdata)->match == true) { 2909 bf_data_t* rndata = rdata->next; 2910 renonce_list_remove(info->renonce_list, rdata); 2911 rdata = rndata; 2912 continue; 2913 } 2914 2915 /* update stage */ 2916 bf_data_t* ndata = id_list->head; 2917 while (ndata != NULL) { 2918 if (NONCE(ndata)->nonce == RENONCE(rdata)->id) { 2919 RENONCE(rdata)->stage++; 2920 RENONCE(rdata)->sent = false; 2921 RENONCE(rdata)->received = false; 2922 break; 2923 } 2924 ndata = ndata->next; 2925 } 2926 2927 /* update tasks with wrong or dup nonces recieved */ 2928 if ((RENONCE(rdata)->stage != RENONCE_STAGE_FINISHED) && 2929 (RENONCE(rdata)->received == true)) { 2930 RENONCE(rdata)->stage++; 2931 RENONCE(rdata)->sent = false; 2932 RENONCE(rdata)->received = false; 2933 } 2934 2935 /* clear renonces list if we are running too slow */ 2936 if ((RENONCE(rdata)->stage >= RENONCE_STAGE2) && 2937 (info->renonce_list->count > RENONCE_STAGE2_LIMIT)) { 2938 info->unmatched++; 2939 increase_re_bad_nonces(info, RENONCE(rdata)->src_address); 2940 bf_data_t* rndata = rdata->next; 2941 renonce_list_remove(info->renonce_list, rdata); 2942 rdata = rndata; 2943 continue; 2944 } 2945 2946 if ((RENONCE(rdata)->stage >= RENONCE_STAGE3) && 2947 (info->renonce_list->count > RENONCE_STAGE3_LIMIT)) { 2948 info->unmatched++; 2949 increase_re_bad_nonces(info, RENONCE(rdata)->src_address); 2950 bf_data_t* rndata = rdata->next; 2951 renonce_list_remove(info->renonce_list, rdata); 2952 rdata = rndata; 2953 continue; 2954 } 2955 2956 if ((RENONCE(rdata)->stage == RENONCE_STAGE_FINISHED) && 2957 (RENONCE(rdata)->sent == false)) { 2958 info->unmatched++; 2959 increase_re_bad_nonces(info, RENONCE(rdata)->src_address); 2960 bf_data_t* rndata = rdata->next; 2961 renonce_list_remove(info->renonce_list, rdata); 2962 rdata = rndata; 2963 continue; 2964 } 2965 2966 rdata = rdata->next; 2967 } 2968 L_UNLOCK(info->renonce_list); 2969 2970 /* clear id list */ 2971 bf_data_t* ndata = id_list->head; 2972 while (ndata != NULL) { 2973 nonce_list_pop(id_list); 2974 ndata = id_list->head; 2975 } 2976 2977 gettimeofday(&stop_time, NULL); 2978 2979 #if 0 2980 applog(LOG_DEBUG, "%s: renonceworker_thr: nonces processed [%d]: time elapsed: [%.6f]", 2981 bitfury->drv->name, 2982 nonce_cnt, timediff(start_time, stop_time)); 2983 #endif 2984 2985 cgsleep_us(RENONCEWORKER_DELAY); 2986 } 2987 2988 applog(LOG_INFO, "%s: renonceworker_thr: exiting...", bitfury->drv->name); 2989 return NULL; 2990 } 2991 2992 int16_t update_pid(bf_pid_t *pid, int16_t error) 2993 { 2994 int16_t pTerm, iTerm; 2995 2996 pTerm = 2 * error; 2997 2998 pid->i_state += error; 2999 if(pid->i_state > pid->i_max) 3000 pid->i_state = pid->i_max; 3001 else if(pid->i_state < pid->i_min) 3002 pid->i_state = pid->i_min; 3003 3004 iTerm = pid->i_state; 3005 3006 return (pTerm + iTerm); 3007 } 3008 3009 static void *bitfury_hwmonitor(void *userdata) 3010 { 3011 struct cgpu_info *bitfury = (struct cgpu_info *)userdata; 3012 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 3013 3014 uint8_t board_id, bcm250_id, chip_id; 3015 time_t curr_time; 3016 3017 applog(LOG_INFO, "%s: started hwmonitor thread", bitfury->drv->name); 3018 3019 while (bitfury->shutdown == false) { 3020 if (info->initialised) { 3021 break; 3022 } 3023 cgsleep_us(30); 3024 } 3025 3026 applog(LOG_INFO, "%s: hwmonitor loop started", bitfury->drv->name); 3027 3028 while (bitfury->shutdown == false) { 3029 float max_temp = 0.0; 3030 float t_alarm = 100.0; 3031 3032 bool a_temp = false; 3033 bool a_ichain = false; 3034 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 3035 /* read hw sensor data */ 3036 char buff[256]; 3037 3038 if (info->chipboard[board_id].detected == true) { 3039 memset(buff, 0, sizeof(buff)); 3040 if (device_uart_txrx(board_id + 1, "S", buff) < 0) 3041 quit(1, "%s: %s() failed to get BOARD%d status", 3042 bitfury->drv->name, __func__, board_id + 1); 3043 3044 if (parse_hwstats(info, board_id, buff) < 0) 3045 applog(LOG_ERR, "%s: failed to parse hw stats", 3046 bitfury->drv->name); 3047 3048 info->chipboard[board_id].p_chain1 = info->chipboard[board_id].u_chain1 * info->chipboard[board_id].i_chain1; 3049 info->chipboard[board_id].p_chain2 = info->chipboard[board_id].u_chain2 * info->chipboard[board_id].i_chain2; 3050 3051 /* fan power calculation */ 3052 if (info->chipboard[board_id].rpm != 0) { 3053 if (info->chipboard[board_id].fan_speed > 40) 3054 info->chipboard[board_id].p_fan = (0.1 + 0.0236 * (info->chipboard[board_id].fan_speed - 40)) * 3055 (info->chipboard[board_id].u_board + U_LOSS); 3056 else 3057 info->chipboard[board_id].p_fan = 1.23; 3058 } else { 3059 info->chipboard[board_id].p_fan = 0.0; 3060 } 3061 3062 /* board power calculation */ 3063 #ifdef MINER_X5 3064 float i_board = info->chipboard[board_id].i_chain1; 3065 #endif 3066 3067 #ifdef MINER_X6 3068 float i_board = info->chipboard[board_id].i_chain1 + info->chipboard[board_id].i_chain2; 3069 #endif 3070 info->chipboard[board_id].p_board = ((info->chipboard[board_id].u_board + U_LOSS) * i_board + 2.0 + 3071 info->chipboard[board_id].p_fan); 3072 3073 if (info->chipboard[board_id].a_temp == 1) 3074 a_temp = true; 3075 3076 if ((info->chipboard[board_id].a_ichain1 == 1) || 3077 (info->chipboard[board_id].a_ichain2 == 1)) 3078 a_ichain = true; 3079 3080 if (max_temp < info->chipboard[board_id].temp) 3081 max_temp = info->chipboard[board_id].temp; 3082 3083 if (t_alarm > info->chipboard[board_id].t_alarm) 3084 t_alarm = info->chipboard[board_id].t_alarm; 3085 } 3086 } 3087 3088 /* enable temp alarm */ 3089 if ((a_temp == true) && (info->a_temp == false)) { 3090 applog(LOG_ERR, "%s: temperature alarm enabled: [%5.1f]!!!", 3091 bitfury->drv->name, max_temp); 3092 3093 /* enable fans to full speed*/ 3094 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 3095 if (info->chipboard[board_id].detected == true) { 3096 if (device_uart_transfer(board_id + 1, "F:100") < 0) 3097 quit(1, "%s: %s() failed to set BOARD%d fan speed", 3098 bitfury->drv->name, __func__, board_id + 1); 3099 3100 applog(LOG_INFO, "%s: set BOARD%d fan speed to max speed", 3101 bitfury->drv->name, board_id + 1); 3102 } 3103 } 3104 } 3105 3106 /* temp alarm recovery */ 3107 if ((a_temp == false) && (info->a_temp == true)) { 3108 applog(LOG_ERR, "%s: temperature alarm recovery: [%5.1f]", 3109 bitfury->drv->name, max_temp); 3110 3111 /* restore fans speed */ 3112 set_fan_speed(bitfury); 3113 3114 reinit_x5(info, false); 3115 } 3116 3117 /* enable power chain alarm */ 3118 if ((a_ichain == true) && (info->a_ichain == false)) { 3119 applog(LOG_ERR, "%s: power chain alarm enabled!!!", 3120 bitfury->drv->name); 3121 info->ialarm_start = time(NULL); 3122 } 3123 3124 /* power chain alarm recovery */ 3125 if ((a_ichain == false) && (info->a_ichain == true)) { 3126 if (info->ialarm_count > 1) { 3127 applog(LOG_ERR, "%s: power chain alarm recovery", 3128 bitfury->drv->name); 3129 3130 info->ialarm_count = 1; 3131 info->ialarm_buzzer = false; 3132 info->ialarm_start = time(NULL); 3133 3134 reinit_x5(info, false); 3135 } 3136 } 3137 3138 info->a_temp = a_temp; 3139 info->a_ichain = a_ichain; 3140 3141 if (info->a_temp == true) 3142 applog(LOG_ERR, "%s: ALARM: board temp: [%5.1f] alarm temp: [%5.1f]", 3143 bitfury->drv->name, max_temp, t_alarm); 3144 3145 if (info->a_ichain == true) { 3146 curr_time = time(NULL); 3147 3148 if (curr_time - info->ialarm_start >= info->ialarm_count * ICHAIN_ALARM_INTERVAL) { 3149 info->ialarm_count *= 2; 3150 info->ialarm_start = curr_time; 3151 3152 /* enable power chain */ 3153 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 3154 enable_power_chain(bitfury, board_id, 0); 3155 #ifdef MINER_X5 3156 info->chipboard[board_id].power_enable_time = curr_time; 3157 #endif 3158 #ifdef MINER_X6 3159 info->chipboard[board_id].power1_enable_time = curr_time; 3160 info->chipboard[board_id].power2_enable_time = curr_time; 3161 #endif 3162 } 3163 } 3164 } else if (opt_bf16_power_management_disabled == false) { 3165 if (info->a_net == true) { 3166 /* disable power chain if no internet available */ 3167 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 3168 if (info->chipboard[board_id].detected == true) { 3169 #ifdef MINER_X5 3170 if (info->chipboard[board_id].p_chain1_enabled == 1) { 3171 #endif 3172 #ifdef MINER_X6 3173 if ((info->chipboard[board_id].p_chain1_enabled == 1) || 3174 (info->chipboard[board_id].p_chain2_enabled == 1)) { 3175 #endif 3176 disable_power_chain(bitfury, board_id, 0); 3177 } 3178 } 3179 } 3180 } else { 3181 /* enable power chain - internet recovery */ 3182 bool recovery = false; 3183 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 3184 if (info->chipboard[board_id].detected == true) { 3185 #ifdef MINER_X5 3186 if ((info->chipboard[board_id].p_chain1_enabled == 0) && 3187 (info->chipboard[board_id].power_disabled == false)) { 3188 enable_power_chain(bitfury, board_id, 0); 3189 info->chipboard[board_id].power_enable_time = time(NULL); 3190 3191 /* wait for power chain to enable */ 3192 cgsleep_us(POWER_WAIT_INTERVAL); 3193 3194 reinit_x5(info, false); 3195 } 3196 #endif 3197 3198 #ifdef MINER_X6 3199 if ((info->chipboard[board_id].p_chain1_enabled == 0) && 3200 (info->chipboard[board_id].power1_disabled == false)){ 3201 enable_power_chain(bitfury, board_id, 1); 3202 info->chipboard[board_id].power1_enable_time = time(NULL); 3203 recovery = true; 3204 } 3205 3206 if ((info->chipboard[board_id].p_chain2_enabled == 0) && 3207 (info->chipboard[board_id].power2_disabled == false)) { 3208 enable_power_chain(bitfury, board_id, 2); 3209 info->chipboard[board_id].power2_enable_time = time(NULL); 3210 recovery = true; 3211 } 3212 #endif 3213 } 3214 } 3215 3216 /* reinit chips on alarm recovery */ 3217 if (recovery == true) { 3218 /* wait for power chain to enable */ 3219 cgsleep_us(POWER_WAIT_INTERVAL); 3220 3221 reinit_x5(info, false); 3222 } 3223 } 3224 } 3225 3226 /* board temperature regulation */ 3227 char uart_cmd[8]; 3228 if (manual_pid_enabled == false) { 3229 sprintf(uart_cmd, "N:%d", (int)max_temp); 3230 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 3231 if (info->chipboard[board_id].detected == true) { 3232 if (device_uart_transfer(board_id + 1, uart_cmd) < 0) 3233 quit(1, "%s: %s() failed to set BOARD%d next temp", 3234 bitfury->drv->name, __func__, board_id + 1); 3235 3236 applog(LOG_INFO, "%s: set BOARD%d next temp to [%5.1f]", 3237 bitfury->drv->name, board_id + 1, max_temp); 3238 } 3239 } 3240 } else { 3241 uint8_t max_fan_speed = 0; 3242 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 3243 if (info->chipboard[board_id].detected == true) { 3244 uint16_t pid_temp = 10 * info->chipboard[board_id].temp; 3245 if (10 * max_temp > pid_temp) 3246 pid_temp = 10 * max_temp; 3247 3248 int16_t fan_speed = update_pid(&info->chipboard[board_id].pid, 3249 (pid_temp - 10 * info->chipboard[board_id].target_temp) / 10); 3250 3251 if (fan_speed > 100) 3252 fan_speed = 100; 3253 else if (fan_speed < 0) 3254 fan_speed = 0; 3255 3256 if (max_fan_speed < fan_speed) 3257 max_fan_speed = fan_speed; 3258 } 3259 } 3260 3261 sprintf(uart_cmd, "F:%d", max_fan_speed); 3262 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 3263 if (info->chipboard[board_id].detected == true) { 3264 if (device_uart_transfer(board_id + 1, uart_cmd) < 0) 3265 quit(1, "%s: %s() failed to set BOARD%d fan speed", 3266 bitfury->drv->name, __func__, board_id + 1); 3267 3268 applog(LOG_INFO, "%s: set BOARD%d fan speed to [%d]", 3269 bitfury->drv->name, board_id + 1, max_fan_speed); 3270 } 3271 } 3272 } 3273 3274 /* board power management */ 3275 if (opt_bf16_power_management_disabled == false) { 3276 curr_time = time(NULL); 3277 3278 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 3279 if (info->chipboard[board_id].detected == true) { 3280 #ifdef MINER_X5 3281 uint8_t disabled_chips = 0; 3282 uint8_t total_chips = 0; 3283 #endif 3284 3285 #ifdef MINER_X6 3286 uint8_t disabled_chips_chain1 = 0; 3287 uint8_t total_chips_chain1 = 0; 3288 uint8_t disabled_chips_chain2 = 0; 3289 uint8_t total_chips_chain2 = 0; 3290 #endif 3291 for (bcm250_id = 0; bcm250_id < BCM250_NUM; bcm250_id++) { 3292 uint8_t first_good_chip = info->chipboard[board_id].bcm250[bcm250_id].first_good_chip; 3293 uint8_t last_good_chip = info->chipboard[board_id].bcm250[bcm250_id].last_good_chip; 3294 3295 /* chips loop */ 3296 for (chip_id = first_good_chip; chip_id < last_good_chip; chip_id++) { 3297 #ifdef MINER_X5 3298 total_chips++; 3299 3300 if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status == DISABLED) 3301 disabled_chips++; 3302 #endif 3303 3304 #ifdef MINER_X6 3305 if (bcm250_id < BCM250_NUM / 2) { 3306 total_chips_chain1++; 3307 3308 if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status == DISABLED) 3309 disabled_chips_chain1++; 3310 } 3311 3312 if ((bcm250_id >= BCM250_NUM / 2) && (bcm250_id < BCM250_NUM)) { 3313 total_chips_chain2++; 3314 3315 if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status == DISABLED) 3316 disabled_chips_chain2++; 3317 } 3318 #endif 3319 } 3320 } 3321 3322 #ifdef MINER_X5 3323 /* disable chain power if all chips failed */ 3324 if ((total_chips == disabled_chips) && 3325 (info->chipboard[board_id].p_chain1_enabled == 1)) { 3326 disable_power_chain(bitfury, board_id, 0); 3327 3328 /* increase disable counter until we reach long enough work time */ 3329 time_t work_interval = curr_time - info->chipboard[board_id].power_enable_time; 3330 if (work_interval < CHAIN_WORK_INTERVAL) 3331 info->chipboard[board_id].power_disable_count *= 2; 3332 3333 info->chipboard[board_id].power_disabled = true; 3334 info->chipboard[board_id].power_disable_time = curr_time; 3335 info->chipboard[board_id].chips_disabled = info->chipboard[board_id].chips_num; 3336 } 3337 3338 /* enable disabled chain */ 3339 if ((info->chipboard[board_id].p_chain1_enabled == 0) && 3340 (info->chipboard[board_id].power_disabled == true) && 3341 (curr_time - info->chipboard[board_id].power_disable_time >= info->chipboard[board_id].power_disable_count * CHAIN_REENABLE_INTERVAL)) { 3342 time_t disable_interval = curr_time - info->chipboard[board_id].power_disable_time; 3343 info->chipboard[board_id].power_disable_time = curr_time; 3344 info->chipboard[board_id].chips_disabled = 0; 3345 3346 enable_power_chain(bitfury, board_id, 0); 3347 info->chipboard[board_id].power_enable_time = curr_time; 3348 info->chipboard[board_id].power_disabled = false; 3349 3350 /* wait for power chain to enable */ 3351 cgsleep_us(POWER_WAIT_INTERVAL); 3352 3353 reinit_x5(info, true); 3354 applog(LOG_NOTICE, "%s: reenabled power on BOARD%d: time interval [%d]", 3355 bitfury->drv->name, 3356 board_id + 1, (int)disable_interval); 3357 #ifdef FILELOG 3358 filelog(info, "%s: reenabled power on BOARD%d: time interval [%d]", 3359 bitfury->drv->name, 3360 board_id + 1, (int)disable_interval); 3361 #endif 3362 } 3363 #endif 3364 3365 #ifdef MINER_X6 3366 /* disable power on chain 1 only if chips on both chains failed 3367 * as chain 2 data channel depends on chain 1 */ 3368 if ((total_chips_chain1 == disabled_chips_chain1) && 3369 (info->chipboard[board_id].p_chain1_enabled == 1) && 3370 (info->chipboard[board_id].power2_disabled == true)) { 3371 disable_power_chain(bitfury, board_id, 0); 3372 3373 /* increase disable counter until we reach long enough work time */ 3374 time_t work_interval = curr_time - info->chipboard[board_id].power1_enable_time; 3375 if (work_interval < CHAIN_WORK_INTERVAL) 3376 info->chipboard[board_id].power1_disable_count *= 2; 3377 3378 info->chipboard[board_id].power1_disabled = true; 3379 info->chipboard[board_id].power2_disabled = true; 3380 info->chipboard[board_id].power1_disable_time = curr_time; 3381 info->chipboard[board_id].power2_disable_time = curr_time; 3382 info->chipboard[board_id].chips_disabled = info->chipboard[board_id].chips_num; 3383 } else 3384 if ((total_chips_chain2 == disabled_chips_chain2) && 3385 (info->chipboard[board_id].p_chain2_enabled == 1)) { 3386 disable_power_chain(bitfury, board_id, 2); 3387 3388 /* increase disable counter until we reach long enough work time */ 3389 time_t work_interval = curr_time - info->chipboard[board_id].power2_enable_time; 3390 if (work_interval < CHAIN_WORK_INTERVAL) 3391 info->chipboard[board_id].power2_disable_count *= 2; 3392 3393 info->chipboard[board_id].power2_disabled = true; 3394 info->chipboard[board_id].power2_disable_time = curr_time; 3395 info->chipboard[board_id].chips_disabled = info->chipboard[board_id].chips_num / 2; 3396 } 3397 3398 /* HW FIX: try to reenable disabled chain */ 3399 if ((info->chipboard[board_id].p_chain1_enabled == 0) && 3400 (info->chipboard[board_id].power1_disabled == true) && 3401 (curr_time - info->chipboard[board_id].power1_disable_time >= info->chipboard[board_id].power1_disable_count * CHAIN_REENABLE_INTERVAL)) { 3402 time_t disable_interval = curr_time - info->chipboard[board_id].power1_disable_time; 3403 info->chipboard[board_id].power1_disable_time = curr_time; 3404 info->chipboard[board_id].power2_disable_time = curr_time; 3405 info->chipboard[board_id].chips_disabled = 0; 3406 3407 enable_power_chain(bitfury, board_id, 0); 3408 info->chipboard[board_id].power1_enable_time = curr_time; 3409 info->chipboard[board_id].power2_enable_time = curr_time; 3410 info->chipboard[board_id].power1_disabled = false; 3411 info->chipboard[board_id].power2_disabled = false; 3412 3413 /* wait for power chain to enable */ 3414 cgsleep_us(POWER_WAIT_INTERVAL); 3415 3416 reinit_x5(info, true); 3417 applog(LOG_NOTICE, "%s: reenabled power on BOARD%d: time interval [%d]", 3418 bitfury->drv->name, 3419 board_id + 1, (int)disable_interval); 3420 #ifdef FILELOG 3421 filelog(info, "%s: reenabled power on BOARD%d: time interval [%d]", 3422 bitfury->drv->name, 3423 board_id + 1, (int)disable_interval); 3424 #endif 3425 3426 } else 3427 if ((info->chipboard[board_id].p_chain2_enabled == 0) && 3428 (info->chipboard[board_id].power2_disabled == true) && 3429 (curr_time - info->chipboard[board_id].power2_disable_time >= info->chipboard[board_id].power2_disable_count * CHAIN_REENABLE_INTERVAL)) { 3430 time_t disable_interval = curr_time - info->chipboard[board_id].power2_disable_time; 3431 info->chipboard[board_id].power2_disable_time = curr_time; 3432 info->chipboard[board_id].chips_disabled = 0; 3433 3434 enable_power_chain(bitfury, board_id, 2); 3435 info->chipboard[board_id].power2_enable_time = curr_time; 3436 info->chipboard[board_id].power2_disabled = false; 3437 3438 /* wait for power chain to enable */ 3439 cgsleep_us(POWER_WAIT_INTERVAL); 3440 3441 reinit_x5(info, true); 3442 applog(LOG_NOTICE, "%s: reenabled chainboard 2 on BOARD%d: time interval [%d]", 3443 bitfury->drv->name, 3444 board_id + 1, (int)disable_interval); 3445 #ifdef FILELOG 3446 filelog(info, "%s: reenabled chainboard 2 on BOARD%d: time interval [%d]", 3447 bitfury->drv->name, 3448 board_id + 1, (int)disable_interval); 3449 #endif 3450 } 3451 #endif 3452 /* switch renonce chip to next board */ 3453 if ((info->renonce_chips == 1) && 3454 (renonce_chip_address[board_id].board_id == board_id) && 3455 #ifdef MINER_X5 3456 (info->chipboard[board_id].power_disabled == true)) { 3457 #endif 3458 #ifdef MINER_X6 3459 (info->chipboard[board_id].power1_disabled == true) && 3460 (info->chipboard[board_id].power2_disabled == true)) { 3461 #endif 3462 uint8_t next_board_id = (board_id + 1) % CHIPBOARD_NUM; 3463 uint8_t next_bcm250_id = renonce_chip_address[board_id].bcm250_id; 3464 uint8_t next_chip_id = renonce_chip_address[board_id].chip_id; 3465 3466 /* board id should be set last */ 3467 renonce_chip_address[next_board_id].bcm250_id = next_bcm250_id; 3468 renonce_chip_address[next_board_id].chip_id = next_chip_id; 3469 renonce_chip_address[next_board_id].board_id = next_board_id; 3470 3471 info->chipboard[next_board_id].bcm250[next_bcm250_id].chips[next_chip_id].status = UNINITIALIZED; 3472 3473 applog(LOG_NOTICE, "%s: changed renonce chip address to: [%d:%d:%2d]", 3474 bitfury->drv->name, 3475 next_board_id, next_bcm250_id, next_chip_id); 3476 3477 renonce_chip_address[board_id].board_id = -1; 3478 renonce_chip_address[board_id].bcm250_id = -1; 3479 renonce_chip_address[board_id].chip_id = -1; 3480 } 3481 } 3482 } 3483 } 3484 3485 cgsleep_us(HWMONITOR_DELAY); 3486 } 3487 3488 applog(LOG_INFO, "%s: hwmonitor_thr: exiting...", bitfury->drv->name); 3489 return NULL; 3490 } 3491 3492 static void *bitfury_alarm(void *userdata) 3493 { 3494 struct cgpu_info *bitfury = (struct cgpu_info *)userdata; 3495 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 3496 3497 struct pool *pool; 3498 int i; 3499 time_t curr_time_t; 3500 struct timeval curr_time; 3501 3502 applog(LOG_INFO, "%s: started alarm thread", bitfury->drv->name); 3503 3504 /* blink lamps once */ 3505 led_red_enable(info); 3506 led_green_enable(info); 3507 3508 cgsleep_ms(1000); 3509 3510 led_red_disable(info); 3511 led_green_disable(info); 3512 buzzer_disable(info); 3513 3514 applog(LOG_INFO, "%s: alarm loop started", bitfury->drv->name); 3515 3516 while (bitfury->shutdown == false) { 3517 curr_time_t = time(NULL); 3518 gettimeofday(&curr_time, NULL); 3519 /* check if there are enabled pools present */ 3520 bool idle = true; 3521 for (i = 0; i < total_pools; i++) { 3522 pool = pools[i]; 3523 if (pool->idle == false) 3524 idle = false; 3525 } 3526 3527 if (idle == true) 3528 info->a_net = true; 3529 else 3530 info->a_net = false; 3531 3532 /* temperature alarm processing */ 3533 if ((info->a_temp == true) && (info->a_ichain == false)) { 3534 if (timediff_us(info->led_red_switch, curr_time) >= LED_RED_INTERVAL) { 3535 if (info->led_red_enabled == true) 3536 led_red_disable(info); 3537 else 3538 led_red_enable(info); 3539 } 3540 3541 /* enable buzzer */ 3542 if (timediff_us(info->buzzer_switch, curr_time) >= BUZZER_INTERVAL) { 3543 if (info->buzzer_enabled == true) 3544 buzzer_disable(info); 3545 else 3546 buzzer_enable(info); 3547 } 3548 } else if ((info->a_ichain == false) && (info->a_net == false)) { 3549 if (info->led_red_enabled == true) 3550 led_red_disable(info); 3551 3552 if (info->buzzer_enabled == true) 3553 buzzer_disable(info); 3554 } 3555 3556 /* power chain alarm processing */ 3557 if ((info->a_ichain == true) && (info->a_temp == false)) { 3558 if (timediff_us(info->led_red_switch, curr_time) >= LED_RED_INTERVAL) { 3559 if (info->led_red_enabled == true) 3560 led_red_disable(info); 3561 else 3562 led_red_enable(info); 3563 } 3564 3565 if (info->ialarm_buzzer == false) { 3566 buzzer_enable(info); 3567 cgsleep_ms(1000); 3568 buzzer_disable(info); 3569 3570 info->ialarm_buzzer = true; 3571 } 3572 3573 /* enable buzzer */ 3574 if (curr_time_t - info->ialarm_start >= info->ialarm_count * ICHAIN_ALARM_INTERVAL) { 3575 buzzer_enable(info); 3576 cgsleep_ms(1000); 3577 buzzer_disable(info); 3578 } 3579 } else if ((info->a_temp == false) && (info->a_net == false)) { 3580 if (info->led_red_enabled == true) 3581 led_red_disable(info); 3582 3583 if (info->buzzer_enabled == true) 3584 buzzer_disable(info); 3585 } 3586 3587 /* blink green lamp if there are enabled pools present and no alarms active */ 3588 if ((info->a_net == false) && (info->a_temp == false) && (info->a_ichain == false)) { 3589 if (info->led_red_enabled == true) 3590 led_red_disable(info); 3591 3592 if (timediff_us(info->led_green_switch, curr_time) >= LED_GREEN_INTERVAL) { 3593 if (info->led_green_enabled == true) 3594 led_green_disable(info); 3595 else 3596 led_green_enable(info); 3597 } 3598 } else { 3599 if (info->led_green_enabled == true) 3600 led_green_disable(info); 3601 3602 if ((info->a_temp == false) && (info->a_ichain == false)) { 3603 if (timediff_us(info->led_red_switch, curr_time) >= LED_RED_NET_INTERVAL) { 3604 if (info->led_red_enabled == true) 3605 led_red_disable(info); 3606 else 3607 led_red_enable(info); 3608 } 3609 } 3610 } 3611 3612 cgsleep_us(ALARM_DELAY); 3613 } 3614 3615 led_red_disable(info); 3616 led_green_disable(info); 3617 buzzer_disable(info); 3618 3619 applog(LOG_INFO, "%s: alarm_thr: exiting...", bitfury->drv->name); 3620 return NULL; 3621 } 3622 3623 static void *bitfury_statistics(void *userdata) 3624 { 3625 struct cgpu_info *bitfury = (struct cgpu_info *)userdata; 3626 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 3627 3628 struct timeval start_time, stop_time; 3629 uint8_t board_id, bcm250_id, chip_id; 3630 3631 float u_board; 3632 float i_total; 3633 float p_total; 3634 float u_chip; 3635 float p_chip; 3636 3637 time_t time0 = time(NULL); 3638 time_t time1 = time(NULL); 3639 time_t time2; 3640 3641 /* statistics calculation loop */ 3642 while (bitfury->shutdown == false) { 3643 time2 = time(NULL); 3644 if (time2 - time1 >= AVG_TIME_DELTA) { 3645 gettimeofday(&start_time, NULL); 3646 3647 u_board = 0.0; 3648 i_total = 0.0; 3649 p_total = 0.0; 3650 u_chip = 0.0; 3651 p_chip = 0.0; 3652 3653 info->chips_failed = 0; 3654 info->chips_disabled = 0; 3655 3656 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 3657 if (info->chipboard[board_id].detected == true) { 3658 info->chipboard[board_id].chips_failed = 0; 3659 info->chips_disabled += info->chipboard[board_id].chips_disabled; 3660 3661 /* concentrator loop */ 3662 for (bcm250_id = 0; bcm250_id < BCM250_NUM; bcm250_id++) { 3663 uint8_t first_good_chip = info->chipboard[board_id].bcm250[bcm250_id].first_good_chip; 3664 uint8_t last_good_chip = info->chipboard[board_id].bcm250[bcm250_id].last_good_chip; 3665 3666 info->chipboard[board_id].bcm250[bcm250_id].chips_failed = 0; 3667 3668 /* chips loop */ 3669 for (chip_id = first_good_chip; chip_id < last_good_chip; chip_id++) { 3670 3671 if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status >= FAILING) { 3672 info->chipboard[board_id].bcm250[bcm250_id].chips_failed++; 3673 info->chipboard[board_id].chips_failed++; 3674 info->chips_failed++; 3675 } 3676 3677 if (opt_bf16_stats_enabled) { 3678 get_average(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].task_switch, 3679 (float)info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].task_switch_dx, 3680 (float)(time2 - time1), AVG_TIME_INTERVAL); 3681 get_average(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_cmd, 3682 (float)info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_cmd_dx, 3683 (float)(time2 - time1), AVG_TIME_INTERVAL); 3684 get_average(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_cmd_none, 3685 (float)info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_cmd_none_dx, 3686 (float)(time2 - time1), AVG_TIME_INTERVAL); 3687 3688 get_average(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces, 3689 (float)info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_dx, 3690 (float)(time2 - time1), AVG_TIME_INTERVAL); 3691 3692 get_average(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].hashrate, 3693 (float)info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_dx, 3694 (float)(time2 - time1), AVG_TIME_INTERVAL); 3695 get_average(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].hashrate_good, 3696 (float)info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_good_dx, 3697 (float)(time2 - time1), AVG_TIME_INTERVAL); 3698 get_average(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].hashrate_diff, 3699 (float)info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_diff_dx, 3700 (float)(time2 - time1), AVG_TIME_INTERVAL); 3701 get_average(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].hashrate_bad, 3702 (float)info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_bad_dx, 3703 (float)(time2 - time1), AVG_TIME_INTERVAL); 3704 3705 if (opt_bf16_renonce != RENONCE_DISABLED) { 3706 get_average(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].hashrate_re, 3707 (float)info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_re_dx, 3708 (float)(time2 - time1), AVG_TIME_INTERVAL); 3709 get_average(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].hashrate_re_good, 3710 (float)info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_re_good_dx, 3711 (float)(time2 - time1), AVG_TIME_INTERVAL); 3712 get_average(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].hashrate_re_bad, 3713 (float)info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_re_bad_dx, 3714 (float)(time2 - time1), AVG_TIME_INTERVAL); 3715 } 3716 } 3717 3718 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].task_switch_dx = 0; 3719 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_cmd_dx = 0; 3720 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_cmd_none_dx = 0; 3721 3722 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_dx = 0; 3723 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_good_dx = 0; 3724 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_diff_dx = 0; 3725 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_bad_dx = 0; 3726 3727 if (opt_bf16_renonce != RENONCE_DISABLED) { 3728 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_re_dx = 0; 3729 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_re_good_dx = 0; 3730 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces_re_bad_dx = 0; 3731 } 3732 3733 if (opt_bf16_stats_enabled) { 3734 if (opt_bf16_renonce != RENONCE_DISABLED) 3735 applog(LOG_NOTICE, "STATS: chp [%d:%d:%2d], tsk/s [%4.0f], " 3736 "ncs/s [%4.0f], sts/s [%3.0f], none/s [%3.0f], hr/s [%8.3f] hr+/s [%8.3f] rhr/s [%8.3f]", 3737 board_id, bcm250_id, chip_id, 3738 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].task_switch, 3739 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces, 3740 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_cmd, 3741 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_cmd_none, 3742 CHIP_COEFF * info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].hashrate, 3743 CHIP_COEFF * info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].hashrate_good, 3744 CHIP_COEFF * (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].hashrate_good + 3745 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].hashrate_re_good)); 3746 else 3747 applog(LOG_NOTICE, "STATS: chp [%d:%d:%2d], tsk/s [%4.0f], " 3748 "ncs/s [%3.0f], sts/s [%3.0f], none/s [%3.0f], hr/s [%8.3f] hr+/s [%8.3f]", 3749 board_id, bcm250_id, chip_id, 3750 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].task_switch, 3751 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonces, 3752 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_cmd, 3753 info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status_cmd_none, 3754 CHIP_COEFF * info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].hashrate, 3755 CHIP_COEFF * info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].hashrate_good); 3756 } 3757 } 3758 3759 if (opt_bf16_stats_enabled) { 3760 get_average(&info->chipboard[board_id].bcm250[bcm250_id].task_switch, 3761 (float)info->chipboard[board_id].bcm250[bcm250_id].task_switch_dx, 3762 (float)(time2 - time1), AVG_TIME_INTERVAL); 3763 get_average(&info->chipboard[board_id].bcm250[bcm250_id].status_cmd, 3764 (float)info->chipboard[board_id].bcm250[bcm250_id].status_cmd_dx, 3765 (float)(time2 - time1), AVG_TIME_INTERVAL); 3766 get_average(&info->chipboard[board_id].bcm250[bcm250_id].status_cmd_none, 3767 (float)info->chipboard[board_id].bcm250[bcm250_id].status_cmd_none_dx, 3768 (float)(time2 - time1), AVG_TIME_INTERVAL); 3769 3770 get_average(&info->chipboard[board_id].bcm250[bcm250_id].nonces, 3771 (float)info->chipboard[board_id].bcm250[bcm250_id].nonces_dx, 3772 (float)(time2 - time1), AVG_TIME_INTERVAL); 3773 3774 get_average(&info->chipboard[board_id].bcm250[bcm250_id].hashrate, 3775 (float)info->chipboard[board_id].bcm250[bcm250_id].nonces_dx, 3776 (float)(time2 - time1), AVG_TIME_INTERVAL); 3777 get_average(&info->chipboard[board_id].bcm250[bcm250_id].hashrate_good, 3778 (float)info->chipboard[board_id].bcm250[bcm250_id].nonces_good_dx, 3779 (float)(time2 - time1), AVG_TIME_INTERVAL); 3780 get_average(&info->chipboard[board_id].bcm250[bcm250_id].hashrate_diff, 3781 (float)info->chipboard[board_id].bcm250[bcm250_id].nonces_diff_dx, 3782 (float)(time2 - time1), AVG_TIME_INTERVAL); 3783 get_average(&info->chipboard[board_id].bcm250[bcm250_id].hashrate_bad, 3784 (float)info->chipboard[board_id].bcm250[bcm250_id].nonces_bad_dx, 3785 (float)(time2 - time1), AVG_TIME_INTERVAL); 3786 3787 if (opt_bf16_renonce != RENONCE_DISABLED) { 3788 get_average(&info->chipboard[board_id].bcm250[bcm250_id].hashrate_re, 3789 (float)info->chipboard[board_id].bcm250[bcm250_id].nonces_re_dx, 3790 (float)(time2 - time1), AVG_TIME_INTERVAL); 3791 get_average(&info->chipboard[board_id].bcm250[bcm250_id].hashrate_re_good, 3792 (float)info->chipboard[board_id].bcm250[bcm250_id].nonces_re_good_dx, 3793 (float)(time2 - time1), AVG_TIME_INTERVAL); 3794 get_average(&info->chipboard[board_id].bcm250[bcm250_id].hashrate_re_bad, 3795 (float)info->chipboard[board_id].bcm250[bcm250_id].nonces_re_bad_dx, 3796 (float)(time2 - time1), AVG_TIME_INTERVAL); 3797 } 3798 } 3799 3800 info->chipboard[board_id].bcm250[bcm250_id].task_switch_dx = 0; 3801 info->chipboard[board_id].bcm250[bcm250_id].status_cmd_dx = 0; 3802 info->chipboard[board_id].bcm250[bcm250_id].status_cmd_none_dx = 0; 3803 3804 info->chipboard[board_id].bcm250[bcm250_id].nonces_dx = 0; 3805 info->chipboard[board_id].bcm250[bcm250_id].nonces_good_dx = 0; 3806 info->chipboard[board_id].bcm250[bcm250_id].nonces_diff_dx = 0; 3807 info->chipboard[board_id].bcm250[bcm250_id].nonces_bad_dx = 0; 3808 3809 if (opt_bf16_renonce != RENONCE_DISABLED) { 3810 info->chipboard[board_id].bcm250[bcm250_id].nonces_re_dx = 0; 3811 info->chipboard[board_id].bcm250[bcm250_id].nonces_re_good_dx = 0; 3812 info->chipboard[board_id].bcm250[bcm250_id].nonces_re_bad_dx = 0; 3813 } 3814 } 3815 3816 if (opt_bf16_stats_enabled) { 3817 get_average(&info->chipboard[board_id].task_switch, 3818 (float)info->chipboard[board_id].task_switch_dx, 3819 (float)(time2 - time1), AVG_TIME_INTERVAL); 3820 get_average(&info->chipboard[board_id].status_cmd, 3821 (float)info->chipboard[board_id].status_cmd_dx, 3822 (float)(time2 - time1), AVG_TIME_INTERVAL); 3823 get_average(&info->chipboard[board_id].status_cmd_none, 3824 (float)info->chipboard[board_id].status_cmd_none_dx, 3825 (float)(time2 - time1), AVG_TIME_INTERVAL); 3826 3827 get_average(&info->chipboard[board_id].nonces, 3828 (float)info->chipboard[board_id].nonces_dx, 3829 (float)(time2 - time1), AVG_TIME_INTERVAL); 3830 } 3831 3832 get_average(&info->chipboard[board_id].hashrate, 3833 (float)info->chipboard[board_id].nonces_dx, 3834 (float)(time2 - time1), AVG_TIME_INTERVAL); 3835 get_average(&info->chipboard[board_id].hashrate_good, 3836 (float)info->chipboard[board_id].nonces_good_dx, 3837 (float)(time2 - time1), AVG_TIME_INTERVAL); 3838 get_average(&info->chipboard[board_id].hashrate_diff, 3839 (float)info->chipboard[board_id].nonces_diff_dx, 3840 (float)(time2 - time1), AVG_TIME_INTERVAL); 3841 get_average(&info->chipboard[board_id].hashrate_bad, 3842 (float)info->chipboard[board_id].nonces_bad_dx, 3843 (float)(time2 - time1), AVG_TIME_INTERVAL); 3844 3845 info->chipboard[board_id].task_switch_dx = 0; 3846 info->chipboard[board_id].status_cmd_dx = 0; 3847 info->chipboard[board_id].status_cmd_none_dx = 0; 3848 3849 info->chipboard[board_id].nonces_dx = 0; 3850 info->chipboard[board_id].nonces_good_dx = 0; 3851 info->chipboard[board_id].nonces_diff_dx = 0; 3852 info->chipboard[board_id].nonces_bad_dx = 0; 3853 3854 u_board += (info->chipboard[board_id].u_board + U_LOSS); 3855 #ifdef MINER_X5 3856 i_total += (info->chipboard[board_id].i_chain1); 3857 u_chip += (info->chipboard[board_id].u_chain1); 3858 p_chip += (info->chipboard[board_id].p_chain1); 3859 #endif 3860 3861 #ifdef MINER_X6 3862 i_total += (info->chipboard[board_id].i_chain1 + info->chipboard[board_id].i_chain2); 3863 u_chip += (info->chipboard[board_id].u_chain1 + info->chipboard[board_id].u_chain2); 3864 p_chip += (info->chipboard[board_id].p_chain1 + info->chipboard[board_id].p_chain2); 3865 #endif 3866 p_total += info->chipboard[board_id].p_board; 3867 3868 if (opt_bf16_renonce != RENONCE_DISABLED) { 3869 get_average(&info->chipboard[board_id].hashrate_re, 3870 (float)info->chipboard[board_id].nonces_re_dx, 3871 (float)(time2 - time1), AVG_TIME_INTERVAL); 3872 get_average(&info->chipboard[board_id].hashrate_re_good, 3873 (float)info->chipboard[board_id].nonces_re_good_dx, 3874 (float)(time2 - time1), AVG_TIME_INTERVAL); 3875 get_average(&info->chipboard[board_id].hashrate_re_bad, 3876 (float)info->chipboard[board_id].nonces_re_bad_dx, 3877 (float)(time2 - time1), AVG_TIME_INTERVAL); 3878 3879 info->chipboard[board_id].nonces_re_dx = 0; 3880 info->chipboard[board_id].nonces_re_good_dx = 0; 3881 info->chipboard[board_id].nonces_re_bad_dx = 0; 3882 } 3883 3884 get_average(&info->chipboard[board_id].txrx_speed, 3885 (float)info->chipboard[board_id].bytes_transmitted_dx, 3886 (float)(time2 - time1), AVG_TIME_INTERVAL); 3887 3888 info->chipboard[board_id].bytes_transmitted_dx = 0; 3889 3890 if (opt_bf16_stats_enabled) { 3891 if (opt_bf16_renonce != RENONCE_DISABLED) { 3892 applog(LOG_NOTICE, "STATS: board [%d] hrate: good: [%8.3f] re_good: [%8.3f] => " 3893 "[%8.3f] toren: [%8.3f] bad: [%8.3f] total: [%8.3f]", 3894 board_id, 3895 CHIP_COEFF * (info->chipboard[board_id].hashrate_good), 3896 CHIP_COEFF * (info->chipboard[board_id].hashrate_re_good), 3897 CHIP_COEFF * (info->chipboard[board_id].hashrate_good + info->chipboard[board_id].hashrate_re_good), 3898 CHIP_COEFF * (info->chipboard[board_id].hashrate - info->chipboard[board_id].hashrate_good), 3899 CHIP_COEFF * (info->chipboard[board_id].hashrate_bad), 3900 CHIP_COEFF * (info->chipboard[board_id].hashrate)); 3901 } else { 3902 applog(LOG_NOTICE, "STATS: board [%d] hrate: good: [%8.3f] " 3903 "bad: [%8.3f] total: [%8.3f]", 3904 board_id, 3905 CHIP_COEFF * (info->chipboard[board_id].hashrate_good), 3906 CHIP_COEFF * (info->chipboard[board_id].hashrate_bad), 3907 CHIP_COEFF * (info->chipboard[board_id].hashrate)); 3908 } 3909 3910 #ifdef MINER_X5 3911 applog(LOG_NOTICE, "STATS: TX/RX: [%5.3f] Mbit/s UB: [%3.1f] " 3912 "U1: [%3.1f] I1: [%3.1f] T: [%3.1f] RPM: [%4d] FAN: [%3d]", 3913 8.0 * info->chipboard[board_id].txrx_speed / 1000000, 3914 info->chipboard[board_id].u_board + U_LOSS, 3915 info->chipboard[board_id].u_chain1, 3916 info->chipboard[board_id].i_chain1, 3917 info->chipboard[board_id].temp, 3918 info->chipboard[board_id].rpm, 3919 info->chipboard[board_id].fan_speed); 3920 #endif 3921 3922 #ifdef MINER_X6 3923 applog(LOG_NOTICE, "STATS: TX/RX: [%5.3f] Mbit/s UB: [%3.1f] " 3924 "U1: [%3.1f] U2: [%3.1f] I1: [%3.1f] I2: [%3.1f] T: [%3.1f] RPM: [%4d] FAN: [%3d]", 3925 8.0 * info->chipboard[board_id].txrx_speed / 1000000, 3926 info->chipboard[board_id].u_board + U_LOSS, 3927 info->chipboard[board_id].u_chain1, 3928 info->chipboard[board_id].u_chain2, 3929 info->chipboard[board_id].i_chain1, 3930 info->chipboard[board_id].i_chain2, 3931 info->chipboard[board_id].temp, 3932 info->chipboard[board_id].rpm, 3933 info->chipboard[board_id].fan_speed); 3934 #endif 3935 3936 applog(LOG_NOTICE, "STATS: ver: [%d] fw: [%d] hwid: [%s]", 3937 info->chipboard[board_id].board_ver, 3938 info->chipboard[board_id].board_fwver, 3939 info->chipboard[board_id].board_hwid); 3940 } 3941 } 3942 } 3943 3944 if (opt_bf16_stats_enabled) { 3945 get_average(&info->task_switch, 3946 (float)info->task_switch_dx, 3947 (float)(time2 - time1), AVG_TIME_INTERVAL); 3948 get_average(&info->status_cmd, 3949 (float)info->status_cmd_dx, 3950 (float)(time2 - time1), AVG_TIME_INTERVAL); 3951 get_average(&info->status_cmd_none, 3952 (float)info->status_cmd_none_dx, 3953 (float)(time2 - time1), AVG_TIME_INTERVAL); 3954 3955 get_average(&info->chipboard[board_id].nonces, 3956 (float)info->chipboard[board_id].nonces_dx, 3957 (float)(time2 - time1), AVG_TIME_INTERVAL); 3958 } 3959 3960 get_average(&info->hashrate, 3961 (float)info->nonces_dx, 3962 (float)(time2 - time1), AVG_TIME_INTERVAL); 3963 get_average(&info->hashrate_good, 3964 (float)info->nonces_good_dx, 3965 (float)(time2 - time1), AVG_TIME_INTERVAL); 3966 get_average(&info->hashrate_diff, 3967 (float)info->nonces_diff_dx, 3968 (float)(time2 - time1), AVG_TIME_INTERVAL); 3969 get_average(&info->hashrate_bad, 3970 (float)info->nonces_bad_dx, 3971 (float)(time2 - time1), AVG_TIME_INTERVAL); 3972 3973 info->task_switch_dx = 0; 3974 info->status_cmd_dx = 0; 3975 info->status_cmd_none_dx = 0; 3976 3977 info->nonces_dx = 0; 3978 info->nonces_good_dx = 0; 3979 info->nonces_diff_dx = 0; 3980 info->nonces_bad_dx = 0; 3981 3982 if (opt_bf16_renonce != RENONCE_DISABLED) { 3983 get_average(&info->hashrate_re, 3984 (float)info->nonces_re_dx, 3985 (float)(time2 - time1), AVG_TIME_INTERVAL); 3986 get_average(&info->hashrate_re_good, 3987 (float)info->nonces_re_good_dx, 3988 (float)(time2 - time1), AVG_TIME_INTERVAL); 3989 get_average(&info->hashrate_re_bad, 3990 (float)info->nonces_re_bad_dx, 3991 (float)(time2 - time1), AVG_TIME_INTERVAL); 3992 3993 info->nonces_re_dx = 0; 3994 info->nonces_re_good_dx = 0; 3995 info->nonces_re_bad_dx = 0; 3996 } 3997 3998 time1 = time2; 3999 4000 gettimeofday(&stop_time, NULL); 4001 4002 uint32_t uptime = time2 - time0; 4003 uint32_t hours = uptime / 3600; 4004 uint8_t minutes = (uptime - hours * 3600) / 60; 4005 uint8_t seconds = uptime - hours * 3600 - minutes * 60; 4006 4007 info->u_avg = u_board / info->active_chipboard_num; 4008 info->i_total = i_total; 4009 info->p_total = p_total; 4010 info->u_chip = u_chip; 4011 info->p_chip = p_chip; 4012 4013 if (opt_bf16_stats_enabled) { 4014 if (opt_bf16_renonce != RENONCE_DISABLED) { 4015 applog(LOG_NOTICE, "STATS: rencs: [%d] stale: [%d] nws: [%d] rnws: [%d] failed: [%d]", 4016 info->renonce_list->count, 4017 info->stale_work_list->count, 4018 info->noncework_list->count, 4019 info->renoncework_list->count, 4020 info->chips_failed); 4021 4022 applog(LOG_NOTICE, "STATS: %4.0fGH/s osc: 0x%02x re_osc: 0x%02x " 4023 "%3.1fV %3.1fA %4.1fW %.3fW/GH", 4024 CHIP_COEFF * (info->hashrate_good + info->hashrate_re_good), 4025 bf16_chip_clock, 4026 bf16_renonce_chip_clock, 4027 info->u_avg, 4028 info->i_total, 4029 info->p_total, 4030 (info->a_net == true) ? 4031 0.0 : 4032 info->p_total / (CHIP_COEFF * (info->hashrate_good + info->hashrate_re_good))); 4033 4034 applog(LOG_NOTICE, "STATS: TOTAL: %5.1fGH/s %5.3fV %3.1fA %5.2fW " 4035 "CHIP: %5.1fGH/s GOOD: %4.1fGH/s RENONCE: %4.1fGH/s BAD: %4.1fGH/s", 4036 CHIP_COEFF * info->hashrate / (info->chips_num - info->renonce_chips - info->chips_failed), 4037 info->u_chip / (info->chips_num - info->chips_disabled), 4038 (info->a_net == true) ? 0.0 : info->p_chip / info->u_chip, 4039 info->p_chip / (info->chips_num - info->chips_disabled), 4040 CHIP_COEFF * (info->hashrate_good + info->hashrate_re_good) / (info->chips_num - info->renonce_chips - info->chips_failed), 4041 CHIP_COEFF * info->hashrate_good / (info->chips_num - info->renonce_chips - info->chips_failed), 4042 CHIP_COEFF * info->hashrate_re_good / (info->chips_num - info->renonce_chips - info->chips_failed), 4043 CHIP_COEFF * info->hashrate_re_bad / (info->chips_num - info->renonce_chips - info->chips_failed)); 4044 4045 #if 1 4046 applog(LOG_NOTICE, "STATS: m0: [%lu] mm0: [%lu] m1: [%lu] mm1: [%lu] m2: [%lu] mm2: [%lu] " 4047 "m3: [%lu] mm3: [%lu] um: [%lu]", 4048 info->stage0_match / (time2 - time0), 4049 info->stage0_mismatch / (time2 - time0), 4050 info->stage1_match / (time2 - time0), 4051 info->stage1_mismatch / (time2 - time0), 4052 info->stage2_match / (time2 - time0), 4053 info->stage2_mismatch / (time2 - time0), 4054 info->stage3_match / (time2 - time0), 4055 info->stage3_mismatch / (time2 - time0), 4056 info->unmatched / (time2 - time0)); 4057 #endif 4058 } else { 4059 applog(LOG_NOTICE, "STATS: stale: [%d] nws: [%d]", 4060 info->stale_work_list->count, info->noncework_list->count); 4061 4062 applog(LOG_NOTICE, "STATS: %4.0fGH/s osc: 0x%02x" 4063 "%3.1fV %3.1fA %4.1fW %.3fW/GH", 4064 CHIP_COEFF * info->hashrate_good, 4065 bf16_chip_clock, 4066 info->u_avg, 4067 info->i_total, 4068 info->p_total, 4069 (info->a_net == true) ? 4070 0.0 : 4071 info->p_total / (CHIP_COEFF * info->hashrate_good)); 4072 4073 applog(LOG_NOTICE, "STATS: TOTAL: %5.1fGH/s %5.3fV %3.1fA %5.2fW " 4074 "CHIP: %5.1fGH/s GOOD: %4.1fGH/s BAD: %4.1fGH/s", 4075 CHIP_COEFF * info->hashrate / (info->chips_num - info->chips_failed), 4076 info->u_chip / (info->chips_num - info->chips_disabled), 4077 (info->a_net == true) ? 0.0 : info->p_chip / info->u_chip, 4078 info->p_chip / (info->chips_num - info->chips_disabled), 4079 CHIP_COEFF * info->hashrate_good / (info->chips_num - info->chips_failed), 4080 CHIP_COEFF * info->hashrate_good / (info->chips_num - info->chips_failed), 4081 CHIP_COEFF * info->hashrate_bad / (info->chips_num - info->chips_failed)); 4082 } 4083 4084 applog(LOG_NOTICE, "STATS: uptime: [%4d:%02d:%02d] time elapsed: [%.6f] ", 4085 hours, minutes, seconds, timediff(start_time, stop_time)); 4086 } 4087 } 4088 4089 cgsleep_us(STATISTICS_DELAY); 4090 } 4091 4092 applog(LOG_INFO, "%s: statistics_thr: exiting...", bitfury->drv->name); 4093 return NULL; 4094 } 4095 4096 static bool bitfury16_thread_prepare(struct thr_info *thr) 4097 { 4098 struct cgpu_info *bitfury = thr->cgpu; 4099 struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); 4100 4101 info->thr = thr; 4102 4103 if (thr_info_create(&(info->chipworker_thr), NULL, bitfury_chipworker, (void *)bitfury)) { 4104 applog(LOG_ERR, "%s: %s() chipworker thread create failed", 4105 bitfury->drv->name, __func__); 4106 return false; 4107 } 4108 pthread_detach(info->chipworker_thr.pth); 4109 4110 applog(LOG_INFO, "%s: thread prepare: starting chipworker thread", bitfury->drv->name); 4111 4112 if (thr_info_create(&(info->nonceworker_thr), NULL, bitfury_nonceworker, (void *)bitfury)) { 4113 applog(LOG_ERR, "%s: %s() nonceworker thread create failed", 4114 bitfury->drv->name, __func__); 4115 return false; 4116 } 4117 pthread_detach(info->nonceworker_thr.pth); 4118 4119 applog(LOG_INFO, "%s: thread prepare: starting nonceworker thread", bitfury->drv->name); 4120 4121 if (opt_bf16_renonce != RENONCE_DISABLED) { 4122 if (thr_info_create(&(info->renonceworker_thr), NULL, bitfury_renonceworker, (void *)bitfury)) { 4123 applog(LOG_ERR, "%s: %s() renonceworker thread create failed", 4124 bitfury->drv->name, __func__); 4125 return false; 4126 } 4127 pthread_detach(info->renonceworker_thr.pth); 4128 4129 applog(LOG_INFO, "%s: thread prepare: starting renonceworker thread", bitfury->drv->name); 4130 } 4131 4132 if (thr_info_create(&(info->hwmonitor_thr), NULL, bitfury_hwmonitor, (void *)bitfury)) { 4133 applog(LOG_ERR, "%s: %s() hwmonitor thread create failed", 4134 bitfury->drv->name, __func__); 4135 return false; 4136 } 4137 pthread_detach(info->hwmonitor_thr.pth); 4138 4139 applog(LOG_INFO, "%s: thread prepare: starting hwmonitor thread", bitfury->drv->name); 4140 4141 if (thr_info_create(&(info->alarm_thr), NULL, bitfury_alarm, (void *)bitfury)) { 4142 applog(LOG_ERR, "%s: %s() alarm thread create failed", 4143 bitfury->drv->name, __func__); 4144 return false; 4145 } 4146 pthread_detach(info->alarm_thr.pth); 4147 4148 applog(LOG_INFO, "%s: thread prepare: starting alarm thread", bitfury->drv->name); 4149 4150 if (thr_info_create(&(info->statistics_thr), NULL, bitfury_statistics, (void *)bitfury)) { 4151 applog(LOG_ERR, "%s: %s() statistics thread create failed", 4152 bitfury->drv->name, __func__); 4153 return false; 4154 } 4155 pthread_detach(info->statistics_thr.pth); 4156 4157 applog(LOG_INFO, "%s: thread prepare: starting statistics thread", bitfury->drv->name); 4158 4159 return true; 4160 } 4161 4162 static int64_t bitfury16_scanwork(struct thr_info *thr) 4163 { 4164 struct cgpu_info *bitfury = thr->cgpu; 4165 struct bitfury16_info *info = bitfury->device_data; 4166 int64_t hashcount = 0; 4167 4168 applog(LOG_INFO, "%s: scan work", bitfury->drv->name); 4169 4170 mutex_lock(&info->nonces_good_lock); 4171 if (info->nonces_good_cg) { 4172 hashcount += 0xffffffffull * info->nonces_good_cg; 4173 info->nonces_good_cg = 0; 4174 } 4175 mutex_unlock(&info->nonces_good_lock); 4176 4177 return hashcount; 4178 } 4179 4180 static void prepare_work(struct cgpu_info *bitfury, struct work *work, bool rolled) 4181 { 4182 struct bitfury16_info *info = (struct bitfury16_info *)bitfury->device_data; 4183 4184 bf_workd_t* wdata = cgmalloc(sizeof(bf_workd_t)); 4185 4186 wdata->work = work; 4187 wdata->rolled = rolled; 4188 wdata->generated = time(NULL); 4189 4190 /* generate task payload */ 4191 cg_memcpy(wdata->payload.midstate, work->midstate, 32); 4192 wdata->payload.m7 = *(uint32_t *)(work->data + 64); 4193 wdata->payload.ntime = *(uint32_t *)(work->data + 68); 4194 wdata->payload.nbits = *(uint32_t *)(work->data + 72); 4195 4196 workd_list_push(info->work_list, wdata); 4197 } 4198 4199 static bool bitfury16_queue_full(struct cgpu_info *bitfury) 4200 { 4201 struct bitfury16_info *info = (struct bitfury16_info *)bitfury->device_data; 4202 struct work *work, *usework; 4203 uint16_t need = 0; 4204 uint16_t generated = 0; 4205 uint16_t roll, roll_limit; 4206 bool rolled; 4207 4208 if (info->initialised == false) { 4209 cgsleep_us(30); 4210 return true; 4211 } 4212 4213 L_LOCK(info->work_list); 4214 uint16_t work_count = info->work_list->count; 4215 L_UNLOCK(info->work_list); 4216 if (work_count < WORK_QUEUE_LEN) 4217 need = WORK_QUEUE_LEN - work_count; 4218 else 4219 return true; 4220 4221 /* Ensure we do enough rolling to reduce CPU 4222 but dont roll too much to have them end up stale */ 4223 work = get_queued(bitfury); 4224 if (work) { 4225 roll_limit = work->drv_rolllimit; 4226 roll = 0; 4227 4228 L_LOCK(info->work_list); 4229 do { 4230 if (roll == 0) { 4231 usework = work; 4232 rolled = false; 4233 } else { 4234 usework = copy_work_noffset(work, roll); 4235 rolled = true; 4236 } 4237 4238 prepare_work(bitfury, usework, rolled); 4239 generated++; 4240 } while ((--need > 0) && (++roll <= roll_limit)); 4241 L_UNLOCK(info->work_list); 4242 4243 applog(LOG_INFO, "%s: queue full: generated %d works", bitfury->drv->name, generated); 4244 } else 4245 cgsleep_us(30); 4246 4247 if (need > 0) 4248 return false; 4249 else 4250 return true; 4251 } 4252 4253 static void bitfury16_flush_work(struct cgpu_info *bitfury) 4254 { 4255 struct bitfury16_info *info = (struct bitfury16_info *)bitfury->device_data; 4256 uint16_t flushed = 0; 4257 4258 if (info->initialised == false) 4259 return; 4260 4261 bf_works_t works; 4262 4263 /* flush work list */ 4264 L_LOCK(info->work_list); 4265 L_LOCK(info->stale_work_list); 4266 bf_data_t* wdata = info->work_list->head; 4267 while (wdata != NULL) { 4268 workd_list_push(info->stale_work_list, WORKD(wdata)); 4269 workd_list_remove(info->work_list, &works); 4270 4271 wdata = info->work_list->head; 4272 flushed++; 4273 } 4274 L_UNLOCK(info->stale_work_list); 4275 L_UNLOCK(info->work_list); 4276 4277 /* flush nonces list */ 4278 L_LOCK(info->noncework_list); 4279 bf_data_t* nwdata = info->noncework_list->head; 4280 while (nwdata != NULL) { 4281 noncework_list_pop(info->noncework_list); 4282 nwdata = info->noncework_list->head; 4283 } 4284 L_UNLOCK(info->noncework_list); 4285 4286 if (opt_bf16_renonce != RENONCE_DISABLED) { 4287 /* flush renonces list */ 4288 L_LOCK(info->renonce_list); 4289 bf_data_t* rdata = info->renonce_list->head; 4290 while (rdata != NULL) { 4291 renonce_list_pop(info->renonce_list); 4292 rdata = info->renonce_list->head; 4293 } 4294 L_UNLOCK(info->renonce_list); 4295 4296 /* flush renoncework list */ 4297 L_LOCK(info->renoncework_list); 4298 bf_data_t* rnwdata = info->renoncework_list->head; 4299 while (rnwdata != NULL) { 4300 renoncework_list_pop(info->renoncework_list); 4301 rnwdata = info->renoncework_list->head; 4302 } 4303 L_UNLOCK(info->renoncework_list); 4304 } 4305 4306 applog(LOG_INFO, "%s: flushed %d works", bitfury->drv->name, flushed); 4307 } 4308 4309 static struct api_data *bitfury16_api_stats(struct cgpu_info *bitfury) 4310 { 4311 uint8_t board_id, bcm250_id, chip_id; 4312 struct bitfury16_info *info = bitfury->device_data; 4313 char data[128]; 4314 char value[128]; 4315 struct api_data *root = NULL; 4316 4317 applog(LOG_INFO, "%s: API stats", bitfury->drv->name); 4318 4319 if (info->initialised == false) 4320 return NULL; 4321 4322 #ifdef MINER_X5 4323 root = api_add_string(root, "Device name", "Bitfury X5", true); 4324 #endif 4325 #ifdef MINER_X6 4326 root = api_add_string(root, "Device name", "Bitfury X6", true); 4327 #endif 4328 root = api_add_uint8(root, "Boards number", &info->chipboard_num, false); 4329 root = api_add_uint8(root, "Boards detected", &info->chipboard_num, false); 4330 root = api_add_uint8(root, "Chips number", &info->chips_num, false); 4331 4332 /* software revision chages according to comments in CHANGELOG */ 4333 root = api_add_string(root, "hwv1", "1", true); 4334 root = api_add_string(root, "hwv2", "2", true); 4335 root = api_add_string(root, "hwv3", "11", true); 4336 root = api_add_string(root, "hwv4", "0", true); 4337 root = api_add_string(root, "hwv5", "0", true); 4338 4339 /* U avg */ 4340 sprintf(value, "%.1f", info->u_avg); 4341 root = api_add_string(root, "U avg", value, true); 4342 4343 /* I total */ 4344 sprintf(value, "%.1f", info->i_total); 4345 root = api_add_string(root, "I total", value, true); 4346 4347 /* P total */ 4348 sprintf(value, "%.1f", info->p_total); 4349 root = api_add_string(root, "P total", value, true); 4350 4351 if (opt_bf16_renonce != RENONCE_DISABLED) { 4352 /* Efficiency */ 4353 sprintf(value, "%.3f", 4354 (info->a_net == true) ? 4355 0.0 : 4356 info->p_total / (CHIP_COEFF * (info->hashrate_good + info->hashrate_re_good))); 4357 root = api_add_string(root, "Efficiency", value, true); 4358 4359 /* Chip GHS total avg */ 4360 sprintf(value, "%.1f", CHIP_COEFF * info->hashrate / (info->chips_num - info->renonce_chips - info->chips_failed)); 4361 root = api_add_string(root, "Chip GHS total avg", value, true); 4362 4363 /* Chip GHS avg */ 4364 sprintf(value, "%.1f", CHIP_COEFF * (info->hashrate_good + info->hashrate_re_good) / (info->chips_num - info->renonce_chips - info->chips_failed)); 4365 root = api_add_string(root, "Chip GHS avg", value, true); 4366 4367 /* Chip GHS good avg */ 4368 sprintf(value, "%.1f", CHIP_COEFF * info->hashrate_good / (info->chips_num - info->renonce_chips - info->chips_failed)); 4369 root = api_add_string(root, "Chip GHS good avg", value, true); 4370 4371 /* Chip GHS re avg */ 4372 sprintf(value, "%.1f", CHIP_COEFF * info->hashrate_re_good / (info->chips_num - info->renonce_chips - info->chips_failed)); 4373 root = api_add_string(root, "Chip GHS re avg", value, true); 4374 4375 /* Chip GHS bad avg */ 4376 sprintf(value, "%.1f", CHIP_COEFF * info->hashrate_re_bad / (info->chips_num - info->renonce_chips - info->chips_failed)); 4377 root = api_add_string(root, "Chip GHS bad avg", value, true); 4378 } else { 4379 /* Efficiency */ 4380 sprintf(value, "%.3f", 4381 (info->a_net == true) ? 4382 0.0 : 4383 info->p_total / (CHIP_COEFF * info->hashrate_good)); 4384 root = api_add_string(root, "Efficiency", value, true); 4385 4386 /* Chip GHS total avg */ 4387 sprintf(value, "%.1f", CHIP_COEFF * info->hashrate / (info->chips_num - info->chips_failed)); 4388 root = api_add_string(root, "Chip GHS total avg", value, true); 4389 4390 /* Chip GHS avg */ 4391 sprintf(value, "%.1f", CHIP_COEFF * info->hashrate_good / (info->chips_num - info->chips_failed)); 4392 root = api_add_string(root, "Chip GHS avg", value, true); 4393 4394 /* Chip GHS good avg */ 4395 sprintf(value, "%.1f", CHIP_COEFF * info->hashrate_good / (info->chips_num - info->chips_failed)); 4396 root = api_add_string(root, "Chip GHS good avg", value, true); 4397 4398 /* Chip GHS re avg */ 4399 sprintf(value, "%.1f", 0.0); 4400 root = api_add_string(root, "Chip GHS re avg", value, true); 4401 4402 /* Chip GHS bad avg */ 4403 sprintf(value, "%.1f", CHIP_COEFF * info->hashrate_bad / (info->chips_num - info->chips_failed)); 4404 root = api_add_string(root, "Chip GHS bad avg", value, true); 4405 } 4406 4407 /* U Chip avg */ 4408 sprintf(value, "%.3f", info->u_chip / (info->chips_num - info->chips_disabled)); 4409 root = api_add_string(root, "U Chip avg", value, true); 4410 4411 /* I Chip avg */ 4412 sprintf(value, "%.1f", (info->a_net == true) ? 0.0 : info->p_chip / info->u_chip); 4413 root = api_add_string(root, "I Chip avg", value, true); 4414 4415 /* P Chip avg */ 4416 sprintf(value, "%.2f", info->p_chip / (info->chips_num - info->chips_disabled)); 4417 root = api_add_string(root, "P Chip avg", value, true); 4418 4419 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 4420 /* board status */ 4421 sprintf(data, "Board%d detected", board_id); 4422 if (info->chipboard[board_id].detected == true) 4423 root = api_add_string(root, data, "1", true); 4424 else 4425 root = api_add_string(root, data, "0", true); 4426 4427 /* number of concentratord on board */ 4428 sprintf(data, "Board%d BTC250", board_id); 4429 root = api_add_uint8(root, data, &info->chipboard[board_id].bcm250_num, false); 4430 4431 /* number of chips on board */ 4432 sprintf(data, "Board%d BTC16", board_id); 4433 root = api_add_uint8(root, data, &info->chipboard[board_id].chips_num, false); 4434 4435 /* number of good chips on board */ 4436 sprintf(data, "Board%d BTC16 good", board_id); 4437 uint8_t chips_good = info->chipboard[board_id].chips_num - info->chipboard[board_id].chips_failed; 4438 root = api_add_uint8(root, data, &chips_good, true); 4439 4440 sprintf(data, "Board%d Clock", board_id); 4441 if (info->chipboard[board_id].detected == true) 4442 sprintf(value, "%d (0x%02x)", bf16_chip_clock, bf16_chip_clock); 4443 else 4444 sprintf(value, "%d (0x%02x)", 0, 0); 4445 4446 root = api_add_string(root, data, value, true); 4447 4448 sprintf(data, "Board%d GHS av", board_id); 4449 if (opt_bf16_renonce != RENONCE_DISABLED) { 4450 sprintf(value, "%.2f", 4451 CHIP_COEFF * (info->chipboard[board_id].hashrate_good + info->chipboard[board_id].hashrate_re_good)); 4452 } else { 4453 sprintf(value, "%.2f", CHIP_COEFF * (info->chipboard[board_id].hashrate_good)); 4454 } 4455 root = api_add_string(root, data, value, true); 4456 4457 /* number of chips per concentrator */ 4458 uint8_t i = 0; 4459 memset(value, 0, sizeof(value)); 4460 4461 for (bcm250_id = 0; bcm250_id < BCM250_NUM; bcm250_id++) { 4462 sprintf(data, "Board%d BTC250_%d BTC16", board_id, bcm250_id); 4463 root = api_add_uint8(root, data, &info->chipboard[board_id].bcm250[bcm250_id].chips_num, false); 4464 4465 uint8_t first_good_chip = info->chipboard[board_id].bcm250[bcm250_id].first_good_chip; 4466 uint8_t last_good_chip = info->chipboard[board_id].bcm250[bcm250_id].last_good_chip; 4467 4468 /* chips loop */ 4469 for (chip_id = first_good_chip; chip_id < last_good_chip; chip_id++, i++) { 4470 bf_chip_address_t chip_address; 4471 chip_address.board_id = board_id; 4472 chip_address.bcm250_id = bcm250_id; 4473 chip_address.chip_id = chip_id; 4474 4475 if (info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].status < FAILING) { 4476 if ((opt_bf16_renonce != RENONCE_DISABLED) && 4477 (renonce_chip(chip_address) == 1)) 4478 value[i] = 'O'; 4479 else 4480 value[i] = 'o'; 4481 } else { 4482 if ((opt_bf16_renonce != RENONCE_DISABLED) && 4483 (renonce_chip(chip_address) == 1)) 4484 value[i] = 'X'; 4485 else 4486 value[i] = 'x'; 4487 } 4488 } 4489 4490 if (bcm250_id != BCM250_NUM - 1) 4491 value[i++] = ' '; 4492 } 4493 4494 sprintf(data, "Board%d BF16 Status", board_id); 4495 root = api_add_string(root, data, value, true); 4496 4497 /* MSP version data */ 4498 /* board version */ 4499 sprintf(data, "Board%d Ver", board_id); 4500 root = api_add_uint32(root, data, &info->chipboard[board_id].board_ver, false); 4501 4502 /* board firmware version */ 4503 sprintf(data, "Board%d FW", board_id); 4504 root = api_add_uint32(root, data, &info->chipboard[board_id].board_fwver, false); 4505 4506 /* board hardware id */ 4507 sprintf(data, "Board%d HWID", board_id); 4508 root = api_add_string(root, data, info->chipboard[board_id].board_hwid, true); 4509 4510 /* MSP hw data */ 4511 /* T */ 4512 sprintf(data, "Board%d T", board_id); 4513 sprintf(value, "%.1f", info->chipboard[board_id].temp); 4514 root = api_add_string(root, data, value, true); 4515 4516 /* UB */ 4517 sprintf(data, "Board%d UB", board_id); 4518 sprintf(value, "%.1f", info->chipboard[board_id].u_board); 4519 root = api_add_string(root, data, value, true); 4520 4521 /* P1 */ 4522 sprintf(data, "Board%d P1", board_id); 4523 root = api_add_uint8(root, data, &info->chipboard[board_id].p_chain1_enabled, false); 4524 4525 /* P2 */ 4526 sprintf(data, "Board%d P2", board_id); 4527 root = api_add_uint8(root, data, &info->chipboard[board_id].p_chain2_enabled, false); 4528 4529 /* U1 */ 4530 sprintf(data, "Board%d U1", board_id); 4531 sprintf(value, "%.1f", info->chipboard[board_id].u_chain1); 4532 root = api_add_string(root, data, value, true); 4533 4534 /* U2 */ 4535 sprintf(data, "Board%d U2", board_id); 4536 sprintf(value, "%.1f", info->chipboard[board_id].u_chain2); 4537 root = api_add_string(root, data, value, true); 4538 4539 /* I1 */ 4540 sprintf(data, "Board%d I1", board_id); 4541 sprintf(value, "%.1f", info->chipboard[board_id].i_chain1); 4542 root = api_add_string(root, data, value, true); 4543 4544 /* I2 */ 4545 sprintf(data, "Board%d I2", board_id); 4546 sprintf(value, "%.1f", info->chipboard[board_id].i_chain2); 4547 root = api_add_string(root, data, value, true); 4548 4549 /* RPM */ 4550 sprintf(data, "Board%d PRM", board_id); 4551 root = api_add_uint32(root, data, &info->chipboard[board_id].rpm, true); 4552 4553 /* A */ 4554 sprintf(data, "Board%d T_Alarm", board_id); 4555 root = api_add_uint8(root, data, &info->chipboard[board_id].a_temp, true); 4556 4557 sprintf(data, "Board%d I1_Alarm", board_id); 4558 root = api_add_uint8(root, data, &info->chipboard[board_id].a_ichain1, true); 4559 4560 sprintf(data, "Board%d I2_Alarm", board_id); 4561 root = api_add_uint8(root, data, &info->chipboard[board_id].a_ichain2, true); 4562 4563 /* F */ 4564 sprintf(data, "Board%d F", board_id); 4565 root = api_add_uint8(root, data, &info->chipboard[board_id].fan_speed, false); 4566 4567 /* AI */ 4568 sprintf(data, "Board%d AI", board_id); 4569 sprintf(value, "%.1f", info->chipboard[board_id].i_alarm); 4570 root = api_add_string(root, data, value, true); 4571 4572 /* AT */ 4573 sprintf(data, "Board%d AT", board_id); 4574 sprintf(value, "%.0f", info->chipboard[board_id].t_alarm); 4575 root = api_add_string(root, data, value, true); 4576 4577 /* AG */ 4578 sprintf(data, "Board%d AG", board_id); 4579 sprintf(value, "%.0f", info->chipboard[board_id].t_gisteresis); 4580 root = api_add_string(root, data, value, true); 4581 4582 /* FM */ 4583 sprintf(data, "Board%d FM", board_id); 4584 #ifdef MINER_X5 4585 sprintf(value, "%c", info->chipboard[board_id].fan_mode); 4586 #endif 4587 4588 #ifdef MINER_X6 4589 if (manual_pid_enabled == true) 4590 sprintf(value, "A"); 4591 else 4592 sprintf(value, "%c", info->chipboard[board_id].fan_mode); 4593 #endif 4594 root = api_add_string(root, data, value, true); 4595 4596 /* TT */ 4597 sprintf(data, "Board%d TT", board_id); 4598 sprintf(value, "%.0f", info->chipboard[board_id].target_temp); 4599 root = api_add_string(root, data, value, true); 4600 } 4601 4602 return root; 4603 } 4604 4605 static void bitfury16_shutdown(struct thr_info *thr) 4606 { 4607 struct cgpu_info *bitfury = thr->cgpu; 4608 struct bitfury16_info *info = (struct bitfury16_info *)bitfury->device_data; 4609 uint8_t board_id; 4610 4611 bitfury->shutdown = true; 4612 4613 cgsleep_ms(300); 4614 4615 /* flush next board temp to default value */ 4616 if (manual_pid_enabled == false) { 4617 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 4618 if (info->chipboard[board_id].detected == true) { 4619 if (device_uart_transfer(board_id + 1, "N") < 0) 4620 quit(1, "%s: %s() failed to set BOARD%d next temp", 4621 bitfury->drv->name, __func__, board_id + 1); 4622 4623 applog(LOG_INFO, "%s: set BOARD%d next temp to default value", 4624 bitfury->drv->name, board_id + 1); 4625 } 4626 } 4627 } else { 4628 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 4629 if (info->chipboard[board_id].detected == true) { 4630 if (device_uart_transfer(board_id + 1, "F") < 0) 4631 quit(1, "%s: %s() failed to set BOARD%d fan speed to auto mode", 4632 bitfury->drv->name, __func__, board_id + 1); 4633 4634 applog(LOG_INFO, "%s: set BOARD%d fan speed to auto mode", 4635 bitfury->drv->name, board_id + 1); 4636 } 4637 } 4638 } 4639 4640 /* disable power chain */ 4641 for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { 4642 disable_power_chain(bitfury, board_id, 0); 4643 } 4644 4645 mutex_destroy(&info->nonces_good_lock); 4646 4647 /* close devices */ 4648 close_spi_device(SPI_CHANNEL1); 4649 close_spi_device(SPI_CHANNEL2); 4650 close_ctrl_device(); 4651 close_uart_device(UART_CHANNEL1); 4652 close_uart_device(UART_CHANNEL2); 4653 4654 #ifdef FILELOG 4655 filelog(info, "%s: cgminer stopped", bitfury->drv->name); 4656 fclose(info->logfile); 4657 mutex_destroy(&info->logfile_mutex); 4658 #endif 4659 4660 applog(LOG_INFO, "%s: driver shutdown", bitfury->drv->name); 4661 } 4662 4663 /* Currently hardcoded to BF1 devices */ 4664 struct device_drv bitfury16_drv = { 4665 .drv_id = DRIVER_bitfury16, 4666 .dname = "bitfury16", 4667 .name = "BF16", 4668 .drv_detect = bitfury16_detect, 4669 .get_api_stats = bitfury16_api_stats, 4670 .identify_device = bitfury16_identify, 4671 .thread_prepare = bitfury16_thread_prepare, 4672 .hash_work = hash_queued_work, 4673 .scanwork = bitfury16_scanwork, 4674 .queue_full = bitfury16_queue_full, 4675 .flush_work = bitfury16_flush_work, 4676 .thread_shutdown = bitfury16_shutdown 4677 };