driver-cointerra.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377
  1. /*
  2. * Copyright 2013-2014 Con Kolivas <kernel@kolivas.org>
  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 "miner.h"
  11. #include "driver-cointerra.h"
  12. static const char *cointerra_hdr = "ZZ";
  13. int opt_ps_load;
  14. static void cta_gen_message(char *msg, char type)
  15. {
  16. memset(msg, 0, CTA_MSG_SIZE);
  17. memcpy(msg, cointerra_hdr, 2);
  18. msg[CTA_MSG_TYPE] = type;
  19. }
  20. /* Find the number of leading zero bits in diff */
  21. static uint8_t diff_to_bits(double diff)
  22. {
  23. uint64_t diff64;
  24. uint8_t i;
  25. diff /= 0.9999847412109375;
  26. diff *= (double)2147483648.0;
  27. if (diff > 0x8000000000000000ULL)
  28. diff = 0x8000000000000000ULL;
  29. /* Convert it to an integer */
  30. diff64 = diff;
  31. for (i = 0; diff64; i++, diff64 >>= 1);
  32. return i;
  33. }
  34. static double bits_to_diff(uint8_t bits)
  35. {
  36. double ret = 1.0;
  37. if (likely(bits > 32))
  38. ret *= 1ull << (bits - 32);
  39. else if (unlikely(bits < 32))
  40. ret /= 1ull << (32 - bits);
  41. return ret;
  42. }
  43. static bool cta_reset_init(char *buf)
  44. {
  45. return ((buf[CTA_MSG_TYPE] == CTA_RECV_RDONE) && ((buf[CTA_RESET_TYPE]&0x3) == CTA_RESET_INIT));
  46. }
  47. static char *mystrstr(char *haystack, int size, const char *needle)
  48. {
  49. int loop = 0;
  50. while (loop < (size-1)) {
  51. if ((haystack[loop] == needle[0])&&
  52. (haystack[loop+1] == needle[1]))
  53. return &haystack[loop];
  54. loop++;
  55. }
  56. return NULL;
  57. }
  58. static bool cta_open(struct cgpu_info *cointerra)
  59. {
  60. int err, amount, offset = 0;
  61. char buf[CTA_MSG_SIZE];
  62. cgtimer_t ts_start;
  63. bool ret = false;
  64. if (cointerra->usbinfo.nodev)
  65. return false;
  66. applog(LOG_INFO, "CTA_OPEN");
  67. cta_gen_message(buf, CTA_SEND_RESET);
  68. // set the initial difficulty
  69. buf[CTA_RESET_TYPE] = CTA_RESET_INIT | CTA_RESET_DIFF;
  70. buf[CTA_RESET_DIFF] = diff_to_bits(CTA_INIT_DIFF);
  71. buf[CTA_RESET_LOAD] = opt_cta_load ? opt_cta_load : 255;
  72. buf[CTA_RESET_PSLOAD] = opt_ps_load;
  73. if (cointerra->usbinfo.nodev)
  74. return ret;
  75. err = usb_write(cointerra, buf, CTA_MSG_SIZE, &amount, C_CTA_WRITE);
  76. if (err) {
  77. applog(LOG_INFO, "Write error %d, wrote %d of %d", err, amount, CTA_MSG_SIZE);
  78. return ret;
  79. }
  80. cgtimer_time(&ts_start);
  81. /* Read from the device for up to 2 seconds discarding any data that
  82. * doesn't match a reset complete acknowledgement. */
  83. while (42) {
  84. cgtimer_t ts_now, ts_diff;
  85. char *msg;
  86. cgtimer_time(&ts_now);
  87. cgtimer_sub(&ts_now, &ts_start, &ts_diff);
  88. if (cgtimer_to_ms(&ts_diff) > 2000) {
  89. applog(LOG_DEBUG, "%s %d: Timed out waiting for response to reset init",
  90. cointerra->drv->name, cointerra->device_id);
  91. break;
  92. }
  93. if (cointerra->usbinfo.nodev)
  94. break;
  95. err = usb_read(cointerra, buf + offset, CTA_MSG_SIZE - offset, &amount, C_CTA_READ);
  96. if (err && err != LIBUSB_ERROR_TIMEOUT) {
  97. applog(LOG_INFO, "%s %d: Read error %d, read %d", cointerra->drv->name,
  98. cointerra->device_id, err, amount);
  99. break;
  100. }
  101. if (!amount)
  102. continue;
  103. msg = mystrstr(buf, amount, cointerra_hdr);
  104. if (!msg) {
  105. /* Keep the last byte in case it's the first byte of
  106. * the 2 byte header. */
  107. offset = 1;
  108. memmove(buf, buf + amount - 1, offset);
  109. continue;
  110. }
  111. if (msg > buf) {
  112. /* length of message = offset for next usb_read after moving */
  113. offset = CTA_MSG_SIZE - (msg - buf);
  114. memmove(buf, msg, offset);
  115. continue;
  116. }
  117. /* We have a full sized message starting with the header now */
  118. if (cta_reset_init(buf)) {
  119. /* We can't store any other data returned with this
  120. * reset since we have not allocated any memory for
  121. * a cointerra_info structure yet. */
  122. applog(LOG_INFO, "%s %d: Successful reset init received",
  123. cointerra->drv->name, cointerra->device_id);
  124. ret = true;
  125. break;
  126. }
  127. }
  128. return ret;
  129. }
  130. static void cta_clear_work(struct cgpu_info *cgpu)
  131. {
  132. struct work *work, *tmp;
  133. wr_lock(&cgpu->qlock);
  134. HASH_ITER(hh, cgpu->queued_work, work, tmp) {
  135. __work_completed(cgpu, work);
  136. free_work(work);
  137. }
  138. wr_unlock(&cgpu->qlock);
  139. }
  140. static void cta_close(struct cgpu_info *cointerra)
  141. {
  142. struct cointerra_info *info = cointerra->device_data;
  143. /* Wait for read thread to die */
  144. pthread_join(info->read_thr, NULL);
  145. /* Open does the same reset init followed by response as is required to
  146. * close the device. */
  147. if (!cta_open(cointerra)) {
  148. applog(LOG_INFO, "%s %d: Reset on close failed", cointerra->drv->name,
  149. cointerra->device_id);
  150. }
  151. mutex_destroy(&info->lock);
  152. mutex_destroy(&info->sendlock);
  153. /* Don't free info here to avoid trying to access dereferenced members
  154. * once a device is unplugged. */
  155. cta_clear_work(cointerra);
  156. }
  157. static struct cgpu_info *cta_detect_one(struct libusb_device *dev, struct usb_find_devices *found)
  158. {
  159. struct cgpu_info *cointerra = usb_alloc_cgpu(&cointerra_drv, 1);
  160. int tries = 0;
  161. if (!usb_init(cointerra, dev, found))
  162. goto fail;
  163. applog(LOG_INFO, "%s %d: Found at %s", cointerra->drv->name,
  164. cointerra->device_id, cointerra->device_path);
  165. while (!cta_open(cointerra) && !cointerra->usbinfo.nodev) {
  166. if (tries++ > 3)
  167. goto failed_open;
  168. applog(LOG_INFO, "%s %d: Failed to open %d times, retrying", cointerra->drv->name,
  169. cointerra->device_id, tries);
  170. }
  171. if (!add_cgpu(cointerra))
  172. goto fail_close;
  173. update_usb_stats(cointerra);
  174. applog(LOG_INFO, "%s %d: Successfully set up %s", cointerra->drv->name,
  175. cointerra->device_id, cointerra->device_path);
  176. return cointerra;
  177. fail_close:
  178. cta_close(cointerra);
  179. failed_open:
  180. applog(LOG_INFO, "%s %d: Failed to initialise %s", cointerra->drv->name,
  181. cointerra->device_id, cointerra->device_path);
  182. fail:
  183. usb_free_cgpu(cointerra);
  184. return NULL;
  185. }
  186. static void cta_detect(bool __maybe_unused hotplug)
  187. {
  188. usb_detect(&cointerra_drv, cta_detect_one);
  189. }
  190. /* This function will remove a work item from the hashtable if it matches the
  191. * id in work->subid and return a pointer to the work but it will not free the
  192. * work. It may return NULL if it cannot find matching work. */
  193. static struct work *take_work_by_id(struct cgpu_info *cgpu, uint16_t id)
  194. {
  195. struct work *work, *tmp, *ret = NULL;
  196. wr_lock(&cgpu->qlock);
  197. HASH_ITER(hh, cgpu->queued_work, work, tmp) {
  198. if (work->subid == id) {
  199. ret = work;
  200. break;
  201. }
  202. }
  203. if (ret)
  204. __work_completed(cgpu, ret);
  205. wr_unlock(&cgpu->qlock);
  206. return ret;
  207. }
  208. /* This function will look up a work item in the hashtable if it matches the
  209. * id in work->subid and return a cloned work item if it matches. It may return
  210. * NULL if it cannot find matching work. */
  211. static struct work *clone_work_by_id(struct cgpu_info *cgpu, uint16_t id)
  212. {
  213. struct work *work, *tmp, *ret = NULL;
  214. rd_lock(&cgpu->qlock);
  215. HASH_ITER(hh, cgpu->queued_work, work, tmp) {
  216. if (work->subid == id) {
  217. ret = work;
  218. break;
  219. }
  220. }
  221. if (ret)
  222. ret = copy_work(ret);
  223. rd_unlock(&cgpu->qlock);
  224. return ret;
  225. }
  226. static bool cta_send_msg(struct cgpu_info *cointerra, char *buf);
  227. static uint16_t hu16_from_msg(char *buf, int msg)
  228. {
  229. return le16toh(*(uint16_t *)&buf[msg]);
  230. }
  231. static uint32_t hu32_from_msg(char *buf, int msg)
  232. {
  233. return le32toh(*(uint32_t *)&buf[msg]);
  234. }
  235. static uint64_t hu64_from_msg(char *buf, int msg)
  236. {
  237. return le64toh(*(uint64_t *)&buf[msg]);
  238. }
  239. static uint8_t u8_from_msg(char *buf, int msg)
  240. {
  241. return *(uint8_t *)&buf[msg];
  242. }
  243. static void msg_from_hu16(char *buf, int msg, uint16_t val)
  244. {
  245. *(uint16_t *)&buf[msg] = htole16(val);
  246. }
  247. static void cta_parse_reqwork(struct cgpu_info *cointerra, struct cointerra_info *info,
  248. char *buf)
  249. {
  250. uint16_t retwork;
  251. retwork = hu16_from_msg(buf, CTA_REQWORK_REQUESTS);
  252. applog(LOG_DEBUG, "%s %d: Request work message for %u items received",
  253. cointerra->drv->name, cointerra->device_id, retwork);
  254. mutex_lock(&info->lock);
  255. info->requested = retwork;
  256. /* Wake up the main scanwork loop since we need more
  257. * work. */
  258. pthread_cond_signal(&info->wake_cond);
  259. mutex_unlock(&info->lock);
  260. }
  261. static void cta_parse_recvmatch(struct thr_info *thr, struct cgpu_info *cointerra,
  262. struct cointerra_info *info, char *buf)
  263. {
  264. uint32_t timestamp_offset, mcu_tag;
  265. uint16_t retwork;
  266. struct work *work;
  267. /* No endian switch needs doing here since it's sent and returned as
  268. * the same 4 bytes */
  269. retwork = *(uint16_t *)(&buf[CTA_DRIVER_TAG]);
  270. mcu_tag = hu32_from_msg(buf, CTA_MCU_TAG);
  271. applog(LOG_DEBUG, "%s %d: Match message for id 0x%04x MCU id 0x%08x received",
  272. cointerra->drv->name, cointerra->device_id, retwork, mcu_tag);
  273. work = clone_work_by_id(cointerra, retwork);
  274. if (likely(work)) {
  275. uint8_t wdiffbits = u8_from_msg(buf, CTA_WORK_DIFFBITS);
  276. uint32_t nonce = hu32_from_msg(buf, CTA_MATCH_NONCE);
  277. unsigned char rhash[32];
  278. char outhash[16];
  279. double wdiff;
  280. bool ret;
  281. timestamp_offset = hu32_from_msg(buf, CTA_MATCH_NOFFSET);
  282. if (timestamp_offset) {
  283. struct work *base_work = work;
  284. work = copy_work_noffset(base_work, timestamp_offset);
  285. free_work(base_work);
  286. }
  287. /* Test against the difficulty we asked for along with the work */
  288. wdiff = bits_to_diff(wdiffbits);
  289. ret = test_nonce_diff(work, nonce, wdiff);
  290. if (opt_debug) {
  291. /* Debugging, remove me */
  292. swab256(rhash, work->hash);
  293. __bin2hex(outhash, rhash, 8);
  294. applog(LOG_WARNING, "submit work %s 0x%04x 0x%08x %d 0x%08x",
  295. outhash, retwork, mcu_tag, timestamp_offset, nonce);
  296. }
  297. if (likely(ret)) {
  298. uint8_t asic, core, pipe, coreno;
  299. int pipeno, bitchar, bitbit;
  300. uint64_t hashes;
  301. asic = u8_from_msg(buf, CTA_MCU_ASIC);
  302. core = u8_from_msg(buf, CTA_MCU_CORE);
  303. pipe = u8_from_msg(buf, CTA_MCU_PIPE);
  304. pipeno = asic * 512 + core * 128 + pipe;
  305. coreno = asic * 4 + core;
  306. if (unlikely(asic > 1 || core > 3 || pipe > 127 || pipeno > 1023)) {
  307. applog(LOG_WARNING, "%s %d: MCU invalid pipe asic %d core %d pipe %d",
  308. cointerra->drv->name, cointerra->device_id, asic, core, pipe);
  309. coreno = 0;
  310. } else {
  311. info->last_pipe_nonce[pipeno] = time(NULL);
  312. bitchar = pipeno / 8;
  313. bitbit = pipeno % 8;
  314. info->pipe_bitmap[bitchar] |= 0x80 >> bitbit;
  315. }
  316. applog(LOG_DEBUG, "%s %d: Submitting tested work job_id %s work_id %u",
  317. cointerra->drv->name, cointerra->device_id, work->job_id, work->subid);
  318. ret = submit_tested_work(thr, work);
  319. hashes = (uint64_t)wdiff * 0x100000000ull;
  320. mutex_lock(&info->lock);
  321. info->share_hashes += hashes;
  322. info->tot_core_hashes[coreno] += hashes;
  323. info->hashes += nonce;
  324. mutex_unlock(&info->lock);
  325. } else {
  326. char sendbuf[CTA_MSG_SIZE];
  327. uint8_t asic, core, coreno;
  328. asic = u8_from_msg(buf, CTA_MCU_ASIC);
  329. core = u8_from_msg(buf, CTA_MCU_CORE);
  330. coreno = asic * 4 + core;
  331. inc_hw_errors(thr);
  332. applog(LOG_WARNING, "%s %d: Notify bad match work",
  333. cointerra->drv->name, cointerra->device_id);
  334. if (coreno < CTA_CORES)
  335. info->fmatch_errors[coreno]++;
  336. if (opt_debug) {
  337. uint64_t sdiff = share_diff(work);
  338. unsigned char midstate[32], wdata[12];
  339. char hexmidstate[68], hexwdata[28];
  340. uint16_t wid;
  341. memcpy(&wid, &info->work_id, 2);
  342. flip32(midstate, work->midstate);
  343. __bin2hex(hexmidstate, midstate, 32);
  344. flip12(wdata, &work->data[64]);
  345. __bin2hex(hexwdata, wdata, 12);
  346. applog(LOG_DEBUG, "False match sent: work id %u midstate %s blkhdr %s",
  347. wid, hexmidstate, hexwdata);
  348. applog(LOG_DEBUG, "False match reports: work id 0x%04x MCU id 0x%08x work diff %.1f",
  349. retwork, mcu_tag, wdiff);
  350. applog(LOG_DEBUG, "False match tested: nonce 0x%08x noffset %d %s",
  351. nonce, timestamp_offset, outhash);
  352. applog(LOG_DEBUG, "False match devdiff set to %.1f share diff calc %"PRIu64,
  353. work->device_diff, sdiff);
  354. }
  355. /* Tell the device we got a false match */
  356. cta_gen_message(sendbuf, CTA_SEND_FMATCH);
  357. memcpy(sendbuf + 3, buf + 3, CTA_MSG_SIZE - 3);
  358. cta_send_msg(cointerra, sendbuf);
  359. }
  360. free_work(work);
  361. } else {
  362. applog(LOG_WARNING, "%s %d: Matching work id 0x%X %d not found", cointerra->drv->name,
  363. cointerra->device_id, retwork, __LINE__);
  364. inc_hw_errors(thr);
  365. mutex_lock(&info->lock);
  366. info->no_matching_work++;
  367. mutex_unlock(&info->lock);
  368. }
  369. }
  370. static void cta_parse_wdone(struct thr_info *thr, struct cgpu_info *cointerra,
  371. struct cointerra_info *info, char *buf)
  372. {
  373. uint16_t retwork = *(uint16_t *)(&buf[CTA_DRIVER_TAG]);
  374. struct work *work = take_work_by_id(cointerra, retwork);
  375. uint64_t hashes;
  376. if (likely(work)) {
  377. free_work(work);
  378. applog(LOG_DEBUG, "%s %d: Done work found id 0x%X %d",
  379. cointerra->drv->name, cointerra->device_id, retwork, __LINE__);
  380. } else {
  381. applog(LOG_WARNING, "%s %d: Done work not found id 0x%X %d",
  382. cointerra->drv->name, cointerra->device_id, retwork, __LINE__);
  383. inc_hw_errors(thr);
  384. }
  385. /* Removing hashes from work done message */
  386. hashes = hu64_from_msg(buf, CTA_WDONE_NONCES);
  387. if (unlikely(hashes > (61 * 0x100000000ull))) {
  388. applog(LOG_INFO, "%s Invalid hash returned %"PRIu64"x %"PRIu64"x %"PRIu64"X",
  389. __func__, info->hashes, hashes, hashes);
  390. hashes = 0;
  391. }
  392. mutex_lock(&info->lock);
  393. info->hashes += hashes;
  394. mutex_unlock(&info->lock);
  395. }
  396. static void u16array_from_msg(uint16_t *u16, int entries, int var, char *buf)
  397. {
  398. int i, j;
  399. for (i = 0, j = 0; i < entries; i++, j += sizeof(uint16_t))
  400. u16[i] = hu16_from_msg(buf, var + j);
  401. }
  402. static void cta_parse_statread(struct cgpu_info *cointerra, struct cointerra_info *info,
  403. char *buf)
  404. {
  405. float max_temp = 0;
  406. int i;
  407. mutex_lock(&info->lock);
  408. u16array_from_msg(info->coretemp, CTA_CORES, CTA_STAT_CORETEMPS, buf);
  409. info->ambtemp_low = hu16_from_msg(buf, CTA_STAT_AMBTEMP_LOW);
  410. info->ambtemp_avg = hu16_from_msg(buf, CTA_STAT_AMBTEMP_AVG);
  411. info->ambtemp_high = hu16_from_msg(buf, CTA_STAT_AMBTEMP_HIGH);
  412. u16array_from_msg(info->pump_tachs, CTA_PUMPS, CTA_STAT_PUMP_TACHS, buf);
  413. u16array_from_msg(info->fan_tachs, CTA_FANS, CTA_STAT_FAN_TACHS, buf);
  414. u16array_from_msg(info->corevolts, CTA_CORES, CTA_STAT_CORE_VOLTS, buf);
  415. info->volts33 = hu16_from_msg(buf, CTA_STAT_VOLTS33);
  416. info->volts12 = hu16_from_msg(buf, CTA_STAT_VOLTS12);
  417. info->inactive = hu16_from_msg(buf, CTA_STAT_INACTIVE);
  418. info->active = hu16_from_msg(buf, CTA_STAT_ACTIVE);
  419. mutex_unlock(&info->lock);
  420. for (i = 0; i < CTA_CORES; i++) {
  421. if (info->coretemp[i] > max_temp)
  422. max_temp = info->coretemp[i];
  423. }
  424. max_temp /= 100.0;
  425. /* Store the max temperature in the cgpu struct as an exponentially
  426. * changing value. */
  427. cointerra->temp = cointerra->temp * 0.63 + max_temp * 0.37;
  428. }
  429. static void u8array_from_msg(uint8_t *u8, int entries, int var, char *buf)
  430. {
  431. int i;
  432. for (i = 0; i < entries; i++)
  433. u8[i] = u8_from_msg(buf, var + i);
  434. }
  435. static void cta_parse_statset(struct cointerra_info *info, char *buf)
  436. {
  437. mutex_lock(&info->lock);
  438. u8array_from_msg(info->coreperf, CTA_CORES, CTA_STAT_PERFMODE, buf);
  439. u8array_from_msg(info->fanspeed, CTA_FANS, CTA_STAT_FANSPEEDS, buf);
  440. info->dies_active = u8_from_msg(buf, CTA_STAT_DIES_ACTIVE);
  441. u8array_from_msg(info->pipes_enabled, CTA_CORES, CTA_STAT_PIPES_ENABLED, buf);
  442. u16array_from_msg(info->corefreqs, CTA_CORES, CTA_STAT_CORE_FREQS, buf);
  443. info->uptime = hu32_from_msg(buf,CTA_STAT_UPTIME);
  444. mutex_unlock(&info->lock);
  445. }
  446. static void cta_parse_irstat(struct cointerra_info *info, char *buf)
  447. {
  448. uint8_t channel = u8_from_msg(buf,CTA_IRSTAT_CHANNEL);
  449. if (channel >= CTA_CORES)
  450. return;
  451. mutex_lock(&info->lock);
  452. info->irstat_vin[channel] = hu16_from_msg(buf,CTA_IRSTAT_VIN);
  453. info->irstat_iin[channel] = hu16_from_msg(buf,CTA_IRSTAT_IIN);
  454. info->irstat_vout[channel] = hu16_from_msg(buf,CTA_IRSTAT_VOUT);
  455. info->irstat_iout[channel] = hu16_from_msg(buf,CTA_IRSTAT_IOUT);
  456. info->irstat_temp1[channel] = hu16_from_msg(buf,CTA_IRSTAT_TEMP1);
  457. info->irstat_temp2[channel] = hu16_from_msg(buf,CTA_IRSTAT_TEMP2);
  458. info->irstat_pout[channel] = hu16_from_msg(buf,CTA_IRSTAT_POUT);
  459. info->irstat_pin[channel] = hu16_from_msg(buf,CTA_IRSTAT_PIN);
  460. info->irstat_efficiency[channel] = hu16_from_msg(buf,CTA_IRSTAT_EFF);
  461. info->irstat_status[channel] = hu16_from_msg(buf,CTA_IRSTAT_STATUS);
  462. mutex_unlock(&info->lock);
  463. }
  464. static void cta_parse_info(struct cgpu_info *cointerra, struct cointerra_info *info,
  465. char *buf)
  466. {
  467. mutex_lock(&info->lock);
  468. info->hwrev = hu64_from_msg(buf, CTA_INFO_HWREV);
  469. info->serial = hu32_from_msg(buf, CTA_INFO_SERNO);
  470. info->asics = u8_from_msg(buf, CTA_INFO_NUMASICS);
  471. info->dies = u8_from_msg(buf, CTA_INFO_NUMDIES);
  472. info->cores = hu16_from_msg(buf, CTA_INFO_NUMCORES);
  473. info->board_number = u8_from_msg(buf, CTA_INFO_BOARDNUMBER);
  474. info->fwrev[0] = u8_from_msg(buf, CTA_INFO_FWREV_MAJ);
  475. info->fwrev[1] = u8_from_msg(buf, CTA_INFO_FWREV_MIN);
  476. info->fwrev[2] = u8_from_msg(buf, CTA_INFO_FWREV_MIC);
  477. info->fw_year = hu16_from_msg(buf, CTA_INFO_FWDATE_YEAR);
  478. info->fw_month = u8_from_msg(buf, CTA_INFO_FWDATE_MONTH);
  479. info->fw_day = u8_from_msg(buf, CTA_INFO_FWDATE_DAY);
  480. info->init_diffbits = u8_from_msg(buf, CTA_INFO_INITDIFFBITS);
  481. info->min_diffbits = u8_from_msg(buf, CTA_INFO_MINDIFFBITS);
  482. info->max_diffbits = u8_from_msg(buf, CTA_INFO_MAXDIFFBITS);
  483. mutex_unlock(&info->lock);
  484. if (!cointerra->unique_id) {
  485. uint32_t b32 = htobe32(info->serial);
  486. cointerra->unique_id = bin2hex((unsigned char *)&b32, 4);
  487. }
  488. }
  489. static void cta_parse_rdone(struct cgpu_info *cointerra, struct cointerra_info *info,
  490. char *buf)
  491. {
  492. uint8_t reset_type, diffbits;
  493. uint64_t wdone;
  494. reset_type = buf[CTA_RESET_TYPE];
  495. diffbits = buf[CTA_RESET_DIFF];
  496. wdone = hu64_from_msg(buf, CTA_WDONE_NONCES);
  497. if (wdone) {
  498. applog(LOG_INFO, "%s %d: Reset done type %u message %u diffbits %"PRIu64" done received",
  499. cointerra->drv->name, cointerra->device_id, reset_type, diffbits, wdone);
  500. mutex_lock(&info->lock);
  501. info->hashes += wdone;
  502. mutex_unlock(&info->lock);
  503. }
  504. /* Note that the cgsem that is posted here must not be waited on while
  505. * holding the info->lock to not get into a livelock since this
  506. * function also grabs the lock first and it's always best to not sleep
  507. * while holding a lock. */
  508. if (reset_type == CTA_RESET_NEW) {
  509. cta_clear_work(cointerra);
  510. /* Tell reset sender that the reset is complete
  511. * and it may resume. */
  512. cgsem_post(&info->reset_sem);
  513. }
  514. }
  515. static void cta_zero_stats(struct cgpu_info *cointerra);
  516. static void cta_parse_debug(struct cointerra_info *info, char *buf)
  517. {
  518. mutex_lock(&info->lock);
  519. info->tot_underruns = hu16_from_msg(buf, CTA_STAT_UNDERRUNS);
  520. u16array_from_msg(info->tot_hw_errors, CTA_CORES, CTA_STAT_HW_ERRORS, buf);
  521. info->tot_hashes = hu64_from_msg(buf, CTA_STAT_HASHES);
  522. info->tot_flushed_hashes = hu64_from_msg(buf, CTA_STAT_FLUSHED_HASHES);
  523. info->autovoltage = u8_from_msg(buf, CTA_STAT_AUTOVOLTAGE);
  524. info->current_ps_percent = u8_from_msg(buf, CTA_STAT_POWER_PERCENT);
  525. info->power_used = hu16_from_msg(buf,CTA_STAT_POWER_USED);
  526. info->power_voltage = hu16_from_msg(buf,CTA_STAT_VOLTAGE);
  527. info->ipower_used = hu16_from_msg(buf,CTA_STAT_IPOWER_USED);
  528. info->ipower_voltage = hu16_from_msg(buf,CTA_STAT_IVOLTAGE);
  529. info->power_temps[0] = hu16_from_msg(buf,CTA_STAT_PS_TEMP1);
  530. info->power_temps[1] = hu16_from_msg(buf,CTA_STAT_PS_TEMP2);
  531. mutex_unlock(&info->lock);
  532. /* Autovoltage is positive only once at startup and eventually drops
  533. * to zero. After that time we reset the stats since they're unreliable
  534. * till then. */
  535. if (unlikely(!info->autovoltage_complete && !info->autovoltage)) {
  536. struct cgpu_info *cointerra = info->thr->cgpu;
  537. info->autovoltage_complete = true;
  538. cgtime(&cointerra->dev_start_tv);
  539. cta_zero_stats(cointerra);
  540. cointerra->total_mhashes = 0;
  541. cointerra->accepted = 0;
  542. cointerra->rejected = 0;
  543. cointerra->hw_errors = 0;
  544. cointerra->utility = 0.0;
  545. cointerra->last_share_pool_time = 0;
  546. cointerra->diff1 = 0;
  547. cointerra->diff_accepted = 0;
  548. cointerra->diff_rejected = 0;
  549. cointerra->last_share_diff = 0;
  550. }
  551. }
  552. static int verify_checksum(char *buf)
  553. {
  554. unsigned char checksum = 0;
  555. unsigned char i;
  556. for (i = 0; i < 63; i++)
  557. checksum += buf[i];
  558. return (checksum == buf[63]);
  559. }
  560. static void cta_parse_msg(struct thr_info *thr, struct cgpu_info *cointerra,
  561. struct cointerra_info *info, char *buf)
  562. {
  563. if ((buf[CTA_MSG_TYPE] != CTA_RECV_MATCH)&&
  564. (buf[CTA_MSG_TYPE] != CTA_RECV_WDONE)) {
  565. if (unlikely(verify_checksum(buf) == 0)) {
  566. inc_hw_errors(thr);
  567. applog(LOG_WARNING, "%s %d: checksum bad",cointerra->drv->name,cointerra->device_id);
  568. return;
  569. }
  570. }
  571. switch (buf[CTA_MSG_TYPE]) {
  572. default:
  573. case CTA_RECV_UNUSED:
  574. applog(LOG_INFO, "%s %d: Unidentified message type %u",
  575. cointerra->drv->name, cointerra->device_id, buf[CTA_MSG_TYPE]);
  576. break;
  577. case CTA_RECV_REQWORK:
  578. cta_parse_reqwork(cointerra, info, buf);
  579. break;
  580. case CTA_RECV_MATCH:
  581. cta_parse_recvmatch(thr, cointerra, info, buf);
  582. break;
  583. case CTA_RECV_WDONE:
  584. applog(LOG_DEBUG, "%s %d: Work done message received",
  585. cointerra->drv->name, cointerra->device_id);
  586. cta_parse_wdone(thr, cointerra, info, buf);
  587. break;
  588. case CTA_RECV_STATREAD:
  589. applog(LOG_DEBUG, "%s %d: Status readings message received",
  590. cointerra->drv->name, cointerra->device_id);
  591. cta_parse_statread(cointerra, info, buf);
  592. break;
  593. case CTA_RECV_STATSET:
  594. applog(LOG_DEBUG, "%s %d: Status settings message received",
  595. cointerra->drv->name, cointerra->device_id);
  596. cta_parse_statset(info, buf);
  597. break;
  598. case CTA_RECV_INFO:
  599. applog(LOG_DEBUG, "%s %d: Info message received",
  600. cointerra->drv->name, cointerra->device_id);
  601. cta_parse_info(cointerra, info, buf);
  602. break;
  603. case CTA_RECV_MSG:
  604. applog(LOG_NOTICE, "%s %d: MSG: %s",
  605. cointerra->drv->name, cointerra->device_id, &buf[CTA_MSG_RECVD]);
  606. break;
  607. case CTA_RECV_RDONE:
  608. cta_parse_rdone(cointerra, info, buf);
  609. break;
  610. case CTA_RECV_STATDEBUG:
  611. cta_parse_debug(info, buf);
  612. break;
  613. case CTA_RECV_IRSTAT:
  614. cta_parse_irstat(info, buf);
  615. break;
  616. }
  617. }
  618. static void *cta_recv_thread(void *arg)
  619. {
  620. struct thr_info *thr = (struct thr_info *)arg;
  621. struct cgpu_info *cointerra = thr->cgpu;
  622. struct cointerra_info *info = cointerra->device_data;
  623. char threadname[24];
  624. int offset = 0;
  625. snprintf(threadname, 24, "cta_recv/%d", cointerra->device_id);
  626. RenameThread(threadname);
  627. while (likely(!cointerra->shutdown)) {
  628. char buf[CTA_READBUF_SIZE];
  629. int amount, err;
  630. if (unlikely(cointerra->usbinfo.nodev)) {
  631. applog(LOG_DEBUG, "%s %d: Device disappeared, disabling recv thread",
  632. cointerra->drv->name, cointerra->device_id);
  633. break;
  634. }
  635. err = usb_read(cointerra, buf + offset, CTA_MSG_SIZE, &amount, C_CTA_READ);
  636. if (err && err != LIBUSB_ERROR_TIMEOUT) {
  637. applog(LOG_ERR, "%s %d: Read error %d, read %d", cointerra->drv->name,
  638. cointerra->device_id, err, amount);
  639. break;
  640. }
  641. offset += amount;
  642. while (offset >= CTA_MSG_SIZE) {
  643. char *msg = mystrstr(buf, offset, cointerra_hdr);
  644. int begin;
  645. if (unlikely(!msg)) {
  646. applog(LOG_WARNING, "%s %d: No message header found, discarding buffer",
  647. cointerra->drv->name, cointerra->device_id);
  648. inc_hw_errors(thr);
  649. /* Save the last byte in case it's the fist
  650. * byte of a header. */
  651. begin = CTA_MSG_SIZE - 1;
  652. offset -= begin;
  653. memmove(buf, buf + begin, offset);
  654. continue;
  655. }
  656. if (unlikely(msg != buf)) {
  657. begin = msg - buf;
  658. applog(LOG_WARNING, "%s %d: Reads out of sync, discarding %d bytes",
  659. cointerra->drv->name, cointerra->device_id, begin);
  660. inc_hw_errors(thr);
  661. offset -= begin;
  662. memmove(buf, msg, offset);
  663. if (offset < CTA_MSG_SIZE)
  664. break;
  665. }
  666. /* We have enough buffer for a full message, parse now */
  667. cta_parse_msg(thr, cointerra, info, msg);
  668. offset -= CTA_MSG_SIZE;
  669. if (offset > 0)
  670. memmove(buf, buf + CTA_MSG_SIZE, offset);
  671. }
  672. }
  673. return NULL;
  674. }
  675. static bool cta_send_msg(struct cgpu_info *cointerra, char *buf)
  676. {
  677. struct cointerra_info *info = cointerra->device_data;
  678. int amount, err;
  679. if (unlikely(cointerra->usbinfo.nodev))
  680. return false;
  681. /* Serialise usb writes to prevent overlap in case multiple threads
  682. * send messages */
  683. mutex_lock(&info->sendlock);
  684. err = usb_write(cointerra, buf, CTA_MSG_SIZE, &amount, C_CTA_WRITE);
  685. mutex_unlock(&info->sendlock);
  686. if (unlikely(err || amount != CTA_MSG_SIZE)) {
  687. applog(LOG_ERR, "%s %d: Write error %d, wrote %d of %d", cointerra->drv->name,
  688. cointerra->device_id, err, amount, CTA_MSG_SIZE);
  689. return false;
  690. }
  691. return true;
  692. }
  693. static bool cta_prepare(struct thr_info *thr)
  694. {
  695. struct cgpu_info *cointerra = thr->cgpu;
  696. struct cointerra_info *info = calloc(sizeof(struct cointerra_info), 1);
  697. char buf[CTA_MSG_SIZE];
  698. if (unlikely(cointerra->usbinfo.nodev))
  699. return false;
  700. if (unlikely(!info))
  701. quit(1, "Failed to calloc info in cta_detect_one");
  702. cointerra->device_data = info;
  703. /* Nominally set a requested value when starting, preempting the need
  704. * for a req-work message. */
  705. info->requested = CTA_MAX_QUEUE;
  706. info->thr = thr;
  707. mutex_init(&info->lock);
  708. mutex_init(&info->sendlock);
  709. if (unlikely(pthread_cond_init(&info->wake_cond, NULL)))
  710. quit(1, "Failed to create cta pthread cond");
  711. cgsem_init(&info->reset_sem);
  712. if (pthread_create(&info->read_thr, NULL, cta_recv_thread, (void *)thr))
  713. quit(1, "Failed to create cta_recv_thread");
  714. /* Request a single status setting message */
  715. cta_gen_message(buf, CTA_SEND_REQUEST);
  716. msg_from_hu16(buf, CTA_REQ_MSGTYPE, CTA_RECV_STATSET);
  717. msg_from_hu16(buf, CTA_REQ_INTERVAL, 0);
  718. if (!cta_send_msg(cointerra, buf))
  719. return false;
  720. /* Request status debug messages every 60 seconds */
  721. cta_gen_message(buf, CTA_SEND_REQUEST);
  722. msg_from_hu16(buf, CTA_REQ_MSGTYPE, CTA_RECV_STATDEBUG);
  723. msg_from_hu16(buf, CTA_REQ_INTERVAL, 6000);
  724. if (!cta_send_msg(cointerra, buf))
  725. return false;
  726. cgtime(&info->core_hash_start);
  727. return true;
  728. }
  729. static void cta_send_reset(struct cgpu_info *cointerra, struct cointerra_info *info,
  730. uint8_t reset_type, uint8_t diffbits);
  731. static void cta_flush_work(struct cgpu_info *cointerra);
  732. /* *_fill and *_scanwork are serialised wrt to each other */
  733. static bool cta_fill(struct cgpu_info *cointerra)
  734. {
  735. struct cointerra_info *info = cointerra->device_data;
  736. bool ret = true;
  737. char buf[CTA_MSG_SIZE];
  738. struct work *work = NULL;
  739. unsigned short nroll_limit;
  740. uint32_t swab[8];
  741. uint8_t diffbits;
  742. //applog(LOG_WARNING, "%s %d: cta_fill %d", cointerra->drv->name, cointerra->device_id,__LINE__);
  743. if (unlikely(info->thr->work_restart))
  744. cta_flush_work(cointerra);
  745. mutex_lock(&info->lock);
  746. if (!info->requested)
  747. goto out_unlock;
  748. work = get_queued(cointerra);
  749. if (unlikely(!work)) {
  750. ret = false;
  751. goto out_unlock;
  752. }
  753. if (--info->requested > 0)
  754. ret = false;
  755. /* It does not matter what endian this uint16_t is since it will be
  756. * the same value on sending to the MC as returning in match/done. This
  757. * will automatically wrap as a uint16_t. It cannot be zero for the MCU
  758. * though. */
  759. if (unlikely(++info->work_id == 0))
  760. info->work_id = 1;
  761. work->subid = info->work_id;
  762. diffbits = diff_to_bits(work->device_diff);
  763. cta_gen_message(buf, CTA_SEND_WORK);
  764. memcpy(buf + CTA_DRIVER_TAG, &info->work_id, 2);
  765. flip32(swab, work->midstate);
  766. memcpy(buf + CTA_WORK_MIDSTATE, swab, 32);
  767. flip12(swab, &work->data[64]);
  768. memcpy(buf + CTA_WORK_DATA, swab, 12);
  769. nroll_limit = htole16(work->drv_rolllimit);
  770. memcpy(buf + CTA_WORK_NROLL, &nroll_limit, 2);
  771. memcpy(buf + CTA_WORK_DIFFBITS, &diffbits, 1);
  772. out_unlock:
  773. mutex_unlock(&info->lock);
  774. if (work) {
  775. cgtime(&work->tv_work_start);
  776. applog(LOG_DEBUG, "%s %d: Sending work job_id %s work_id %u", cointerra->drv->name,
  777. cointerra->device_id, work->job_id, work->subid);
  778. if (unlikely(!cta_send_msg(cointerra, buf))) {
  779. work_completed(cointerra, work);
  780. applog(LOG_INFO, "%s %d: Failed to send work",
  781. cointerra->drv->name, cointerra->device_id);
  782. /* The device will fail after this */
  783. }
  784. }
  785. return ret;
  786. }
  787. static void cta_send_reset(struct cgpu_info *cointerra, struct cointerra_info *info,
  788. uint8_t reset_type, uint8_t diffbits)
  789. {
  790. char buf[CTA_MSG_SIZE];
  791. int ret, retries = 0;
  792. /* Clear any accumulated messages in case we've gotten out of sync. */
  793. cgsem_reset(&info->reset_sem);
  794. resend:
  795. cta_gen_message(buf, CTA_SEND_RESET);
  796. buf[CTA_RESET_TYPE] = reset_type;
  797. buf[CTA_RESET_LOAD] = opt_cta_load ? opt_cta_load : 255;
  798. buf[CTA_RESET_PSLOAD] = opt_ps_load;
  799. applog(LOG_INFO, "%s %d: Sending Reset type %u with diffbits %u", cointerra->drv->name,
  800. cointerra->device_id, reset_type, diffbits);
  801. cta_send_msg(cointerra, buf);
  802. /* Wait for read thread to parse a reset message and signal us we may
  803. * return to submitting other messages. Use a timeout in case we have
  804. * a problem and the reset done message never returns. */
  805. if (reset_type == CTA_RESET_NEW) {
  806. ret = cgsem_mswait(&info->reset_sem, CTA_RESET_TIMEOUT);
  807. if (ret) {
  808. if (++retries < 5) {
  809. applog(LOG_INFO, "%s %d: Timed out waiting for reset done msg, retrying",
  810. cointerra->drv->name, cointerra->device_id);
  811. goto resend;
  812. }
  813. applog(LOG_WARNING, "%s %d: Timed out waiting for reset done msg",
  814. cointerra->drv->name, cointerra->device_id);
  815. }
  816. /* Good place to flush any work we have */
  817. flush_queue(cointerra);
  818. }
  819. }
  820. static void cta_flush_work(struct cgpu_info *cointerra)
  821. {
  822. struct cointerra_info *info = cointerra->device_data;
  823. applog(LOG_INFO, "%s %d: cta_flush_work %d", cointerra->drv->name, cointerra->device_id,
  824. __LINE__);
  825. cta_send_reset(cointerra, info, CTA_RESET_NEW, 0);
  826. info->thr->work_restart = false;
  827. }
  828. static void cta_update_work(struct cgpu_info *cointerra)
  829. {
  830. struct cointerra_info *info = cointerra->device_data;
  831. applog(LOG_INFO, "%s %d: Update work", cointerra->drv->name, cointerra->device_id);
  832. cta_send_reset(cointerra, info, CTA_RESET_UPDATE, 0);
  833. }
  834. static void cta_zero_corehashes(struct cointerra_info *info)
  835. {
  836. int i;
  837. for (i = 0; i < CTA_CORES; i++)
  838. info->tot_core_hashes[i] = 0;
  839. cgtime(&info->core_hash_start);
  840. }
  841. /* Send per core hashrate calculations at regular intervals ~every 5 minutes */
  842. static void cta_send_corehashes(struct cgpu_info *cointerra, struct cointerra_info *info,
  843. double corehash_time)
  844. {
  845. uint16_t core_ghs[CTA_CORES];
  846. double k[CTA_CORES];
  847. char buf[CTA_MSG_SIZE];
  848. int i, offset;
  849. for (i = 0; i < CTA_CORES; i++) {
  850. k[i] = (double)info->tot_core_hashes[i];
  851. #if 0
  852. k[i] /= ((double)32 * (double)0x100000000ull);
  853. k[i] = sqrt(k[i]) + 1;
  854. k[i] *= k[i];
  855. k[i] = k[i] * 32 * ((double)0x100000000ull );
  856. #endif
  857. k[i] /= ((double)1000000000 * corehash_time);
  858. core_ghs[i] = k[i];
  859. }
  860. cta_gen_message(buf, CTA_SEND_COREHASHRATE);
  861. offset = CTA_CORE_HASHRATES;
  862. for (i = 0; i < CTA_CORES; i++) {
  863. msg_from_hu16(buf, offset, core_ghs[i]);
  864. offset += 2; // uint16_t
  865. }
  866. cta_send_msg(cointerra, buf);
  867. }
  868. static int64_t cta_scanwork(struct thr_info *thr)
  869. {
  870. struct cgpu_info *cointerra = thr->cgpu;
  871. struct cointerra_info *info = cointerra->device_data;
  872. double corehash_time;
  873. struct timeval now;
  874. uint32_t runtime;
  875. int64_t hashes;
  876. applog(LOG_DEBUG, "%s %d: cta_scanwork %d", cointerra->drv->name, cointerra->device_id,__LINE__);
  877. if (unlikely(cointerra->usbinfo.nodev)) {
  878. hashes = -1;
  879. goto out;
  880. }
  881. cgtime(&now);
  882. if (unlikely(thr->work_restart)) {
  883. applog(LOG_INFO, "%s %d: Flush work line %d",
  884. cointerra->drv->name, cointerra->device_id,__LINE__);
  885. cta_flush_work(cointerra);
  886. } else {
  887. struct timespec abstime, tsdiff = {0, 500000000};
  888. time_t now_t;
  889. int i;
  890. timeval_to_spec(&abstime, &now);
  891. timeraddspec(&abstime, &tsdiff);
  892. /* Discard work that was started more than 5 minutes ago as
  893. * a safety precaution backup in case the hardware failed to
  894. * return a work done message for some work items. */
  895. age_queued_work(cointerra, 300.0);
  896. /* Each core should be 1.7MH so at max diff of 32 should
  897. * average a share every ~80 seconds.Use this opportunity to
  898. * unset the bits in any pipes that have not returned a valid
  899. * nonce for over 30 full nonce ranges or 2400s. */
  900. now_t = time(NULL);
  901. for (i = 0; i < 1024; i++) {
  902. if (unlikely(now_t > info->last_pipe_nonce[i] + 2400)) {
  903. int bitchar = i / 8, bitbit = i % 8;
  904. info->pipe_bitmap[bitchar] &= ~(0x80 >> bitbit);
  905. }
  906. }
  907. /* Sleep for up to 0.5 seconds, waking if we need work or
  908. * have received a restart message. */
  909. mutex_lock(&info->lock);
  910. pthread_cond_timedwait(&info->wake_cond, &info->lock, &abstime);
  911. mutex_unlock(&info->lock);
  912. if (thr->work_restart) {
  913. applog(LOG_INFO, "%s %d: Flush work line %d",
  914. cointerra->drv->name, cointerra->device_id,__LINE__);
  915. cta_flush_work(cointerra);
  916. }
  917. }
  918. corehash_time = tdiff(&now, &info->core_hash_start);
  919. if (corehash_time > 300) {
  920. cta_send_corehashes(cointerra, info, corehash_time);
  921. cta_zero_corehashes(info);
  922. }
  923. mutex_lock(&info->lock);
  924. hashes = info->share_hashes;
  925. info->tot_share_hashes += info->share_hashes;
  926. info->tot_calc_hashes += info->hashes;
  927. runtime = cgpu_runtime(thr->cgpu);
  928. runtime /= 30;
  929. info->old_hashes[runtime % 32] = info->tot_calc_hashes;
  930. info->hashes = info->share_hashes = 0;
  931. mutex_unlock(&info->lock);
  932. if (unlikely(cointerra->usbinfo.nodev))
  933. hashes = -1;
  934. out:
  935. return hashes;
  936. }
  937. /* This is used for a work restart. We don't actually perform the work restart
  938. * here but wake up the scanwork loop if it's waiting on the conditional so
  939. * that it can test for the restart message. */
  940. static void cta_wake(struct cgpu_info *cointerra)
  941. {
  942. struct cointerra_info *info = cointerra->device_data;
  943. mutex_lock(&info->lock);
  944. pthread_cond_signal(&info->wake_cond);
  945. mutex_unlock(&info->lock);
  946. }
  947. static void cta_shutdown(struct thr_info *thr)
  948. {
  949. struct cgpu_info *cointerra = thr->cgpu;
  950. cta_close(cointerra);
  951. }
  952. static void cta_zero_stats(struct cgpu_info *cointerra)
  953. {
  954. struct cointerra_info *info = cointerra->device_data;
  955. int i;
  956. info->tot_calc_hashes = 0;
  957. info->tot_reset_hashes = info->tot_hashes;
  958. info->tot_share_hashes = 0;
  959. cta_zero_corehashes(info);
  960. for (i = 0; i < 16 * 2; i++)
  961. info->old_hashes[i] = 0;
  962. }
  963. static int bits_set(char v)
  964. {
  965. int c;
  966. for (c = 0; v; c++)
  967. v &= v - 1;
  968. return c;
  969. }
  970. static struct api_data *cta_api_stats(struct cgpu_info *cgpu)
  971. {
  972. struct api_data *root = NULL;
  973. struct cointerra_info *info = cgpu->device_data;
  974. double dev_runtime = cgpu_runtime(cgpu);
  975. int i, asic, core, coreno = 0;
  976. struct timeval now;
  977. char bitmaphex[36];
  978. uint64_t ghs, val;
  979. char buf[64];
  980. uint32_t runtime = cgpu_runtime(cgpu);
  981. /* Info data */
  982. root = api_add_uint16(root, "HW Revision", &info->hwrev, false);
  983. root = api_add_uint32(root, "Serial", &info->serial, false);
  984. root = api_add_uint8(root, "Asics", &info->asics, false);
  985. root = api_add_uint8(root, "Dies", &info->dies, false);
  986. root = api_add_uint16(root, "Cores", &info->cores, false);
  987. root = api_add_uint8(root, "Board number", &info->board_number, false);
  988. sprintf(buf, "%u.%u.%u", info->fwrev[0], info->fwrev[1], info->fwrev[2]);
  989. root = api_add_string(root, "FW Revision", buf, true);
  990. sprintf(buf, "%04u-%02u-%02u", info->fw_year, info->fw_month, info->fw_day);
  991. root = api_add_string(root, "FW Date", buf, true);
  992. root = api_add_uint8(root, "Init diffbits", &info->init_diffbits, false);
  993. root = api_add_uint8(root, "Min diffbits", &info->min_diffbits, false);
  994. root = api_add_uint8(root, "Max diffbits", &info->max_diffbits, false);
  995. /* Status readings */
  996. for (i = 0; i < CTA_CORES; i++) {
  997. sprintf(buf, "CoreTemp%d", i);
  998. root = api_add_int16(root, buf, &info->coretemp[i], false);
  999. }
  1000. root = api_add_int16(root, "Ambient Low", &info->ambtemp_low, false);
  1001. root = api_add_int16(root, "Ambient Avg", &info->ambtemp_avg, false);
  1002. root = api_add_int16(root, "Ambient High", &info->ambtemp_high, false);
  1003. for (i = 0; i < CTA_PUMPS; i++) {
  1004. sprintf(buf, "PumpRPM%d", i);
  1005. root = api_add_uint16(root, buf, &info->pump_tachs[i], false);
  1006. }
  1007. for (i = 0; i < CTA_FANS; i++) {
  1008. sprintf(buf, "FanRPM%d", i);
  1009. root = api_add_uint16(root, buf, &info->fan_tachs[i], false);
  1010. }
  1011. for (i = 0; i < CTA_CORES; i++) {
  1012. sprintf(buf, "CoreFreqs%d", i);
  1013. root = api_add_uint16(root, buf, &info->corefreqs[i], false);
  1014. }
  1015. for (i = 0; i < CTA_CORES; i++) {
  1016. sprintf(buf, "CoreVolts%d", i);
  1017. root = api_add_uint16(root, buf, &info->corevolts[i], false);
  1018. }
  1019. root = api_add_uint16(root, "Volts3.3", &info->volts33, false);
  1020. root = api_add_uint16(root, "Volts12", &info->volts12, false);
  1021. root = api_add_uint16(root, "Inactive", &info->inactive, false);
  1022. root = api_add_uint16(root, "Active", &info->active, false);
  1023. /* Status settings */
  1024. for (i = 0; i < CTA_CORES; i++) {
  1025. sprintf(buf, "CorePerfMode%d", i);
  1026. root = api_add_uint8(root, buf, &info->coreperf[i], false);
  1027. }
  1028. for (i = 0; i < CTA_FANS; i++) {
  1029. sprintf(buf, "FanSpeed%d", i);
  1030. root = api_add_uint8(root, buf, &info->fanspeed[i], false);
  1031. }
  1032. root = api_add_uint8(root, "DiesActive", &info->dies_active, false);
  1033. for (i = 0; i < CTA_CORES; i++) {
  1034. sprintf(buf, "PipesEnabled%d", i);
  1035. root = api_add_uint8(root, buf, &info->pipes_enabled[i], false);
  1036. }
  1037. /* Status debug */
  1038. root = api_add_int(root, "Underruns", &info->tot_underruns, false);
  1039. for (i = 0; i < CTA_CORES; i++) {
  1040. sprintf(buf, "HWErrors%d", i);
  1041. root = api_add_uint16(root, buf, &info->tot_hw_errors[i], false);
  1042. }
  1043. ghs = info->tot_calc_hashes / dev_runtime;
  1044. root = api_add_uint64(root, "Calc hashrate", &ghs, true);
  1045. ghs = (info->tot_hashes - info->tot_reset_hashes) / dev_runtime;
  1046. root = api_add_uint64(root, "Hashrate", &ghs, true);
  1047. //root = api_add_uint64(root, "cgminer 15m Hashrate", &cgpu->rolling15, true);
  1048. // get runtime in 30 second steps
  1049. runtime = runtime / 30;
  1050. // store the current hashes
  1051. info->old_hashes[runtime%32] = info->tot_calc_hashes;
  1052. // calc the 15 minute average hashrate
  1053. ghs = (info->old_hashes[(runtime+31)%32] - info->old_hashes[(runtime+1)%32])/(15*60);
  1054. root = api_add_uint64(root, "15m Hashrate", &ghs, true);
  1055. ghs = info->tot_share_hashes / dev_runtime;
  1056. root = api_add_uint64(root, "Share hashrate", &ghs, true);
  1057. root = api_add_uint64(root, "Total calc hashes", &info->tot_calc_hashes, false);
  1058. ghs = info->tot_hashes - info->tot_reset_hashes;
  1059. root = api_add_uint64(root, "Total hashes", &ghs, true);
  1060. root = api_add_uint64(root, "Total raw hashes", &info->tot_hashes, false);
  1061. root = api_add_uint64(root, "Total share hashes", &info->tot_share_hashes, false);
  1062. root = api_add_uint64(root, "Total flushed hashes", &info->tot_flushed_hashes, false);
  1063. val = cgpu->diff_accepted * 0x100000000ull;
  1064. root = api_add_uint64(root, "Accepted hashes", &val, true);
  1065. ghs = val / dev_runtime;
  1066. root = api_add_uint64(root, "Accepted hashrate", &ghs, true);
  1067. val = cgpu->diff_rejected * 0x100000000ull;
  1068. root = api_add_uint64(root, "Rejected hashes", &val, true);
  1069. ghs = val / dev_runtime;
  1070. root = api_add_uint64(root, "Rejected hashrate", &ghs, true);
  1071. cgtime(&now);
  1072. dev_runtime = tdiff(&now, &info->core_hash_start);
  1073. if (dev_runtime < 1)
  1074. dev_runtime = 1;
  1075. for (i = 0; i < CTA_CORES; i++) {
  1076. sprintf(buf, "Core%d hashrate", i);
  1077. ghs = info->tot_core_hashes[i] / dev_runtime;
  1078. root = api_add_uint64(root, buf, &ghs, true);
  1079. }
  1080. root = api_add_uint32(root, "Uptime",&info->uptime,false);
  1081. for (asic = 0; asic < 2; asic++) {
  1082. for (core = 0; core < 4; core++) {
  1083. char bitmapcount[40], asiccore[12];
  1084. int count = 0;
  1085. sprintf(asiccore, "Asic%dCore%d", asic, core);
  1086. __bin2hex(bitmaphex, &info->pipe_bitmap[coreno], 16);
  1087. for (i = coreno; i < coreno + 16; i++)
  1088. count += bits_set(info->pipe_bitmap[i]);
  1089. snprintf(bitmapcount, 40, "%d:%s", count, bitmaphex);
  1090. root = api_add_string(root, asiccore, bitmapcount, true);
  1091. coreno += 16;
  1092. }
  1093. }
  1094. root = api_add_uint8(root, "AV", &info->autovoltage, false);
  1095. root = api_add_uint8(root, "Power Supply Percent", &info->current_ps_percent, false);
  1096. //if (info->power_used != 0) {
  1097. {
  1098. double value = info->power_used/100.0;
  1099. value *= (info->power_voltage/100.0);
  1100. root = api_add_double(root, "Power Used", &value, true);
  1101. }
  1102. root = api_add_uint16(root, "IOUT", &info->power_used, false);
  1103. root = api_add_uint16(root, "VOUT", &info->power_voltage, false);
  1104. root = api_add_uint16(root, "IIN", &info->ipower_used, false);
  1105. root = api_add_uint16(root, "VIN", &info->ipower_voltage, false);
  1106. root = api_add_uint16(root, "PSTemp1", &info->power_temps[0], false);
  1107. root = api_add_uint16(root, "PSTemp2", &info->power_temps[1], false);
  1108. //}
  1109. for (core = 0; core < CTA_CORES; core++) {
  1110. char name[20];
  1111. char str[20];
  1112. double value;
  1113. sprintf(name,"IRVIN%d",core+1);
  1114. value = info->irstat_vin[core]/100.0;
  1115. root = api_add_double(root,name,&value,true);
  1116. sprintf(name,"IRIIN%d",core+1);
  1117. value = info->irstat_iin[core]/100.0;
  1118. root = api_add_double(root,name,&value,true);
  1119. sprintf(name,"IRVOUT%d",core+1);
  1120. value = info->irstat_vout[core]/100.0;
  1121. root = api_add_double(root,name,&value,true);
  1122. sprintf(name,"IRIOUT%d",core+1);
  1123. value = info->irstat_iout[core]/100.0;
  1124. root = api_add_double(root,name,&value,true);
  1125. sprintf(name,"IRTEMP1_%d",core+1);
  1126. value = info->irstat_temp1[core]/100.0;
  1127. root = api_add_double(root,name,&value,true);
  1128. sprintf(name,"IRTEMP2_%d",core+1);
  1129. value = info->irstat_temp2[core]/100.0;
  1130. root = api_add_double(root,name,&value,true);
  1131. sprintf(name,"IRPOUT%d",core+1);
  1132. value = info->irstat_pout[core]/100.0;
  1133. root = api_add_double(root,name,&value,true);
  1134. sprintf(name,"IRPIN%d",core+1);
  1135. value = info->irstat_pin[core]/100.0;
  1136. root = api_add_double(root,name,&value,true);
  1137. sprintf(name,"IREFFICIENCY%d",core+1);
  1138. value = info->irstat_efficiency[core]/100.0;
  1139. root = api_add_double(root,name,&value,true);
  1140. sprintf(name,"IRSTATUS%d",core+1);
  1141. //root = api_add_uint16(root,name,&info->irstat_status[core],false);
  1142. sprintf(str,"0x%04X",info->irstat_status[core]);
  1143. root = api_add_string(root, name, str, true);
  1144. }
  1145. for (i = 0; i < CTA_CORES; i++) {
  1146. sprintf(buf, "CoreFmatch%d", i);
  1147. root = api_add_int16(root, buf, &info->fmatch_errors[i], false);
  1148. }
  1149. return root;
  1150. }
  1151. static void cta_statline_before(char *buf, size_t bufsiz, struct cgpu_info *cointerra)
  1152. {
  1153. struct cointerra_info *info = cointerra->device_data;
  1154. double max_volt = 0;
  1155. int freq = 0, i;
  1156. for (i = 0; i < CTA_CORES; i++) {
  1157. if (info->corevolts[i] > max_volt)
  1158. max_volt = info->corevolts[i];
  1159. if (info->corefreqs[i] > freq)
  1160. freq = info->corefreqs[i];
  1161. }
  1162. max_volt /= 1000;
  1163. tailsprintf(buf, bufsiz, "%3dMHz %3.1fC %3.2fV", freq, cointerra->temp, max_volt);
  1164. }
  1165. struct device_drv cointerra_drv = {
  1166. .drv_id = DRIVER_cointerra,
  1167. .dname = "cointerra",
  1168. .name = "CTA",
  1169. .drv_detect = cta_detect,
  1170. .thread_prepare = cta_prepare,
  1171. .hash_work = hash_queued_work,
  1172. .queue_full = cta_fill,
  1173. .update_work = cta_update_work,
  1174. .scanwork = cta_scanwork,
  1175. .flush_work = cta_wake,
  1176. .get_api_stats = cta_api_stats,
  1177. .get_statline_before = cta_statline_before,
  1178. .thread_shutdown = cta_shutdown,
  1179. .zero_stats = cta_zero_stats,
  1180. .max_diff = 64, // Set it below the actual limit to check nonces
  1181. };