/ bf16-bitfury16.c
bf16-bitfury16.c
   1  #include <arpa/inet.h>
   2  
   3  #include "miner.h"
   4  
   5  #include "bf16-bitfury16.h"
   6  #include "bf16-communication.h"
   7  #include "bf16-ctrldevice.h"
   8  
   9  #include "math.h"
  10  #include "sha2.h"
  11  #include "driver-bitfury16.h"
  12  
  13  //#define FLIP_BITS
  14  
  15  bf_cmd_description_t cmd_description[CHIP_CMD_NUM] = {
  16  	{
  17  		.cmd_code        = CHIP_CMD_TASK_STATUS,
  18  		.cmd_description = "CHIP_CMD_TASK_STATUS"
  19  	},
  20  	{
  21  		.cmd_code        = CHIP_CMD_TASK_WRITE,
  22  		.cmd_description = "CHIP_CMD_TASK_WRITE"
  23  	},
  24  	{
  25  		.cmd_code        = CHIP_CMD_TASK_SWITCH,
  26  		.cmd_description = "CHIP_CMD_TASK_SWITCH"
  27  	},
  28  	{
  29  		.cmd_code        = CHIP_CMD_READ_NONCE,
  30  		.cmd_description = "CHIP_CMD_READ_NONCE"
  31  	},
  32  	{
  33  		.cmd_code        = CHIP_CMD_SET_CLOCK,
  34  		.cmd_description = "CHIP_CMD_SET_CLOCK"
  35  	},
  36  	{
  37  		.cmd_code        = CHIP_CMD_TOGGLE,
  38  		.cmd_description = "CHIP_CMD_TOGGLE"
  39  	},
  40  	{
  41  		.cmd_code        = CHIP_CMD_SET_MASK,
  42  		.cmd_description = "CHIP_CMD_SET_MASK"
  43  	},
  44  	{
  45  		.cmd_code        = CHIP_CMD_CREATE_CHANNEL,
  46  		.cmd_description = "CHIP_CMD_CREATE_CHANNEL"
  47  	}
  48  };
  49  
  50  char* get_cmd_description(bf_cmd_code_t cmd_code)
  51  {
  52  	uint8_t i;
  53  
  54  	for (i = 0; i < CHIP_CMD_NUM; i++)
  55  		if (cmd_description[i].cmd_code == cmd_code)
  56  			return cmd_description[i].cmd_description;
  57  
  58  	return NULL;
  59  }
  60  
  61  static void shift_bits(uint8_t* data, uint8_t size, uint8_t nbits)
  62  {
  63  	uint8_t i;
  64  	uint8_t bytes = nbits / 8;
  65  	uint8_t bits  = nbits % 8;
  66  
  67  	for (i = 0; i < size; i++) {
  68  		data[i] = (data[i + bytes] << bits);
  69  		uint8_t minor = (data[i + bytes + 1] >> (8 - bits));
  70  		data[i] |= minor;
  71  	}
  72  }
  73  
  74  static uint8_t extra_bytes(uint8_t depth)
  75  {
  76  	return (depth * 3) / 8 + 1;
  77  }
  78  
  79  static uint8_t analyze_rx_data(bf_command_t* command, bf_cmd_status_t* cmd_status, uint32_t* nonces)
  80  {
  81  	uint8_t i;
  82  	uint8_t res = 0;
  83  
  84  	if (command->cmd_code & CHIP_CMD_READ_NONCE) {
  85  		shift_bits(command->rx, 49 + 2 + extra_bytes(command->depth), command->depth * 3);
  86  
  87  		command->status	   = command->rx[0];
  88  		cmd_status->status = command->rx[0];
  89  		command->checksum             = command->rx[1];
  90  		cmd_status->checksum_expected = command->checksum;
  91  
  92  		if (nonces == NULL)
  93  			return 1;
  94  
  95  		uint32_t nonce = 0x00000000;
  96  
  97  		/* fill nonces buffer */
  98  		for (i = 0; i <= 48; i++) {
  99  			if ((i % 4 == 0) && (i != 0)) {
 100  				if ((nonce & 0x0fffffff) != 0x0fffffff)
 101  					nonce ^= 0xaaaaaaaa;
 102  				nonces[i/4 - 1] = nonce;
 103  
 104  				if (i == 48)
 105  					break;
 106  
 107  				nonce = 0x00000000;
 108  			}
 109  
 110  			nonce |= (command->rx[i + 2] << 8*(4 - (i%4) - 1));
 111  		}
 112  
 113  #if 0
 114  		char data[128];
 115  		memset(data, 0, sizeof(data));
 116  		for (i = 0; i < 49 + 2 + extra_bytes(command->depth); i++)
 117  			sprintf(data, "%s%02x", data, command->rx[i]);
 118  		applog(LOG_DEBUG, "BF16: RX <- [%s]", data);
 119  #endif
 120  
 121  		for (i = 0; i < 48; i ++)
 122  			command->nonce_checksum += command->rx[i + 2];
 123  		command->nonce_checksum += command->rx[1];
 124  
 125  		cmd_status->nonce_checksum_expected = command->nonce_checksum;
 126  
 127  		if (command->checksum != command->rx[1]) {
 128  			command->checksum_error       = true;
 129  			cmd_status->checksum_error    = true;
 130  			cmd_status->checksum_received = command->rx[50];
 131  			res = 1;
 132  #if 0
 133  			applog(LOG_ERR, "Checksum mismatch: received [%02x] expected [%02x]", command->rx[1], 0x04);
 134  #endif
 135  		} else {
 136  			command->checksum_error    = false;
 137  			cmd_status->checksum_error = false;
 138  		}
 139  
 140  		if ((command->nonce_checksum != command->rx[50]) &&
 141  			(command->nonce_checksum != command->rx[50] + 1)) {
 142  			command->nonce_checksum_error       = true;
 143  			cmd_status->nonce_checksum_error    = true;
 144  			cmd_status->nonce_checksum_received = command->rx[50];
 145  
 146  			res += 2;
 147  #if 0
 148  			applog(LOG_ERR, "Nonce checksum mismatch: received [%02x] expected [%02x]", command->rx[50], checksum);
 149  #endif
 150  		} else {
 151  			command->nonce_checksum_error    = false;
 152  			cmd_status->nonce_checksum_error = false;
 153  		}
 154  	} else {
 155  		shift_bits(command->rx, 2 + extra_bytes(command->depth), command->depth * 3);
 156  
 157  		if (opt_bf16_test_chip != NULL) {
 158  			char data[16];
 159  			memset(data, 0, sizeof(data));
 160  			for (i = 0; i < 2 + extra_bytes(command->depth); i++)
 161  				sprintf(data, "%s%02x", data, command->rx[i]);
 162  			applog(LOG_NOTICE, "BF16: RX <- [%s]", data);
 163  		}
 164  
 165  		command->status	     = command->rx[0];
 166  		cmd_status->status   = command->rx[0];
 167  		uint8_t cmd_checksum = command->rx[1];
 168  		cmd_status->checksum_expected = command->checksum;
 169  
 170  #if 0
 171  		applog(LOG_DEBUG, "Command checksum: [%02x]", cmd_checksum);
 172  		applog(LOG_DEBUG, "Command status:   [%02x]", command->status);
 173  #endif
 174  
 175  		if ((command->checksum != cmd_checksum) &&
 176  		    (command->checksum != cmd_checksum + 1)) {
 177  			command->checksum_error       = true;
 178  			cmd_status->checksum_error    = true;
 179  			cmd_status->checksum_received = cmd_checksum;
 180  			res = 1;
 181  
 182  			if (opt_bf16_test_chip != NULL) {
 183  				applog(LOG_ERR, "BF16: checksum mismatch: received [%02x] expected [%02x]",
 184  						cmd_checksum, command->checksum);
 185  			}
 186  		} else {
 187  			command->checksum_error    = false;
 188  			cmd_status->checksum_error = false;
 189  		}
 190  	}
 191  
 192  	return res;
 193  }
 194  
 195  /* SPI BTC250 primitives */
 196  uint8_t create_channel(spi_channel_id_t spi_channel, uint8_t* channel_path, uint8_t channel_length)
 197  {
 198  	int res = 0;
 199  
 200  	uint8_t* channel_path_buff = cgcalloc(channel_length, sizeof(uint8_t));
 201  	cg_memcpy(channel_path_buff, channel_path, channel_length);
 202  
 203  	res = device_spi_transfer(spi_channel, channel_path_buff, channel_length);
 204  
 205  	free(channel_path_buff);
 206  
 207  	return res;
 208  }
 209  
 210  uint8_t destroy_channel(spi_channel_id_t spi_channel, uint8_t depth)
 211  {
 212  	bf_command_t chip_command;
 213  	bf_chip_address_t chip_address = { 0x00, 0x00, 0x0f };
 214  
 215  	/* send command to 0x0f address */
 216  	spi_command_init(&chip_command, depth, chip_address, CHIP_CMD_TASK_SWITCH, 0, NULL);
 217  	return spi_command_exec(spi_channel, &chip_command, NULL);
 218  }
 219  
 220  /* SPI BTC16 primitives  */
 221  void spi_emit_reset(spi_channel_id_t spi_channel)
 222  {
 223  	device_ctrl_transfer(spi_channel, 1, F_RST);
 224  
 225  	uint8_t data[2] = { 0x00, 0x00 };
 226  	device_spi_transfer(spi_channel, data, sizeof(data));
 227  
 228  	device_ctrl_transfer(spi_channel, 0, F_RST);
 229  }
 230  
 231  uint8_t send_toggle(spi_channel_id_t spi_channel, uint8_t depth, bf_chip_address_t chip_address)
 232  {
 233  	bf_command_t chip_command;
 234  	uint8_t toggle[4] = { 0xa5, 0x00, 0x00, 0x02 };
 235  
 236  	spi_command_init(&chip_command, depth, chip_address, CHIP_CMD_TOGGLE, 3, toggle);
 237  	return spi_command_exec(spi_channel, &chip_command, NULL);
 238  }
 239  
 240  uint8_t set_clock(spi_channel_id_t spi_channel, uint8_t depth,
 241  		bf_chip_address_t chip_address, uint8_t clock)
 242  {
 243  	bf_command_t chip_command;
 244  	uint8_t clock_buf[4];
 245  
 246  	memset(clock_buf, 0, 4);
 247  	gen_clock_data(clock, 1, clock_buf);
 248  	spi_command_init(&chip_command, depth, chip_address, CHIP_CMD_SET_CLOCK, 3, clock_buf);
 249  	return spi_command_exec(spi_channel, &chip_command, NULL);
 250  }
 251  
 252  /* cmd buffer primitives */
 253  int8_t cmd_buffer_init(bf_cmd_buffer_t* cmd_buffer)
 254  {
 255  	if (cmd_buffer == NULL)
 256  		return -1;
 257  
 258  	cmd_buffer->cmd_list = cgmalloc(sizeof(bf_list_t));
 259  	cmd_buffer->cmd_list->head  = NULL;
 260  	cmd_buffer->cmd_list->tail  = NULL;
 261  	cmd_buffer->cmd_list->count = 0;
 262  
 263  	cmd_buffer->tx_buffer = cgcalloc(CMD_BUFFER_LEN, sizeof(uint8_t));
 264  	cmd_buffer->rx_buffer = cgcalloc(CMD_BUFFER_LEN, sizeof(uint8_t));
 265  
 266  	memset(cmd_buffer->tx_buffer, 0, CMD_BUFFER_LEN);
 267  	memset(cmd_buffer->rx_buffer, 0, CMD_BUFFER_LEN);
 268  
 269  	cmd_buffer->free_bytes = CMD_BUFFER_LEN;
 270  	cmd_buffer->tx_offset  = 0;
 271  	cmd_buffer->rx_offset  = 0;
 272  	cmd_buffer->status     = EMPTY;
 273  
 274  	return 0;
 275  }
 276  
 277  int8_t cmd_buffer_deinit(bf_cmd_buffer_t* cmd_buffer)
 278  {
 279  	if (cmd_buffer == NULL)
 280  		return -1;
 281  
 282  	/* free cmd buffer */
 283  	while (cmd_buffer->cmd_list->head != NULL) {
 284  		bf_data_t* cdata = cmd_buffer->cmd_list->head;
 285  		LIST_POP_HEAD(cmd_buffer->cmd_list);
 286  		free(cdata->data);
 287  		free(cdata);
 288  	}
 289  
 290  	free(cmd_buffer->cmd_list);
 291  
 292  	/* free RX/TX buffer */
 293  	free(cmd_buffer->tx_buffer);
 294  	free(cmd_buffer->rx_buffer);
 295  
 296  	cmd_buffer->free_bytes = CMD_BUFFER_LEN;
 297  	cmd_buffer->tx_offset  = 0;
 298  	cmd_buffer->rx_offset  = 0;
 299  	cmd_buffer->status     = EMPTY;
 300  
 301  	return 0;
 302  }
 303  
 304  int8_t cmd_buffer_clear(bf_cmd_buffer_t* cmd_buffer)
 305  {
 306  	if (cmd_buffer == NULL)
 307  		return -1;
 308  
 309  	/* release cmd buffer data memory */
 310  	while (cmd_buffer->cmd_list->head != NULL) {
 311  		bf_data_t* cdata = cmd_buffer->cmd_list->head;
 312  		LIST_POP_HEAD(cmd_buffer->cmd_list);
 313  		free(cdata->data);
 314  		free(cdata);
 315  	}
 316  
 317  	cmd_buffer->cmd_list->count = 0;
 318  
 319  	/* clear RX/TX buffer */
 320  	memset(cmd_buffer->tx_buffer, 0, CMD_BUFFER_LEN);
 321  	memset(cmd_buffer->rx_buffer, 0, CMD_BUFFER_LEN);
 322  
 323  	cmd_buffer->free_bytes = CMD_BUFFER_LEN;
 324  	cmd_buffer->tx_offset  = 0;
 325  	cmd_buffer->rx_offset  = 0;
 326  	cmd_buffer->status     = EMPTY;
 327  
 328  	return 0;
 329  }
 330  
 331  int8_t cmd_buffer_push(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth,
 332  		const bf_chip_address_t chip_address, const bf_chip_address_t src_address,
 333  		const bf_works_t work, const uint32_t id,
 334  		const bf_cmd_code_t cmd_code, const uint8_t data_length, const uint8_t* tx)
 335  {
 336  	uint8_t res = 0;
 337  
 338  	if (cmd_buffer == NULL)
 339  		return -1;
 340  
 341  	if (cmd_buffer->status == EXECUTED)
 342  		return -2;
 343  
 344  	bf_command_t command;
 345  	memset(&command, 0, sizeof(bf_command_t));
 346  
 347  	uint8_t buff[192];
 348  	memset(buff, 0, sizeof(buff));
 349  
 350  	if (cmd_code != CHIP_CMD_CREATE_CHANNEL) {
 351  		res = spi_command_init(&command, depth, chip_address, cmd_code, data_length, tx);
 352  		if (res != 0)
 353  			return res;
 354  	}
 355  
 356  	/* init structure */
 357  	bf_data_t* cdata = cgmalloc(sizeof(bf_data_t));
 358  	cdata->data = cgmalloc(sizeof(bf_cmd_t));
 359  	cdata->next = NULL;
 360  	cdata->prev = NULL;
 361  
 362  	cg_memcpy(&CMD(cdata)->chip_address, &chip_address, sizeof(bf_chip_address_t));
 363  	cg_memcpy(&CMD(cdata)->src_address,  &src_address,  sizeof(bf_chip_address_t));
 364  	cg_memcpy(&CMD(cdata)->work,         &work,         sizeof(bf_works_t));
 365  	CMD(cdata)->id       = id;
 366  	CMD(cdata)->depth    = command.depth;
 367  	CMD(cdata)->checksum = command.checksum;
 368  	CMD(cdata)->cmd_code = cmd_code;
 369  
 370  	if (CMD(cdata)->cmd_code & CHIP_CMD_READ_NONCE)
 371  		CMD(cdata)->data_length = command.data_length + 49 + 2 + extra_bytes(command.depth);
 372  	else if (CMD(cdata)->cmd_code == CHIP_CMD_CREATE_CHANNEL)
 373  		CMD(cdata)->data_length = data_length;
 374  	else
 375  		CMD(cdata)->data_length = command.data_length + 2 + extra_bytes(command.depth);
 376  
 377  	if (cmd_buffer->free_bytes < CMD(cdata)->data_length) {
 378  		/* not enough TX/RX buffer space available */
 379  		free(cdata->data);
 380  		free(cdata);
 381  		return -3;
 382  	}
 383  
 384  	/* init send buffer */
 385  	if (cmd_code != CHIP_CMD_CREATE_CHANNEL) {
 386  		cg_memcpy(buff, command.tx, command.data_length);
 387  		cg_memcpy(cmd_buffer->tx_buffer + cmd_buffer->tx_offset, buff, CMD(cdata)->data_length);
 388  	} else
 389  		cg_memcpy(cmd_buffer->tx_buffer + cmd_buffer->tx_offset, tx, CMD(cdata)->data_length);
 390  
 391  #if 0
 392  	uint16_t i;
 393  	char data[384];
 394  	memset(data, 0, sizeof(data));
 395  	for (i = 0; i < command.data_length; i++)
 396  		sprintf(data, "%s%02x", data, command.tx[i]);
 397  	applog(LOG_DEBUG, "BF16: TX -> [%s]", data);
 398  #endif
 399  
 400  	cmd_buffer->tx_offset  += CMD(cdata)->data_length;
 401  	cmd_buffer->free_bytes -= CMD(cdata)->data_length;
 402  
 403  	/* add cmd to buffer */
 404  	LIST_PUSH_TAIL(cmd_buffer->cmd_list, cdata);	
 405  	cmd_buffer->cmd_list->count++;
 406  
 407  	return 0;
 408  }
 409  
 410  int8_t cmd_buffer_push_send_toggle(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth,
 411  		const bf_chip_address_t chip_address)
 412  {
 413  	bf_works_t work;
 414  	uint8_t toggle[4] = { 0xa5, 0x00, 0x00, 0x02 };
 415  
 416  	return cmd_buffer_push(cmd_buffer, depth, chip_address, chip_address,
 417  			work, 0, CHIP_CMD_TOGGLE, 3, toggle);
 418  }
 419  
 420  int8_t cmd_buffer_push_set_clock(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth,
 421  		const bf_chip_address_t chip_address, uint8_t clock)
 422  {
 423  	bf_works_t work;
 424  	uint8_t clock_buf[4];
 425  
 426  	memset(clock_buf, 0, 4);
 427  	gen_clock_data(clock, 1, clock_buf);
 428  
 429  	return cmd_buffer_push(cmd_buffer, depth, chip_address, chip_address,
 430  			work, 0, CHIP_CMD_SET_CLOCK, 3, clock_buf);
 431  }
 432  
 433  int8_t cmd_buffer_push_set_mask(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth,
 434  		const bf_chip_address_t chip_address, uint8_t mask)
 435  {
 436  	uint8_t i;
 437  	bf_works_t work;
 438  	uint8_t noncemask[4];
 439  
 440  	for (i = 0; i < 4; i++)
 441  		noncemask[i] = (mask >> (8*(4 - i - 1))) & 0xff;
 442  
 443  	return cmd_buffer_push(cmd_buffer, depth, chip_address, chip_address,
 444  			work, 0, CHIP_CMD_SET_MASK, 3, noncemask);
 445  }
 446  
 447  int8_t cmd_buffer_push_create_channel(bf_cmd_buffer_t* cmd_buffer,
 448  		uint8_t* channel_path, uint8_t channel_length)
 449  {
 450  	bf_works_t work;
 451  	bf_chip_address_t chip_address = { 0x00, 0x00, 0x00 };
 452  
 453  	return cmd_buffer_push(cmd_buffer, 0, chip_address, chip_address,
 454  			work, 0, CHIP_CMD_CREATE_CHANNEL, channel_length, channel_path);
 455  }
 456  
 457  int8_t cmd_buffer_push_destroy_channel(bf_cmd_buffer_t* cmd_buffer, const uint8_t depth)
 458  {
 459  	bf_works_t work;
 460  	bf_chip_address_t chip_address = { 0x00, 0x00, 0x0f };
 461  
 462  	return cmd_buffer_push(cmd_buffer, depth, chip_address, chip_address,
 463  			work, 0, CHIP_CMD_TASK_SWITCH, 0, NULL);
 464  }
 465  
 466  bool match_nonce(uint32_t nonce, uint32_t mask, uint8_t nbits)
 467  {
 468  	uint32_t fixed_mask = (uint32_t)(pow(2, nbits) - 1);
 469  	return ((nonce & fixed_mask) == (mask & fixed_mask));
 470  }
 471  
 472  uint8_t find_nonces(uint32_t* curr_nonces, uint32_t* prev_nonces, uint32_t* valid_nonces)
 473  {
 474  	uint8_t i, j;
 475  	uint8_t found  = 0;
 476  	uint8_t nonces = 0;
 477  	uint8_t diff = 0;
 478  
 479  	uint32_t found_nonces[12];
 480  	memset(found_nonces, 0, sizeof(found_nonces));
 481  
 482  	for (i = 0; i < 12; i++) {
 483  		if (((curr_nonces[i] & 0x0fffffff) != 0x0fffffff) &&
 484  			(curr_nonces[i] != prev_nonces[i])) {
 485  			found_nonces[found++] = curr_nonces[i];
 486  		}
 487  
 488  		if (((curr_nonces[i] & 0x0fffffff) == 0x0fffffff) &&
 489  			(curr_nonces[i] != prev_nonces[i]))
 490  			diff++;
 491  	}
 492  
 493  	for (i = 0; i < found; i++) {
 494  		if (found_nonces[i] == 0x00000000)
 495  			continue;
 496  
 497  		for (j = i; j < found; j++) {
 498  			if ((j != i) && (found_nonces[i] == found_nonces[j]))
 499  				found_nonces[j] = 0x00000000;
 500  		}
 501  
 502  		valid_nonces[nonces++] = found_nonces[i];
 503  	}
 504  
 505  	return nonces;
 506  }
 507  
 508  int8_t cmd_buffer_pop(bf_cmd_buffer_t* cmd_buffer, bf_cmd_status_t* cmd_status, uint32_t* nonces)
 509  {
 510  	if (cmd_buffer == NULL)
 511  		return -1;
 512  
 513  	if (cmd_buffer->status != EXECUTED)
 514  		return -2;
 515  
 516  	if (cmd_buffer->cmd_list->head == NULL)
 517  		return -3;
 518  
 519  	uint8_t buff[192];
 520  	bf_command_t chip_command;
 521  	memset(buff, 0, sizeof(buff));
 522  	memset(chip_command.rx, 0, sizeof(chip_command.rx));
 523  
 524  	/* extract command from list */
 525  	bf_data_t* cdata = cmd_buffer->cmd_list->head;
 526  
 527  	chip_command.cmd_code             = CMD(cdata)->cmd_code;
 528  	chip_command.depth                = CMD(cdata)->depth;
 529  	chip_command.data_length          = CMD(cdata)->data_length;
 530  	chip_command.status               = 0;
 531  	chip_command.checksum             = CMD(cdata)->checksum;
 532  	chip_command.nonce_checksum       = 0;
 533  	chip_command.checksum_error       = false;
 534  	chip_command.nonce_checksum_error = false;
 535  
 536  	/* extract chip return data */
 537  	cg_memcpy(buff, cmd_buffer->rx_buffer + cmd_buffer->rx_offset, CMD(cdata)->data_length);
 538  	cmd_buffer->rx_offset += CMD(cdata)->data_length;
 539  	if (CMD(cdata)->cmd_code & CHIP_CMD_READ_NONCE) {
 540  		cg_memcpy(chip_command.rx, buff + CMD(cdata)->data_length - (49 + 2 + extra_bytes(chip_command.depth)),
 541  				49 + 2 + extra_bytes(chip_command.depth));
 542  		memset(nonces, 0, 12 * sizeof(uint32_t));
 543  		analyze_rx_data(&chip_command, cmd_status, nonces);
 544  	} else if (CMD(cdata)->cmd_code == CHIP_CMD_CREATE_CHANNEL) {
 545  		cg_memcpy(chip_command.rx, buff, CMD(cdata)->data_length);
 546  	} else {
 547  		cg_memcpy(chip_command.rx, buff + CMD(cdata)->data_length - (2 + extra_bytes(chip_command.depth)),
 548  				2 + extra_bytes(chip_command.depth));
 549  		analyze_rx_data(&chip_command, cmd_status, NULL);
 550  	}
 551  
 552  	/* prepare cmd_status */
 553  	cg_memcpy(&cmd_status->chip_address, &CMD(cdata)->chip_address, sizeof(bf_chip_address_t));
 554  	cg_memcpy(&cmd_status->src_address,  &CMD(cdata)->src_address,  sizeof(bf_chip_address_t));
 555  	cg_memcpy(&cmd_status->work,         &CMD(cdata)->work,         sizeof(bf_works_t));
 556  	cmd_status->id       = CMD(cdata)->id;
 557  	cmd_status->cmd_code = CMD(cdata)->cmd_code;
 558  
 559  	/* push memory back to free cmd list */
 560  	LIST_POP_HEAD(cmd_buffer->cmd_list);
 561  	cmd_buffer->cmd_list->count--;
 562  	free(cdata->data);
 563  	free(cdata);
 564  
 565  	return 0;
 566  }
 567  
 568  int8_t cmd_buffer_exec(spi_channel_id_t spi_channel, bf_cmd_buffer_t* cmd_buffer)
 569  {
 570  	if (cmd_buffer == NULL)
 571  		return -1;
 572  
 573  	if (cmd_buffer->status == TX_READY) {
 574  		device_spi_txrx(spi_channel, cmd_buffer->tx_buffer, cmd_buffer->rx_buffer, cmd_buffer->tx_offset);
 575  		cmd_buffer->status = EXECUTED;
 576  	} else
 577  		return -2;
 578  
 579  	return 0;
 580  }
 581  
 582  /* BF16 command primitives */
 583  uint8_t gen_clock_data(uint8_t clock, uint8_t prescaler, uint8_t data[4])
 584  {
 585  	uint8_t i;
 586  	uint32_t data32 = 0x00000000;
 587  
 588  	if (clock > 0x3f)
 589  		return -1;
 590  
 591  	if ((prescaler != 0) && (prescaler != 1))
 592  		return -1;
 593  
 594  	uint32_t magic_const = 0x38;
 595  	uint32_t prescaler1 = prescaler;
 596  	uint32_t clock1 = clock;
 597  	uint32_t prescaler2 = prescaler;
 598  	uint32_t clock2 = clock;
 599  
 600  	magic_const <<= 20;
 601  
 602  	if (prescaler == 1) {
 603  		prescaler1 <<= 19;
 604  		prescaler2 <<= 12;
 605  	}
 606  
 607  	clock1 <<= 13;
 608  	clock2 <<= 6;
 609  
 610  	data32 = magic_const | prescaler1 | clock1 | prescaler2 | clock2;
 611  	for (i = 0; i < 4; i++)
 612  		data[i] = (data32 >> (8*(4 - i - 1))) & 0xff;
 613  
 614  	return 0;
 615  }
 616  
 617  #ifdef FLIP_BITS
 618  static uint32_t flip_bits(uint32_t data, uint8_t nbits)
 619  {
 620  	uint32_t ret = 0x00000000;
 621  	uint8_t i;
 622  
 623  	for (i = 0; i < nbits; i++)
 624  		ret |= (((data >> i) & 0x1) << (nbits - (i + 1)));
 625  
 626  	return ret;
 627  }
 628  #endif
 629  
 630  uint32_t gen_mask(uint32_t nonce, uint8_t nbits)
 631  {
 632  	uint32_t mask = 0x00000000;
 633  
 634  	uint32_t mask_code = (nbits << 16);
 635  
 636  	/* highest 16 bits of nonce counter */
 637  	uint32_t nonce_code = (nonce & 0x0007ffff);
 638  #ifdef FLIP_BITS
 639  	uint32_t nonce_cntr = flip_bits(nonce_code, 19);
 640  	nonce_code = (flip_bits(nonce_cntr - 2, 19) ^ 0xaaaaaaaa);
 641  	mask = (mask_code | (nonce_code & (uint32_t)(pow(2, nbits) - 1)));
 642  #else
 643  	nonce_code = ((nonce_code ^ 0xaaaaaaaa) & (uint32_t)(pow(2, nbits) - 1));
 644  	mask = (mask_code | nonce_code);
 645  #endif
 646  
 647  	return mask;
 648  }
 649  
 650  void ms3steps16(uint32_t* p, uint32_t* w, uint32_t* task)
 651  {
 652  	uint32_t a, b, c, d, e, f, g, h, new_e, new_a;
 653  	uint8_t i;
 654  
 655  	a = p[0];
 656  	b = p[1];
 657  	c = p[2];
 658  	d = p[3];
 659  	e = p[4];
 660  	f = p[5];
 661  	g = p[6];
 662  	h = p[7];
 663  	for (i = 0; i < 3; i++) {
 664  		new_e = w[i] + sha256_k[i] + h + CH(e,f,g) + SHA256_F2(e) + d;
 665  		new_a = w[i] + sha256_k[i] + h + CH(e,f,g) + SHA256_F2(e) +
 666  		        SHA256_F1(a) + MAJ(a,b,c);
 667  		d = c;
 668  		c = b;
 669  		b = a;
 670  		a = new_a;
 671  		h = g;
 672  		g = f;
 673  		f = e;
 674  		e = new_e;
 675  	}
 676  
 677  	task[18] = ntohl(a ^ 0xaaaaaaaa);
 678  	task[17] = ntohl(b ^ 0xaaaaaaaa);
 679  	task[16] = ntohl(c ^ 0xaaaaaaaa);
 680  	task[15] = ntohl(d ^ 0xaaaaaaaa);
 681  	task[11] = ntohl(e ^ 0xaaaaaaaa);
 682  	task[10] = ntohl(f ^ 0xaaaaaaaa);
 683  	task[9]  = ntohl(g ^ 0xaaaaaaaa);
 684  	task[8]  = ntohl(h ^ 0xaaaaaaaa);
 685  }
 686  
 687  uint8_t gen_task_data(uint32_t* midstate, uint32_t merkle, uint32_t ntime,
 688  		uint32_t nbits, uint32_t mask, uint8_t* task)
 689  {
 690  	uint8_t  i;
 691  	uint32_t tmp;
 692  	uint32_t w[3];
 693  
 694  	w[0] = merkle;
 695  	w[1] = ntime;
 696  	w[2] = nbits;
 697  
 698  	for (i = 0; i < 8; i++) {
 699  		tmp = midstate[i];
 700  		tmp ^= 0xaaaaaaaa;
 701  		tmp = ntohl(tmp);
 702  		cg_memcpy(task + i*4, &tmp, sizeof(tmp));
 703  	}
 704  
 705  	ms3steps16(midstate, w, (uint32_t*)task);
 706  
 707  	for (i = 0; i < 3; i++) {
 708  		tmp = w[i];
 709  		tmp ^= 0xaaaaaaaa;
 710  		tmp = ntohl(tmp);
 711  		cg_memcpy(task + (12 + i)*4, &tmp, sizeof(tmp));
 712  	}
 713  
 714  	mask = ntohl(mask);
 715  	cg_memcpy(task + 19*4, &mask, sizeof(mask));
 716  
 717  	return 0;
 718  }
 719  
 720  uint8_t spi_command_init(bf_command_t* command, const uint8_t depth,
 721  		const bf_chip_address_t chip_address, const bf_cmd_code_t cmd_code,
 722  		const uint8_t data_length, const uint8_t* tx)
 723  {
 724  	uint8_t i;
 725  
 726  	memset(command->tx, 0, sizeof(command->tx));
 727  	memset(command->rx, 0, sizeof(command->rx));
 728  
 729  	command->tx[0] = 0x01;
 730  	command->data_length = 1;
 731  
 732  	if ((chip_address.chip_id > 10) && (chip_address.chip_id != 0x0f))
 733  		return 1;
 734  	else {
 735  		cg_memcpy(&command->chip_address, &chip_address, sizeof(bf_chip_address_t));
 736  		command->tx[1] = (command->chip_address.chip_id << 4);
 737  		command->data_length++;
 738  	}
 739  
 740  	command->depth = depth;
 741  
 742  	command->cmd_code = cmd_code;
 743  	command->tx[2] = command->cmd_code;
 744  	command->data_length++;
 745  
 746  	if (data_length <= 79) {
 747  		command->tx[3] = data_length;
 748  		command->data_length++;
 749  	} else
 750  		return 1;
 751  
 752  	/* fill TX data */
 753  	if (data_length == 0) {
 754  		command->tx[4] = 0x00;
 755  		command->data_length++;
 756  	} else if (tx != NULL) {
 757  		cg_memcpy(command->tx + 4, tx, data_length + 1);
 758  		command->data_length += (data_length + 1);
 759  	} else
 760  		return 1;
 761  
 762  	/* calculate checksum */
 763  	command->checksum = 0;
 764  	command->nonce_checksum = 0;
 765  	for (i = 2; i < command->data_length; i++)
 766  		command->checksum += command->tx[i];
 767  
 768  	command->checksum_error       = false;
 769  	command->nonce_checksum_error = false;
 770  
 771  	return 0;
 772  }
 773  
 774  uint8_t spi_command_exec(spi_channel_id_t spi_channel, bf_command_t* command, uint32_t* nonces)
 775  {
 776  	uint8_t buff[192];
 777  	uint8_t res = 0;
 778  	bf_cmd_status_t cmd_status;
 779  
 780  	if (command->cmd_code & CHIP_CMD_READ_NONCE) {
 781  		memset(buff, 0x00, command->data_length + 49 + 2 + extra_bytes(command->depth));
 782  		cg_memcpy(buff, command->tx, command->data_length);
 783  		device_spi_transfer(spi_channel, buff, command->data_length + 49 + 2 + extra_bytes(command->depth));
 784  		cg_memcpy(command->rx, buff + command->data_length, 49 + 2 + extra_bytes(command->depth));
 785  
 786  #if 0
 787  		uint16_t i;
 788  		char data[256];
 789  		memset(data, 0, sizeof(data));
 790  		for (i = 0; i < command->data_length; i++)
 791  			sprintf(data, "%s%02x", data, command->tx[i]);
 792  		applog(LOG_DEBUG, "BF16: TX -> [%s]", data);
 793  #endif
 794  
 795  		return analyze_rx_data(command, &cmd_status, nonces);
 796  	} else {
 797  		memset(buff, 0x00, command->data_length + 2 + extra_bytes(command->depth));
 798  		cg_memcpy(buff, command->tx, command->data_length);
 799  		device_spi_transfer(spi_channel, buff, command->data_length + 2 + extra_bytes(command->depth));
 800  		cg_memcpy(command->rx, buff + command->data_length, 2 + extra_bytes(command->depth));
 801  
 802  		if (opt_bf16_test_chip != NULL) {
 803  			uint16_t i;
 804  			char data[256];
 805  			memset(data, 0, sizeof(data));
 806  			for (i = 0; i < command->data_length; i++)
 807  				sprintf(data, "%s%02x", data, command->tx[i]);
 808  			applog(LOG_NOTICE, "BF16: TX -> [%s]", data);
 809  		}
 810  
 811  		return analyze_rx_data(command, &cmd_status, nonces);
 812  	}
 813  
 814  	return res;
 815  }
 816  
 817  /* dynamic work list primitives */
 818  bf_list_t* workd_list_init(void)
 819  {
 820  	bf_list_t* list = cgmalloc(sizeof(bf_list_t));
 821  	list->head = NULL;
 822  	list->tail = NULL;
 823  	list->count = 0;
 824  	pthread_mutex_init(&list->lock, NULL);
 825  
 826  	return list;
 827  }
 828  
 829  int8_t workd_list_deinit(bf_list_t* list, struct cgpu_info *bitfury)
 830  {
 831  	if (list == NULL)
 832  		return -1;
 833  
 834  	/* free work list */
 835  	L_LOCK(list);
 836  	while (list->head != NULL) {
 837  		bf_data_t* wdata = list->head;
 838  		LIST_POP_HEAD(list);
 839  
 840  		if (WORKD(wdata)->rolled)
 841  			free_work(WORKD(wdata)->work);
 842  		else
 843  			work_completed(bitfury, WORKD(wdata)->work);
 844  
 845  		free(wdata);
 846  	}
 847  	L_UNLOCK(list);
 848  
 849  	pthread_mutex_destroy(&list->lock);
 850  	list->count = 0;
 851  	free(list);
 852  
 853  	return 0;
 854  }
 855  
 856  int8_t workd_list_push(bf_list_t* list, bf_workd_t* work)
 857  {
 858  	if ((list == NULL) || (work == NULL))
 859  		return -1;
 860  
 861  	bf_data_t* wdata = cgmalloc(sizeof(bf_data_t));
 862  	wdata->data = work;
 863  	wdata->next = NULL;
 864  	wdata->prev = NULL;
 865  
 866  	LIST_PUSH_TAIL(list, wdata);
 867  	list->count++;
 868  
 869  	return 0;
 870  }
 871  
 872  int8_t workd_list_pop(bf_list_t* list, struct cgpu_info *bitfury)
 873  {
 874  	if (list == NULL)
 875  		return -1;
 876  
 877  	bf_data_t* wdata = list->head;
 878  	if (wdata != NULL) {
 879  		LIST_POP_HEAD(list);	
 880  
 881  		if (WORKD(wdata)->rolled)
 882  			free_work(WORKD(wdata)->work);
 883  		else
 884  			work_completed(bitfury, WORKD(wdata)->work);
 885  
 886  		list->count--;
 887  		free(wdata->data);
 888  		free(wdata);
 889  	} else
 890  		return -1;
 891  
 892  	return 0;
 893  }
 894  
 895  int8_t workd_list_remove(bf_list_t* list, bf_works_t* works)
 896  {
 897  	if (list == NULL)
 898  		return -1;
 899  
 900  	bf_data_t* wdata = list->head;
 901  	if (wdata != NULL) {
 902  		LIST_POP_HEAD(list);	
 903  
 904  		cg_memcpy(&works->work,    WORKD(wdata)->work,     sizeof(struct work));
 905  		cg_memcpy(&works->payload, &WORKD(wdata)->payload, sizeof(bf_payload_t));
 906  
 907  		list->count--;
 908  		free(wdata);
 909  	} else
 910  		return -1;
 911  
 912  	return 0;
 913  }
 914  
 915  /* nonces list primitives */
 916  bf_list_t* nonce_list_init(void)
 917  {
 918  	bf_list_t* list = cgmalloc(sizeof(bf_list_t));
 919  	list->head = NULL;
 920  	list->tail = NULL;
 921  	list->count = 0;
 922  	pthread_mutex_init(&list->lock, NULL);
 923  
 924  	return list;
 925  }
 926  
 927  int8_t nonce_list_deinit(bf_list_t* list)
 928  {
 929  	if (list == NULL)
 930  		return -1;
 931  
 932  	/* free nonce list */
 933  	L_LOCK(list);
 934  	while (list->head != NULL) {
 935  		bf_data_t* ndata = list->head;
 936  		LIST_POP_HEAD(list);
 937  		free(ndata->data);
 938  		free(ndata);
 939  	}
 940  	L_UNLOCK(list);
 941  
 942  	pthread_mutex_destroy(&list->lock);
 943  	list->count = 0;
 944  	free(list);
 945  	
 946  	return 0;
 947  }
 948  
 949  int8_t nonce_list_push(bf_list_t* list, uint32_t nonce)
 950  {
 951  	if (list == NULL)
 952  		return -1;
 953  
 954  	/* find nonce duplicates */
 955  	bf_data_t* ndata = list->head;
 956  	while (ndata != NULL) {
 957  		if (NONCE(ndata)->nonce == nonce)
 958  			return -1;
 959  		ndata = ndata->next;
 960  	}
 961  
 962  	ndata = cgmalloc(sizeof(bf_data_t));
 963  	ndata->data = cgmalloc(sizeof(bf_nonce_t));
 964  	NONCE(ndata)->nonce = nonce;
 965  	ndata->next = NULL;
 966  	ndata->prev = NULL;
 967  
 968  	LIST_PUSH_TAIL(list, ndata);
 969  	list->count++;
 970  
 971  	return 0;
 972  }
 973  
 974  uint32_t nonce_list_pop(bf_list_t* list)
 975  {
 976  	uint32_t nonce = 0;
 977  
 978  	bf_data_t* ndata = list->head;
 979  	if (ndata != NULL) {
 980  		nonce = NONCE(ndata)->nonce;
 981  		LIST_POP_HEAD(list);	
 982  		list->count--;
 983  		free(ndata->data);
 984  		free(ndata);
 985  	} else
 986  		return -1;
 987  
 988  	return nonce;
 989  }
 990  
 991  /* renoncework list primitives */
 992  bf_list_t* renoncework_list_init(void)
 993  {
 994  	bf_list_t* list = cgmalloc(sizeof(bf_list_t));
 995  	list->head = NULL;
 996  	list->tail = NULL;
 997  	list->count = 0;
 998  	pthread_mutex_init(&list->lock, NULL);
 999  
1000  	return list;
1001  }
1002  
1003  int8_t renoncework_list_deinit(bf_list_t* list)
1004  {
1005  	if (list == NULL)
1006  		return -1;
1007  
1008  	/* free renoncework list */
1009  	L_LOCK(list);
1010  	while (list->head != NULL) {
1011  		bf_data_t* rnwdata = list->head;
1012  		LIST_POP_HEAD(list);
1013  
1014  		free(rnwdata->data);
1015  		free(rnwdata);
1016  	}
1017  	L_UNLOCK(list);
1018  
1019  	pthread_mutex_destroy(&list->lock);
1020  	list->count = 0;
1021  	free(list);
1022  
1023  	return 0;
1024  }
1025  
1026  int8_t renoncework_list_push(bf_list_t* list, bf_chip_address_t src_address, uint32_t nonce)
1027  {
1028  	if (list == NULL)
1029  		return -1;
1030  
1031  	bf_data_t* rnwdata = cgmalloc(sizeof(bf_data_t));
1032  	rnwdata->data = cgmalloc(sizeof(bf_renoncework_t));
1033  	rnwdata->next = NULL;
1034  	rnwdata->prev = NULL;
1035  
1036  	cg_memcpy(&RENONCEWORK(rnwdata)->src_address, &src_address, sizeof(bf_chip_address_t));
1037  	RENONCEWORK(rnwdata)->nonce = nonce;
1038  
1039  	LIST_PUSH_TAIL(list, rnwdata);
1040  	list->count++;
1041  
1042  	return 0;
1043  }
1044  
1045  int8_t renoncework_list_pop(bf_list_t* list)
1046  {
1047  	if (list == NULL)
1048  		return -1;
1049  
1050  	bf_data_t* rnwdata = list->head;
1051  	if (rnwdata != NULL) {
1052  		LIST_POP_HEAD(list);	
1053  		list->count--;
1054  		free(rnwdata->data);
1055  		free(rnwdata);
1056  	} else
1057  		return -1;
1058  
1059  	return 0;
1060  }
1061  
1062  /* noncework list primitives */
1063  bf_list_t* noncework_list_init(void)
1064  {
1065  	bf_list_t* list = cgmalloc(sizeof(bf_list_t));
1066  	list->head = NULL;
1067  	list->tail = NULL;
1068  	list->count = 0;
1069  	pthread_mutex_init(&list->lock, NULL);
1070  
1071  	return list;
1072  }
1073  
1074  int8_t noncework_list_deinit(bf_list_t* list)
1075  {
1076  	if (list == NULL)
1077  		return -1;
1078  
1079  	/* free noncework list */
1080  	L_LOCK(list);
1081  	while (list->head != NULL) {
1082  		bf_data_t* nwdata = list->head;
1083  		LIST_POP_HEAD(list);
1084  
1085  		free(nwdata->data);
1086  		free(nwdata);
1087  	}
1088  	L_UNLOCK(list);
1089  
1090  	pthread_mutex_destroy(&list->lock);
1091  	list->count = 0;
1092  	free(list);
1093  
1094  	return 0;
1095  }
1096  
1097  int8_t noncework_list_push(bf_list_t* list, bf_chip_address_t chip_address,
1098  		bf_chip_address_t src_address, bf_works_t cwork, bf_works_t owork, uint32_t nonce)
1099  {
1100  	if (list == NULL)
1101  		return -1;
1102  
1103  	bf_data_t* nwdata = cgmalloc(sizeof(bf_data_t));
1104  	nwdata->data = cgmalloc(sizeof(bf_noncework_t));
1105  	nwdata->next = NULL;
1106  	nwdata->prev = NULL;
1107  
1108  	cg_memcpy(&NONCEWORK(nwdata)->cwork, &cwork, sizeof(bf_works_t));
1109  	cg_memcpy(&NONCEWORK(nwdata)->owork, &owork, sizeof(bf_works_t));
1110  	cg_memcpy(&NONCEWORK(nwdata)->chip_address, &chip_address, sizeof(bf_chip_address_t));
1111  	cg_memcpy(&NONCEWORK(nwdata)->src_address,  &src_address,  sizeof(bf_chip_address_t));
1112  	NONCEWORK(nwdata)->nonce = nonce;
1113  
1114  	LIST_PUSH_TAIL(list, nwdata);
1115  	list->count++;
1116  
1117  	return 0;
1118  }
1119  
1120  int8_t noncework_list_pop(bf_list_t* list)
1121  {
1122  	if (list == NULL)
1123  		return -1;
1124  
1125  	bf_data_t* nwdata = list->head;
1126  	if (nwdata != NULL) {
1127  		LIST_POP_HEAD(list);	
1128  		list->count--;
1129  		free(nwdata->data);
1130  		free(nwdata);
1131  	} else
1132  		return -1;
1133  
1134  	return 0;
1135  }
1136  
1137  /* renonce list primitives */
1138  bf_list_t* renonce_list_init(void)
1139  {
1140  	bf_list_t* list = cgmalloc(sizeof(bf_list_t));
1141  	list->head = NULL;
1142  	list->tail = NULL;
1143  	list->count = 0;
1144  	pthread_mutex_init(&list->lock, NULL);
1145  
1146  	return list;
1147  }
1148  
1149  int8_t renonce_list_deinit(bf_list_t* list)
1150  {
1151  	if (list == NULL)
1152  		return -1;
1153  
1154  	/* free renonce list */
1155  	L_LOCK(list);
1156  	while (list->head != NULL) {
1157  		bf_data_t* rdata = list->head;
1158  		LIST_POP_HEAD(list);
1159  
1160  		free(rdata->data);
1161  		free(rdata);
1162  	}
1163  	L_UNLOCK(list);
1164  
1165  	pthread_mutex_destroy(&list->lock);
1166  	list->count = 0;
1167  	free(list);
1168  
1169  	return 0;
1170  }
1171  
1172  int8_t renonce_list_push(bf_list_t* list, uint32_t id, uint32_t nonce, bf_chip_address_t src_address,
1173  		bf_works_t cwork, bf_works_t owork)
1174  {
1175  	if (list == NULL)
1176  		return -1;
1177  
1178  	bf_data_t* rdata = cgmalloc(sizeof(bf_data_t));
1179  	rdata->data = cgmalloc(sizeof(bf_renonce_t));
1180  	rdata->next = NULL;
1181  	rdata->prev = NULL;
1182  
1183  	cg_memcpy(&RENONCE(rdata)->cwork, &cwork, sizeof(bf_works_t));
1184  	cg_memcpy(&RENONCE(rdata)->owork, &owork, sizeof(bf_works_t));
1185  	cg_memcpy(&RENONCE(rdata)->src_address, &src_address, sizeof(bf_chip_address_t));
1186  	RENONCE(rdata)->id    = id;
1187  	RENONCE(rdata)->nonce = nonce;
1188  	RENONCE(rdata)->stage = RENONCE_STAGE0;
1189  	RENONCE(rdata)->sent      = false;
1190  	RENONCE(rdata)->received  = false;
1191  	RENONCE(rdata)->match     = false;
1192  
1193  	LIST_PUSH_TAIL(list, rdata);
1194  	list->count++;
1195  
1196  	return 0;
1197  }
1198  
1199  int8_t renonce_list_pop(bf_list_t* list)
1200  {
1201  	if (list == NULL)
1202  		return -1;
1203  
1204  	bf_data_t* rdata = list->head;
1205  	if (rdata != NULL) {
1206  		LIST_POP_HEAD(list);	
1207  		list->count--;
1208  		free(rdata->data);
1209  		free(rdata);
1210  	} else
1211  		return -1;
1212  
1213  	return 0;
1214  }
1215  
1216  int8_t renonce_list_remove(bf_list_t* list, bf_data_t* rdata)
1217  {
1218  	if (list == NULL)
1219  		return -1;
1220  
1221  	if (rdata != NULL) {
1222  		LIST_REMOVE(list, rdata);
1223  		list->count--;
1224  		free(rdata->data);
1225  		free(rdata);
1226  	} else
1227  		return -1;
1228  
1229  	return 0;
1230  }