driver-knc-spi-fpga.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  1. /*
  2. * cgminer driver for KnCminer devices
  3. *
  4. * Copyright 2013 Con Kolivas <kernel@kolivas.org>
  5. * Copyright 2013 KnCminer
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the Free
  9. * Software Foundation; either version 3 of the License, or (at your option)
  10. * any later version. See COPYING for more details.
  11. */
  12. #include <stdlib.h>
  13. #include <assert.h>
  14. #include <fcntl.h>
  15. #include <limits.h>
  16. #include <unistd.h>
  17. #include <sys/ioctl.h>
  18. #include <linux/types.h>
  19. #include <linux/spi/spidev.h>
  20. #include "logging.h"
  21. #include "miner.h"
  22. #define MAX_SPIS 1
  23. #define MAX_BYTES_IN_SPI_XSFER 4096
  24. /* /dev/spidevB.C, where B = bus, C = chipselect */
  25. #define SPI_DEVICE_TEMPLATE "/dev/spidev%d.%d"
  26. #define SPI_MODE (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH)
  27. #define SPI_BITS_PER_WORD 32
  28. #define SPI_MAX_SPEED 3000000
  29. #define SPI_DELAY_USECS 0
  30. /* Max number of ASICs permitted on one SPI device */
  31. #define MAX_ASICS 6
  32. #define CORES_PER_ASIC 192
  33. /* How many hardware errors in a row before disabling the core */
  34. #define HW_ERR_LIMIT 10
  35. #define DISA_ERR_LIMIT 3
  36. #define MAX_ACTIVE_WORKS (192 * 2 * 6 * 2)
  37. #define WORK_MIDSTATE_WORDS 8
  38. #define WORK_DATA_WORDS 3
  39. #define WORK_STALE_US 60000000
  40. #define SECONDS_IN_MINUTE 60
  41. /* Keep core disabled for no longer than 15 minutes */
  42. #define CORE_DISA_PERIOD_US (15 * SECONDS_IN_MINUTE * 1000000)
  43. /* DP = Disable Policy */
  44. bool opt_knc_DP_checkworkid = false;
  45. bool opt_knc_DP_disable_permanently = false;
  46. struct spidev_context {
  47. int fd;
  48. uint32_t speed;
  49. uint16_t delay;
  50. uint8_t mode;
  51. uint8_t bits;
  52. };
  53. struct spi_request {
  54. #define CMD_NOP 0
  55. #define CMD_GET_VERSION 1
  56. #define CMD_SUBMIT_WORK 2
  57. #define CMD_FLUSH_QUEUE 3
  58. #define WORK_ID_MASK 0x7FFF
  59. #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  60. uint32_t cmd :4;
  61. uint32_t rsvd :1; /* set to zero */
  62. uint32_t queue_id :12;
  63. uint32_t work_id :15;
  64. #else
  65. uint32_t work_id :15;
  66. uint32_t queue_id :12;
  67. uint32_t rsvd :1; /* set to zero */
  68. uint32_t cmd :4;
  69. #endif
  70. uint32_t midstate[WORK_MIDSTATE_WORDS];
  71. uint32_t data[WORK_DATA_WORDS];
  72. };
  73. struct spi_response {
  74. #define RESPONSE_TYPE_NOP 0
  75. #define RESPONSE_TYPE_NONCE_FOUND 1
  76. #define RESPONSE_TYPE_WORK_DONE 2
  77. #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  78. uint32_t type :2;
  79. uint32_t asic :3;
  80. uint32_t queue_id :12;
  81. uint32_t work_id :15;
  82. #else
  83. uint32_t work_id :15;
  84. uint32_t queue_id :12;
  85. uint32_t asic :3;
  86. uint32_t type :2;
  87. #endif
  88. uint32_t nonce;
  89. uint32_t core;
  90. };
  91. #define MAX_REQUESTS_IN_BATCH ( MAX_BYTES_IN_SPI_XSFER / \
  92. sizeof(struct spi_request) \
  93. )
  94. static struct spi_request spi_txbuf[MAX_REQUESTS_IN_BATCH];
  95. #define MAX_RESPONSES_IN_BATCH ( (sizeof(spi_txbuf) - 12) / \
  96. sizeof(struct spi_response) \
  97. )
  98. struct spi_rx_t {
  99. #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  100. uint32_t rsvd_1 :31;
  101. uint32_t response_queue_full :1;
  102. #else
  103. uint32_t response_queue_full :1;
  104. uint32_t rsvd_1 :31;
  105. #endif
  106. #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  107. uint32_t rsvd_2 :16;
  108. uint32_t works_accepted :16;
  109. #else
  110. uint32_t works_accepted :16;
  111. uint32_t rsvd_2 :16;
  112. #endif
  113. uint32_t rsvd_3;
  114. struct spi_response responses[MAX_RESPONSES_IN_BATCH];
  115. };
  116. static struct spi_rx_t spi_rxbuf;
  117. struct active_work {
  118. struct work *work;
  119. uint32_t work_id;
  120. struct timeval begin;
  121. };
  122. struct core_disa_data {
  123. struct timeval disa_begin;
  124. uint8_t asic;
  125. uint8_t core;
  126. };
  127. struct knc_state {
  128. struct spidev_context *ctx;
  129. int devices;
  130. uint32_t salt;
  131. uint32_t next_work_id;
  132. /* read - last read item, next is at (read + 1) mod BUFSIZE
  133. * write - next write item, last written at (write - 1) mod BUFSIZE
  134. * When buffer is empty, read + 1 == write
  135. * Buffer full condition: read == write
  136. */
  137. int read_q, write_q;
  138. #define KNC_QUEUED_BUFFER_SIZE (MAX_REQUESTS_IN_BATCH + 1)
  139. struct active_work queued_fifo[KNC_QUEUED_BUFFER_SIZE];
  140. int read_a, write_a;
  141. #define KNC_ACTIVE_BUFFER_SIZE (MAX_ACTIVE_WORKS + 1)
  142. struct active_work active_fifo[KNC_ACTIVE_BUFFER_SIZE];
  143. uint8_t hwerrs[MAX_ASICS * 256];
  144. uint8_t disa_cnt[MAX_ASICS * 256];
  145. uint32_t hwerr_work_id[MAX_ASICS * 256];
  146. int read_d, write_d;
  147. #define KNC_DISA_CORES_SIZE (MAX_ASICS * 256)
  148. struct core_disa_data disa_cores_fifo[KNC_DISA_CORES_SIZE];
  149. /* Local stats */
  150. #define KNC_MINUTES_IN_STATS_BUFFER 60
  151. unsigned int last_hour_shares[MAX_ASICS][256][KNC_MINUTES_IN_STATS_BUFFER + 1];
  152. unsigned int last_hour_hwerrs[MAX_ASICS][256][KNC_MINUTES_IN_STATS_BUFFER + 1];
  153. unsigned int last_hour_shares_index[MAX_ASICS][256];
  154. unsigned int last_hour_hwerrs_index[MAX_ASICS][256];
  155. pthread_mutex_t lock;
  156. };
  157. static inline bool knc_queued_fifo_full(struct knc_state *knc)
  158. {
  159. return (knc->read_q == knc->write_q);
  160. }
  161. static inline bool knc_active_fifo_full(struct knc_state *knc)
  162. {
  163. return (knc->read_a == knc->write_a);
  164. }
  165. static inline void knc_queued_fifo_inc_idx(int *idx)
  166. {
  167. if (unlikely(*idx >= ((int)KNC_QUEUED_BUFFER_SIZE - 1)))
  168. *idx = 0;
  169. else
  170. ++(*idx);
  171. }
  172. static inline void knc_active_fifo_inc_idx(int *idx)
  173. {
  174. if (unlikely(*idx >= (KNC_ACTIVE_BUFFER_SIZE - 1)))
  175. *idx = 0;
  176. else
  177. ++(*idx);
  178. }
  179. static inline void knc_disa_cores_fifo_inc_idx(int *idx)
  180. {
  181. if (unlikely(*idx >= (KNC_DISA_CORES_SIZE - 1)))
  182. *idx = 0;
  183. else
  184. ++(*idx);
  185. }
  186. /* Find SPI device with index idx, init it */
  187. static struct spidev_context *spi_new(int idx)
  188. {
  189. struct spidev_context *ctx;
  190. char dev_fname[PATH_MAX];
  191. if (NULL == (ctx = malloc(sizeof(struct spidev_context)))) {
  192. applog(LOG_ERR, "KnC spi: Out of memory");
  193. goto l_exit_error;
  194. }
  195. ctx->mode = SPI_MODE;
  196. ctx->bits = SPI_BITS_PER_WORD;
  197. ctx->speed = SPI_MAX_SPEED;
  198. ctx->delay = SPI_DELAY_USECS;
  199. ctx->fd = -1;
  200. sprintf(dev_fname, SPI_DEVICE_TEMPLATE,
  201. idx, /* bus */
  202. 0 /* chipselect */
  203. );
  204. if (0 > (ctx->fd = open(dev_fname, O_RDWR))) {
  205. applog(LOG_ERR, "KnC spi: Can not open SPI device %s: %m",
  206. dev_fname);
  207. goto l_free_exit_error;
  208. }
  209. /*
  210. * spi mode
  211. */
  212. if (0 > ioctl(ctx->fd, SPI_IOC_WR_MODE, &ctx->mode))
  213. goto l_ioctl_error;
  214. if (0 > ioctl(ctx->fd, SPI_IOC_RD_MODE, &ctx->mode))
  215. goto l_ioctl_error;
  216. /*
  217. * bits per word
  218. */
  219. if (0 > ioctl(ctx->fd, SPI_IOC_WR_BITS_PER_WORD, &ctx->bits))
  220. goto l_ioctl_error;
  221. if (0 > ioctl(ctx->fd, SPI_IOC_RD_BITS_PER_WORD, &ctx->bits))
  222. goto l_ioctl_error;
  223. /*
  224. * max speed hz
  225. */
  226. if (0 > ioctl(ctx->fd, SPI_IOC_WR_MAX_SPEED_HZ, &ctx->speed))
  227. goto l_ioctl_error;
  228. if (0 > ioctl(ctx->fd, SPI_IOC_RD_MAX_SPEED_HZ, &ctx->speed))
  229. goto l_ioctl_error;
  230. applog(LOG_INFO, "KnC spi: device %s uses mode %hhu, bits %hhu, speed %u",
  231. dev_fname, ctx->mode, ctx->bits, ctx->speed);
  232. return ctx;
  233. l_ioctl_error:
  234. applog(LOG_ERR, "KnC spi: ioctl error on SPI device %s: %m", dev_fname);
  235. close(ctx->fd);
  236. l_free_exit_error:
  237. free(ctx);
  238. l_exit_error:
  239. return NULL;
  240. }
  241. static void spi_free(struct spidev_context *ctx)
  242. {
  243. if (NULL == ctx)
  244. return;
  245. close(ctx->fd);
  246. free(ctx);
  247. }
  248. static int spi_transfer(struct spidev_context *ctx, uint8_t *txbuf,
  249. uint8_t *rxbuf, int len)
  250. {
  251. struct spi_ioc_transfer xfr;
  252. int ret;
  253. memset(rxbuf, 0xff, len);
  254. ret = len;
  255. xfr.tx_buf = (unsigned long)txbuf;
  256. xfr.rx_buf = (unsigned long)rxbuf;
  257. xfr.len = len;
  258. xfr.speed_hz = ctx->speed;
  259. xfr.delay_usecs = ctx->delay;
  260. xfr.bits_per_word = ctx->bits;
  261. xfr.cs_change = 0;
  262. xfr.pad = 0;
  263. if (1 > (ret = ioctl(ctx->fd, SPI_IOC_MESSAGE(1), &xfr)))
  264. applog(LOG_ERR, "KnC spi xfer: ioctl error on SPI device: %m");
  265. return ret;
  266. }
  267. static void stats_zero_data_if_curindex_updated(unsigned int *data, unsigned int *index, unsigned int cur_index)
  268. {
  269. if (cur_index != *index) {
  270. unsigned int i;
  271. for (i = (*index + 1) % (KNC_MINUTES_IN_STATS_BUFFER + 1);
  272. i != cur_index;
  273. i = ((i + 1 ) % (KNC_MINUTES_IN_STATS_BUFFER + 1)))
  274. data[i] = 0;
  275. data[cur_index] = 0;
  276. *index = cur_index;
  277. }
  278. }
  279. static void stats_update(unsigned int *data, unsigned int *index, unsigned int cur_index)
  280. {
  281. stats_zero_data_if_curindex_updated(data, index, cur_index);
  282. ++(data[cur_index]);
  283. }
  284. static unsigned int get_accumulated_stats(unsigned int *data, unsigned int *index, unsigned int cur_index)
  285. {
  286. unsigned int res, i;
  287. stats_zero_data_if_curindex_updated(data, index, cur_index);
  288. res = 0;
  289. for (i = 0; i < (KNC_MINUTES_IN_STATS_BUFFER + 1); ++i) {
  290. if (i != cur_index)
  291. res += data[i];
  292. }
  293. return res;
  294. }
  295. static inline void stats_good_share(struct knc_state *knc, uint32_t asic, uint32_t core, struct timespec *ts)
  296. {
  297. if ((asic >= MAX_ASICS) || (core >= 256))
  298. return;
  299. unsigned int cur_minute = (ts->tv_sec / SECONDS_IN_MINUTE) % (KNC_MINUTES_IN_STATS_BUFFER + 1);
  300. stats_update(knc->last_hour_shares[asic][core], &(knc->last_hour_shares_index[asic][core]), cur_minute);
  301. }
  302. static inline void stats_bad_share(struct knc_state *knc, uint32_t asic, uint32_t core, struct timespec *ts)
  303. {
  304. if ((asic >= MAX_ASICS) || (core >= 256))
  305. return;
  306. unsigned int cur_minute = (ts->tv_sec / SECONDS_IN_MINUTE) % (KNC_MINUTES_IN_STATS_BUFFER + 1);
  307. stats_update(knc->last_hour_hwerrs[asic][core], &(knc->last_hour_hwerrs_index[asic][core]), cur_minute);
  308. }
  309. static inline unsigned int get_hour_shares(struct knc_state *knc, uint32_t asic, uint32_t core, struct timespec *ts)
  310. {
  311. if ((asic >= MAX_ASICS) || (core >= 256))
  312. return 0;
  313. unsigned int cur_minute = (ts->tv_sec / SECONDS_IN_MINUTE) % (KNC_MINUTES_IN_STATS_BUFFER + 1);
  314. return get_accumulated_stats(knc->last_hour_shares[asic][core], &(knc->last_hour_shares_index[asic][core]), cur_minute);
  315. }
  316. static inline unsigned int get_hour_errors(struct knc_state *knc, uint32_t asic, uint32_t core, struct timespec *ts)
  317. {
  318. if ((asic >= MAX_ASICS) || (core >= 256))
  319. return 0;
  320. unsigned int cur_minute = (ts->tv_sec / SECONDS_IN_MINUTE) % (KNC_MINUTES_IN_STATS_BUFFER + 1);
  321. return get_accumulated_stats(knc->last_hour_hwerrs[asic][core], &(knc->last_hour_hwerrs_index[asic][core]), cur_minute);
  322. }
  323. static struct api_data *knc_api_stats(struct cgpu_info *cgpu)
  324. {
  325. struct knc_state *knc = cgpu->device_data;
  326. struct api_data *root = NULL;
  327. unsigned int cursize;
  328. int asic, core, n;
  329. char buf[4096];
  330. struct timespec ts_now;
  331. clock_gettime(CLOCK_MONOTONIC, &ts_now);
  332. for (asic = 0; asic < MAX_ASICS; ++asic) {
  333. char asic_name[128];
  334. snprintf(asic_name, sizeof(asic_name), "asic_%d_shares", asic + 1);
  335. cursize = 0;
  336. for (core = 0; core < CORES_PER_ASIC; ++core) {
  337. unsigned int shares = get_hour_shares(knc, asic, core, &ts_now);
  338. n = snprintf(buf + cursize, sizeof(buf) - cursize, "%d,", shares);
  339. cursize += n;
  340. if (sizeof(buf) < cursize) {
  341. cursize = sizeof(buf);
  342. break;
  343. }
  344. }
  345. if (0 < cursize)
  346. buf[cursize - 1] = '\0'; /* last comma */
  347. root = api_add_string(root, asic_name, buf, true);
  348. snprintf(asic_name, sizeof(asic_name), "asic_%d_hwerrs", asic + 1);
  349. cursize = 0;
  350. for (core = 0; core < CORES_PER_ASIC; ++core) {
  351. unsigned int errors = get_hour_errors(knc, asic, core, &ts_now);
  352. n = snprintf(buf + cursize, sizeof(buf) - cursize, "%d,", errors);
  353. cursize += n;
  354. if (sizeof(buf) < cursize) {
  355. cursize = sizeof(buf);
  356. break;
  357. }
  358. }
  359. if (0 < cursize)
  360. buf[cursize - 1] = '\0'; /* last comma */
  361. root = api_add_string(root, asic_name, buf, true);
  362. }
  363. return root;
  364. }
  365. static void disable_core(uint8_t asic, uint8_t core)
  366. {
  367. char str[256];
  368. snprintf(str, sizeof(str), "i2cset -y 2 0x2%hhu %hhu 0", asic, core);
  369. if (0 != WEXITSTATUS(system(str)))
  370. applog(LOG_ERR, "KnC: system call failed");
  371. }
  372. static void enable_core(uint8_t asic, uint8_t core)
  373. {
  374. char str[256];
  375. snprintf(str, sizeof(str), "i2cset -y 2 0x2%hhu %hhu 1", asic, core);
  376. if (0 != WEXITSTATUS(system(str)))
  377. applog(LOG_ERR, "KnC: system call failed");
  378. }
  379. static int64_t timediff(const struct timeval *a, const struct timeval *b)
  380. {
  381. struct timeval diff;
  382. timersub(a, b, &diff);
  383. return diff.tv_sec * 1000000 + diff.tv_usec;
  384. }
  385. static void knc_check_disabled_cores(struct knc_state *knc)
  386. {
  387. struct core_disa_data *core;
  388. int next_read_d, cidx;
  389. struct timeval now;
  390. int64_t us;
  391. next_read_d = knc->read_d;
  392. knc_disa_cores_fifo_inc_idx(&next_read_d);
  393. if (next_read_d == knc->write_d)
  394. return; /* queue empty */
  395. core = &knc->disa_cores_fifo[next_read_d];
  396. gettimeofday(&now, NULL);
  397. us = timediff(&now, &core->disa_begin);
  398. if ((us >= 0) && (us < CORE_DISA_PERIOD_US))
  399. return; /* latest disabled core still not expired */
  400. cidx = core->asic * 256 + core->core;
  401. enable_core(core->asic, core->core);
  402. knc->hwerrs[cidx] = 0;
  403. applog(LOG_NOTICE,
  404. "KnC: core %u-%u was enabled back from disabled state",
  405. core->asic, core->core);
  406. knc->read_d = next_read_d;
  407. }
  408. static void knc_work_from_queue_to_spi(struct knc_state *knc,
  409. struct active_work *q_work,
  410. struct spi_request *spi_req, uint32_t work_id)
  411. {
  412. uint32_t *buf_from, *buf_to;
  413. int i;
  414. spi_req->cmd = CMD_SUBMIT_WORK;
  415. spi_req->queue_id = 0; /* at the moment we have one and only queue #0 */
  416. spi_req->work_id = (work_id ^ knc->salt) & WORK_ID_MASK;
  417. q_work->work_id = spi_req->work_id;
  418. buf_to = spi_req->midstate;
  419. buf_from = (uint32_t *)q_work->work->midstate;
  420. for (i = 0; i < WORK_MIDSTATE_WORDS; ++i)
  421. buf_to[i] = le32toh(buf_from[8 - i - 1]);
  422. buf_to = spi_req->data;
  423. buf_from = (uint32_t *)&(q_work->work->data[16 * 4]);
  424. for (i = 0; i < WORK_DATA_WORDS; ++i)
  425. buf_to[i] = le32toh(buf_from[3 - i - 1]);
  426. }
  427. static int64_t knc_process_response(struct thr_info *thr, struct cgpu_info *cgpu,
  428. struct spi_rx_t *rxbuf)
  429. {
  430. struct knc_state *knc = cgpu->device_data;
  431. int submitted, successful, i, num_sent;
  432. int next_read_q, next_read_a;
  433. struct timeval now;
  434. struct timespec ts_now;
  435. struct work *work;
  436. int64_t us;
  437. num_sent = knc->write_q - knc->read_q - 1;
  438. if (knc->write_q <= knc->read_q)
  439. num_sent += KNC_QUEUED_BUFFER_SIZE;
  440. knc->next_work_id += rxbuf->works_accepted;
  441. /* Actually process SPI response */
  442. if (rxbuf->works_accepted) {
  443. applog(LOG_DEBUG, "KnC spi: raw response %08X %08X",
  444. ((uint32_t *)rxbuf)[0], ((uint32_t *)rxbuf)[1]);
  445. applog(LOG_DEBUG,
  446. "KnC spi: response, accepted %u (from %u), full %u",
  447. rxbuf->works_accepted, num_sent,
  448. rxbuf->response_queue_full);
  449. }
  450. /* move works_accepted number of items from queued_fifo to active_fifo */
  451. gettimeofday(&now, NULL);
  452. clock_gettime(CLOCK_MONOTONIC, &ts_now);
  453. submitted = 0;
  454. for (i = 0; i < rxbuf->works_accepted; ++i) {
  455. next_read_q = knc->read_q;
  456. knc_queued_fifo_inc_idx(&next_read_q);
  457. if ((next_read_q == knc->write_q) || knc_active_fifo_full(knc))
  458. break;
  459. memcpy(&knc->active_fifo[knc->write_a],
  460. &knc->queued_fifo[next_read_q],
  461. sizeof(struct active_work));
  462. knc->active_fifo[knc->write_a].begin = now;
  463. knc->queued_fifo[next_read_q].work = NULL;
  464. knc->read_q = next_read_q;
  465. knc_active_fifo_inc_idx(&knc->write_a);
  466. ++submitted;
  467. }
  468. if (submitted != rxbuf->works_accepted) {
  469. applog(LOG_ERR,
  470. "KnC: accepted by FPGA %u works, but only %d submitted",
  471. rxbuf->works_accepted, submitted);
  472. }
  473. /* check for completed works and calculated nonces */
  474. gettimeofday(&now, NULL);
  475. successful = 0;
  476. for (i = 0; i < (int)MAX_RESPONSES_IN_BATCH; ++i) {
  477. if ((rxbuf->responses[i].type != RESPONSE_TYPE_NONCE_FOUND) &&
  478. (rxbuf->responses[i].type != RESPONSE_TYPE_WORK_DONE))
  479. continue;
  480. applog(LOG_DEBUG, "KnC spi: raw response %08X %08X",
  481. ((uint32_t *)&rxbuf->responses[i])[0],
  482. ((uint32_t *)&rxbuf->responses[i])[1]);
  483. applog(LOG_DEBUG, "KnC spi: response, T:%u C:%u-%u Q:%u W:%u",
  484. rxbuf->responses[i].type,
  485. rxbuf->responses[i].asic, rxbuf->responses[i].core,
  486. rxbuf->responses[i].queue_id,
  487. rxbuf->responses[i].work_id);
  488. /* Find active work with matching ID */
  489. next_read_a = knc->read_a;
  490. knc_active_fifo_inc_idx(&next_read_a);
  491. while (next_read_a != knc->write_a) {
  492. if (knc->active_fifo[next_read_a].work_id ==
  493. rxbuf->responses[i].work_id)
  494. break;
  495. /* check for stale works */
  496. us = timediff(&now,
  497. &knc->active_fifo[next_read_a].begin);
  498. if ((us < 0) || (us >= WORK_STALE_US)) {
  499. applog(LOG_DEBUG,
  500. "KnC spi: remove stale work %u",
  501. knc->active_fifo[next_read_a].work_id);
  502. work = knc->active_fifo[next_read_a].work;
  503. knc_active_fifo_inc_idx(&knc->read_a);
  504. work_completed(cgpu, work);
  505. if (next_read_a != knc->read_a) {
  506. memcpy(&(knc->active_fifo[next_read_a]),
  507. &(knc->active_fifo[knc->read_a]),
  508. sizeof(struct active_work));
  509. }
  510. knc->active_fifo[knc->read_a].work = NULL;
  511. }
  512. knc_active_fifo_inc_idx(&next_read_a);
  513. }
  514. if (next_read_a == knc->write_a)
  515. continue;
  516. applog(LOG_DEBUG, "KnC spi: response work %u found",
  517. rxbuf->responses[i].work_id);
  518. work = knc->active_fifo[next_read_a].work;
  519. if (rxbuf->responses[i].type == RESPONSE_TYPE_NONCE_FOUND) {
  520. if (NULL != thr) {
  521. int cidx = rxbuf->responses[i].asic * 256 +
  522. rxbuf->responses[i].core;
  523. if (submit_nonce(thr, work,
  524. rxbuf->responses[i].nonce)) {
  525. stats_good_share(knc, rxbuf->responses[i].asic, rxbuf->responses[i].core, &ts_now);
  526. if (cidx < (int)sizeof(knc->hwerrs)) {
  527. knc->hwerrs[cidx] = 0;
  528. knc->disa_cnt[cidx] = 0;
  529. knc->hwerr_work_id[cidx] = 0xFFFFFFFF;
  530. }
  531. successful++;
  532. } else {
  533. stats_bad_share(knc, rxbuf->responses[i].asic, rxbuf->responses[i].core, &ts_now);
  534. bool process_hwerr = (cidx < (int)sizeof(knc->hwerrs));
  535. if (process_hwerr && opt_knc_DP_checkworkid &&
  536. (knc->hwerr_work_id[cidx] == rxbuf->responses[i].work_id))
  537. process_hwerr = false;
  538. if (process_hwerr) {
  539. knc->hwerr_work_id[cidx] = rxbuf->responses[i].work_id;
  540. if (++(knc->hwerrs[cidx]) >= HW_ERR_LIMIT) {
  541. struct core_disa_data *core;
  542. core = &knc->disa_cores_fifo[knc->write_d];
  543. core->disa_begin = now;
  544. core->asic = rxbuf->responses[i].asic;
  545. core->core = rxbuf->responses[i].core;
  546. disable_core(core->asic, core->core);
  547. if (opt_knc_DP_disable_permanently &&
  548. (++(knc->disa_cnt[cidx]) >= DISA_ERR_LIMIT)) {
  549. applog(LOG_WARNING,
  550. "KnC: core %u-%u was disabled permanently", core->asic, core->core);
  551. } else {
  552. applog(LOG_WARNING,
  553. "KnC: core %u-%u was disabled due to %u HW errors in a row",
  554. core->asic, core->core, HW_ERR_LIMIT);
  555. knc_disa_cores_fifo_inc_idx(&knc->write_d);
  556. }
  557. }
  558. }
  559. };
  560. }
  561. continue;
  562. }
  563. /* Work completed */
  564. knc_active_fifo_inc_idx(&knc->read_a);
  565. work_completed(cgpu, work);
  566. if (next_read_a != knc->read_a) {
  567. memcpy(&(knc->active_fifo[next_read_a]),
  568. &(knc->active_fifo[knc->read_a]),
  569. sizeof(struct active_work));
  570. }
  571. knc->active_fifo[knc->read_a].work = NULL;
  572. }
  573. return ((uint64_t)successful) * 0x100000000UL;
  574. }
  575. /* Send flush command via SPI */
  576. static int _internal_knc_flush_fpga(struct knc_state *knc)
  577. {
  578. int len;
  579. spi_txbuf[0].cmd = CMD_FLUSH_QUEUE;
  580. spi_txbuf[0].queue_id = 0; /* at the moment we have one and only queue #0 */
  581. len = spi_transfer(knc->ctx, (uint8_t *)spi_txbuf,
  582. (uint8_t *)&spi_rxbuf, sizeof(struct spi_request));
  583. if (len != sizeof(struct spi_request))
  584. return -1;
  585. len /= sizeof(struct spi_response);
  586. return len;
  587. }
  588. static bool knc_detect_one(struct spidev_context *ctx)
  589. {
  590. /* Scan device for ASICs */
  591. int chip_id, devices = 0;
  592. struct cgpu_info *cgpu;
  593. struct knc_state *knc;
  594. for (chip_id = 0; chip_id < MAX_ASICS; ++chip_id) {
  595. /* TODO: perform the ASIC test/detection */
  596. ++devices;
  597. }
  598. if (!devices) {
  599. applog(LOG_INFO, "SPI detected, but not KnCminer ASICs");
  600. return false;
  601. }
  602. applog(LOG_INFO, "Found a KnC miner with %d ASICs", devices);
  603. cgpu = calloc(1, sizeof(*cgpu));
  604. knc = calloc(1, sizeof(*knc));
  605. if (!cgpu || !knc) {
  606. applog(LOG_ERR, "KnC miner detected, but failed to allocate memory");
  607. return false;
  608. }
  609. knc->ctx = ctx;
  610. knc->devices = devices;
  611. knc->read_q = 0;
  612. knc->write_q = 1;
  613. knc->read_a = 0;
  614. knc->write_a = 1;
  615. knc->read_d = 0;
  616. knc->write_d = 1;
  617. knc->salt = rand();
  618. mutex_init(&knc->lock);
  619. memset(knc->hwerr_work_id, 0xFF, sizeof(knc->hwerr_work_id));
  620. _internal_knc_flush_fpga(knc);
  621. cgpu->drv = &knc_drv;
  622. cgpu->name = "KnCminer";
  623. cgpu->threads = 1; // .. perhaps our number of devices?
  624. cgpu->device_data = knc;
  625. add_cgpu(cgpu);
  626. return true;
  627. }
  628. // http://www.concentric.net/~Ttwang/tech/inthash.htm
  629. static unsigned long mix(unsigned long a, unsigned long b, unsigned long c)
  630. {
  631. a = a - b; a = a - c; a = a ^ (c >> 13);
  632. b = b - c; b = b - a; b = b ^ (a << 8);
  633. c = c - a; c = c - b; c = c ^ (b >> 13);
  634. a = a - b; a = a - c; a = a ^ (c >> 12);
  635. b = b - c; b = b - a; b = b ^ (a << 16);
  636. c = c - a; c = c - b; c = c ^ (b >> 5);
  637. a = a - b; a = a - c; a = a ^ (c >> 3);
  638. b = b - c; b = b - a; b = b ^ (a << 10);
  639. c = c - a; c = c - b; c = c ^ (b >> 15);
  640. return c;
  641. }
  642. /* Probe devices and register with add_cgpu */
  643. void knc_detect(bool __maybe_unused hotplug)
  644. {
  645. int idx;
  646. srand(mix(clock(), time(NULL), getpid()));
  647. /* Loop through all possible SPI interfaces */
  648. for (idx = 0; idx < MAX_SPIS; ++idx) {
  649. struct spidev_context *ctx = spi_new(idx + 1);
  650. if (ctx != NULL) {
  651. if (!knc_detect_one(ctx))
  652. spi_free(ctx);
  653. }
  654. }
  655. }
  656. /* return value is number of nonces that have been checked since
  657. * previous call
  658. */
  659. static int64_t knc_scanwork(struct thr_info *thr)
  660. {
  661. struct cgpu_info *cgpu = thr->cgpu;
  662. struct knc_state *knc = cgpu->device_data;
  663. int len, num, next_read_q;
  664. int64_t ret;
  665. applog(LOG_DEBUG, "KnC running scanwork");
  666. knc_check_disabled_cores(knc);
  667. num = 0;
  668. mutex_lock(&knc->lock);
  669. /* Prepare tx buffer */
  670. memset(spi_txbuf, 0, sizeof(spi_txbuf));
  671. next_read_q = knc->read_q;
  672. knc_queued_fifo_inc_idx(&next_read_q);
  673. while (next_read_q != knc->write_q) {
  674. knc_work_from_queue_to_spi(knc, &knc->queued_fifo[next_read_q],
  675. &spi_txbuf[num], knc->next_work_id + num);
  676. knc_queued_fifo_inc_idx(&next_read_q);
  677. ++num;
  678. }
  679. /* knc->read_q is advanced in knc_process_response, not here.
  680. * knc->next_work_id is advanced in knc_process_response as well,
  681. * because only after SPI response we know how many works were actually
  682. * consumed by FPGA.
  683. */
  684. len = spi_transfer(knc->ctx, (uint8_t *)spi_txbuf,
  685. (uint8_t *)&spi_rxbuf, sizeof(spi_txbuf));
  686. if (len != sizeof(spi_rxbuf)) {
  687. ret = -1;
  688. goto out_unlock;
  689. }
  690. applog(LOG_DEBUG, "KnC spi: %d works in request", num);
  691. ret = knc_process_response(thr, cgpu, &spi_rxbuf);
  692. out_unlock:
  693. mutex_unlock(&knc->lock);
  694. return ret;
  695. }
  696. static bool knc_queue_full(struct cgpu_info *cgpu)
  697. {
  698. struct knc_state *knc = cgpu->device_data;
  699. int queue_full = false;
  700. struct work *work;
  701. applog(LOG_DEBUG, "KnC running queue full");
  702. mutex_lock(&knc->lock);
  703. if (knc_queued_fifo_full(knc)) {
  704. queue_full = true;
  705. goto out_unlock;
  706. }
  707. work = get_queued(cgpu);
  708. if (!work)
  709. goto out_unlock;
  710. knc->queued_fifo[knc->write_q].work = work;
  711. knc_queued_fifo_inc_idx(&(knc->write_q));
  712. if (knc_queued_fifo_full(knc))
  713. queue_full = true;
  714. out_unlock:
  715. mutex_unlock(&knc->lock);
  716. return queue_full;
  717. }
  718. static void knc_flush_work(struct cgpu_info *cgpu)
  719. {
  720. struct knc_state *knc = cgpu->device_data;
  721. int len, next_read_q, next_read_a;
  722. struct work *work;
  723. applog(LOG_ERR, "KnC running flushwork");
  724. mutex_lock(&knc->lock);
  725. /* Drain queued works */
  726. next_read_q = knc->read_q;
  727. knc_queued_fifo_inc_idx(&next_read_q);
  728. while (next_read_q != knc->write_q) {
  729. work = knc->queued_fifo[next_read_q].work;
  730. work_completed(cgpu, work);
  731. knc->queued_fifo[next_read_q].work = NULL;
  732. knc->read_q = next_read_q;
  733. knc_queued_fifo_inc_idx(&next_read_q);
  734. }
  735. /* Drain active works */
  736. next_read_a = knc->read_a;
  737. knc_active_fifo_inc_idx(&next_read_a);
  738. while (next_read_a != knc->write_a) {
  739. work = knc->active_fifo[next_read_a].work;
  740. work_completed(cgpu, work);
  741. knc->active_fifo[next_read_a].work = NULL;
  742. knc->read_a = next_read_a;
  743. knc_active_fifo_inc_idx(&next_read_a);
  744. }
  745. len = _internal_knc_flush_fpga(knc);
  746. if (len > 0)
  747. knc_process_response(NULL, cgpu, &spi_rxbuf);
  748. mutex_unlock(&knc->lock);
  749. }
  750. struct device_drv knc_drv = {
  751. .drv_id = DRIVER_knc,
  752. .dname = "KnCminer",
  753. .name = "KnC",
  754. .drv_detect = knc_detect, // Probe for devices, add with add_cgpu
  755. .hash_work = hash_queued_work,
  756. .scanwork = knc_scanwork,
  757. .queue_full = knc_queue_full,
  758. .flush_work = knc_flush_work,
  759. .get_api_stats = knc_api_stats,
  760. };