driver-knc.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. /*
  2. * Copyright 2013 Luke Dashjr
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the Free
  6. * Software Foundation; either version 3 of the License, or (at your option)
  7. * any later version. See COPYING for more details.
  8. */
  9. #include "config.h"
  10. #include <stdbool.h>
  11. #include <stddef.h>
  12. #include <stdint.h>
  13. #include <sys/ioctl.h>
  14. #include <sys/types.h>
  15. #include <sys/stat.h>
  16. #include <fcntl.h>
  17. #ifdef HAVE_LINUX_I2C_DEV_USER_H
  18. #include <linux/i2c-dev-user.h>
  19. #else
  20. #include <linux/i2c-dev.h>
  21. #endif
  22. #include <linux/spi/spidev.h>
  23. #include <uthash.h>
  24. #include "deviceapi.h"
  25. #include "logging.h"
  26. #include "miner.h"
  27. #include "spidevc.h"
  28. #define KNC_POLL_INTERVAL_US 10000
  29. #define KNC_SPI_SPEED 3000000
  30. #define KNC_SPI_DELAY 0
  31. #define KNC_SPI_MODE (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH)
  32. #define KNC_SPI_BITS 8
  33. static const char * const i2cpath = "/dev/i2c-2";
  34. enum knc_request_cmd {
  35. KNC_REQ_SUBMIT_WORK = 2,
  36. KNC_REQ_FLUSH_QUEUE = 3,
  37. };
  38. enum knc_reply_type {
  39. KNC_REPLY_NONCE_FOUND = 1,
  40. KNC_REPLY_WORK_DONE = 2,
  41. };
  42. struct device_drv knc_drv;
  43. struct knc_device {
  44. int i2c;
  45. struct spi_port *spi;
  46. bool need_flush;
  47. struct work *workqueue;
  48. int workqueue_size;
  49. int workqueue_max;
  50. int next_id;
  51. struct work *devicework;
  52. };
  53. struct knc_core {
  54. int asicno;
  55. };
  56. static
  57. bool knc_detect_one(const char *devpath)
  58. {
  59. static struct cgpu_info *prev_cgpu = NULL;
  60. struct cgpu_info *cgpu;
  61. int i;
  62. const int fd = open(i2cpath, O_RDWR);
  63. char *leftover = NULL;
  64. const int i2cslave = strtol(devpath, &leftover, 0);
  65. uint8_t buf[0x20];
  66. if (leftover && leftover[0])
  67. return false;
  68. if (unlikely(fd == -1))
  69. {
  70. applog(LOG_DEBUG, "%s: Failed to open %s", __func__, i2cpath);
  71. return false;
  72. }
  73. if (ioctl(fd, I2C_SLAVE, i2cslave))
  74. {
  75. close(fd);
  76. applog(LOG_DEBUG, "%s: Failed to select i2c slave 0x%x",
  77. __func__, i2cslave);
  78. return false;
  79. }
  80. i = i2c_smbus_read_i2c_block_data(fd, 0, 0x20, buf);
  81. close(fd);
  82. if (-1 == i)
  83. {
  84. applog(LOG_DEBUG, "%s: 0x%x: Failed to read i2c block data",
  85. __func__, i2cslave);
  86. return false;
  87. }
  88. for (i = 0; ; ++i)
  89. {
  90. if (buf[i] == 3)
  91. break;
  92. if (i == 0x1f)
  93. return false;
  94. }
  95. cgpu = malloc(sizeof(*cgpu));
  96. *cgpu = (struct cgpu_info){
  97. .drv = &knc_drv,
  98. .device_path = strdup(devpath),
  99. .deven = DEV_ENABLED,
  100. .procs = 192,
  101. .threads = prev_cgpu ? 0 : 1,
  102. };
  103. const bool rv = add_cgpu_slave(cgpu, prev_cgpu);
  104. prev_cgpu = cgpu;
  105. return rv;
  106. }
  107. static int knc_detect_auto(void)
  108. {
  109. const int first = 0x20, last = 0x26;
  110. char devpath[4];
  111. int found = 0, i;
  112. for (i = first; i <= last; ++i)
  113. {
  114. sprintf(devpath, "%d", i);
  115. if (knc_detect_one(devpath))
  116. ++found;
  117. }
  118. return found;
  119. }
  120. static void knc_detect(void)
  121. {
  122. generic_detect(&knc_drv, knc_detect_one, knc_detect_auto, GDF_REQUIRE_DNAME | GDF_DEFAULT_NOAUTO);
  123. }
  124. static
  125. bool knc_spi_open(const char *repr, struct spi_port * const spi)
  126. {
  127. const char * const spipath = "/dev/spidev1.0";
  128. const int fd = open(spipath, O_RDWR);
  129. const uint8_t lsbfirst = 0;
  130. if (fd == -1)
  131. return false;
  132. if (ioctl(fd, SPI_IOC_WR_MODE , &spi->mode )) goto fail;
  133. if (ioctl(fd, SPI_IOC_WR_LSB_FIRST , &lsbfirst )) goto fail;
  134. if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &spi->bits )) goto fail;
  135. if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ , &spi->speed)) goto fail;
  136. spi->fd = fd;
  137. return true;
  138. fail:
  139. close(fd);
  140. spi->fd = -1;
  141. applog(LOG_WARNING, "%s: Failed to open %s", repr, spipath);
  142. return false;
  143. }
  144. static
  145. bool knc_spi_txrx(struct spi_port * const spi)
  146. {
  147. const void * const wrbuf = spi_gettxbuf(spi);
  148. void * const rdbuf = spi_getrxbuf(spi);
  149. const size_t bufsz = spi_getbufsz(spi);
  150. const int fd = spi->fd;
  151. struct spi_ioc_transfer xf = {
  152. .tx_buf = (uintptr_t) wrbuf,
  153. .rx_buf = (uintptr_t) rdbuf,
  154. .len = bufsz,
  155. .delay_usecs = spi->delay,
  156. .speed_hz = spi->speed,
  157. .bits_per_word = spi->bits,
  158. };
  159. return (ioctl(fd, SPI_IOC_MESSAGE(1), &xf) > 0);
  160. }
  161. static
  162. void knc_clean_flush(struct spi_port * const spi)
  163. {
  164. const uint8_t flushcmd = KNC_REQ_FLUSH_QUEUE << 4;
  165. const size_t spi_req_sz = 0x1000;
  166. spi_clear_buf(spi);
  167. spi_emit_buf(spi, &flushcmd, 1);
  168. spi_emit_nop(spi, spi_req_sz - spi_getbufsz(spi));
  169. applog(LOG_DEBUG, "%s: Issuing flush command to clear out device queues", knc_drv.dname);
  170. spi_txrx(spi);
  171. }
  172. static
  173. bool knc_init(struct thr_info * const thr)
  174. {
  175. const int max_cores = 192;
  176. struct thr_info *mythr;
  177. struct cgpu_info * const cgpu = thr->cgpu, *proc;
  178. struct knc_device *knc;
  179. struct knc_core *knccore;
  180. struct spi_port *spi;
  181. const int i2c = open(i2cpath, O_RDWR);
  182. int i2cslave, i, j;
  183. uint8_t buf[0x20];
  184. if (unlikely(i2c == -1))
  185. {
  186. applog(LOG_DEBUG, "%s: Failed to open %s", __func__, i2cpath);
  187. return false;
  188. }
  189. for (proc = cgpu; proc; )
  190. {
  191. if (proc->device != proc)
  192. {
  193. applog(LOG_WARNING, "%"PRIpreprv": Extra processor?", proc->proc_repr);
  194. continue;
  195. }
  196. i2cslave = atoi(proc->device_path);
  197. if (ioctl(i2c, I2C_SLAVE, i2cslave))
  198. {
  199. applog(LOG_DEBUG, "%s: Failed to select i2c slave 0x%x",
  200. __func__, i2cslave);
  201. return false;
  202. }
  203. for (i = 0; i < max_cores; i += 0x20)
  204. {
  205. i2c_smbus_read_i2c_block_data(i2c, i, 0x20, buf);
  206. for (j = 0; j < 0x20; ++j)
  207. {
  208. mythr = proc->thr[0];
  209. mythr->cgpu_data = knccore = malloc(sizeof(*knccore));
  210. *knccore = (struct knc_core){
  211. .asicno = i2cslave - 0x20,
  212. };
  213. if (proc != cgpu)
  214. {
  215. mythr->queue_full = true;
  216. proc->device_data = NULL;
  217. }
  218. if (buf[j] != 3)
  219. proc->deven = DEV_DISABLED;
  220. proc = proc->next_proc;
  221. if ((!proc) || proc->device == proc)
  222. goto nomorecores;
  223. }
  224. }
  225. nomorecores: ;
  226. }
  227. cgpu->device_data = knc = malloc(sizeof(*knc));
  228. spi = malloc(sizeof(*spi));
  229. *knc = (struct knc_device){
  230. .i2c = i2c,
  231. .spi = spi,
  232. .workqueue_max = 1,
  233. };
  234. *spi = (struct spi_port){
  235. .txrx = knc_spi_txrx,
  236. .cgpu = cgpu,
  237. .repr = knc_drv.dname,
  238. .logprio = LOG_ERR,
  239. .speed = KNC_SPI_SPEED,
  240. .delay = KNC_SPI_DELAY,
  241. .mode = KNC_SPI_MODE,
  242. .bits = KNC_SPI_BITS,
  243. };
  244. if (!knc_spi_open(cgpu->dev_repr, spi))
  245. return false;
  246. knc_clean_flush(spi);
  247. timer_set_now(&thr->tv_poll);
  248. return true;
  249. }
  250. static
  251. void knc_remove_local_queue(struct knc_device * const knc, struct work * const work)
  252. {
  253. DL_DELETE(knc->workqueue, work);
  254. free_work(work);
  255. --knc->workqueue_size;
  256. }
  257. static
  258. void knc_prune_local_queue(struct thr_info *thr)
  259. {
  260. struct cgpu_info * const cgpu = thr->cgpu;
  261. struct knc_device * const knc = cgpu->device_data;
  262. struct work *work, *tmp;
  263. DL_FOREACH_SAFE(knc->workqueue, work, tmp)
  264. {
  265. if (stale_work(work, false))
  266. knc_remove_local_queue(knc, work);
  267. }
  268. thr->queue_full = (knc->workqueue_size >= knc->workqueue_max);
  269. }
  270. static
  271. bool knc_queue_append(struct thr_info * const thr, struct work * const work)
  272. {
  273. struct cgpu_info * const cgpu = thr->cgpu;
  274. struct knc_device * const knc = cgpu->device_data;
  275. if (knc->workqueue_size >= knc->workqueue_max)
  276. {
  277. knc_prune_local_queue(thr);
  278. if (thr->queue_full)
  279. return false;
  280. }
  281. DL_APPEND(knc->workqueue, work);
  282. ++knc->workqueue_size;
  283. thr->queue_full = (knc->workqueue_size >= knc->workqueue_max);
  284. if (thr->queue_full)
  285. knc_prune_local_queue(thr);
  286. return true;
  287. }
  288. #define HASH_LAST_ADDED(head, out) \
  289. (out = (ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail)))
  290. static
  291. void knc_queue_flush(struct thr_info * const thr)
  292. {
  293. struct cgpu_info * const cgpu = thr->cgpu;
  294. struct knc_device * const knc = cgpu->device_data;
  295. struct work *work, *tmp;
  296. if (!knc)
  297. return;
  298. DL_FOREACH_SAFE(knc->workqueue, work, tmp)
  299. {
  300. knc_remove_local_queue(knc, work);
  301. }
  302. thr->queue_full = false;
  303. HASH_LAST_ADDED(knc->devicework, work);
  304. if (stale_work(work, true))
  305. {
  306. knc->need_flush = true;
  307. timer_set_now(&thr->tv_poll);
  308. }
  309. }
  310. static inline
  311. uint16_t get_u16be(const void * const p)
  312. {
  313. const uint8_t * const b = p;
  314. return (((uint16_t)b[0]) << 8) | b[1];
  315. }
  316. static inline
  317. uint32_t get_u32be(const void * const p)
  318. {
  319. const uint8_t * const b = p;
  320. return (((uint32_t)b[0]) << 0x18)
  321. | (((uint32_t)b[1]) << 0x10)
  322. | (((uint32_t)b[2]) << 8)
  323. | b[3];
  324. }
  325. static
  326. void knc_poll(struct thr_info * const thr)
  327. {
  328. struct thr_info *mythr;
  329. struct cgpu_info * const cgpu = thr->cgpu, *proc;
  330. struct knc_device * const knc = cgpu->device_data;
  331. struct spi_port * const spi = knc->spi;
  332. struct knc_core *knccore;
  333. struct work *work, *tmp;
  334. uint8_t buf[0x30], *rxbuf;
  335. int works_sent = 0, asicno, i;
  336. uint16_t workaccept;
  337. int workid = knc->next_id;
  338. uint32_t nonce, coreno;
  339. size_t spi_req_sz = 0x1000;
  340. unsigned long delay_usecs = KNC_POLL_INTERVAL_US;
  341. knc_prune_local_queue(thr);
  342. spi_clear_buf(spi);
  343. if (knc->need_flush)
  344. {
  345. applog(LOG_NOTICE, "%s: Abandoning stale searches to restart", knc_drv.dname);
  346. buf[0] = KNC_REQ_FLUSH_QUEUE << 4;
  347. spi_emit_buf(spi, buf, sizeof(buf));
  348. }
  349. DL_FOREACH(knc->workqueue, work)
  350. {
  351. buf[0] = KNC_REQ_SUBMIT_WORK << 4;
  352. buf[1] = 0;
  353. buf[2] = (workid >> 8) & 0x7f;
  354. buf[3] = workid & 0xff;
  355. for (i = 0; i < 0x20; ++i)
  356. buf[4 + i] = work->midstate[0x1f - i];
  357. for (i = 0; i < 0xc; ++i)
  358. buf[0x24 + i] = work->data[0x4b - i];
  359. spi_emit_buf(spi, buf, sizeof(buf));
  360. ++works_sent;
  361. ++workid;
  362. }
  363. spi_emit_nop(spi, spi_req_sz - spi_getbufsz(spi));
  364. spi_txrx(spi);
  365. rxbuf = spi_getrxbuf(spi);
  366. if (rxbuf[3] & 1)
  367. applog(LOG_DEBUG, "%s: Receive buffer overflow reported", knc_drv.dname);
  368. workaccept = get_u16be(&rxbuf[6]);
  369. applog(LOG_DEBUG, "%s: %lu/%d jobs accepted to queue (max=%d)",
  370. knc_drv.dname, (unsigned long)workaccept, works_sent, knc->workqueue_max);
  371. while (true)
  372. {
  373. rxbuf += 0xc;
  374. spi_req_sz -= 0xc;
  375. if (spi_req_sz < 0xc)
  376. break;
  377. const int rtype = rxbuf[0] >> 6;
  378. if (rtype && opt_debug)
  379. {
  380. char x[(0xc * 2) + 1];
  381. bin2hex(x, rxbuf, 0xc);
  382. applog(LOG_DEBUG, "%s: RECV: %s", knc_drv.dname, x);
  383. }
  384. if (rtype != KNC_REPLY_NONCE_FOUND && rtype != KNC_REPLY_WORK_DONE)
  385. continue;
  386. asicno = (rxbuf[0] & 0x38) >> 3;
  387. coreno = get_u32be(&rxbuf[8]);
  388. proc = cgpu;
  389. while (true)
  390. {
  391. knccore = proc->thr[0]->cgpu_data;
  392. if (knccore->asicno == asicno)
  393. break;
  394. do {
  395. proc = proc->next_proc;
  396. } while(proc != proc->device);
  397. }
  398. for (i = 0; i < coreno; ++i)
  399. proc = proc->next_proc;
  400. mythr = proc->thr[0];
  401. i = get_u16be(&rxbuf[2]);
  402. HASH_FIND_INT(knc->devicework, &i, work);
  403. if (!work)
  404. {
  405. const char * const msgtype = (rtype == KNC_REPLY_NONCE_FOUND) ? "nonce found" : "work done";
  406. applog(LOG_WARNING, "%"PRIpreprv": Got %s message about unknown work 0x%04x",
  407. proc->proc_repr, msgtype, i);
  408. if (KNC_REPLY_NONCE_FOUND == rtype)
  409. {
  410. nonce = get_u32be(&rxbuf[4]);
  411. nonce = le32toh(nonce);
  412. inc_hw_errors2(mythr, NULL, &nonce);
  413. }
  414. else
  415. inc_hw_errors2(mythr, NULL, NULL);
  416. continue;
  417. }
  418. switch (rtype)
  419. {
  420. case KNC_REPLY_NONCE_FOUND:
  421. nonce = get_u32be(&rxbuf[4]);
  422. nonce = le32toh(nonce);
  423. submit_nonce(mythr, work, nonce);
  424. break;
  425. case KNC_REPLY_WORK_DONE:
  426. HASH_DEL(knc->devicework, work);
  427. free_work(work);
  428. hashes_done2(mythr, 0x100000000, NULL);
  429. break;
  430. }
  431. }
  432. if (knc->need_flush)
  433. {
  434. knc->need_flush = false;
  435. HASH_ITER(hh, knc->devicework, work, tmp)
  436. {
  437. HASH_DEL(knc->devicework, work);
  438. free_work(work);
  439. }
  440. delay_usecs = 0;
  441. }
  442. if (workaccept)
  443. {
  444. if (workaccept >= knc->workqueue_max)
  445. {
  446. knc->workqueue_max = workaccept;
  447. delay_usecs = 0;
  448. }
  449. DL_FOREACH_SAFE(knc->workqueue, work, tmp)
  450. {
  451. --knc->workqueue_size;
  452. DL_DELETE(knc->workqueue, work);
  453. work->device_id = knc->next_id++ & 0x7fff;
  454. HASH_ADD_INT(knc->devicework, device_id, work);
  455. if (!--workaccept)
  456. break;
  457. }
  458. thr->queue_full = (knc->workqueue_size >= knc->workqueue_max);
  459. }
  460. timer_set_delay_from_now(&thr->tv_poll, delay_usecs);
  461. }
  462. struct device_drv knc_drv = {
  463. .dname = "knc",
  464. .name = "KNC",
  465. .drv_detect = knc_detect,
  466. .thread_init = knc_init,
  467. .minerloop = minerloop_queue,
  468. .queue_append = knc_queue_append,
  469. .queue_flush = knc_queue_flush,
  470. .poll = knc_poll,
  471. };