driver-cointerra.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376
  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_INFO, "%s %d: checksum bad",cointerra->drv->name,cointerra->device_id);
  568. }
  569. }
  570. switch (buf[CTA_MSG_TYPE]) {
  571. default:
  572. case CTA_RECV_UNUSED:
  573. applog(LOG_INFO, "%s %d: Unidentified message type %u",
  574. cointerra->drv->name, cointerra->device_id, buf[CTA_MSG_TYPE]);
  575. break;
  576. case CTA_RECV_REQWORK:
  577. cta_parse_reqwork(cointerra, info, buf);
  578. break;
  579. case CTA_RECV_MATCH:
  580. cta_parse_recvmatch(thr, cointerra, info, buf);
  581. break;
  582. case CTA_RECV_WDONE:
  583. applog(LOG_DEBUG, "%s %d: Work done message received",
  584. cointerra->drv->name, cointerra->device_id);
  585. cta_parse_wdone(thr, cointerra, info, buf);
  586. break;
  587. case CTA_RECV_STATREAD:
  588. applog(LOG_DEBUG, "%s %d: Status readings message received",
  589. cointerra->drv->name, cointerra->device_id);
  590. cta_parse_statread(cointerra, info, buf);
  591. break;
  592. case CTA_RECV_STATSET:
  593. applog(LOG_DEBUG, "%s %d: Status settings message received",
  594. cointerra->drv->name, cointerra->device_id);
  595. cta_parse_statset(info, buf);
  596. break;
  597. case CTA_RECV_INFO:
  598. applog(LOG_DEBUG, "%s %d: Info message received",
  599. cointerra->drv->name, cointerra->device_id);
  600. cta_parse_info(cointerra, info, buf);
  601. break;
  602. case CTA_RECV_MSG:
  603. applog(LOG_NOTICE, "%s %d: MSG: %s",
  604. cointerra->drv->name, cointerra->device_id, &buf[CTA_MSG_RECVD]);
  605. break;
  606. case CTA_RECV_RDONE:
  607. cta_parse_rdone(cointerra, info, buf);
  608. break;
  609. case CTA_RECV_STATDEBUG:
  610. cta_parse_debug(info, buf);
  611. break;
  612. case CTA_RECV_IRSTAT:
  613. cta_parse_irstat(info, buf);
  614. break;
  615. }
  616. }
  617. static void *cta_recv_thread(void *arg)
  618. {
  619. struct thr_info *thr = (struct thr_info *)arg;
  620. struct cgpu_info *cointerra = thr->cgpu;
  621. struct cointerra_info *info = cointerra->device_data;
  622. char threadname[24];
  623. int offset = 0;
  624. snprintf(threadname, 24, "cta_recv/%d", cointerra->device_id);
  625. RenameThread(threadname);
  626. while (likely(!cointerra->shutdown)) {
  627. char buf[CTA_READBUF_SIZE];
  628. int amount, err;
  629. if (unlikely(cointerra->usbinfo.nodev)) {
  630. applog(LOG_DEBUG, "%s %d: Device disappeared, disabling recv thread",
  631. cointerra->drv->name, cointerra->device_id);
  632. break;
  633. }
  634. err = usb_read(cointerra, buf + offset, CTA_MSG_SIZE, &amount, C_CTA_READ);
  635. if (err && err != LIBUSB_ERROR_TIMEOUT) {
  636. applog(LOG_ERR, "%s %d: Read error %d, read %d", cointerra->drv->name,
  637. cointerra->device_id, err, amount);
  638. break;
  639. }
  640. offset += amount;
  641. while (offset >= CTA_MSG_SIZE) {
  642. char *msg = mystrstr(buf, offset, cointerra_hdr);
  643. int begin;
  644. if (unlikely(!msg)) {
  645. applog(LOG_WARNING, "%s %d: No message header found, discarding buffer",
  646. cointerra->drv->name, cointerra->device_id);
  647. inc_hw_errors(thr);
  648. /* Save the last byte in case it's the fist
  649. * byte of a header. */
  650. begin = CTA_MSG_SIZE - 1;
  651. offset -= begin;
  652. memmove(buf, buf + begin, offset);
  653. continue;
  654. }
  655. if (unlikely(msg != buf)) {
  656. begin = msg - buf;
  657. applog(LOG_WARNING, "%s %d: Reads out of sync, discarding %d bytes",
  658. cointerra->drv->name, cointerra->device_id, begin);
  659. inc_hw_errors(thr);
  660. offset -= begin;
  661. memmove(buf, msg, offset);
  662. if (offset < CTA_MSG_SIZE)
  663. break;
  664. }
  665. /* We have enough buffer for a full message, parse now */
  666. cta_parse_msg(thr, cointerra, info, msg);
  667. offset -= CTA_MSG_SIZE;
  668. if (offset > 0)
  669. memmove(buf, buf + CTA_MSG_SIZE, offset);
  670. }
  671. }
  672. return NULL;
  673. }
  674. static bool cta_send_msg(struct cgpu_info *cointerra, char *buf)
  675. {
  676. struct cointerra_info *info = cointerra->device_data;
  677. int amount, err;
  678. if (unlikely(cointerra->usbinfo.nodev))
  679. return false;
  680. /* Serialise usb writes to prevent overlap in case multiple threads
  681. * send messages */
  682. mutex_lock(&info->sendlock);
  683. err = usb_write(cointerra, buf, CTA_MSG_SIZE, &amount, C_CTA_WRITE);
  684. mutex_unlock(&info->sendlock);
  685. if (unlikely(err || amount != CTA_MSG_SIZE)) {
  686. applog(LOG_ERR, "%s %d: Write error %d, wrote %d of %d", cointerra->drv->name,
  687. cointerra->device_id, err, amount, CTA_MSG_SIZE);
  688. return false;
  689. }
  690. return true;
  691. }
  692. static bool cta_prepare(struct thr_info *thr)
  693. {
  694. struct cgpu_info *cointerra = thr->cgpu;
  695. struct cointerra_info *info = calloc(sizeof(struct cointerra_info), 1);
  696. char buf[CTA_MSG_SIZE];
  697. if (unlikely(cointerra->usbinfo.nodev))
  698. return false;
  699. if (unlikely(!info))
  700. quit(1, "Failed to calloc info in cta_detect_one");
  701. cointerra->device_data = info;
  702. /* Nominally set a requested value when starting, preempting the need
  703. * for a req-work message. */
  704. info->requested = CTA_MAX_QUEUE;
  705. info->thr = thr;
  706. mutex_init(&info->lock);
  707. mutex_init(&info->sendlock);
  708. if (unlikely(pthread_cond_init(&info->wake_cond, NULL)))
  709. quit(1, "Failed to create cta pthread cond");
  710. cgsem_init(&info->reset_sem);
  711. if (pthread_create(&info->read_thr, NULL, cta_recv_thread, (void *)thr))
  712. quit(1, "Failed to create cta_recv_thread");
  713. /* Request a single status setting message */
  714. cta_gen_message(buf, CTA_SEND_REQUEST);
  715. msg_from_hu16(buf, CTA_REQ_MSGTYPE, CTA_RECV_STATSET);
  716. msg_from_hu16(buf, CTA_REQ_INTERVAL, 0);
  717. if (!cta_send_msg(cointerra, buf))
  718. return false;
  719. /* Request status debug messages every 60 seconds */
  720. cta_gen_message(buf, CTA_SEND_REQUEST);
  721. msg_from_hu16(buf, CTA_REQ_MSGTYPE, CTA_RECV_STATDEBUG);
  722. msg_from_hu16(buf, CTA_REQ_INTERVAL, 6000);
  723. if (!cta_send_msg(cointerra, buf))
  724. return false;
  725. cgtime(&info->core_hash_start);
  726. return true;
  727. }
  728. static void cta_send_reset(struct cgpu_info *cointerra, struct cointerra_info *info,
  729. uint8_t reset_type, uint8_t diffbits);
  730. static void cta_flush_work(struct cgpu_info *cointerra);
  731. /* *_fill and *_scanwork are serialised wrt to each other */
  732. static bool cta_fill(struct cgpu_info *cointerra)
  733. {
  734. struct cointerra_info *info = cointerra->device_data;
  735. bool ret = true;
  736. char buf[CTA_MSG_SIZE];
  737. struct work *work = NULL;
  738. unsigned short nroll_limit;
  739. uint32_t swab[8];
  740. uint8_t diffbits;
  741. //applog(LOG_WARNING, "%s %d: cta_fill %d", cointerra->drv->name, cointerra->device_id,__LINE__);
  742. if (unlikely(info->thr->work_restart))
  743. cta_flush_work(cointerra);
  744. mutex_lock(&info->lock);
  745. if (!info->requested)
  746. goto out_unlock;
  747. work = get_queued(cointerra);
  748. if (unlikely(!work)) {
  749. ret = false;
  750. goto out_unlock;
  751. }
  752. if (--info->requested > 0)
  753. ret = false;
  754. /* It does not matter what endian this uint16_t is since it will be
  755. * the same value on sending to the MC as returning in match/done. This
  756. * will automatically wrap as a uint16_t. It cannot be zero for the MCU
  757. * though. */
  758. if (unlikely(++info->work_id == 0))
  759. info->work_id = 1;
  760. work->subid = info->work_id;
  761. diffbits = diff_to_bits(work->device_diff);
  762. cta_gen_message(buf, CTA_SEND_WORK);
  763. memcpy(buf + CTA_DRIVER_TAG, &info->work_id, 2);
  764. flip32(swab, work->midstate);
  765. memcpy(buf + CTA_WORK_MIDSTATE, swab, 32);
  766. flip12(swab, &work->data[64]);
  767. memcpy(buf + CTA_WORK_DATA, swab, 12);
  768. nroll_limit = htole16(work->drv_rolllimit);
  769. memcpy(buf + CTA_WORK_NROLL, &nroll_limit, 2);
  770. memcpy(buf + CTA_WORK_DIFFBITS, &diffbits, 1);
  771. out_unlock:
  772. mutex_unlock(&info->lock);
  773. if (work) {
  774. cgtime(&work->tv_work_start);
  775. applog(LOG_DEBUG, "%s %d: Sending work job_id %s work_id %u", cointerra->drv->name,
  776. cointerra->device_id, work->job_id, work->subid);
  777. if (unlikely(!cta_send_msg(cointerra, buf))) {
  778. work_completed(cointerra, work);
  779. applog(LOG_INFO, "%s %d: Failed to send work",
  780. cointerra->drv->name, cointerra->device_id);
  781. /* The device will fail after this */
  782. }
  783. }
  784. return ret;
  785. }
  786. static void cta_send_reset(struct cgpu_info *cointerra, struct cointerra_info *info,
  787. uint8_t reset_type, uint8_t diffbits)
  788. {
  789. char buf[CTA_MSG_SIZE];
  790. int ret, retries = 0;
  791. /* Clear any accumulated messages in case we've gotten out of sync. */
  792. cgsem_reset(&info->reset_sem);
  793. resend:
  794. cta_gen_message(buf, CTA_SEND_RESET);
  795. buf[CTA_RESET_TYPE] = reset_type;
  796. buf[CTA_RESET_LOAD] = opt_cta_load ? opt_cta_load : 255;
  797. buf[CTA_RESET_PSLOAD] = opt_ps_load;
  798. applog(LOG_INFO, "%s %d: Sending Reset type %u with diffbits %u", cointerra->drv->name,
  799. cointerra->device_id, reset_type, diffbits);
  800. cta_send_msg(cointerra, buf);
  801. /* Wait for read thread to parse a reset message and signal us we may
  802. * return to submitting other messages. Use a timeout in case we have
  803. * a problem and the reset done message never returns. */
  804. if (reset_type == CTA_RESET_NEW) {
  805. ret = cgsem_mswait(&info->reset_sem, CTA_RESET_TIMEOUT);
  806. if (ret) {
  807. if (++retries < 5) {
  808. applog(LOG_INFO, "%s %d: Timed out waiting for reset done msg, retrying",
  809. cointerra->drv->name, cointerra->device_id);
  810. goto resend;
  811. }
  812. applog(LOG_WARNING, "%s %d: Timed out waiting for reset done msg",
  813. cointerra->drv->name, cointerra->device_id);
  814. }
  815. /* Good place to flush any work we have */
  816. flush_queue(cointerra);
  817. }
  818. }
  819. static void cta_flush_work(struct cgpu_info *cointerra)
  820. {
  821. struct cointerra_info *info = cointerra->device_data;
  822. applog(LOG_INFO, "%s %d: cta_flush_work %d", cointerra->drv->name, cointerra->device_id,
  823. __LINE__);
  824. cta_send_reset(cointerra, info, CTA_RESET_NEW, 0);
  825. info->thr->work_restart = false;
  826. }
  827. static void cta_update_work(struct cgpu_info *cointerra)
  828. {
  829. struct cointerra_info *info = cointerra->device_data;
  830. applog(LOG_INFO, "%s %d: Update work", cointerra->drv->name, cointerra->device_id);
  831. cta_send_reset(cointerra, info, CTA_RESET_UPDATE, 0);
  832. }
  833. static void cta_zero_corehashes(struct cointerra_info *info)
  834. {
  835. int i;
  836. for (i = 0; i < CTA_CORES; i++)
  837. info->tot_core_hashes[i] = 0;
  838. cgtime(&info->core_hash_start);
  839. }
  840. /* Send per core hashrate calculations at regular intervals ~every 5 minutes */
  841. static void cta_send_corehashes(struct cgpu_info *cointerra, struct cointerra_info *info,
  842. double corehash_time)
  843. {
  844. uint16_t core_ghs[CTA_CORES];
  845. double k[CTA_CORES];
  846. char buf[CTA_MSG_SIZE];
  847. int i, offset;
  848. for (i = 0; i < CTA_CORES; i++) {
  849. k[i] = (double)info->tot_core_hashes[i];
  850. #if 0
  851. k[i] /= ((double)32 * (double)0x100000000ull);
  852. k[i] = sqrt(k[i]) + 1;
  853. k[i] *= k[i];
  854. k[i] = k[i] * 32 * ((double)0x100000000ull );
  855. #endif
  856. k[i] /= ((double)1000000000 * corehash_time);
  857. core_ghs[i] = k[i];
  858. }
  859. cta_gen_message(buf, CTA_SEND_COREHASHRATE);
  860. offset = CTA_CORE_HASHRATES;
  861. for (i = 0; i < CTA_CORES; i++) {
  862. msg_from_hu16(buf, offset, core_ghs[i]);
  863. offset += 2; // uint16_t
  864. }
  865. cta_send_msg(cointerra, buf);
  866. }
  867. static int64_t cta_scanwork(struct thr_info *thr)
  868. {
  869. struct cgpu_info *cointerra = thr->cgpu;
  870. struct cointerra_info *info = cointerra->device_data;
  871. double corehash_time;
  872. struct timeval now;
  873. uint32_t runtime;
  874. int64_t hashes;
  875. applog(LOG_DEBUG, "%s %d: cta_scanwork %d", cointerra->drv->name, cointerra->device_id,__LINE__);
  876. if (unlikely(cointerra->usbinfo.nodev)) {
  877. hashes = -1;
  878. goto out;
  879. }
  880. cgtime(&now);
  881. if (unlikely(thr->work_restart)) {
  882. applog(LOG_INFO, "%s %d: Flush work line %d",
  883. cointerra->drv->name, cointerra->device_id,__LINE__);
  884. cta_flush_work(cointerra);
  885. } else {
  886. struct timespec abstime, tsdiff = {0, 500000000};
  887. time_t now_t;
  888. int i;
  889. timeval_to_spec(&abstime, &now);
  890. timeraddspec(&abstime, &tsdiff);
  891. /* Discard work that was started more than 5 minutes ago as
  892. * a safety precaution backup in case the hardware failed to
  893. * return a work done message for some work items. */
  894. age_queued_work(cointerra, 300.0);
  895. /* Each core should be 1.7MH so at max diff of 32 should
  896. * average a share every ~80 seconds.Use this opportunity to
  897. * unset the bits in any pipes that have not returned a valid
  898. * nonce for over 30 full nonce ranges or 2400s. */
  899. now_t = time(NULL);
  900. for (i = 0; i < 1024; i++) {
  901. if (unlikely(now_t > info->last_pipe_nonce[i] + 2400)) {
  902. int bitchar = i / 8, bitbit = i % 8;
  903. info->pipe_bitmap[bitchar] &= ~(0x80 >> bitbit);
  904. }
  905. }
  906. /* Sleep for up to 0.5 seconds, waking if we need work or
  907. * have received a restart message. */
  908. mutex_lock(&info->lock);
  909. pthread_cond_timedwait(&info->wake_cond, &info->lock, &abstime);
  910. mutex_unlock(&info->lock);
  911. if (thr->work_restart) {
  912. applog(LOG_INFO, "%s %d: Flush work line %d",
  913. cointerra->drv->name, cointerra->device_id,__LINE__);
  914. cta_flush_work(cointerra);
  915. }
  916. }
  917. corehash_time = tdiff(&now, &info->core_hash_start);
  918. if (corehash_time > 300) {
  919. cta_send_corehashes(cointerra, info, corehash_time);
  920. cta_zero_corehashes(info);
  921. }
  922. mutex_lock(&info->lock);
  923. hashes = info->share_hashes;
  924. info->tot_share_hashes += info->share_hashes;
  925. info->tot_calc_hashes += info->hashes;
  926. runtime = cgpu_runtime(thr->cgpu);
  927. runtime /= 30;
  928. info->old_hashes[runtime % 32] = info->tot_calc_hashes;
  929. info->hashes = info->share_hashes = 0;
  930. mutex_unlock(&info->lock);
  931. if (unlikely(cointerra->usbinfo.nodev))
  932. hashes = -1;
  933. out:
  934. return hashes;
  935. }
  936. /* This is used for a work restart. We don't actually perform the work restart
  937. * here but wake up the scanwork loop if it's waiting on the conditional so
  938. * that it can test for the restart message. */
  939. static void cta_wake(struct cgpu_info *cointerra)
  940. {
  941. struct cointerra_info *info = cointerra->device_data;
  942. mutex_lock(&info->lock);
  943. pthread_cond_signal(&info->wake_cond);
  944. mutex_unlock(&info->lock);
  945. }
  946. static void cta_shutdown(struct thr_info *thr)
  947. {
  948. struct cgpu_info *cointerra = thr->cgpu;
  949. cta_close(cointerra);
  950. }
  951. static void cta_zero_stats(struct cgpu_info *cointerra)
  952. {
  953. struct cointerra_info *info = cointerra->device_data;
  954. int i;
  955. info->tot_calc_hashes = 0;
  956. info->tot_reset_hashes = info->tot_hashes;
  957. info->tot_share_hashes = 0;
  958. cta_zero_corehashes(info);
  959. for (i = 0; i < 16 * 2; i++)
  960. info->old_hashes[i] = 0;
  961. }
  962. static int bits_set(char v)
  963. {
  964. int c;
  965. for (c = 0; v; c++)
  966. v &= v - 1;
  967. return c;
  968. }
  969. static struct api_data *cta_api_stats(struct cgpu_info *cgpu)
  970. {
  971. struct api_data *root = NULL;
  972. struct cointerra_info *info = cgpu->device_data;
  973. double dev_runtime = cgpu_runtime(cgpu);
  974. int i, asic, core, coreno = 0;
  975. struct timeval now;
  976. char bitmaphex[36];
  977. uint64_t ghs, val;
  978. char buf[64];
  979. uint32_t runtime = cgpu_runtime(cgpu);
  980. /* Info data */
  981. root = api_add_uint16(root, "HW Revision", &info->hwrev, false);
  982. root = api_add_uint32(root, "Serial", &info->serial, false);
  983. root = api_add_uint8(root, "Asics", &info->asics, false);
  984. root = api_add_uint8(root, "Dies", &info->dies, false);
  985. root = api_add_uint16(root, "Cores", &info->cores, false);
  986. root = api_add_uint8(root, "Board number", &info->board_number, false);
  987. sprintf(buf, "%u.%u.%u", info->fwrev[0], info->fwrev[1], info->fwrev[2]);
  988. root = api_add_string(root, "FW Revision", buf, true);
  989. sprintf(buf, "%04u-%02u-%02u", info->fw_year, info->fw_month, info->fw_day);
  990. root = api_add_string(root, "FW Date", buf, true);
  991. root = api_add_uint8(root, "Init diffbits", &info->init_diffbits, false);
  992. root = api_add_uint8(root, "Min diffbits", &info->min_diffbits, false);
  993. root = api_add_uint8(root, "Max diffbits", &info->max_diffbits, false);
  994. /* Status readings */
  995. for (i = 0; i < CTA_CORES; i++) {
  996. sprintf(buf, "CoreTemp%d", i);
  997. root = api_add_int16(root, buf, &info->coretemp[i], false);
  998. }
  999. root = api_add_int16(root, "Ambient Low", &info->ambtemp_low, false);
  1000. root = api_add_int16(root, "Ambient Avg", &info->ambtemp_avg, false);
  1001. root = api_add_int16(root, "Ambient High", &info->ambtemp_high, false);
  1002. for (i = 0; i < CTA_PUMPS; i++) {
  1003. sprintf(buf, "PumpRPM%d", i);
  1004. root = api_add_uint16(root, buf, &info->pump_tachs[i], false);
  1005. }
  1006. for (i = 0; i < CTA_FANS; i++) {
  1007. sprintf(buf, "FanRPM%d", i);
  1008. root = api_add_uint16(root, buf, &info->fan_tachs[i], false);
  1009. }
  1010. for (i = 0; i < CTA_CORES; i++) {
  1011. sprintf(buf, "CoreFreqs%d", i);
  1012. root = api_add_uint16(root, buf, &info->corefreqs[i], false);
  1013. }
  1014. for (i = 0; i < CTA_CORES; i++) {
  1015. sprintf(buf, "CoreVolts%d", i);
  1016. root = api_add_uint16(root, buf, &info->corevolts[i], false);
  1017. }
  1018. root = api_add_uint16(root, "Volts3.3", &info->volts33, false);
  1019. root = api_add_uint16(root, "Volts12", &info->volts12, false);
  1020. root = api_add_uint16(root, "Inactive", &info->inactive, false);
  1021. root = api_add_uint16(root, "Active", &info->active, false);
  1022. /* Status settings */
  1023. for (i = 0; i < CTA_CORES; i++) {
  1024. sprintf(buf, "CorePerfMode%d", i);
  1025. root = api_add_uint8(root, buf, &info->coreperf[i], false);
  1026. }
  1027. for (i = 0; i < CTA_FANS; i++) {
  1028. sprintf(buf, "FanSpeed%d", i);
  1029. root = api_add_uint8(root, buf, &info->fanspeed[i], false);
  1030. }
  1031. root = api_add_uint8(root, "DiesActive", &info->dies_active, false);
  1032. for (i = 0; i < CTA_CORES; i++) {
  1033. sprintf(buf, "PipesEnabled%d", i);
  1034. root = api_add_uint8(root, buf, &info->pipes_enabled[i], false);
  1035. }
  1036. /* Status debug */
  1037. root = api_add_int(root, "Underruns", &info->tot_underruns, false);
  1038. for (i = 0; i < CTA_CORES; i++) {
  1039. sprintf(buf, "HWErrors%d", i);
  1040. root = api_add_uint16(root, buf, &info->tot_hw_errors[i], false);
  1041. }
  1042. ghs = info->tot_calc_hashes / dev_runtime;
  1043. root = api_add_uint64(root, "Calc hashrate", &ghs, true);
  1044. ghs = (info->tot_hashes - info->tot_reset_hashes) / dev_runtime;
  1045. root = api_add_uint64(root, "Hashrate", &ghs, true);
  1046. //root = api_add_uint64(root, "cgminer 15m Hashrate", &cgpu->rolling15, true);
  1047. // get runtime in 30 second steps
  1048. runtime = runtime / 30;
  1049. // store the current hashes
  1050. info->old_hashes[runtime%32] = info->tot_calc_hashes;
  1051. // calc the 15 minute average hashrate
  1052. ghs = (info->old_hashes[(runtime+31)%32] - info->old_hashes[(runtime+1)%32])/(15*60);
  1053. root = api_add_uint64(root, "15m Hashrate", &ghs, true);
  1054. ghs = info->tot_share_hashes / dev_runtime;
  1055. root = api_add_uint64(root, "Share hashrate", &ghs, true);
  1056. root = api_add_uint64(root, "Total calc hashes", &info->tot_calc_hashes, false);
  1057. ghs = info->tot_hashes - info->tot_reset_hashes;
  1058. root = api_add_uint64(root, "Total hashes", &ghs, true);
  1059. root = api_add_uint64(root, "Total raw hashes", &info->tot_hashes, false);
  1060. root = api_add_uint64(root, "Total share hashes", &info->tot_share_hashes, false);
  1061. root = api_add_uint64(root, "Total flushed hashes", &info->tot_flushed_hashes, false);
  1062. val = cgpu->diff_accepted * 0x100000000ull;
  1063. root = api_add_uint64(root, "Accepted hashes", &val, true);
  1064. ghs = val / dev_runtime;
  1065. root = api_add_uint64(root, "Accepted hashrate", &ghs, true);
  1066. val = cgpu->diff_rejected * 0x100000000ull;
  1067. root = api_add_uint64(root, "Rejected hashes", &val, true);
  1068. ghs = val / dev_runtime;
  1069. root = api_add_uint64(root, "Rejected hashrate", &ghs, true);
  1070. cgtime(&now);
  1071. dev_runtime = tdiff(&now, &info->core_hash_start);
  1072. if (dev_runtime < 1)
  1073. dev_runtime = 1;
  1074. for (i = 0; i < CTA_CORES; i++) {
  1075. sprintf(buf, "Core%d hashrate", i);
  1076. ghs = info->tot_core_hashes[i] / dev_runtime;
  1077. root = api_add_uint64(root, buf, &ghs, true);
  1078. }
  1079. root = api_add_uint32(root, "Uptime",&info->uptime,false);
  1080. for (asic = 0; asic < 2; asic++) {
  1081. for (core = 0; core < 4; core++) {
  1082. char bitmapcount[40], asiccore[12];
  1083. int count = 0;
  1084. sprintf(asiccore, "Asic%dCore%d", asic, core);
  1085. __bin2hex(bitmaphex, &info->pipe_bitmap[coreno], 16);
  1086. for (i = coreno; i < coreno + 16; i++)
  1087. count += bits_set(info->pipe_bitmap[i]);
  1088. snprintf(bitmapcount, 40, "%d:%s", count, bitmaphex);
  1089. root = api_add_string(root, asiccore, bitmapcount, true);
  1090. coreno += 16;
  1091. }
  1092. }
  1093. root = api_add_uint8(root, "AV", &info->autovoltage, false);
  1094. root = api_add_uint8(root, "Power Supply Percent", &info->current_ps_percent, false);
  1095. //if (info->power_used != 0) {
  1096. {
  1097. double value = info->power_used/100.0;
  1098. value *= (info->power_voltage/100.0);
  1099. root = api_add_double(root, "Power Used", &value, true);
  1100. }
  1101. root = api_add_uint16(root, "IOUT", &info->power_used, false);
  1102. root = api_add_uint16(root, "VOUT", &info->power_voltage, false);
  1103. root = api_add_uint16(root, "IIN", &info->ipower_used, false);
  1104. root = api_add_uint16(root, "VIN", &info->ipower_voltage, false);
  1105. root = api_add_uint16(root, "PSTemp1", &info->power_temps[0], false);
  1106. root = api_add_uint16(root, "PSTemp2", &info->power_temps[1], false);
  1107. //}
  1108. for (core = 0; core < CTA_CORES; core++) {
  1109. char name[20];
  1110. char str[20];
  1111. double value;
  1112. sprintf(name,"IRVIN%d",core+1);
  1113. value = info->irstat_vin[core]/100.0;
  1114. root = api_add_double(root,name,&value,true);
  1115. sprintf(name,"IRIIN%d",core+1);
  1116. value = info->irstat_iin[core]/100.0;
  1117. root = api_add_double(root,name,&value,true);
  1118. sprintf(name,"IRVOUT%d",core+1);
  1119. value = info->irstat_vout[core]/100.0;
  1120. root = api_add_double(root,name,&value,true);
  1121. sprintf(name,"IRIOUT%d",core+1);
  1122. value = info->irstat_iout[core]/100.0;
  1123. root = api_add_double(root,name,&value,true);
  1124. sprintf(name,"IRTEMP1_%d",core+1);
  1125. value = info->irstat_temp1[core]/100.0;
  1126. root = api_add_double(root,name,&value,true);
  1127. sprintf(name,"IRTEMP2_%d",core+1);
  1128. value = info->irstat_temp2[core]/100.0;
  1129. root = api_add_double(root,name,&value,true);
  1130. sprintf(name,"IRPOUT%d",core+1);
  1131. value = info->irstat_pout[core]/100.0;
  1132. root = api_add_double(root,name,&value,true);
  1133. sprintf(name,"IRPIN%d",core+1);
  1134. value = info->irstat_pin[core]/100.0;
  1135. root = api_add_double(root,name,&value,true);
  1136. sprintf(name,"IREFFICIENCY%d",core+1);
  1137. value = info->irstat_efficiency[core]/100.0;
  1138. root = api_add_double(root,name,&value,true);
  1139. sprintf(name,"IRSTATUS%d",core+1);
  1140. //root = api_add_uint16(root,name,&info->irstat_status[core],false);
  1141. sprintf(str,"0x%04X",info->irstat_status[core]);
  1142. root = api_add_string(root, name, str, true);
  1143. }
  1144. for (i = 0; i < CTA_CORES; i++) {
  1145. sprintf(buf, "CoreFmatch%d", i);
  1146. root = api_add_uint16(root, buf, &info->fmatch_errors[i], false);
  1147. }
  1148. return root;
  1149. }
  1150. static void cta_statline_before(char *buf, size_t bufsiz, struct cgpu_info *cointerra)
  1151. {
  1152. struct cointerra_info *info = cointerra->device_data;
  1153. double max_volt = 0;
  1154. int freq = 0, i;
  1155. for (i = 0; i < CTA_CORES; i++) {
  1156. if (info->corevolts[i] > max_volt)
  1157. max_volt = info->corevolts[i];
  1158. if (info->corefreqs[i] > freq)
  1159. freq = info->corefreqs[i];
  1160. }
  1161. max_volt /= 1000;
  1162. tailsprintf(buf, bufsiz, "%3dMHz %3.1fC %3.2fV", freq, cointerra->temp, max_volt);
  1163. }
  1164. struct device_drv cointerra_drv = {
  1165. .drv_id = DRIVER_cointerra,
  1166. .dname = "cointerra",
  1167. .name = "CTA",
  1168. .drv_detect = cta_detect,
  1169. .thread_prepare = cta_prepare,
  1170. .hash_work = hash_queued_work,
  1171. .queue_full = cta_fill,
  1172. .update_work = cta_update_work,
  1173. .scanwork = cta_scanwork,
  1174. .flush_work = cta_wake,
  1175. .get_api_stats = cta_api_stats,
  1176. .get_statline_before = cta_statline_before,
  1177. .thread_shutdown = cta_shutdown,
  1178. .zero_stats = cta_zero_stats,
  1179. .max_diff = 64, // Set it below the actual limit to check nonces
  1180. };