diff --git a/api-example.c b/api-example.c index fac8be9703..5cc5adbc98 100644 --- a/api-example.c +++ b/api-example.c @@ -8,7 +8,7 @@ */ /* Compile: - * gcc api-example.c -Icompat/jansson-2.6/src -Icompat/libusb-1.0/libusb -o cgminer-api + * gcc api-example.c -Icompat/jansson-2.9/src -o cgminer-api */ #include "config.h" @@ -23,7 +23,7 @@ #include #include "compat.h" -#include "miner.h" +#include "util.h" #if defined(unix) || defined(__APPLE__) #include diff --git a/bf16-bitfury16.c b/bf16-bitfury16.c index dce4597ce1..69dedd08db 100644 --- a/bf16-bitfury16.c +++ b/bf16-bitfury16.c @@ -342,10 +342,6 @@ int8_t cmd_buffer_push(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth, return -2; bf_command_t command; - memset(&command, 0, sizeof(bf_command_t)); - - uint8_t buff[192]; - memset(buff, 0, sizeof(buff)); if (cmd_code != CHIP_CMD_CREATE_CHANNEL) { res = spi_command_init(&command, depth, chip_address, cmd_code, data_length, tx); @@ -361,7 +357,10 @@ int8_t cmd_buffer_push(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth, cg_memcpy(&CMD(cdata)->chip_address, &chip_address, sizeof(bf_chip_address_t)); cg_memcpy(&CMD(cdata)->src_address, &src_address, sizeof(bf_chip_address_t)); - cg_memcpy(&CMD(cdata)->work, &work, sizeof(bf_works_t)); + + if (cmd_code & CHIP_CMD_TASK_WRITE) + cg_memcpy(&CMD(cdata)->work, &work, sizeof(bf_works_t)); + CMD(cdata)->id = id; CMD(cdata)->depth = command.depth; CMD(cdata)->checksum = command.checksum; @@ -382,10 +381,9 @@ int8_t cmd_buffer_push(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth, } /* init send buffer */ - if (cmd_code != CHIP_CMD_CREATE_CHANNEL) { - cg_memcpy(buff, command.tx, command.data_length); - cg_memcpy(cmd_buffer->tx_buffer + cmd_buffer->tx_offset, buff, CMD(cdata)->data_length); - } else + if (cmd_code != CHIP_CMD_CREATE_CHANNEL) + cg_memcpy(cmd_buffer->tx_buffer + cmd_buffer->tx_offset, command.tx, CMD(cdata)->data_length); + else cg_memcpy(cmd_buffer->tx_buffer + cmd_buffer->tx_offset, tx, CMD(cdata)->data_length); #if 0 @@ -516,9 +514,7 @@ int8_t cmd_buffer_pop(bf_cmd_buffer_t* cmd_buffer, bf_cmd_status_t* cmd_status, if (cmd_buffer->cmd_list->head == NULL) return -3; - uint8_t buff[192]; bf_command_t chip_command; - memset(buff, 0, sizeof(buff)); memset(chip_command.rx, 0, sizeof(chip_command.rx)); /* extract command from list */ @@ -534,25 +530,30 @@ int8_t cmd_buffer_pop(bf_cmd_buffer_t* cmd_buffer, bf_cmd_status_t* cmd_status, chip_command.nonce_checksum_error = false; /* extract chip return data */ - cg_memcpy(buff, cmd_buffer->rx_buffer + cmd_buffer->rx_offset, CMD(cdata)->data_length); - cmd_buffer->rx_offset += CMD(cdata)->data_length; + uint16_t rx_offset; if (CMD(cdata)->cmd_code & CHIP_CMD_READ_NONCE) { - cg_memcpy(chip_command.rx, buff + CMD(cdata)->data_length - (49 + 2 + extra_bytes(chip_command.depth)), - 49 + 2 + extra_bytes(chip_command.depth)); + rx_offset = cmd_buffer->rx_offset + CMD(cdata)->data_length - (49 + 2 + extra_bytes(chip_command.depth)); + cg_memcpy(chip_command.rx, cmd_buffer->rx_buffer + rx_offset, 49 + 2 + extra_bytes(chip_command.depth)); + memset(nonces, 0, 12 * sizeof(uint32_t)); analyze_rx_data(&chip_command, cmd_status, nonces); } else if (CMD(cdata)->cmd_code == CHIP_CMD_CREATE_CHANNEL) { - cg_memcpy(chip_command.rx, buff, CMD(cdata)->data_length); + cg_memcpy(chip_command.rx, cmd_buffer->rx_buffer + cmd_buffer->rx_offset, CMD(cdata)->data_length); } else { - cg_memcpy(chip_command.rx, buff + CMD(cdata)->data_length - (2 + extra_bytes(chip_command.depth)), - 2 + extra_bytes(chip_command.depth)); + rx_offset = cmd_buffer->rx_offset + CMD(cdata)->data_length - (2 + extra_bytes(chip_command.depth)); + cg_memcpy(chip_command.rx, cmd_buffer->rx_buffer + rx_offset, 2 + extra_bytes(chip_command.depth)); analyze_rx_data(&chip_command, cmd_status, NULL); } + cmd_buffer->rx_offset += CMD(cdata)->data_length; + /* prepare cmd_status */ cg_memcpy(&cmd_status->chip_address, &CMD(cdata)->chip_address, sizeof(bf_chip_address_t)); cg_memcpy(&cmd_status->src_address, &CMD(cdata)->src_address, sizeof(bf_chip_address_t)); - cg_memcpy(&cmd_status->work, &CMD(cdata)->work, sizeof(bf_works_t)); + + if (CMD(cdata)->cmd_code & CHIP_CMD_TASK_WRITE) + cg_memcpy(&cmd_status->work, &CMD(cdata)->work, sizeof(bf_works_t)); + cmd_status->id = CMD(cdata)->id; cmd_status->cmd_code = CMD(cdata)->cmd_code; @@ -698,8 +699,7 @@ uint8_t gen_task_data(uint32_t* midstate, uint32_t merkle, uint32_t ntime, for (i = 0; i < 8; i++) { tmp = midstate[i]; tmp ^= 0xaaaaaaaa; - tmp = ntohl(tmp); - cg_memcpy(task + i*4, &tmp, sizeof(tmp)); + *(uint32_t *)(task + i*4) = ntohl(tmp); } ms3steps16(midstate, w, (uint32_t*)task); @@ -707,12 +707,10 @@ uint8_t gen_task_data(uint32_t* midstate, uint32_t merkle, uint32_t ntime, for (i = 0; i < 3; i++) { tmp = w[i]; tmp ^= 0xaaaaaaaa; - tmp = ntohl(tmp); - cg_memcpy(task + (12 + i)*4, &tmp, sizeof(tmp)); + *(uint32_t *)(task + (12 + i)*4) = ntohl(tmp); } - mask = ntohl(mask); - cg_memcpy(task + 19*4, &mask, sizeof(mask)); + *(uint32_t *)(task + 19*4) = ntohl(mask); return 0; } diff --git a/bf16-mspcontrol.c b/bf16-mspcontrol.c index c12f899568..f9f17c1a61 100644 --- a/bf16-mspcontrol.c +++ b/bf16-mspcontrol.c @@ -103,7 +103,7 @@ void parse_board_detect(struct cgpu_info *bitfury, uint8_t board_id, char* data) struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); char* start = data; - char val[4]; + char val[16]; memset(val, 0, sizeof(val)); /* BRD_DET*/ diff --git a/bf16-spidevice.c b/bf16-spidevice.c index 32da0ff15c..6c9b6daf39 100644 --- a/bf16-spidevice.c +++ b/bf16-spidevice.c @@ -20,12 +20,12 @@ int8_t spi_init(device_t* attr, spi_channel_id_t channel_id, int8_t mode, uint32 break; } - attr->mode = mode; + attr->mode = mode; attr->speed = speed; - attr->bits = 8; - attr->size = size; - attr->rx = malloc(size); - attr->tx = malloc(size); + attr->bits = 32; + attr->size = size; + attr->rx = malloc(size); + attr->tx = malloc(size); int fd; if ((fd = open(attr->device, O_RDWR)) < 0) { @@ -74,10 +74,24 @@ int8_t spi_init(device_t* attr, spi_channel_id_t channel_id, int8_t mode, uint32 void spi_transfer(device_t *attr) { + uint16_t i; + uint32_t tx_buff[SPI_BUFFER_SIZE / 4]; + uint32_t rx_buff[SPI_BUFFER_SIZE / 4]; + + memset(tx_buff, 0, sizeof(tx_buff)); + memset(rx_buff, 0, sizeof(rx_buff)); + + uint32_t datalen = (attr->datalen % 4 == 0) ? + attr->datalen : + (4 * (attr->datalen / 4 + 1)); + + for (i = 0; i <= datalen / 4; i++) + tx_buff[i] = ntohl(*(uint32_t *)(attr->tx + 4*i)); + struct spi_ioc_transfer tr = { - .tx_buf = (unsigned long) (attr->tx), - .rx_buf = (unsigned long) (attr->rx), - .len = attr->datalen, + .tx_buf = (unsigned long) (tx_buff), + .rx_buf = (unsigned long) (rx_buff), + .len = datalen, .delay_usecs = attr->delay, .speed_hz = attr->speed, .bits_per_word = attr->bits @@ -86,6 +100,9 @@ void spi_transfer(device_t *attr) if (ioctl(attr->fd, SPI_IOC_MESSAGE(1), &tr) < 0) quit(1, "BF16: %s() failed to send SPI message: %s", __func__, strerror(errno)); + for (i = 0; i < attr->datalen / 4; i++) + *(uint32_t *)(attr->rx + 4*i) = ntohl(rx_buff[i]); + #if 0 uint16_t i; char data[2*4096]; @@ -99,7 +116,6 @@ void spi_transfer(device_t *attr) sprintf(data, "%s%02x", data, attr->rx[i]); applog(LOG_DEBUG, "BF16: RX <- [%s]", data); #endif - } void spi_release(device_t *attr) diff --git a/bf16-spidevice.h b/bf16-spidevice.h index a7545a2291..0d28f132fc 100644 --- a/bf16-spidevice.h +++ b/bf16-spidevice.h @@ -4,7 +4,7 @@ #include "bf16-device.h" #define SPI_BUFFER_SIZE 4096 -#define SPI_SPEED 20000000 +#define SPI_SPEED 12000000 typedef enum { SPI_CHANNEL1 = 1, diff --git a/bf16-uartdevice.c b/bf16-uartdevice.c index 6bff340a2c..45dc529da8 100644 --- a/bf16-uartdevice.c +++ b/bf16-uartdevice.c @@ -24,8 +24,8 @@ int8_t uart_init(device_t* attr, uart_channel_id_t channel_id, int8_t mode, uint attr->speed = speed; attr->bits = 8; attr->size = size; - attr->rx = malloc(size); - attr->tx = malloc(size); + attr->rx = malloc(size + 1); + attr->tx = malloc(size + 1); int fd; if ((fd = open(attr->device, O_RDWR | O_NOCTTY | O_NDELAY)) < 0) diff --git a/cgminer.c b/cgminer.c index 81f77e5afe..2e24dfd30b 100644 --- a/cgminer.c +++ b/cgminer.c @@ -860,7 +860,7 @@ static char *set_int_0_to_7680(const char *arg, int *i) return set_int_range(arg, i, 0, 7680); } -#if defined(USE_AVALON4) || defined(USE_AVALON7) +#if defined(USE_AVALON4) static char *set_int_1_to_60(const char *arg, int *i) { return set_int_range(arg, i, 1, 60); @@ -1464,18 +1464,6 @@ static struct opt_table opt_config_table[] = { OPT_WITHOUT_ARG("--avalon7-iic-detect", opt_set_bool, &opt_avalon7_iic_detect, "Enable Avalon7 detect through iic controller"), - OPT_WITH_ARG("--avalon7-freqadj-time", - set_int_1_to_60, opt_show_intval, &opt_avalon7_freqadj_time, - "Set Avalon7 check interval when run in AVA7_FREQ_TEMPADJ_MODE"), - OPT_WITH_ARG("--avalon7-delta-temp", - opt_set_intval, opt_show_intval, &opt_avalon7_delta_temp, - "Set Avalon7 delta temperature when reset freq in AVA7_FREQ_TEMPADJ_MODE"), - OPT_WITH_ARG("--avalon7-delta-freq", - opt_set_intval, opt_show_intval, &opt_avalon7_delta_freq, - "Set Avalon7 delta freq when adjust freq in AVA7_FREQ_TEMPADJ_MODE"), - OPT_WITH_ARG("--avalon7-freqadj-temp", - opt_set_intval, opt_show_intval, &opt_avalon7_freqadj_temp, - "Set Avalon7 check temperature when run into AVA7_FREQ_TEMPADJ_MODE"), OPT_WITH_ARG("--avalon7-nonce-mask", set_int_24_to_32, opt_show_intval, &opt_avalon7_nonce_mask, "Set A3212 nonce mask, range 24-32."), diff --git a/driver-avalon7.c b/driver-avalon7.c index 4e3d2e5983..e65f4a271f 100644 --- a/driver-avalon7.c +++ b/driver-avalon7.c @@ -47,10 +47,6 @@ int opt_avalon7_smart_speed = AVA7_DEFAULT_SMART_SPEED; * 2. option 1 + adjust by average frequency */ bool opt_avalon7_iic_detect = AVA7_DEFAULT_IIC_DETECT; -int opt_avalon7_freqadj_time = AVA7_DEFAULT_FREQADJ_TIME; -int opt_avalon7_delta_temp = AVA7_DEFAULT_DELTA_T; -int opt_avalon7_delta_freq = AVA7_DEFAULT_DELTA_FREQ; -int opt_avalon7_freqadj_temp = AVA7_TEMP_FREQADJ; uint32_t opt_avalon7_th_pass = AVA7_DEFAULT_TH_PASS; uint32_t opt_avalon7_th_fail = AVA7_DEFAULT_TH_FAIL; @@ -521,8 +517,6 @@ static inline uint32_t adjust_fan(struct avalon7_info *info, int id) info->fan_pct[id] = opt_avalon7_fan_min; out: pwm = get_fan_pwm(info->fan_pct[id]); - if (info->freq_mode[id] == AVA7_FREQ_TEMPADJ_MODE) - pwm = get_fan_pwm(opt_avalon7_fan_max); if (info->cutoff[id]) pwm = get_fan_pwm(opt_avalon7_fan_max); @@ -1356,8 +1350,6 @@ static bool avalon7_prepare(struct thr_info *thr) cgtime(&(info->last_fan_adj)); cgtime(&info->last_stratum); cgtime(&info->last_detect); - cgtime(&info->last_fadj); - cgtime(&info->last_tcheck); cglock_init(&info->update_lock); cglock_init(&info->pool0.data_lock); @@ -1387,7 +1379,7 @@ static void detect_modules(struct cgpu_info *avalon7) struct avalon7_pkg send_pkg; struct avalon7_ret ret_pkg; uint32_t tmp; - int i, j, err, rlen; + int i, j, k, err, rlen; uint8_t dev_index; uint8_t rbuf[AVA7_AUC_P_SIZE]; @@ -1467,6 +1459,9 @@ static void detect_modules(struct cgpu_info *avalon7) info->set_voltage[i][j] = opt_avalon7_voltage; info->get_voltage[i][j] = 0; info->get_vin[i][j] = 0; + + for (k = 0; k < 5; k++) + info->temp[i][j][k] = -273; } info->freq_mode[i] = AVA7_FREQ_INIT_MODE; @@ -1805,39 +1800,6 @@ static void avalon7_set_finish(struct cgpu_info *avalon7, int addr) avalon7_iic_xfer_pkg(avalon7, addr, &send_pkg, NULL); } -/* miner [0, miner_count], 0 means all miners */ -static void avalon7_freq_dec(struct cgpu_info *avalon7, int addr, unsigned int miner_id, unsigned int freq[][AVA7_DEFAULT_PLL_CNT], unsigned int val) -{ - struct avalon7_info *info = avalon7->device_data; - int i, j; - - if (!miner_id) { - for (i = 0; i < info->miner_count[addr]; i++) { - for (j = 0; j < AVA7_DEFAULT_PLL_CNT; j++) { - if (freq[i][j] <= val) { - freq[i][j] = AVA7_DEFAULT_FREQUENCY_MIN; - continue; - } - - if ((freq[i][j] - val) >= AVA7_DEFAULT_FREQUENCY_MIN) - freq[i][j] -= val; - else - freq[i][j] = AVA7_DEFAULT_FREQUENCY_MIN; - } - } - } else { - for (i = 0; i < AVA7_DEFAULT_PLL_CNT; i++) { - if (freq[miner_id][i] <= val) - freq[miner_id][i] = AVA7_DEFAULT_FREQUENCY_MIN; - - if (freq[miner_id][i] >= AVA7_DEFAULT_FREQUENCY_MIN) - freq[miner_id][i] -= val; - else - freq[miner_id][i] -= AVA7_DEFAULT_FREQUENCY_MIN; - } - } -} - static void avalon7_sswork_update(struct cgpu_info *avalon7) { struct avalon7_info *info = avalon7->device_data; @@ -1901,12 +1863,9 @@ static int64_t avalon7_scanhash(struct thr_info *thr) struct avalon7_info *info = avalon7->device_data; struct timeval current; int i, j, k, count = 0; - double device_tdiff; int temp_max; int64_t ret; bool update_settings = false; - bool freq_dec_check = false; - bool freq_adj_check = false; if ((info->connecter == AVA7_CONNECTER_AUC) && (unlikely(avalon7->usbinfo.nodev))) { @@ -1935,18 +1894,6 @@ static int64_t avalon7_scanhash(struct thr_info *thr) } /* Step 3: ASIC configrations (voltage and frequency) */ - device_tdiff = tdiff(¤t, &(info->last_tcheck)); - if (device_tdiff > 3.0 || device_tdiff < 0) { - freq_dec_check = true; - copy_time(&info->last_tcheck, ¤t); - } - - device_tdiff = tdiff(¤t, &(info->last_fadj)); - if (device_tdiff > opt_avalon7_freqadj_time || device_tdiff < 0) { - freq_adj_check = true; - copy_time(&info->last_fadj, ¤t); - } - for (i = 1; i < AVA7_DEFAULT_MODULARS; i++) { if (!info->enable[i]) continue; @@ -1956,33 +1903,14 @@ static int64_t avalon7_scanhash(struct thr_info *thr) /* Check temperautre */ temp_max = get_temp_max(info, i); - /* Check if frequency need decrease */ - if (freq_dec_check && (info->freq_mode[i] != AVA7_FREQ_TEMPADJ_MODE)) { - if (temp_max >= opt_avalon7_freqadj_temp) { - update_settings = true; - info->temp_last_max[i] = temp_max; - avalon7_freq_dec(avalon7, i, 0, info->set_frequency[i], opt_avalon7_delta_freq + 50); - applog(LOG_DEBUG, "%s-%d-%d: set freq after temp check %d-%d", - avalon7->drv->name, avalon7->device_id, i, - info->set_frequency[i][0][0], - info->set_frequency[i][info->miner_count[i] - 1][0]); - info->freq_mode[i] = AVA7_FREQ_TEMPADJ_MODE; - } - } - /* Enter too hot */ - if (temp_max >= info->temp_overheat[i]) { + if (temp_max >= info->temp_overheat[i]) info->cutoff[i] = 1; - info->freq_mode[i] = AVA7_FREQ_CUTOFF_MODE; - } /* Exit too hot */ if (info->cutoff[i] && (temp_max <= (info->temp_overheat[i] - 10))) info->cutoff[i] = 0; - /* State machine for settings - * https://en.bitcoin.it/wiki/Avalon6#Frequency_Statechart - * */ switch (info->freq_mode[i]) { case AVA7_FREQ_INIT_MODE: update_settings = true; @@ -1995,39 +1923,6 @@ static int64_t avalon7_scanhash(struct thr_info *thr) info->freq_mode[i] = AVA7_FREQ_PLLADJ_MODE; break; - case AVA7_FREQ_CUTOFF_MODE: - if (!info->cutoff[i]) - info->freq_mode[i] = AVA7_FREQ_INIT_MODE; - break; - case AVA7_FREQ_TEMPADJ_MODE: - if (freq_adj_check) { - /* if temp_max goes down ,then we don't need adjust frequency */ - if (info->temp_last_max[i] > temp_max) { - applog(LOG_DEBUG, "AVA7_FREQ_TEMPADJ_MODE temp goes down"); - info->temp_last_max[i] = get_temp_max(info, i); - break; - } - - update_settings = true; - info->temp_last_max[i] = get_temp_max(info, i); - avalon7_freq_dec(avalon7, i, 0, info->set_frequency[i], opt_avalon7_delta_freq); - applog(LOG_DEBUG, "%s-%d-%d: update freq (%d-%d) AVA7_FREQ_PLLADJ_MODE", - avalon7->drv->name, avalon7->device_id, i, - info->set_frequency[i][0][0], - info->set_frequency[i][info->miner_count[i] - 1][0]); - } - - if (get_temp_max(info, i) <= (info->temp_target[i] - opt_avalon7_delta_temp)) { - update_settings = true; - for (j = 0; j < info->miner_count[i]; j++) { - for (k = 0; k < AVA7_DEFAULT_PLL_CNT; k++) - info->set_frequency[i][j][k] = opt_avalon7_freq[k]; - } - - info->freq_mode[i] = AVA7_FREQ_INIT_MODE; - break; - } - break; case AVA7_FREQ_PLLADJ_MODE: if (opt_avalon7_smart_speed == AVA7_DEFAULT_SMARTSPEED_OFF) break; diff --git a/driver-avalon7.h b/driver-avalon7.h index 44a3044362..49066a6630 100644 --- a/driver-avalon7.h +++ b/driver-avalon7.h @@ -16,7 +16,6 @@ #ifdef USE_AVALON7 -#define AVA7_TEMP_FREQADJ 104 #define AVA7_FREQUENCY_MAX 1404 #define AVA7_DEFAULT_FAN_MIN 5 /* % */ @@ -149,9 +148,7 @@ #define AVA7_IIC_INFO 0xa6 #define AVA7_FREQ_INIT_MODE 0x0 -#define AVA7_FREQ_CUTOFF_MODE 0x1 -#define AVA7_FREQ_TEMPADJ_MODE 0x2 -#define AVA7_FREQ_PLLADJ_MODE 0x3 +#define AVA7_FREQ_PLLADJ_MODE 0x1 #define AVA7_DEFAULT_FAVG_TIME (15 * 60.0) #define AVA7_DEFAULT_FREQADJ_TIME 60 @@ -190,8 +187,6 @@ struct avalon7_info { struct timeval last_fan_adj; struct timeval last_stratum; struct timeval last_detect; - struct timeval last_fadj; - struct timeval last_tcheck; cglock_t update_lock; @@ -305,10 +300,6 @@ extern int opt_avalon7_aucspeed; extern int opt_avalon7_aucxdelay; extern int opt_avalon7_smart_speed; extern bool opt_avalon7_iic_detect; -extern int opt_avalon7_freqadj_time; -extern int opt_avalon7_delta_temp; -extern int opt_avalon7_delta_freq; -extern int opt_avalon7_freqadj_temp; extern int opt_avalon7_freq_sel; extern uint32_t opt_avalon7_th_pass; extern uint32_t opt_avalon7_th_fail; diff --git a/driver-bitfury16.c b/driver-bitfury16.c index 78776c47db..62318e7880 100644 --- a/driver-bitfury16.c +++ b/driver-bitfury16.c @@ -14,7 +14,7 @@ #define LOGFILE "/var/log/cgminer.log" #endif -#define DISABLE_SEND_CMD_ERROR +//#define DISABLE_SEND_CMD_ERROR #define POWER_WAIT_INTERVAL 100000 #define RENONCE_SEND 5 @@ -108,7 +108,7 @@ int opt_bf16_alarm_temp = -1; char* opt_bf16_test_chip = NULL; /* number of bits to fixate */ -static uint32_t mask_bits = 10; +static uint32_t mask_bits = 12; /* default chip mask */ static uint32_t mask = 0x00000000; @@ -995,15 +995,15 @@ static void init_x5(struct cgpu_info *bitfury) char buff[256]; memset(buff, 0, sizeof(buff)); + info->chipboard[board_id].bcm250 = cgcalloc(BCM250_NUM, sizeof(bf_bcm250_t)); + cmd_buffer_init(&info->chipboard[board_id].cmd_buffer); + device_ctrl_txrx(board_id + 1, 0, F_BDET, buff); parse_board_detect(bitfury, board_id, buff); if (info->chipboard[board_id].detected == true) { applog(LOG_NOTICE, "%s: BOARD%d detected", bitfury->drv->name, board_id + 1); - info->chipboard[board_id].bcm250 = cgcalloc(BCM250_NUM, sizeof(bf_bcm250_t)); - cmd_buffer_init(&info->chipboard[board_id].cmd_buffer); - get_board_info(bitfury, board_id); update_bcm250_map(bitfury, board_id); @@ -1361,6 +1361,11 @@ static void bitfury16_detect(bool hotplug) /* wait for power chain to enable */ cgsleep_us(POWER_WAIT_INTERVAL); + for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { + if (info->chipboard[board_id].detected == true) + info->chipboard[board_id].ready = true; + } + if (opt_bf16_set_clock == true) { applog(LOG_INFO, "%s: setting clock [%02x] to all chips", bitfury->drv->name, bf16_chip_clock); @@ -1539,7 +1544,8 @@ static void bitfury16_detect(bool hotplug) quit(1, "%s: %s() failed to add_cgpu", bitfury->drv->name, __func__); - info->initialised = true; + info->initialised = true; + info->device_ready = true; applog(LOG_INFO, "%s: chip driver initialized", bitfury->drv->name); #ifdef FILELOG @@ -1820,14 +1826,12 @@ static uint8_t renonce_task_update_loop(struct cgpu_info *bitfury, uint8_t board (RENONCE(rdata)->stage == stage)) { /* generate work mask */ uint32_t nonce_mask = gen_mask(RENONCE(rdata)->nonce, mask_bits); - nonce_mask = ntohl(nonce_mask); switch (RENONCE(rdata)->stage) { case RENONCE_STAGE0: case RENONCE_STAGE2: /* generate chip work with new mask */ - cg_memcpy(RENONCE(rdata)->owork.task + 19*4, - &nonce_mask, sizeof(nonce_mask)); + *(uint32_t *)(RENONCE(rdata)->owork.task + 19*4) = ntohl(nonce_mask); /* send task and read nonces at the same time */ ret = cmd_buffer_push(cmd_buffer, @@ -1840,8 +1844,7 @@ static uint8_t renonce_task_update_loop(struct cgpu_info *bitfury, uint8_t board case RENONCE_STAGE1: case RENONCE_STAGE3: /* generate chip work with new mask */ - cg_memcpy(RENONCE(rdata)->cwork.task + 19*4, - &nonce_mask, sizeof(nonce_mask)); + *(uint32_t *)(RENONCE(rdata)->cwork.task + 19*4) = ntohl(nonce_mask); /* send task and read nonces at the same time */ ret = cmd_buffer_push(cmd_buffer, @@ -2181,10 +2184,8 @@ static uint8_t process_nonces(struct cgpu_info *bitfury, bf_cmd_status_t cmd_sta if ((cmd_status.checksum_error == false) && (cmd_status.nonce_checksum_error == false)) { - cg_memcpy(info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].rx, nonces, sizeof(found_nonces)); - - uint8_t found = find_nonces(info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].rx, - info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].rx_prev, + uint8_t found = find_nonces(nonces, + info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].rx, found_nonces); /* check if chip is still mining */ @@ -2291,6 +2292,7 @@ static uint8_t process_nonces(struct cgpu_info *bitfury, bf_cmd_status_t cmd_sta L_UNLOCK(info->renonce_list); } + /* process nonces */ bf_list_t* nonce_list = info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].nonce_list; for (i = 0; i < found; i++) { L_LOCK(nonce_list); @@ -2347,8 +2349,8 @@ static uint8_t process_nonces(struct cgpu_info *bitfury, bf_cmd_status_t cmd_sta } /* rotate works and buffers */ - cg_memcpy(info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].rx_prev, - info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].rx, sizeof(found_nonces)); + cg_memcpy(info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].rx, + nonces, sizeof(found_nonces)); cg_memcpy(&info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].owork, &info->chipboard[board_id].bcm250[bcm250_id].chips[chip_id].cwork, sizeof(bf_works_t)); @@ -2405,13 +2407,13 @@ static void process_cmd_buffer(struct cgpu_info *bitfury, uint8_t board_id) struct bitfury16_info *info = (struct bitfury16_info *)(bitfury->device_data); uint8_t i; bf_cmd_status_t cmd_status; + uint32_t nonces[12]; bf_cmd_buffer_t* cmd_buffer = &info->chipboard[board_id].cmd_buffer; if (cmd_buffer->status == EXECUTED) { /* process extracted data */ uint16_t cmd_number = cmd_buffer->cmd_list->count; for (i = 0; i < cmd_number; i++) { - uint32_t nonces[12]; cmd_buffer_pop(cmd_buffer, &cmd_status, nonces); if ((cmd_status.cmd_code == CHIP_CMD_CREATE_CHANNEL) || @@ -2451,10 +2453,10 @@ static void *bitfury_chipworker(void *userdata) spi_emit_reset(SPI_CHANNEL2); while (bitfury->shutdown == false) { - if ((info->a_temp == false) && - (info->a_ichain == false)) { + if (info->device_ready == true) { for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { - if (info->chipboard[board_id].detected == true) { + if ((info->chipboard[board_id].detected == true) && + (info->chipboard[board_id].ready == true)) { /* prepare send buffer */ struct timeval start_time, stop_time; gettimeofday(&start_time, NULL); @@ -2953,6 +2955,7 @@ static void *bitfury_renonceworker(void *userdata) continue; } + /* remove expired renonce */ if ((RENONCE(rdata)->stage == RENONCE_STAGE_FINISHED) && (RENONCE(rdata)->sent == false)) { info->unmatched++; @@ -3070,12 +3073,16 @@ static void *bitfury_hwmonitor(void *userdata) info->chipboard[board_id].p_board = ((info->chipboard[board_id].u_board + U_LOSS) * i_board + 2.0 + info->chipboard[board_id].p_fan); - if (info->chipboard[board_id].a_temp == 1) + if (info->chipboard[board_id].a_temp == 1) { a_temp = true; + info->device_ready = false; + } if ((info->chipboard[board_id].a_ichain1 == 1) || - (info->chipboard[board_id].a_ichain2 == 1)) + (info->chipboard[board_id].a_ichain2 == 1)) { a_ichain = true; + info->device_ready = false; + } if (max_temp < info->chipboard[board_id].temp) max_temp = info->chipboard[board_id].temp; @@ -3112,6 +3119,7 @@ static void *bitfury_hwmonitor(void *userdata) set_fan_speed(bitfury); reinit_x5(info, false); + info->device_ready = true; } /* enable power chain alarm */ @@ -3132,6 +3140,7 @@ static void *bitfury_hwmonitor(void *userdata) info->ialarm_start = time(NULL); reinit_x5(info, false); + info->device_ready = true; } } @@ -3160,6 +3169,14 @@ static void *bitfury_hwmonitor(void *userdata) info->chipboard[board_id].power2_enable_time = curr_time; #endif } + + /* wait for power chain to enable */ + cgsleep_us(POWER_WAIT_INTERVAL); + + for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { + if (info->chipboard[board_id].detected == true) + info->chipboard[board_id].ready = true; + } } } else if (opt_bf16_power_management_disabled == false) { if (info->a_net == true) { @@ -3173,7 +3190,14 @@ static void *bitfury_hwmonitor(void *userdata) if ((info->chipboard[board_id].p_chain1_enabled == 1) || (info->chipboard[board_id].p_chain2_enabled == 1)) { #endif + info->chipboard[board_id].ready = false; disable_power_chain(bitfury, board_id, 0); + +#ifdef FILELOG + filelog(info, "%s: inet absent: disable power chain on BOARD%d", + bitfury->drv->name, + board_id + 1); +#endif } } } @@ -3187,27 +3211,47 @@ static void *bitfury_hwmonitor(void *userdata) (info->chipboard[board_id].power_disabled == false)) { enable_power_chain(bitfury, board_id, 0); info->chipboard[board_id].power_enable_time = time(NULL); - - /* wait for power chain to enable */ - cgsleep_us(POWER_WAIT_INTERVAL); - - reinit_x5(info, false); + recovery = true; } #endif #ifdef MINER_X6 if ((info->chipboard[board_id].p_chain1_enabled == 0) && - (info->chipboard[board_id].power1_disabled == false)){ + (info->chipboard[board_id].power1_disabled == false) && + (info->chipboard[board_id].p_chain2_enabled == 0) && + (info->chipboard[board_id].power2_disabled == false)) { + enable_power_chain(bitfury, board_id, 0); + info->chipboard[board_id].power1_enable_time = time(NULL); + info->chipboard[board_id].power2_enable_time = time(NULL); + recovery = true; + +#ifdef FILELOG + filelog(info, "%s: inet recovery: reenabled power on BOARD%d", + bitfury->drv->name, + board_id + 1); +#endif + } else if ((info->chipboard[board_id].p_chain1_enabled == 0) && + (info->chipboard[board_id].power1_disabled == false)) { enable_power_chain(bitfury, board_id, 1); info->chipboard[board_id].power1_enable_time = time(NULL); recovery = true; - } - if ((info->chipboard[board_id].p_chain2_enabled == 0) && +#ifdef FILELOG + filelog(info, "%s: inet recovery: reenabled power chain 1 on BOARD%d", + bitfury->drv->name, + board_id + 1); +#endif + } else if ((info->chipboard[board_id].p_chain2_enabled == 0) && (info->chipboard[board_id].power2_disabled == false)) { enable_power_chain(bitfury, board_id, 2); info->chipboard[board_id].power2_enable_time = time(NULL); recovery = true; + +#ifdef FILELOG + filelog(info, "%s: inet recovery: reenabled power chain 2 on BOARD%d", + bitfury->drv->name, + board_id + 1); +#endif } #endif } @@ -3219,6 +3263,12 @@ static void *bitfury_hwmonitor(void *userdata) cgsleep_us(POWER_WAIT_INTERVAL); reinit_x5(info, false); + info->device_ready = true; + + for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { + if (info->chipboard[board_id].detected == true) + info->chipboard[board_id].ready = true; + } } } } @@ -3323,6 +3373,7 @@ static void *bitfury_hwmonitor(void *userdata) /* disable chain power if all chips failed */ if ((total_chips == disabled_chips) && (info->chipboard[board_id].p_chain1_enabled == 1)) { + info->chipboard[board_id].ready = false; disable_power_chain(bitfury, board_id, 0); /* increase disable counter until we reach long enough work time */ @@ -3335,30 +3386,34 @@ static void *bitfury_hwmonitor(void *userdata) info->chipboard[board_id].chips_disabled = info->chipboard[board_id].chips_num; } - /* enable disabled chain */ - if ((info->chipboard[board_id].p_chain1_enabled == 0) && - (info->chipboard[board_id].power_disabled == true) && - (curr_time - info->chipboard[board_id].power_disable_time >= info->chipboard[board_id].power_disable_count * CHAIN_REENABLE_INTERVAL)) { - time_t disable_interval = curr_time - info->chipboard[board_id].power_disable_time; - info->chipboard[board_id].power_disable_time = curr_time; - info->chipboard[board_id].chips_disabled = 0; + /* HW FIX: try to reenable disabled chain */ + if (info->chipboard[board_id].active == true) { + if ((info->chipboard[board_id].p_chain1_enabled == 0) && + (info->chipboard[board_id].power_disabled == true) && + (curr_time - info->chipboard[board_id].power_disable_time >= info->chipboard[board_id].power_disable_count * CHAIN_REENABLE_INTERVAL)) { + time_t disable_interval = curr_time - info->chipboard[board_id].power_disable_time; + info->chipboard[board_id].power_disable_time = curr_time; + info->chipboard[board_id].chips_disabled = 0; + + enable_power_chain(bitfury, board_id, 0); + info->chipboard[board_id].power_enable_time = curr_time; + info->chipboard[board_id].power_disabled = false; - enable_power_chain(bitfury, board_id, 0); - info->chipboard[board_id].power_enable_time = curr_time; - info->chipboard[board_id].power_disabled = false; + /* wait for power chain to enable */ + cgsleep_us(POWER_WAIT_INTERVAL); - /* wait for power chain to enable */ - cgsleep_us(POWER_WAIT_INTERVAL); + reinit_x5(info, true); + info->chipboard[board_id].ready = true; - reinit_x5(info, true); - applog(LOG_NOTICE, "%s: reenabled power on BOARD%d: time interval [%d]", - bitfury->drv->name, - board_id + 1, (int)disable_interval); + applog(LOG_NOTICE, "%s: reenabled power on BOARD%d: time interval [%d]", + bitfury->drv->name, + board_id + 1, (int)disable_interval); #ifdef FILELOG - filelog(info, "%s: reenabled power on BOARD%d: time interval [%d]", - bitfury->drv->name, - board_id + 1, (int)disable_interval); + filelog(info, "%s: reenabled power on BOARD%d: time interval [%d]", + bitfury->drv->name, + board_id + 1, (int)disable_interval); #endif + } } #endif @@ -3368,6 +3423,7 @@ static void *bitfury_hwmonitor(void *userdata) if ((total_chips_chain1 == disabled_chips_chain1) && (info->chipboard[board_id].p_chain1_enabled == 1) && (info->chipboard[board_id].power2_disabled == true)) { + info->chipboard[board_id].ready = false; disable_power_chain(bitfury, board_id, 0); /* increase disable counter until we reach long enough work time */ @@ -3396,57 +3452,63 @@ static void *bitfury_hwmonitor(void *userdata) } /* HW FIX: try to reenable disabled chain */ - if ((info->chipboard[board_id].p_chain1_enabled == 0) && - (info->chipboard[board_id].power1_disabled == true) && - (curr_time - info->chipboard[board_id].power1_disable_time >= info->chipboard[board_id].power1_disable_count * CHAIN_REENABLE_INTERVAL)) { - time_t disable_interval = curr_time - info->chipboard[board_id].power1_disable_time; - info->chipboard[board_id].power1_disable_time = curr_time; - info->chipboard[board_id].power2_disable_time = curr_time; - info->chipboard[board_id].chips_disabled = 0; + if (info->chipboard[board_id].active == true) { + if ((info->chipboard[board_id].p_chain1_enabled == 0) && + (info->chipboard[board_id].power1_disabled == true) && + (curr_time - info->chipboard[board_id].power1_disable_time >= info->chipboard[board_id].power1_disable_count * CHAIN_REENABLE_INTERVAL)) { + time_t disable_interval = curr_time - info->chipboard[board_id].power1_disable_time; + info->chipboard[board_id].power1_disable_time = curr_time; + info->chipboard[board_id].power2_disable_time = curr_time; + info->chipboard[board_id].chips_disabled = 0; - enable_power_chain(bitfury, board_id, 0); - info->chipboard[board_id].power1_enable_time = curr_time; - info->chipboard[board_id].power2_enable_time = curr_time; - info->chipboard[board_id].power1_disabled = false; - info->chipboard[board_id].power2_disabled = false; + enable_power_chain(bitfury, board_id, 0); + info->chipboard[board_id].power1_enable_time = curr_time; + info->chipboard[board_id].power2_enable_time = curr_time; + info->chipboard[board_id].power1_disabled = false; + info->chipboard[board_id].power2_disabled = false; - /* wait for power chain to enable */ - cgsleep_us(POWER_WAIT_INTERVAL); + /* wait for power chain to enable */ + cgsleep_us(POWER_WAIT_INTERVAL); - reinit_x5(info, true); - applog(LOG_NOTICE, "%s: reenabled power on BOARD%d: time interval [%d]", - bitfury->drv->name, - board_id + 1, (int)disable_interval); + reinit_x5(info, true); + info->chipboard[board_id].ready = true; + + applog(LOG_NOTICE, "%s: reenabled power on BOARD%d: time interval [%d]", + bitfury->drv->name, + board_id + 1, (int)disable_interval); #ifdef FILELOG - filelog(info, "%s: reenabled power on BOARD%d: time interval [%d]", - bitfury->drv->name, - board_id + 1, (int)disable_interval); + filelog(info, "%s: reenabled power on BOARD%d: time interval [%d]", + bitfury->drv->name, + board_id + 1, (int)disable_interval); #endif - } else - if ((info->chipboard[board_id].p_chain2_enabled == 0) && - (info->chipboard[board_id].power2_disabled == true) && - (curr_time - info->chipboard[board_id].power2_disable_time >= info->chipboard[board_id].power2_disable_count * CHAIN_REENABLE_INTERVAL)) { - time_t disable_interval = curr_time - info->chipboard[board_id].power2_disable_time; - info->chipboard[board_id].power2_disable_time = curr_time; - info->chipboard[board_id].chips_disabled = 0; + } else + if ((info->chipboard[board_id].p_chain2_enabled == 0) && + (info->chipboard[board_id].power2_disabled == true) && + (curr_time - info->chipboard[board_id].power2_disable_time >= info->chipboard[board_id].power2_disable_count * CHAIN_REENABLE_INTERVAL)) { + time_t disable_interval = curr_time - info->chipboard[board_id].power2_disable_time; + info->chipboard[board_id].power2_disable_time = curr_time; + info->chipboard[board_id].chips_disabled = 0; - enable_power_chain(bitfury, board_id, 2); - info->chipboard[board_id].power2_enable_time = curr_time; - info->chipboard[board_id].power2_disabled = false; + enable_power_chain(bitfury, board_id, 2); + info->chipboard[board_id].power2_enable_time = curr_time; + info->chipboard[board_id].power2_disabled = false; - /* wait for power chain to enable */ - cgsleep_us(POWER_WAIT_INTERVAL); + /* wait for power chain to enable */ + cgsleep_us(POWER_WAIT_INTERVAL); - reinit_x5(info, true); - applog(LOG_NOTICE, "%s: reenabled chainboard 2 on BOARD%d: time interval [%d]", - bitfury->drv->name, - board_id + 1, (int)disable_interval); + reinit_x5(info, true); + info->chipboard[board_id].ready = true; + + applog(LOG_NOTICE, "%s: reenabled chainboard 2 on BOARD%d: time interval [%d]", + bitfury->drv->name, + board_id + 1, (int)disable_interval); #ifdef FILELOG - filelog(info, "%s: reenabled chainboard 2 on BOARD%d: time interval [%d]", - bitfury->drv->name, - board_id + 1, (int)disable_interval); + filelog(info, "%s: reenabled chainboard 2 on BOARD%d: time interval [%d]", + bitfury->drv->name, + board_id + 1, (int)disable_interval); #endif + } } #endif /* switch renonce chip to next board */ @@ -3524,9 +3586,10 @@ static void *bitfury_alarm(void *userdata) idle = false; } - if (idle == true) + if (idle == true) { info->a_net = true; - else + info->device_ready = false; + } else info->a_net = false; /* temperature alarm processing */ @@ -4012,12 +4075,15 @@ static void *bitfury_statistics(void *userdata) if (opt_bf16_stats_enabled) { if (opt_bf16_renonce != RENONCE_DISABLED) { - applog(LOG_NOTICE, "STATS: rencs: [%d] stale: [%d] nws: [%d] rnws: [%d] failed: [%d]", + applog(LOG_NOTICE, "STATS: rencs: [%d] stale: [%d] nws: [%d] rnws: [%d] " + "chips: [%d] failed: [%d] disabled: [%d]", info->renonce_list->count, info->stale_work_list->count, info->noncework_list->count, info->renoncework_list->count, - info->chips_failed); + info->chips_num, + info->chips_failed, + info->chips_disabled); applog(LOG_NOTICE, "STATS: %4.0fGH/s osc: 0x%02x re_osc: 0x%02x " "%3.1fV %3.1fA %4.1fW %.3fW/GH", @@ -4213,7 +4279,7 @@ static bool bitfury16_queue_full(struct cgpu_info *bitfury) L_LOCK(info->work_list); uint16_t work_count = info->work_list->count; L_UNLOCK(info->work_list); - if (work_count < WORK_QUEUE_LEN) + if (work_count < WORK_QUEUE_LEN - 60) need = WORK_QUEUE_LEN - work_count; else return true; @@ -4331,9 +4397,9 @@ static struct api_data *bitfury16_api_stats(struct cgpu_info *bitfury) /* software revision chages according to comments in CHANGELOG */ root = api_add_string(root, "hwv1", "1", true); - root = api_add_string(root, "hwv2", "2", true); - root = api_add_string(root, "hwv3", "11", true); - root = api_add_string(root, "hwv4", "0", true); + root = api_add_string(root, "hwv2", "3", true); + root = api_add_string(root, "hwv3", "0", true); + root = api_add_string(root, "hwv4", "1", true); root = api_add_string(root, "hwv5", "0", true); /* U avg */ @@ -4345,7 +4411,7 @@ static struct api_data *bitfury16_api_stats(struct cgpu_info *bitfury) root = api_add_string(root, "I total", value, true); /* P total */ - sprintf(value, "%.1f", info->p_total); + sprintf(value, "%.0f", info->p_total); root = api_add_string(root, "P total", value, true); if (opt_bf16_renonce != RENONCE_DISABLED) { @@ -4639,6 +4705,7 @@ static void bitfury16_shutdown(struct thr_info *thr) /* disable power chain */ for (board_id = 0; board_id < CHIPBOARD_NUM; board_id++) { + info->chipboard[board_id].ready = false; disable_power_chain(bitfury, board_id, 0); } diff --git a/driver-bitfury16.h b/driver-bitfury16.h index 6af78638b2..3076439c37 100644 --- a/driver-bitfury16.h +++ b/driver-bitfury16.h @@ -90,8 +90,6 @@ typedef struct { bf_works_t owork; /* old work */ bf_works_t cwork; /* current work */ uint32_t rx[12]; - uint32_t rx_prev[12]; - } bf_chip_t; /* chip concentrator init map structure */ @@ -226,6 +224,9 @@ typedef struct { time_t power2_enable_time; #endif + /* true if power is enabled on board and power enable timeout reached */ + bool ready; + bf_cmd_buffer_t cmd_buffer; /* chip statistics */ @@ -349,6 +350,10 @@ struct bitfury16_info { bool a_temp; bool a_ichain; bool a_net; + + /* true if all alarms are disabled and power enable timeout reached */ + bool device_ready; + time_t ialarm_start; uint16_t ialarm_count; bool ialarm_buzzer;