driver-avalonlc3.c 80 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777
  1. /*
  2. * Copyright 2016-2017 Mikeqin <Fengling.Qin@gmail.com>
  3. * Copyright 2016 Con Kolivas <kernel@kolivas.org>
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the Free
  7. * Software Foundation; either version 3 of the License, or (at your option)
  8. * any later version. See COPYING for more details.
  9. */
  10. #include <math.h>
  11. #include "config.h"
  12. #include "miner.h"
  13. #include "driver-avalonlc3.h"
  14. #include "crc.h"
  15. #include "sha2.h"
  16. #include "hexdump.c"
  17. #define get_fan_pwm(v) (AVALC3_PWM_MAX - (v) * AVALC3_PWM_MAX / 100)
  18. int opt_avalonlc3_temp_target = AVALC3_DEFAULT_TEMP_TARGET;
  19. int opt_avalonlc3_fan_min = AVALC3_DEFAULT_FAN_MIN;
  20. int opt_avalonlc3_fan_max = AVALC3_DEFAULT_FAN_MAX;
  21. int opt_avalonlc3_voltage_level = AVALC3_INVALID_VOLTAGE_LEVEL;
  22. int opt_avalonlc3_voltage_level_offset = AVALC3_DEFAULT_VOLTAGE_LEVEL_OFFSET;
  23. int opt_avalonlc3_asic_otp = AVALC3_INVALID_ASIC_OTP;
  24. static uint8_t opt_avalonlc3_cycle_hit_flag;
  25. int opt_avalonlc3_freq[AVALC3_DEFAULT_PLL_CNT] =
  26. {
  27. AVALC3_DEFAULT_FREQUENCY,
  28. AVALC3_DEFAULT_FREQUENCY,
  29. AVALC3_DEFAULT_FREQUENCY,
  30. AVALC3_DEFAULT_FREQUENCY
  31. };
  32. int opt_avalonlc3_freq_sel = AVALC3_DEFAULT_FREQUENCY_SEL;
  33. int opt_avalonlc3_polling_delay = AVALC3_DEFAULT_POLLING_DELAY;
  34. int opt_avalonlc3_aucspeed = AVALC3_AUC_SPEED;
  35. int opt_avalonlc3_aucxdelay = AVALC3_AUC_XDELAY;
  36. int opt_avalonlc3_smart_speed = AVALC3_DEFAULT_SMART_SPEED;
  37. /*
  38. * smart speed have 2 modes
  39. * 1. auto speed by A3210 chips
  40. * 2. option 1 + adjust by average frequency
  41. */
  42. bool opt_avalonlc3_iic_detect = AVALC3_DEFAULT_IIC_DETECT;
  43. uint32_t opt_avalonlc3_th_pass = AVALC3_DEFAULT_TH_PASS;
  44. uint32_t opt_avalonlc3_th_fail = AVALC3_DEFAULT_TH_FAIL;
  45. uint32_t opt_avalonlc3_th_init = AVALC3_DEFAULT_TH_INIT;
  46. uint32_t opt_avalonlc3_th_ms = AVALC3_DEFAULT_TH_MS;
  47. uint32_t opt_avalonlc3_th_timeout = AVALC3_DEFAULT_TH_TIMEOUT;
  48. uint32_t opt_avalonlc3_th_add = AVALC3_DEFAULT_TH_ADD;
  49. uint32_t opt_avalonlc3_nonce_mask = AVALC3_DEFAULT_NONCE_MASK;
  50. uint32_t opt_avalonlc3_nonce_check = AVALC3_DEFAULT_NONCE_CHECK;
  51. uint32_t opt_avalonlc3_mux_l2h = AVALC3_DEFAULT_MUX_L2H;
  52. uint32_t opt_avalonlc3_mux_h2l = AVALC3_DEFAULT_MUX_H2L;
  53. uint32_t opt_avalonlc3_h2ltime0_spd = AVALC3_DEFAULT_H2LTIME0_SPD;
  54. uint32_t opt_avalonlc3_roll_enable = AVALC3_DEFAULT_ROLL_ENABLE;
  55. uint32_t opt_avalonlc3_spdlow = AVALC3_DEFAULT_SPDLOW;
  56. uint32_t opt_avalonlc3_spdhigh = AVALC3_DEFAULT_SPDHIGH;
  57. uint32_t opt_avalonlc3_tbase = AVALC3_DEFAULT_TBASE;
  58. uint32_t opt_avalonlc3_pid_p = AVALC3_DEFAULT_PID_P;
  59. uint32_t opt_avalonlc3_pid_i = AVALC3_DEFAULT_PID_I;
  60. uint32_t opt_avalonlc3_pid_d = AVALC3_DEFAULT_PID_D;
  61. uint32_t cpm_table[] =
  62. {
  63. 0x04400000,
  64. 0x04000000,
  65. 0x008ffbe1,
  66. 0x0097fde1,
  67. 0x009fffe1,
  68. 0x009ddf61,
  69. 0x009dcf61,
  70. 0x009f47c1,
  71. 0x009fbfe1,
  72. 0x009f37c1,
  73. 0x009daf61,
  74. 0x009b26c1,
  75. 0x009da761,
  76. 0x00999e61,
  77. 0x009b9ee1,
  78. 0x009d9f61,
  79. 0x009f9fe1,
  80. 0x00991641,
  81. 0x009a96a1,
  82. 0x009c1701,
  83. 0x009d9761,
  84. 0x009f17c1,
  85. 0x00958d61,
  86. 0x00968da1,
  87. 0x00978de1,
  88. 0x00988e21,
  89. 0x00998e61,
  90. 0x009a8ea1,
  91. 0x009b8ee1,
  92. 0x009c8f21,
  93. 0x009d8f61,
  94. 0x009e8fa1,
  95. 0x009f8fe1,
  96. 0x00900401,
  97. 0x00908421,
  98. 0x00910441,
  99. 0x00918461,
  100. 0x00920481,
  101. 0x009284a1,
  102. 0x009304c1,
  103. 0x009384e1,
  104. 0x00940501,
  105. 0x00948521,
  106. 0x00950541,
  107. 0x00958561,
  108. 0x00960581,
  109. 0x009685a1,
  110. 0x009705c1,
  111. 0x009785e1
  112. };
  113. struct avalonlc3_dev_description avalonlc3_dev_table[] = {
  114. {
  115. "LC3",
  116. 0xac3,
  117. 4,
  118. 34,
  119. 5,
  120. {
  121. AVALC3_DEFAULT_FREQUENCY_0M,
  122. AVALC3_DEFAULT_FREQUENCY_0M,
  123. AVALC3_DEFAULT_FREQUENCY_0M,
  124. AVALC3_DEFAULT_FREQUENCY_500M
  125. }
  126. }
  127. };
  128. static uint32_t api_get_cpm(uint32_t freq)
  129. {
  130. return cpm_table[freq / 25];
  131. }
  132. static uint32_t encode_voltage(int volt_level)
  133. {
  134. if (volt_level > AVALC3_DEFAULT_VOLTAGE_LEVEL_MAX)
  135. volt_level = AVALC3_DEFAULT_VOLTAGE_LEVEL_MAX;
  136. else if (volt_level < AVALC3_DEFAULT_VOLTAGE_LEVEL_MIN)
  137. volt_level = AVALC3_DEFAULT_VOLTAGE_LEVEL_MIN;
  138. return volt_level;
  139. }
  140. static double decode_pvt_temp(uint16_t pvt_code)
  141. {
  142. double g = 60.0;
  143. double h = 200.0;
  144. double cal5 = 4094.0;
  145. double j = -0.1;
  146. double fclkm = 6.25;
  147. /* Mode2 temperature equation */
  148. return g + h * (pvt_code / cal5 - 0.5) + j * fclkm;
  149. }
  150. static uint32_t decode_pvt_volt(uint16_t volt)
  151. {
  152. double vref = 1.20;
  153. double r = 16384.0; /* 2 ** 14 */
  154. double c;
  155. c = vref / 5.0 * (6 * (volt - 0.5) / r - 1.0);
  156. if (c < 0)
  157. c = 0;
  158. return c * 1000;
  159. }
  160. #define SERIESRESISTOR 10000
  161. #define THERMISTORNOMINAL 10000
  162. #define BCOEFFICIENT 3500
  163. #define TEMPERATURENOMINAL 25
  164. float decode_auc_temp(int value)
  165. {
  166. float ret, resistance;
  167. if (!((value > 0) && (value < 33000)))
  168. return -273;
  169. resistance = (3.3 * 10000 / value) - 1;
  170. resistance = SERIESRESISTOR / resistance;
  171. ret = resistance / THERMISTORNOMINAL;
  172. ret = logf(ret);
  173. ret /= BCOEFFICIENT;
  174. ret += 1.0 / (TEMPERATURENOMINAL + 273.15);
  175. ret = 1.0 / ret;
  176. ret -= 273.15;
  177. return ret;
  178. }
  179. #define UNPACK32(x, str) \
  180. { \
  181. *((str) + 3) = (uint8_t) ((x) ); \
  182. *((str) + 2) = (uint8_t) ((x) >> 8); \
  183. *((str) + 1) = (uint8_t) ((x) >> 16); \
  184. *((str) + 0) = (uint8_t) ((x) >> 24); \
  185. }
  186. static inline void sha256_prehash(const unsigned char *message, unsigned int len, unsigned char *digest)
  187. {
  188. int i;
  189. sha256_ctx ctx;
  190. sha256_init(&ctx);
  191. sha256_update(&ctx, message, len);
  192. for (i = 0; i < 8; i++)
  193. UNPACK32(ctx.h[i], &digest[i << 2]);
  194. }
  195. char *set_avalonlc3_fan(char *arg)
  196. {
  197. int val1, val2, ret;
  198. ret = sscanf(arg, "%d-%d", &val1, &val2);
  199. if (ret < 1)
  200. return "No value passed to avalonlc3-fan";
  201. if (ret == 1)
  202. val2 = val1;
  203. if (val1 < 0 || val1 > 100 || val2 < 0 || val2 > 100 || val2 < val1)
  204. return "Invalid value passed to avalonlc3-fan";
  205. opt_avalonlc3_fan_min = val1;
  206. opt_avalonlc3_fan_max = val2;
  207. return NULL;
  208. }
  209. char *set_avalonlc3_freq(char *arg)
  210. {
  211. int val[AVALC3_DEFAULT_PLL_CNT];
  212. char *colon, *data;
  213. int i;
  214. if (!(*arg))
  215. return NULL;
  216. data = arg;
  217. memset(val, 0, sizeof(val));
  218. for (i = 0; i < AVALC3_DEFAULT_PLL_CNT; i++) {
  219. colon = strchr(data, ':');
  220. if (colon)
  221. *(colon++) = '\0';
  222. else {
  223. /* last value */
  224. if (*data) {
  225. val[i] = atoi(data);
  226. if (val[i] > AVALC3_DEFAULT_FREQUENCY_MAX)
  227. return "Invalid value passed to avalonlc3-freq";
  228. }
  229. break;
  230. }
  231. if (*data) {
  232. val[i] = atoi(data);
  233. if (val[i] > AVALC3_DEFAULT_FREQUENCY_MAX)
  234. return "Invalid value passed to avalonlc3-freq";
  235. }
  236. data = colon;
  237. }
  238. for (i = 0; i < AVALC3_DEFAULT_PLL_CNT; i++)
  239. opt_avalonlc3_freq[i] = val[i];
  240. return NULL;
  241. }
  242. char *set_avalonlc3_voltage_level(char *arg)
  243. {
  244. int val, ret;
  245. ret = sscanf(arg, "%d", &val);
  246. if (ret < 1)
  247. return "No value passed to avalonlc3-voltage-level";
  248. if (val < AVALC3_DEFAULT_VOLTAGE_LEVEL_MIN || val > AVALC3_DEFAULT_VOLTAGE_LEVEL_MAX)
  249. return "Invalid value passed to avalonlc3-voltage-level";
  250. opt_avalonlc3_voltage_level = val;
  251. return NULL;
  252. }
  253. char *set_avalonlc3_voltage_level_offset(char *arg)
  254. {
  255. int val, ret;
  256. ret = sscanf(arg, "%d", &val);
  257. if (ret < 1)
  258. return "No value passed to avalonlc3-voltage-level-offset";
  259. if (val < AVALC3_DEFAULT_VOLTAGE_LEVEL_OFFSET_MIN || val > AVALC3_DEFAULT_VOLTAGE_LEVEL_OFFSET_MAX)
  260. return "Invalid value passed to avalonlc3-voltage-level-offset";
  261. opt_avalonlc3_voltage_level_offset = val;
  262. return NULL;
  263. }
  264. char *set_avalonlc3_asic_otp(char *arg)
  265. {
  266. int val, ret;
  267. ret = sscanf(arg, "%d", &val);
  268. if (ret < 1)
  269. return "No value passed to avalonlc3-cinfo-asic";
  270. if (val < 0 || val > (AVALC3_DEFAULT_ASIC_MAX - 1))
  271. return "Invalid value passed to avalonlc3-cinfo-asic";
  272. opt_avalonlc3_asic_otp = val;
  273. opt_avalonlc3_cycle_hit_flag = 0;
  274. return NULL;
  275. }
  276. static int avalonlc3_init_pkg(struct avalonlc3_pkg *pkg, uint8_t type, uint8_t idx, uint8_t cnt)
  277. {
  278. unsigned short crc;
  279. pkg->head[0] = AVALC3_H1;
  280. pkg->head[1] = AVALC3_H2;
  281. pkg->type = type;
  282. pkg->opt = 0;
  283. pkg->idx = idx;
  284. pkg->cnt = cnt;
  285. crc = crc16(pkg->data, AVALC3_P_DATA_LEN);
  286. pkg->crc[0] = (crc & 0xff00) >> 8;
  287. pkg->crc[1] = crc & 0xff;
  288. return 0;
  289. }
  290. static int job_idcmp(uint8_t *job_id, char *pool_job_id)
  291. {
  292. int job_id_len;
  293. unsigned short crc, crc_expect;
  294. if (!pool_job_id)
  295. return 1;
  296. job_id_len = strlen(pool_job_id);
  297. crc_expect = crc16((unsigned char *)pool_job_id, job_id_len);
  298. crc = job_id[0] << 8 | job_id[1];
  299. if (crc_expect == crc)
  300. return 0;
  301. applog(LOG_DEBUG, "avalonlc3: job_id doesn't match! [%04x:%04x (%s)]",
  302. crc, crc_expect, pool_job_id);
  303. return 1;
  304. }
  305. static inline int get_temp_max(struct avalonlc3_info *info, int addr)
  306. {
  307. int i, j;
  308. int max = -273;
  309. for (i = 0; i < info->miner_count[addr]; i++) {
  310. for (j = 0; j < info->asic_count[addr]; j++) {
  311. if (info->temp[addr][i][j] > max)
  312. max = info->temp[addr][i][j];
  313. }
  314. }
  315. if (max < info->temp_mm[addr])
  316. max = info->temp_mm[addr];
  317. return max;
  318. }
  319. /*
  320. * Incremental PID controller
  321. *
  322. * controller input: u, output: t
  323. *
  324. * delta_u = P * [e(k) - e(k-1)] + I * e(k) + D * [e(k) - 2*e(k-1) + e(k-2)];
  325. * e(k) = t(k) - t[target];
  326. * u(k) = u(k-1) + delta_u;
  327. *
  328. */
  329. static inline uint32_t adjust_fan(struct avalonlc3_info *info, int id)
  330. {
  331. int t;
  332. double delta_u;
  333. double delta_p, delta_i, delta_d;
  334. uint32_t pwm;
  335. t = get_temp_max(info, id);
  336. /* update target error */
  337. info->pid_e[id][2] = info->pid_e[id][1];
  338. info->pid_e[id][1] = info->pid_e[id][0];
  339. info->pid_e[id][0] = t - info->temp_target[id];
  340. if (t > AVALC3_DEFAULT_PID_TEMP_MAX) {
  341. info->pid_u[id] = opt_avalonlc3_fan_max;
  342. } else if (t < AVALC3_DEFAULT_PID_TEMP_MIN) {
  343. info->pid_u[id] = opt_avalonlc3_fan_min;
  344. } else if (!info->pid_0[id]) {
  345. /* first, init u as t */
  346. info->pid_0[id] = 1;
  347. info->pid_u[id] = t;
  348. } else {
  349. delta_p = info->pid_p[id] * (info->pid_e[id][0] - info->pid_e[id][1]);
  350. delta_i = info->pid_i[id] * info->pid_e[id][0];
  351. delta_d = info->pid_d[id] * (info->pid_e[id][0] - 2 * info->pid_e[id][1] + info->pid_e[id][2]);
  352. /*Parameter I is int type(1, 2, 3...), but should be used as a smaller value (such as 0.1, 0.01...)*/
  353. delta_u = delta_p + delta_i / 100 + delta_d;
  354. info->pid_u[id] += delta_u;
  355. }
  356. if(info->pid_u[id] > opt_avalonlc3_fan_max)
  357. info->pid_u[id] = opt_avalonlc3_fan_max;
  358. if (info->pid_u[id] < opt_avalonlc3_fan_min)
  359. info->pid_u[id] = opt_avalonlc3_fan_min;
  360. /* Round from float to int */
  361. info->fan_pct[id] = (int)(info->pid_u[id] + 0.5);
  362. pwm = get_fan_pwm(info->fan_pct[id]);
  363. return pwm;
  364. }
  365. static int decode_pkg(struct cgpu_info *avalonlc3, struct avalonlc3_ret *ar, int modular_id)
  366. {
  367. struct avalonlc3_info *info = avalonlc3->device_data;
  368. struct pool *pool, *real_pool;
  369. struct pool *pool_stratum0 = &info->pool0;
  370. struct pool *pool_stratum1 = &info->pool1;
  371. struct pool *pool_stratum2 = &info->pool2;
  372. struct thr_info *thr = NULL;
  373. unsigned short expected_crc;
  374. unsigned short actual_crc;
  375. uint32_t nonce, nonce2, ntime, miner, chip_id, tmp;
  376. uint8_t job_id[2];
  377. int pool_no;
  378. uint32_t i;
  379. int64_t last_diff1;
  380. uint16_t vin;
  381. uint16_t power_info;
  382. uint16_t get_vcore;
  383. uint32_t asic_id, miner_id;
  384. if (likely(avalonlc3->thr))
  385. thr = avalonlc3->thr[0];
  386. if (ar->head[0] != AVALC3_H1 && ar->head[1] != AVALC3_H2) {
  387. applog(LOG_DEBUG, "%s-%d-%d: H1 %02x, H2 %02x",
  388. avalonlc3->drv->name, avalonlc3->device_id, modular_id,
  389. ar->head[0], ar->head[1]);
  390. hexdump(ar->data, 32);
  391. return 1;
  392. }
  393. expected_crc = crc16(ar->data, AVALC3_P_DATA_LEN);
  394. actual_crc = ((ar->crc[0] & 0xff) << 8) | (ar->crc[1] & 0xff);
  395. if (expected_crc != actual_crc) {
  396. applog(LOG_DEBUG, "%s-%d-%d: %02x: expected crc(%04x), actual_crc(%04x)",
  397. avalonlc3->drv->name, avalonlc3->device_id, modular_id,
  398. ar->type, expected_crc, actual_crc);
  399. return 1;
  400. }
  401. switch(ar->type) {
  402. case AVALC3_P_NONCE:
  403. applog(LOG_DEBUG, "%s-%d-%d: AVALC3_P_NONCE", avalonlc3->drv->name, avalonlc3->device_id, modular_id);
  404. memcpy(&miner, ar->data + 0, 4);
  405. memcpy(&nonce2, ar->data + 4, 4);
  406. memcpy(&ntime, ar->data + 8, 4);
  407. memcpy(&nonce, ar->data + 12, 4);
  408. job_id[0] = ar->data[16];
  409. job_id[1] = ar->data[17];
  410. pool_no = (ar->data[18] | (ar->data[19] << 8));
  411. miner = be32toh(miner);
  412. chip_id = (miner >> 16) & 0xffff;
  413. miner &= 0xffff;
  414. ntime = be32toh(ntime);
  415. if (miner >= info->miner_count[modular_id] ||
  416. pool_no >= total_pools || pool_no < 0) {
  417. applog(LOG_DEBUG, "%s-%d-%d: Wrong miner/pool_no %d/%d",
  418. avalonlc3->drv->name, avalonlc3->device_id, modular_id,
  419. miner, pool_no);
  420. break;
  421. }
  422. nonce2 = be32toh(nonce2);
  423. nonce = be32toh(nonce);
  424. if (ntime > info->max_ntime)
  425. info->max_ntime = ntime;
  426. applog(LOG_NOTICE, "%s-%d-%d: Found! P:%d - N2:%08x N:%08x NR:%d/%d [M:%d, A:%d, C:%d - MW: (%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64")]",
  427. avalonlc3->drv->name, avalonlc3->device_id, modular_id,
  428. pool_no, nonce2, nonce, ntime, info->max_ntime,
  429. miner, chip_id, nonce & 0x7f,
  430. info->chip_matching_work[modular_id][miner][0],
  431. info->chip_matching_work[modular_id][miner][1],
  432. info->chip_matching_work[modular_id][miner][2],
  433. info->chip_matching_work[modular_id][miner][3]);
  434. real_pool = pool = pools[pool_no];
  435. if (job_idcmp(job_id, pool->swork.job_id)) {
  436. if (!job_idcmp(job_id, pool_stratum0->swork.job_id)) {
  437. applog(LOG_DEBUG, "%s-%d-%d: Match to previous stratum0! (%s)",
  438. avalonlc3->drv->name, avalonlc3->device_id, modular_id,
  439. pool_stratum0->swork.job_id);
  440. pool = pool_stratum0;
  441. } else if (!job_idcmp(job_id, pool_stratum1->swork.job_id)) {
  442. applog(LOG_DEBUG, "%s-%d-%d: Match to previous stratum1! (%s)",
  443. avalonlc3->drv->name, avalonlc3->device_id, modular_id,
  444. pool_stratum1->swork.job_id);
  445. pool = pool_stratum1;
  446. } else if (!job_idcmp(job_id, pool_stratum2->swork.job_id)) {
  447. applog(LOG_DEBUG, "%s-%d-%d: Match to previous stratum2! (%s)",
  448. avalonlc3->drv->name, avalonlc3->device_id, modular_id,
  449. pool_stratum2->swork.job_id);
  450. pool = pool_stratum2;
  451. } else {
  452. applog(LOG_ERR, "%s-%d-%d: Cannot match to any stratum! (%s)",
  453. avalonlc3->drv->name, avalonlc3->device_id, modular_id,
  454. pool->swork.job_id);
  455. if (likely(thr))
  456. inc_hw_errors(thr);
  457. info->hw_works_i[modular_id][miner]++;
  458. break;
  459. }
  460. }
  461. /* Can happen during init sequence before add_cgpu */
  462. if (unlikely(!thr))
  463. break;
  464. last_diff1 = avalonlc3->diff1;
  465. if (!submit_nonce2_nonce(thr, pool, real_pool, nonce2, nonce, ntime))
  466. info->hw_works_i[modular_id][miner]++;
  467. else {
  468. info->diff1[modular_id] += (avalonlc3->diff1 - last_diff1);
  469. info->chip_matching_work[modular_id][miner][chip_id]++;
  470. }
  471. break;
  472. case AVALC3_P_STATUS:
  473. applog(LOG_DEBUG, "%s-%d-%d: AVALC3_P_STATUS", avalonlc3->drv->name, avalonlc3->device_id, modular_id);
  474. hexdump(ar->data, 32);
  475. memcpy(&tmp, ar->data, 4);
  476. tmp = be32toh(tmp);
  477. info->temp_mm[modular_id] = tmp;
  478. avalonlc3->temp = decode_auc_temp(info->auc_sensor);
  479. memcpy(&tmp, ar->data + 4, 4);
  480. tmp = be32toh(tmp);
  481. info->fan_cpm[modular_id] = tmp;
  482. memcpy(&tmp, ar->data + 8, 4);
  483. info->local_works_i[modular_id][ar->idx] += be32toh(tmp);
  484. memcpy(&tmp, ar->data + 12, 4);
  485. info->hw_works_i[modular_id][ar->idx] += be32toh(tmp);
  486. memcpy(&tmp, ar->data + 16, 4);
  487. info->error_code[modular_id][ar->idx] = be32toh(tmp);
  488. memcpy(&tmp, ar->data + 20, 4);
  489. info->error_code[modular_id][ar->cnt] = be32toh(tmp);
  490. memcpy(&tmp, ar->data + 24, 4);
  491. info->error_crc[modular_id][ar->idx] += be32toh(tmp);
  492. break;
  493. case AVALC3_P_STATUS_OTP:
  494. if (opt_avalonlc3_cycle_hit_flag)
  495. break;
  496. applog(LOG_DEBUG, "%s-%d-%d: AVALC3_P_STATUS_OTP", avalonlc3->drv->name, avalonlc3->device_id, modular_id);
  497. /* ASIC reading cycle limit hit */
  498. if (ar->data[AVALC3_OTP_INDEX_CYCLE_HIT]) {
  499. applog(LOG_DEBUG, "%s-%d-%d: AVALC3_P_STATUS_OTP, OTP read cycle hit!", avalonlc3->drv->name, avalonlc3->device_id, modular_id);
  500. opt_avalonlc3_cycle_hit_flag = 1;
  501. break;
  502. }
  503. miner_id = ar->idx;
  504. if (miner_id > AVALC3_DEFAULT_MINER_CNT)
  505. break;
  506. /* the reading step on MM side, 0:byte 3-0, 1:byte 7-4, 2:byte 11-8, 3:byte 15-12 */
  507. switch (ar->data[AVALC3_OTP_INDEX_READ_STEP]) {
  508. case 0:
  509. memcpy(info->otp_info[modular_id][miner_id] + AVALC3_OTP_INFO_LOTIDCRC_OFFSET, ar->data + AVALC3_OTP_INFO_LOTIDCRC_OFFSET, 4);
  510. break;
  511. case 1:
  512. memcpy(info->otp_info[modular_id][miner_id] + AVALC3_OTP_INFO_LOTIDCRC_OFFSET + 4, ar->data + AVALC3_OTP_INFO_LOTIDCRC_OFFSET + 4, 2);
  513. break;
  514. case 2:
  515. memcpy(info->otp_info[modular_id][miner_id] + AVALC3_OTP_INFO_LOTID_OFFSET, ar->data + AVALC3_OTP_INFO_LOTID_OFFSET, 4);
  516. break;
  517. case 3:
  518. memcpy(info->otp_info[modular_id][miner_id] + AVALC3_OTP_INFO_LOTID_OFFSET + 4, ar->data + AVALC3_OTP_INFO_LOTID_OFFSET + 4, 4);
  519. break;
  520. case 4:
  521. memcpy(info->otp_info[modular_id][miner_id] + AVALC3_OTP_INFO_LOTID_OFFSET + 8, ar->data + AVALC3_OTP_INFO_LOTID_OFFSET + 8, 4);
  522. break;
  523. case 5:
  524. memcpy(info->otp_info[modular_id][miner_id] + AVALC3_OTP_INFO_LOTID_OFFSET + 12, ar->data + AVALC3_OTP_INFO_LOTID_OFFSET + 12, 4);
  525. break;
  526. case 6:
  527. memcpy(info->otp_info[modular_id][miner_id] + AVALC3_OTP_INFO_LOTID_OFFSET + 16, ar->data + AVALC3_OTP_INFO_LOTID_OFFSET + 16, 4);
  528. break;
  529. default:
  530. break;
  531. }
  532. /* get the data behind AVALC3_OTP_INDEX_READ_STEP for later displaying use */
  533. memcpy(info->otp_info[modular_id][miner_id] + AVALC3_OTP_INDEX_READ_STEP, ar->data + AVALC3_OTP_INDEX_READ_STEP, 4);
  534. break;
  535. case AVALC3_P_STATUS_VOLT:
  536. applog(LOG_DEBUG, "%s-%d-%d: AVALC3_P_STATUS_VOLT", avalonlc3->drv->name, avalonlc3->device_id, modular_id);
  537. memcpy(&get_vcore, ar->data, 2);
  538. info->get_voltage[modular_id][0] = be16toh(get_vcore);
  539. break;
  540. case AVALC3_P_STATUS_PLL:
  541. applog(LOG_DEBUG, "%s-%d-%d: AVALC3_P_STATUS_PLL", avalonlc3->drv->name, avalonlc3->device_id, modular_id);
  542. for (i = 0; i < AVALC3_DEFAULT_PLL_CNT; i++) {
  543. memcpy(&tmp, ar->data + i * 4, 4);
  544. info->get_pll[modular_id][ar->idx][i] = be32toh(tmp);
  545. memcpy(&tmp, ar->data + AVALC3_DEFAULT_PLL_CNT * 4 + i * 4, 4);
  546. tmp = be32toh(tmp);
  547. if (tmp)
  548. info->set_frequency[modular_id][ar->idx][i] = tmp;
  549. }
  550. break;
  551. case AVALC3_P_STATUS_PVT:
  552. applog(LOG_DEBUG, "%s-%d-%d: AVALC3_P_STATUS_PVT", avalonlc3->drv->name, avalonlc3->device_id, modular_id);
  553. if (!info->asic_count[modular_id])
  554. break;
  555. if (ar->idx < info->asic_count[modular_id]) {
  556. for (i = 0; i < info->miner_count[modular_id]; i++) {
  557. memcpy(&tmp, ar->data + i * 4, 2);
  558. tmp = be16toh(tmp);
  559. info->temp[modular_id][i][ar->idx] = decode_pvt_temp(tmp);
  560. memcpy(&tmp, ar->data + i * 4 + 2, 2);
  561. tmp = be16toh(tmp);
  562. info->core_volt[modular_id][i][ar->idx][0] = decode_pvt_volt(tmp);
  563. }
  564. }
  565. break;
  566. case AVALC3_P_STATUS_ASIC:
  567. {
  568. int miner_id;
  569. int asic_id;
  570. uint16_t freq;
  571. if (!info->asic_count[modular_id])
  572. break;
  573. miner_id = ar->idx / info->asic_count[modular_id];
  574. asic_id = ar->idx % info->asic_count[modular_id];
  575. applog(LOG_DEBUG, "%s-%d-%d: AVALC3_P_STATUS_ASIC %d-%d",
  576. avalonlc3->drv->name, avalonlc3->device_id, modular_id,
  577. miner_id, asic_id);
  578. if (ar->data[31]) {
  579. memcpy(&tmp, ar->data + 0, 4);
  580. info->get_asic[modular_id][miner_id][asic_id][0] = be32toh(tmp);
  581. memcpy(&tmp, ar->data + 4, 4);
  582. info->get_asic[modular_id][miner_id][asic_id][1] = be32toh(tmp);
  583. }
  584. for (i = 0; i < AVALC3_DEFAULT_PLL_CNT; i++)
  585. info->get_asic[modular_id][miner_id][asic_id][2 + i] = ar->data[8 + i];
  586. for (i = 0; i < AVALC3_DEFAULT_PLL_CNT; i++) {
  587. memcpy(&freq, ar->data + 8 + AVALC3_DEFAULT_PLL_CNT + i * 2, 2);
  588. info->get_frequency[modular_id][miner_id][asic_id][i] = be16toh(freq);
  589. }
  590. }
  591. break;
  592. case AVALC3_P_STATUS_POWER:
  593. applog(LOG_DEBUG, "%s-%d-%d: AVALC3_P_STATUS_POWER", avalonlc3->drv->name, avalonlc3->device_id, modular_id);
  594. if (ar->data[12]) {
  595. for (i = 0; i < AVALC3_DEFAULT_POWER_INFO_CNT - 1; i++) {
  596. memcpy(&power_info, ar->data + i * 2, 2);
  597. info->power_info[i] = be16toh(power_info);
  598. }
  599. }
  600. break;
  601. case AVALC3_P_STATUS_FAC:
  602. applog(LOG_DEBUG, "%s-%d-%d: AVALC3_P_STATUS_FAC", avalonlc3->drv->name, avalonlc3->device_id, modular_id);
  603. info->factory_info[0] = ar->data[0];
  604. break;
  605. case AVALC3_P_STATUS_OC:
  606. applog(LOG_DEBUG, "%s-%d-%d: AVALC3_P_STATUS_OC", avalonlc3->drv->name, avalonlc3->device_id, modular_id);
  607. info->overclocking_info[0] = ar->data[0];
  608. break;
  609. default:
  610. applog(LOG_DEBUG, "%s-%d-%d: Unknown response %x", avalonlc3->drv->name, avalonlc3->device_id, modular_id, ar->type);
  611. break;
  612. }
  613. return 0;
  614. }
  615. /*
  616. # IIC packet format: length[1]+transId[1]+sesId[1]+req[1]+data[60]
  617. # length: 4+len(data)
  618. # transId: 0
  619. # sesId: 0
  620. # req: checkout the header file
  621. # data:
  622. # INIT: clock_rate[4] + reserved[4] + payload[52]
  623. # XFER: txSz[1]+rxSz[1]+options[1]+slaveAddr[1] + payload[56]
  624. */
  625. static int avalonlc3_auc_init_pkg(uint8_t *iic_pkg, struct avalonlc3_iic_info *iic_info, uint8_t *buf, int wlen, int rlen)
  626. {
  627. memset(iic_pkg, 0, AVALC3_AUC_P_SIZE);
  628. switch (iic_info->iic_op) {
  629. case AVALC3_IIC_INIT:
  630. iic_pkg[0] = 12; /* 4 bytes IIC header + 4 bytes speed + 4 bytes xfer delay */
  631. iic_pkg[3] = AVALC3_IIC_INIT;
  632. iic_pkg[4] = iic_info->iic_param.aucParam[0] & 0xff;
  633. iic_pkg[5] = (iic_info->iic_param.aucParam[0] >> 8) & 0xff;
  634. iic_pkg[6] = (iic_info->iic_param.aucParam[0] >> 16) & 0xff;
  635. iic_pkg[7] = iic_info->iic_param.aucParam[0] >> 24;
  636. iic_pkg[8] = iic_info->iic_param.aucParam[1] & 0xff;
  637. iic_pkg[9] = (iic_info->iic_param.aucParam[1] >> 8) & 0xff;
  638. iic_pkg[10] = (iic_info->iic_param.aucParam[1] >> 16) & 0xff;
  639. iic_pkg[11] = iic_info->iic_param.aucParam[1] >> 24;
  640. break;
  641. case AVALC3_IIC_XFER:
  642. iic_pkg[0] = 8 + wlen;
  643. iic_pkg[3] = AVALC3_IIC_XFER;
  644. iic_pkg[4] = wlen;
  645. iic_pkg[5] = rlen;
  646. iic_pkg[7] = iic_info->iic_param.slave_addr;
  647. if (buf && wlen)
  648. memcpy(iic_pkg + 8, buf, wlen);
  649. break;
  650. case AVALC3_IIC_RESET:
  651. case AVALC3_IIC_DEINIT:
  652. case AVALC3_IIC_INFO:
  653. iic_pkg[0] = 4;
  654. iic_pkg[3] = iic_info->iic_op;
  655. break;
  656. default:
  657. break;
  658. }
  659. return 0;
  660. }
  661. static int avalonlc3_iic_xfer(struct cgpu_info *avalonlc3, uint8_t slave_addr,
  662. uint8_t *wbuf, int wlen,
  663. uint8_t *rbuf, int rlen)
  664. {
  665. struct avalonlc3_info *info = avalonlc3->device_data;
  666. struct i2c_ctx *pctx = NULL;
  667. int err = 1;
  668. bool ret = false;
  669. pctx = info->i2c_slaves[slave_addr];
  670. if (!pctx) {
  671. applog(LOG_ERR, "%s-%d: IIC xfer i2c slaves null!", avalonlc3->drv->name, avalonlc3->device_id);
  672. goto out;
  673. }
  674. if (wbuf) {
  675. ret = pctx->write_raw(pctx, wbuf, wlen);
  676. if (!ret) {
  677. applog(LOG_DEBUG, "%s-%d: IIC xfer write raw failed!", avalonlc3->drv->name, avalonlc3->device_id);
  678. goto out;
  679. }
  680. }
  681. cgsleep_ms(5);
  682. if (rbuf) {
  683. ret = pctx->read_raw(pctx, rbuf, rlen);
  684. if (!ret) {
  685. applog(LOG_DEBUG, "%s-%d: IIC xfer read raw failed!", avalonlc3->drv->name, avalonlc3->device_id);
  686. hexdump(rbuf, rlen);
  687. goto out;
  688. }
  689. }
  690. return 0;
  691. out:
  692. return err;
  693. }
  694. static int avalonlc3_auc_xfer(struct cgpu_info *avalonlc3,
  695. uint8_t *wbuf, int wlen, int *write,
  696. uint8_t *rbuf, int rlen, int *read)
  697. {
  698. int err = -1;
  699. if (unlikely(avalonlc3->usbinfo.nodev))
  700. goto out;
  701. usb_buffer_clear(avalonlc3);
  702. err = usb_write(avalonlc3, (char *)wbuf, wlen, write, C_AVALC3_WRITE);
  703. if (err || *write != wlen) {
  704. applog(LOG_DEBUG, "%s-%d: AUC xfer %d, w(%d-%d)!", avalonlc3->drv->name, avalonlc3->device_id, err, wlen, *write);
  705. usb_nodev(avalonlc3);
  706. goto out;
  707. }
  708. cgsleep_ms(opt_avalonlc3_aucxdelay / 4800 + 1);
  709. rlen += 4; /* Add 4 bytes IIC header */
  710. err = usb_read(avalonlc3, (char *)rbuf, rlen, read, C_AVALC3_READ);
  711. if (err || *read != rlen || *read != rbuf[0]) {
  712. applog(LOG_DEBUG, "%s-%d: AUC xfer %d, r(%d-%d-%d)!", avalonlc3->drv->name, avalonlc3->device_id, err, rlen - 4, *read, rbuf[0]);
  713. hexdump(rbuf, rlen);
  714. return -1;
  715. }
  716. *read = rbuf[0] - 4; /* Remove 4 bytes IIC header */
  717. out:
  718. return err;
  719. }
  720. static int avalonlc3_auc_init(struct cgpu_info *avalonlc3, char *ver)
  721. {
  722. struct avalonlc3_iic_info iic_info;
  723. int err, wlen, rlen;
  724. uint8_t wbuf[AVALC3_AUC_P_SIZE];
  725. uint8_t rbuf[AVALC3_AUC_P_SIZE];
  726. if (unlikely(avalonlc3->usbinfo.nodev))
  727. return 1;
  728. /* Try to clean the AUC buffer */
  729. usb_buffer_clear(avalonlc3);
  730. err = usb_read(avalonlc3, (char *)rbuf, AVALC3_AUC_P_SIZE, &rlen, C_AVALC3_READ);
  731. applog(LOG_DEBUG, "%s-%d: AUC usb_read %d, %d!", avalonlc3->drv->name, avalonlc3->device_id, err, rlen);
  732. hexdump(rbuf, AVALC3_AUC_P_SIZE);
  733. /* Reset */
  734. iic_info.iic_op = AVALC3_IIC_RESET;
  735. rlen = 0;
  736. avalonlc3_auc_init_pkg(wbuf, &iic_info, NULL, 0, rlen);
  737. memset(rbuf, 0, AVALC3_AUC_P_SIZE);
  738. err = avalonlc3_auc_xfer(avalonlc3, wbuf, AVALC3_AUC_P_SIZE, &wlen, rbuf, rlen, &rlen);
  739. if (err) {
  740. applog(LOG_ERR, "%s-%d: Failed to reset Avalon USB2IIC Converter", avalonlc3->drv->name, avalonlc3->device_id);
  741. return 1;
  742. }
  743. /* Deinit */
  744. iic_info.iic_op = AVALC3_IIC_DEINIT;
  745. rlen = 0;
  746. avalonlc3_auc_init_pkg(wbuf, &iic_info, NULL, 0, rlen);
  747. memset(rbuf, 0, AVALC3_AUC_P_SIZE);
  748. err = avalonlc3_auc_xfer(avalonlc3, wbuf, AVALC3_AUC_P_SIZE, &wlen, rbuf, rlen, &rlen);
  749. if (err) {
  750. applog(LOG_ERR, "%s-%d: Failed to deinit Avalon USB2IIC Converter", avalonlc3->drv->name, avalonlc3->device_id);
  751. return 1;
  752. }
  753. /* Init */
  754. iic_info.iic_op = AVALC3_IIC_INIT;
  755. iic_info.iic_param.aucParam[0] = opt_avalonlc3_aucspeed;
  756. iic_info.iic_param.aucParam[1] = opt_avalonlc3_aucxdelay;
  757. rlen = AVALC3_AUC_VER_LEN;
  758. avalonlc3_auc_init_pkg(wbuf, &iic_info, NULL, 0, rlen);
  759. memset(rbuf, 0, AVALC3_AUC_P_SIZE);
  760. err = avalonlc3_auc_xfer(avalonlc3, wbuf, AVALC3_AUC_P_SIZE, &wlen, rbuf, rlen, &rlen);
  761. if (err) {
  762. applog(LOG_ERR, "%s-%d: Failed to init Avalon USB2IIC Converter", avalonlc3->drv->name, avalonlc3->device_id);
  763. return 1;
  764. }
  765. hexdump(rbuf, AVALC3_AUC_P_SIZE);
  766. memcpy(ver, rbuf + 4, AVALC3_AUC_VER_LEN);
  767. ver[AVALC3_AUC_VER_LEN] = '\0';
  768. applog(LOG_DEBUG, "%s-%d: USB2IIC Converter version: %s!", avalonlc3->drv->name, avalonlc3->device_id, ver);
  769. return 0;
  770. }
  771. static int avalonlc3_auc_getinfo(struct cgpu_info *avalonlc3)
  772. {
  773. struct avalonlc3_iic_info iic_info;
  774. int err, wlen, rlen;
  775. uint8_t wbuf[AVALC3_AUC_P_SIZE];
  776. uint8_t rbuf[AVALC3_AUC_P_SIZE];
  777. uint8_t *pdata = rbuf + 4;
  778. uint16_t adc_val;
  779. struct avalonlc3_info *info = avalonlc3->device_data;
  780. iic_info.iic_op = AVALC3_IIC_INFO;
  781. /*
  782. * Device info: (9 bytes)
  783. * tempadc(2), reqRdIndex, reqWrIndex,
  784. * respRdIndex, respWrIndex, tx_flags, state
  785. */
  786. rlen = 7;
  787. avalonlc3_auc_init_pkg(wbuf, &iic_info, NULL, 0, rlen);
  788. memset(rbuf, 0, AVALC3_AUC_P_SIZE);
  789. err = avalonlc3_auc_xfer(avalonlc3, wbuf, AVALC3_AUC_P_SIZE, &wlen, rbuf, rlen, &rlen);
  790. if (err) {
  791. applog(LOG_ERR, "%s-%d: AUC Failed to get info ", avalonlc3->drv->name, avalonlc3->device_id);
  792. return 1;
  793. }
  794. applog(LOG_DEBUG, "%s-%d: AUC tempADC(%03d), reqcnt(%d), respcnt(%d), txflag(%d), state(%d)",
  795. avalonlc3->drv->name, avalonlc3->device_id,
  796. pdata[1] << 8 | pdata[0],
  797. pdata[2],
  798. pdata[3],
  799. pdata[5] << 8 | pdata[4],
  800. pdata[6]);
  801. adc_val = pdata[1] << 8 | pdata[0];
  802. info->auc_sensor = 3.3 * adc_val * 10000 / 1023;
  803. return 0;
  804. }
  805. static int avalonlc3_iic_xfer_pkg(struct cgpu_info *avalonlc3, uint8_t slave_addr,
  806. const struct avalonlc3_pkg *pkg, struct avalonlc3_ret *ret)
  807. {
  808. struct avalonlc3_iic_info iic_info;
  809. int err, wcnt, rcnt, rlen = 0;
  810. uint8_t wbuf[AVALC3_AUC_P_SIZE];
  811. uint8_t rbuf[AVALC3_AUC_P_SIZE];
  812. struct avalonlc3_info *info = avalonlc3->device_data;
  813. if (ret)
  814. rlen = AVALC3_READ_SIZE;
  815. if (info->connecter == AVALC3_CONNECTER_AUC) {
  816. if (unlikely(avalonlc3->usbinfo.nodev))
  817. return AVALC3_SEND_ERROR;
  818. iic_info.iic_op = AVALC3_IIC_XFER;
  819. iic_info.iic_param.slave_addr = slave_addr;
  820. avalonlc3_auc_init_pkg(wbuf, &iic_info, (uint8_t *)pkg, AVALC3_WRITE_SIZE, rlen);
  821. err = avalonlc3_auc_xfer(avalonlc3, wbuf, wbuf[0], &wcnt, rbuf, rlen, &rcnt);
  822. if ((pkg->type != AVALC3_P_DETECT) && err == -7 && !rcnt && rlen) {
  823. avalonlc3_auc_init_pkg(wbuf, &iic_info, NULL, 0, rlen);
  824. err = avalonlc3_auc_xfer(avalonlc3, wbuf, wbuf[0], &wcnt, rbuf, rlen, &rcnt);
  825. applog(LOG_DEBUG, "%s-%d-%d: AUC read again!(type:0x%x, err:%d)", avalonlc3->drv->name, avalonlc3->device_id, slave_addr, pkg->type, err);
  826. }
  827. if (err || rcnt != rlen) {
  828. if (info->xfer_err_cnt++ == 100) {
  829. applog(LOG_DEBUG, "%s-%d-%d: AUC xfer_err_cnt reach err = %d, rcnt = %d, rlen = %d",
  830. avalonlc3->drv->name, avalonlc3->device_id, slave_addr,
  831. err, rcnt, rlen);
  832. cgsleep_ms(5 * 1000); /* Wait MM reset */
  833. if (avalonlc3_auc_init(avalonlc3, info->auc_version)) {
  834. applog(LOG_WARNING, "%s-%d: Failed to re-init auc, unplugging for new hotplug",
  835. avalonlc3->drv->name, avalonlc3->device_id);
  836. usb_nodev(avalonlc3);
  837. }
  838. }
  839. return AVALC3_SEND_ERROR;
  840. }
  841. if (ret)
  842. memcpy((char *)ret, rbuf + 4, AVALC3_READ_SIZE);
  843. info->xfer_err_cnt = 0;
  844. }
  845. if (info->connecter == AVALC3_CONNECTER_IIC) {
  846. err = avalonlc3_iic_xfer(avalonlc3, slave_addr, (uint8_t *)pkg, AVALC3_WRITE_SIZE, (uint8_t *)ret, AVALC3_READ_SIZE);
  847. if ((pkg->type != AVALC3_P_DETECT) && err) {
  848. err = avalonlc3_iic_xfer(avalonlc3, slave_addr, (uint8_t *)pkg, AVALC3_WRITE_SIZE, (uint8_t *)ret, AVALC3_READ_SIZE);
  849. applog(LOG_DEBUG, "%s-%d-%d: IIC read again!(type:0x%x, err:%d)", avalonlc3->drv->name, avalonlc3->device_id, slave_addr, pkg->type, err);
  850. }
  851. if (err) {
  852. /* FIXME: Don't care broadcast message with no reply, or it will block other thread when called by avalonlc3_send_bc_pkgs */
  853. if ((pkg->type != AVALC3_P_DETECT) && (slave_addr == AVALC3_MODULE_BROADCAST))
  854. return AVALC3_SEND_OK;
  855. if (info->xfer_err_cnt++ == 100) {
  856. info->xfer_err_cnt = 0;
  857. applog(LOG_DEBUG, "%s-%d-%d: IIC xfer_err_cnt reach err = %d, rcnt = %d, rlen = %d",
  858. avalonlc3->drv->name, avalonlc3->device_id, slave_addr,
  859. err, rcnt, rlen);
  860. cgsleep_ms(5 * 1000); /* Wait MM reset */
  861. }
  862. return AVALC3_SEND_ERROR;
  863. }
  864. info->xfer_err_cnt = 0;
  865. }
  866. return AVALC3_SEND_OK;
  867. }
  868. static int avalonlc3_send_bc_pkgs(struct cgpu_info *avalonlc3, const struct avalonlc3_pkg *pkg)
  869. {
  870. int ret;
  871. do {
  872. ret = avalonlc3_iic_xfer_pkg(avalonlc3, AVALC3_MODULE_BROADCAST, pkg, NULL);
  873. } while (ret != AVALC3_SEND_OK);
  874. return 0;
  875. }
  876. static void avalonlc3_stratum_pkgs(struct cgpu_info *avalonlc3, struct pool *pool)
  877. {
  878. struct avalonlc3_info *info = avalonlc3->device_data;
  879. const int merkle_offset = 36;
  880. struct avalonlc3_pkg pkg;
  881. int i, a, b;
  882. uint32_t tmp;
  883. unsigned char target[32];
  884. int job_id_len, n2size;
  885. unsigned short crc;
  886. int coinbase_len_posthash, coinbase_len_prehash;
  887. uint8_t coinbase_prehash[32];
  888. uint32_t range, start;
  889. /* Send out the first stratum message STATIC */
  890. applog(LOG_DEBUG, "%s-%d: Pool stratum message STATIC: %d, %d, %d, %d, %d",
  891. avalonlc3->drv->name, avalonlc3->device_id,
  892. pool->coinbase_len,
  893. pool->nonce2_offset,
  894. pool->n2size,
  895. merkle_offset,
  896. pool->merkles);
  897. memset(pkg.data, 0, AVALC3_P_DATA_LEN);
  898. tmp = be32toh(pool->coinbase_len);
  899. memcpy(pkg.data, &tmp, 4);
  900. tmp = be32toh(pool->nonce2_offset);
  901. memcpy(pkg.data + 4, &tmp, 4);
  902. n2size = pool->n2size >= 4 ? 4 : pool->n2size;
  903. tmp = be32toh(n2size);
  904. memcpy(pkg.data + 8, &tmp, 4);
  905. tmp = be32toh(merkle_offset);
  906. memcpy(pkg.data + 12, &tmp, 4);
  907. tmp = be32toh(pool->merkles);
  908. memcpy(pkg.data + 16, &tmp, 4);
  909. if (pool->n2size == 3)
  910. range = 0xffffff / (total_devices ? total_devices : 1);
  911. else
  912. range = 0xffffffff / (total_devices ? total_devices : 1);
  913. start = range * avalonlc3->device_id;
  914. tmp = be32toh(start);
  915. memcpy(pkg.data + 20, &tmp, 4);
  916. tmp = be32toh(range);
  917. memcpy(pkg.data + 24, &tmp, 4);
  918. if (info->work_restart) {
  919. info->work_restart = false;
  920. tmp = be32toh(0x1);
  921. memcpy(pkg.data + 28, &tmp, 4);
  922. }
  923. avalonlc3_init_pkg(&pkg, AVALC3_P_STATIC, 1, 1);
  924. if (avalonlc3_send_bc_pkgs(avalonlc3, &pkg))
  925. return;
  926. if (pool->sdiff <= AVALC3_DRV_DIFFMAX)
  927. set_target(target, pool->sdiff);
  928. else
  929. set_target(target, AVALC3_DRV_DIFFMAX);
  930. memcpy(pkg.data, target, 32);
  931. if (opt_debug) {
  932. char *target_str;
  933. target_str = bin2hex(target, 32);
  934. applog(LOG_DEBUG, "%s-%d: Pool stratum target: %s", avalonlc3->drv->name, avalonlc3->device_id, target_str);
  935. free(target_str);
  936. }
  937. avalonlc3_init_pkg(&pkg, AVALC3_P_TARGET, 1, 1);
  938. if (avalonlc3_send_bc_pkgs(avalonlc3, &pkg))
  939. return;
  940. memset(pkg.data, 0, AVALC3_P_DATA_LEN);
  941. job_id_len = strlen(pool->swork.job_id);
  942. crc = crc16((unsigned char *)pool->swork.job_id, job_id_len);
  943. applog(LOG_DEBUG, "%s-%d: Pool stratum message JOBS_ID[%04x]: %s",
  944. avalonlc3->drv->name, avalonlc3->device_id,
  945. crc, pool->swork.job_id);
  946. tmp = ((crc << 16) | pool->pool_no);
  947. if (info->last_jobid != tmp) {
  948. info->last_jobid = tmp;
  949. pkg.data[0] = (crc & 0xff00) >> 8;
  950. pkg.data[1] = crc & 0xff;
  951. pkg.data[2] = pool->pool_no & 0xff;
  952. pkg.data[3] = (pool->pool_no & 0xff00) >> 8;
  953. avalonlc3_init_pkg(&pkg, AVALC3_P_JOB_ID, 1, 1);
  954. if (avalonlc3_send_bc_pkgs(avalonlc3, &pkg))
  955. return;
  956. }
  957. coinbase_len_prehash = pool->nonce2_offset - (pool->nonce2_offset % SHA256_BLOCK_SIZE);
  958. coinbase_len_posthash = pool->coinbase_len - coinbase_len_prehash;
  959. sha256_prehash(pool->coinbase, coinbase_len_prehash, coinbase_prehash);
  960. a = (coinbase_len_posthash / AVALC3_P_DATA_LEN) + 1;
  961. b = coinbase_len_posthash % AVALC3_P_DATA_LEN;
  962. memcpy(pkg.data, coinbase_prehash, 32);
  963. avalonlc3_init_pkg(&pkg, AVALC3_P_COINBASE, 1, a + (b ? 1 : 0));
  964. if (avalonlc3_send_bc_pkgs(avalonlc3, &pkg))
  965. return;
  966. applog(LOG_DEBUG, "%s-%d: Pool stratum message modified COINBASE: %d %d",
  967. avalonlc3->drv->name, avalonlc3->device_id,
  968. a, b);
  969. for (i = 1; i < a; i++) {
  970. memcpy(pkg.data, pool->coinbase + coinbase_len_prehash + i * 32 - 32, 32);
  971. avalonlc3_init_pkg(&pkg, AVALC3_P_COINBASE, i + 1, a + (b ? 1 : 0));
  972. if (avalonlc3_send_bc_pkgs(avalonlc3, &pkg))
  973. return;
  974. }
  975. if (b) {
  976. memset(pkg.data, 0, AVALC3_P_DATA_LEN);
  977. memcpy(pkg.data, pool->coinbase + coinbase_len_prehash + i * 32 - 32, b);
  978. avalonlc3_init_pkg(&pkg, AVALC3_P_COINBASE, i + 1, i + 1);
  979. if (avalonlc3_send_bc_pkgs(avalonlc3, &pkg))
  980. return;
  981. }
  982. b = pool->merkles;
  983. applog(LOG_DEBUG, "%s-%d: Pool stratum message MERKLES: %d", avalonlc3->drv->name, avalonlc3->device_id, b);
  984. for (i = 0; i < b; i++) {
  985. memset(pkg.data, 0, AVALC3_P_DATA_LEN);
  986. memcpy(pkg.data, pool->swork.merkle_bin[i], 32);
  987. avalonlc3_init_pkg(&pkg, AVALC3_P_MERKLES, i + 1, b);
  988. if (avalonlc3_send_bc_pkgs(avalonlc3, &pkg))
  989. return;
  990. }
  991. applog(LOG_DEBUG, "%s-%d: Pool stratum message HEADER: 4", avalonlc3->drv->name, avalonlc3->device_id);
  992. for (i = 0; i < 4; i++) {
  993. memset(pkg.data, 0, AVALC3_P_DATA_LEN);
  994. memcpy(pkg.data, pool->header_bin + i * 32, 32);
  995. avalonlc3_init_pkg(&pkg, AVALC3_P_HEADER, i + 1, 4);
  996. if (avalonlc3_send_bc_pkgs(avalonlc3, &pkg))
  997. return;
  998. }
  999. if (info->connecter == AVALC3_CONNECTER_AUC)
  1000. avalonlc3_auc_getinfo(avalonlc3);
  1001. }
  1002. static struct cgpu_info *avalonlc3_iic_detect(void)
  1003. {
  1004. int i;
  1005. struct avalonlc3_info *info;
  1006. struct cgpu_info *avalonlc3 = NULL;
  1007. struct i2c_ctx *i2c_slave = NULL;
  1008. i2c_slave = i2c_slave_open(I2C_BUS, 0);
  1009. if (!i2c_slave) {
  1010. applog(LOG_ERR, "avalonlc3 init iic failed\n");
  1011. return NULL;
  1012. }
  1013. i2c_slave->exit(i2c_slave);
  1014. i2c_slave = NULL;
  1015. avalonlc3 = cgcalloc(1, sizeof(*avalonlc3));
  1016. avalonlc3->drv = &avalonlc3_drv;
  1017. avalonlc3->deven = DEV_ENABLED;
  1018. avalonlc3->threads = 1;
  1019. add_cgpu(avalonlc3);
  1020. applog(LOG_INFO, "%s-%d: Found at %s", avalonlc3->drv->name, avalonlc3->device_id, I2C_BUS);
  1021. avalonlc3->device_data = cgcalloc(sizeof(struct avalonlc3_info), 1);
  1022. memset(avalonlc3->device_data, 0, sizeof(struct avalonlc3_info));
  1023. info = avalonlc3->device_data;
  1024. for (i = 0; i < AVALC3_DEFAULT_MODULARS; i++) {
  1025. info->enable[i] = false;
  1026. info->reboot[i] = false;
  1027. info->i2c_slaves[i] = i2c_slave_open(I2C_BUS, i);
  1028. if (!info->i2c_slaves[i]) {
  1029. applog(LOG_ERR, "avalonlc3 init i2c slaves failed\n");
  1030. free(avalonlc3->device_data);
  1031. avalonlc3->device_data = NULL;
  1032. free(avalonlc3);
  1033. avalonlc3 = NULL;
  1034. return NULL;
  1035. }
  1036. }
  1037. info->connecter = AVALC3_CONNECTER_IIC;
  1038. return avalonlc3;
  1039. }
  1040. static void detect_modules(struct cgpu_info *avalonlc3);
  1041. static struct cgpu_info *avalonlc3_auc_detect(struct libusb_device *dev, struct usb_find_devices *found)
  1042. {
  1043. int i, modules = 0;
  1044. struct avalonlc3_info *info;
  1045. struct cgpu_info *avalonlc3 = usb_alloc_cgpu(&avalonlc3_drv, 1);
  1046. char auc_ver[AVALC3_AUC_VER_LEN];
  1047. if (!usb_init(avalonlc3, dev, found)) {
  1048. applog(LOG_ERR, "avalonlc3 failed usb_init");
  1049. avalonlc3 = usb_free_cgpu(avalonlc3);
  1050. return NULL;
  1051. }
  1052. /* avalonlc3 prefers not to use zero length packets */
  1053. avalonlc3->nozlp = true;
  1054. /* We try twice on AUC init */
  1055. if (avalonlc3_auc_init(avalonlc3, auc_ver) && avalonlc3_auc_init(avalonlc3, auc_ver))
  1056. return NULL;
  1057. applog(LOG_INFO, "%s-%d: Found at %s", avalonlc3->drv->name, avalonlc3->device_id,
  1058. avalonlc3->device_path);
  1059. avalonlc3->device_data = cgcalloc(sizeof(struct avalonlc3_info), 1);
  1060. memset(avalonlc3->device_data, 0, sizeof(struct avalonlc3_info));
  1061. info = avalonlc3->device_data;
  1062. memcpy(info->auc_version, auc_ver, AVALC3_AUC_VER_LEN);
  1063. info->auc_version[AVALC3_AUC_VER_LEN] = '\0';
  1064. info->auc_speed = opt_avalonlc3_aucspeed;
  1065. info->auc_xdelay = opt_avalonlc3_aucxdelay;
  1066. for (i = 0; i < AVALC3_DEFAULT_MODULARS; i++)
  1067. info->enable[i] = 0;
  1068. info->connecter = AVALC3_CONNECTER_AUC;
  1069. detect_modules(avalonlc3);
  1070. for (i = 0; i < AVALC3_DEFAULT_MODULARS; i++)
  1071. modules += info->enable[i];
  1072. if (!modules) {
  1073. applog(LOG_INFO, "avalonlc3 found but no modules initialised");
  1074. free(info);
  1075. avalonlc3 = usb_free_cgpu(avalonlc3);
  1076. return NULL;
  1077. }
  1078. /* We have an avalonlc3 AUC connected */
  1079. avalonlc3->threads = 1;
  1080. add_cgpu(avalonlc3);
  1081. update_usb_stats(avalonlc3);
  1082. return avalonlc3;
  1083. }
  1084. static inline void avalonlc3_detect(bool __maybe_unused hotplug)
  1085. {
  1086. usb_detect(&avalonlc3_drv, avalonlc3_auc_detect);
  1087. if (!hotplug && opt_avalonlc3_iic_detect)
  1088. avalonlc3_iic_detect();
  1089. }
  1090. static bool avalonlc3_prepare(struct thr_info *thr)
  1091. {
  1092. struct cgpu_info *avalonlc3 = thr->cgpu;
  1093. struct avalonlc3_info *info = avalonlc3->device_data;
  1094. info->last_diff1 = 0;
  1095. info->pending_diff1 = 0;
  1096. info->last_rej = 0;
  1097. info->mm_count = 0;
  1098. info->xfer_err_cnt = 0;
  1099. info->pool_no = 0;
  1100. memset(&(info->firsthash), 0, sizeof(info->firsthash));
  1101. cgtime(&(info->last_fan_adj));
  1102. cgtime(&info->last_stratum);
  1103. cgtime(&info->last_detect);
  1104. cglock_init(&info->update_lock);
  1105. cglock_init(&info->pool0.data_lock);
  1106. cglock_init(&info->pool1.data_lock);
  1107. cglock_init(&info->pool2.data_lock);
  1108. return true;
  1109. }
  1110. static int check_module_exist(struct cgpu_info *avalonlc3, uint8_t mm_dna[AVALC3_MM_DNA_LEN])
  1111. {
  1112. struct avalonlc3_info *info = avalonlc3->device_data;
  1113. int i;
  1114. for (i = 0; i < AVALC3_DEFAULT_MODULARS; i++) {
  1115. /* last byte is \0 */
  1116. if (info->enable[i] && !memcmp(info->mm_dna[i], mm_dna, AVALC3_MM_DNA_LEN))
  1117. return 1;
  1118. }
  1119. return 0;
  1120. }
  1121. static void detect_modules(struct cgpu_info *avalonlc3)
  1122. {
  1123. struct avalonlc3_info *info = avalonlc3->device_data;
  1124. struct avalonlc3_pkg send_pkg;
  1125. struct avalonlc3_ret ret_pkg;
  1126. uint32_t tmp;
  1127. int i, j, k, err, rlen;
  1128. uint8_t dev_index;
  1129. uint8_t rbuf[AVALC3_AUC_P_SIZE];
  1130. /* Detect new modules here */
  1131. for (i = 1; i < AVALC3_DEFAULT_MODULARS + 1; i++) {
  1132. if (info->enable[i])
  1133. continue;
  1134. /* Send out detect pkg */
  1135. applog(LOG_DEBUG, "%s-%d: AVALC3_P_DETECT ID[%d]",
  1136. avalonlc3->drv->name, avalonlc3->device_id, i);
  1137. memset(send_pkg.data, 0, AVALC3_P_DATA_LEN);
  1138. tmp = be32toh(i); /* ID */
  1139. memcpy(send_pkg.data + 28, &tmp, 4);
  1140. avalonlc3_init_pkg(&send_pkg, AVALC3_P_DETECT, 1, 1);
  1141. err = avalonlc3_iic_xfer_pkg(avalonlc3, AVALC3_MODULE_BROADCAST, &send_pkg, &ret_pkg);
  1142. if (err == AVALC3_SEND_OK) {
  1143. if (decode_pkg(avalonlc3, &ret_pkg, AVALC3_MODULE_BROADCAST)) {
  1144. applog(LOG_DEBUG, "%s-%d: Should be AVALC3_P_ACKDETECT(%d), but %d",
  1145. avalonlc3->drv->name, avalonlc3->device_id, AVALC3_P_ACKDETECT, ret_pkg.type);
  1146. continue;
  1147. }
  1148. }
  1149. if (err != AVALC3_SEND_OK) {
  1150. applog(LOG_DEBUG, "%s-%d: AVALC3_P_DETECT: Failed AUC xfer data with err %d",
  1151. avalonlc3->drv->name, avalonlc3->device_id, err);
  1152. break;
  1153. }
  1154. applog(LOG_DEBUG, "%s-%d: Module detect ID[%d]: %d",
  1155. avalonlc3->drv->name, avalonlc3->device_id, i, ret_pkg.type);
  1156. if (ret_pkg.type != AVALC3_P_ACKDETECT)
  1157. break;
  1158. if (check_module_exist(avalonlc3, ret_pkg.data))
  1159. continue;
  1160. /* Check count of modulars */
  1161. if (i == AVALC3_DEFAULT_MODULARS) {
  1162. applog(LOG_NOTICE, "You have connected more than %d machines. This is discouraged.", (AVALC3_DEFAULT_MODULARS - 1));
  1163. info->conn_overloaded = true;
  1164. break;
  1165. } else
  1166. info->conn_overloaded = false;
  1167. memcpy(info->mm_version[i], ret_pkg.data + AVALC3_MM_DNA_LEN, AVALC3_MM_VER_LEN);
  1168. info->mm_version[i][AVALC3_MM_VER_LEN] = '\0';
  1169. for (dev_index = 0; dev_index < (sizeof(avalonlc3_dev_table) / sizeof(avalonlc3_dev_table[0])); dev_index++) {
  1170. if (!strncmp((char *)&(info->mm_version[i]), (char *)(avalonlc3_dev_table[dev_index].dev_id_str), 3)) {
  1171. info->mod_type[i] = avalonlc3_dev_table[dev_index].mod_type;
  1172. info->miner_count[i] = avalonlc3_dev_table[dev_index].miner_count;
  1173. info->asic_count[i] = avalonlc3_dev_table[dev_index].asic_count;
  1174. break;
  1175. }
  1176. }
  1177. if (dev_index == (sizeof(avalonlc3_dev_table) / sizeof(avalonlc3_dev_table[0]))) {
  1178. applog(LOG_NOTICE, "%s-%d: The modular version %s cann't be support",
  1179. avalonlc3->drv->name, avalonlc3->device_id, info->mm_version[i]);
  1180. break;
  1181. }
  1182. info->enable[i] = 1;
  1183. cgtime(&info->elapsed[i]);
  1184. memcpy(info->mm_dna[i], ret_pkg.data, AVALC3_MM_DNA_LEN);
  1185. memcpy(&tmp, ret_pkg.data + AVALC3_MM_DNA_LEN + AVALC3_MM_VER_LEN, 4);
  1186. tmp = be32toh(tmp);
  1187. info->total_asics[i] = tmp;
  1188. info->temp_overheat[i] = AVALC3_DEFAULT_TEMP_OVERHEAT;
  1189. info->temp_target[i] = opt_avalonlc3_temp_target;
  1190. info->fan_pct[i] = opt_avalonlc3_fan_min;
  1191. for (j = 0; j < info->miner_count[i]; j++) {
  1192. if (opt_avalonlc3_voltage_level == AVALC3_INVALID_VOLTAGE_LEVEL)
  1193. info->set_voltage_level[i][j] = avalonlc3_dev_table[dev_index].set_voltage_level;
  1194. else
  1195. info->set_voltage_level[i][j] = opt_avalonlc3_voltage_level;
  1196. for (k = 0; k < info->asic_count[i]; k++)
  1197. info->temp[i][j][k] = -273;
  1198. for (k = 0; k < AVALC3_DEFAULT_PLL_CNT; k++)
  1199. info->set_frequency[i][j][k] = avalonlc3_dev_table[dev_index].set_freq[k];
  1200. if (AVALC3_INVALID_ASIC_OTP == opt_avalonlc3_asic_otp)
  1201. info->set_asic_otp[i][j] = 0; /* default asic: 0 */
  1202. else
  1203. info->set_asic_otp[i][j] = opt_avalonlc3_asic_otp;
  1204. }
  1205. info->get_voltage[i][0] = 0;
  1206. info->freq_mode[i] = AVALC3_FREQ_INIT_MODE;
  1207. memset(info->get_pll[i], 0, sizeof(uint32_t) * info->miner_count[i] * AVALC3_DEFAULT_PLL_CNT);
  1208. info->led_indicator[i] = 0;
  1209. info->cutoff[i] = 0;
  1210. info->fan_cpm[i] = 0;
  1211. info->temp_mm[i] = -273;
  1212. info->local_works[i] = 0;
  1213. info->hw_works[i] = 0;
  1214. /*PID controller*/
  1215. info->pid_u[i] = opt_avalonlc3_fan_min;
  1216. info->pid_p[i] = opt_avalonlc3_pid_p;
  1217. info->pid_i[i] = opt_avalonlc3_pid_i;
  1218. info->pid_d[i] = opt_avalonlc3_pid_d;
  1219. info->pid_e[i][0] = 0;
  1220. info->pid_e[i][1] = 0;
  1221. info->pid_e[i][2] = 0;
  1222. info->pid_0[i] = 0;
  1223. for (j = 0; j < info->miner_count[i]; j++) {
  1224. memset(info->chip_matching_work[i][j], 0, sizeof(uint64_t) * info->asic_count[i]);
  1225. info->local_works_i[i][j] = 0;
  1226. info->hw_works_i[i][j] = 0;
  1227. info->error_code[i][j] = 0;
  1228. info->error_crc[i][j] = 0;
  1229. }
  1230. info->error_code[i][j] = 0;
  1231. info->error_polling_cnt[i] = 0;
  1232. info->diff1[i] = 0;
  1233. applog(LOG_NOTICE, "%s-%d: New module detected! ID[%d-%x]",
  1234. avalonlc3->drv->name, avalonlc3->device_id, i, info->mm_dna[i][AVALC3_MM_DNA_LEN - 1]);
  1235. /* Tell MM, it has been detected */
  1236. memset(send_pkg.data, 0, AVALC3_P_DATA_LEN);
  1237. memcpy(send_pkg.data, info->mm_dna[i], AVALC3_MM_DNA_LEN);
  1238. avalonlc3_init_pkg(&send_pkg, AVALC3_P_SYNC, 1, 1);
  1239. avalonlc3_iic_xfer_pkg(avalonlc3, i, &send_pkg, &ret_pkg);
  1240. /* Keep the usb buffer is empty */
  1241. usb_buffer_clear(avalonlc3);
  1242. usb_read(avalonlc3, (char *)rbuf, AVALC3_AUC_P_SIZE, &rlen, C_AVALC3_READ);
  1243. }
  1244. }
  1245. static void detach_module(struct cgpu_info *avalonlc3, int addr)
  1246. {
  1247. struct avalonlc3_info *info = avalonlc3->device_data;
  1248. info->enable[addr] = 0;
  1249. applog(LOG_NOTICE, "%s-%d: Module detached! ID[%d]",
  1250. avalonlc3->drv->name, avalonlc3->device_id, addr);
  1251. }
  1252. static int polling(struct cgpu_info *avalonlc3)
  1253. {
  1254. struct avalonlc3_info *info = avalonlc3->device_data;
  1255. struct avalonlc3_pkg send_pkg;
  1256. struct avalonlc3_ret ar;
  1257. int i, tmp, ret, decode_err = 0;
  1258. struct timeval current_fan;
  1259. int do_adjust_fan = 0;
  1260. uint32_t fan_pwm;
  1261. double device_tdiff;
  1262. cgtime(&current_fan);
  1263. device_tdiff = tdiff(&current_fan, &(info->last_fan_adj));
  1264. if (device_tdiff > 2.0 || device_tdiff < 0) {
  1265. cgtime(&info->last_fan_adj);
  1266. do_adjust_fan = 1;
  1267. }
  1268. for (i = 1; i < AVALC3_DEFAULT_MODULARS; i++) {
  1269. if (!info->enable[i])
  1270. continue;
  1271. cgsleep_ms(opt_avalonlc3_polling_delay);
  1272. memset(send_pkg.data, 0, AVALC3_P_DATA_LEN);
  1273. /* Red LED */
  1274. tmp = be32toh(info->led_indicator[i]);
  1275. memcpy(send_pkg.data, &tmp, 4);
  1276. /* Adjust fan every 2 seconds*/
  1277. if (do_adjust_fan) {
  1278. fan_pwm = adjust_fan(info, i);
  1279. fan_pwm |= 0x80000000;
  1280. tmp = be32toh(fan_pwm);
  1281. memcpy(send_pkg.data + 4, &tmp, 4);
  1282. }
  1283. if (info->reboot[i]) {
  1284. info->reboot[i] = false;
  1285. send_pkg.data[8] = 0x1;
  1286. }
  1287. avalonlc3_init_pkg(&send_pkg, AVALC3_P_POLLING, 1, 1);
  1288. ret = avalonlc3_iic_xfer_pkg(avalonlc3, i, &send_pkg, &ar);
  1289. if (ret == AVALC3_SEND_OK)
  1290. decode_err = decode_pkg(avalonlc3, &ar, i);
  1291. if (ret != AVALC3_SEND_OK || decode_err) {
  1292. info->error_polling_cnt[i]++;
  1293. memset(send_pkg.data, 0, AVALC3_P_DATA_LEN);
  1294. avalonlc3_init_pkg(&send_pkg, AVALC3_P_RSTMMTX, 1, 1);
  1295. avalonlc3_iic_xfer_pkg(avalonlc3, i, &send_pkg, NULL);
  1296. if (info->error_polling_cnt[i] >= 10)
  1297. detach_module(avalonlc3, i);
  1298. }
  1299. if (ret == AVALC3_SEND_OK && !decode_err) {
  1300. info->error_polling_cnt[i] = 0;
  1301. if ((ar.opt == AVALC3_P_STATUS) &&
  1302. (info->mm_dna[i][AVALC3_MM_DNA_LEN - 1] != ar.opt)) {
  1303. applog(LOG_ERR, "%s-%d-%d: Dup address found %d-%d",
  1304. avalonlc3->drv->name, avalonlc3->device_id, i,
  1305. info->mm_dna[i][AVALC3_MM_DNA_LEN - 1], ar.opt);
  1306. hexdump((uint8_t *)&ar, sizeof(ar));
  1307. detach_module(avalonlc3, i);
  1308. }
  1309. }
  1310. }
  1311. return 0;
  1312. }
  1313. static int copy_pool_stratum(struct pool *pool_stratum, struct pool *pool)
  1314. {
  1315. int i;
  1316. int merkles = pool->merkles, job_id_len;
  1317. size_t coinbase_len = pool->coinbase_len;
  1318. unsigned short crc;
  1319. if (!pool->swork.job_id)
  1320. return 1;
  1321. if (pool_stratum->swork.job_id) {
  1322. job_id_len = strlen(pool->swork.job_id);
  1323. crc = crc16((unsigned char *)pool->swork.job_id, job_id_len);
  1324. job_id_len = strlen(pool_stratum->swork.job_id);
  1325. if (crc16((unsigned char *)pool_stratum->swork.job_id, job_id_len) == crc)
  1326. return 1;
  1327. }
  1328. cg_wlock(&pool_stratum->data_lock);
  1329. free(pool_stratum->swork.job_id);
  1330. free(pool_stratum->nonce1);
  1331. free(pool_stratum->coinbase);
  1332. pool_stratum->coinbase = cgcalloc(coinbase_len, 1);
  1333. memcpy(pool_stratum->coinbase, pool->coinbase, coinbase_len);
  1334. for (i = 0; i < pool_stratum->merkles; i++)
  1335. free(pool_stratum->swork.merkle_bin[i]);
  1336. if (merkles) {
  1337. pool_stratum->swork.merkle_bin = cgrealloc(pool_stratum->swork.merkle_bin,
  1338. sizeof(char *) * merkles + 1);
  1339. for (i = 0; i < merkles; i++) {
  1340. pool_stratum->swork.merkle_bin[i] = cgmalloc(32);
  1341. memcpy(pool_stratum->swork.merkle_bin[i], pool->swork.merkle_bin[i], 32);
  1342. }
  1343. }
  1344. pool_stratum->sdiff = pool->sdiff;
  1345. pool_stratum->coinbase_len = pool->coinbase_len;
  1346. pool_stratum->nonce2_offset = pool->nonce2_offset;
  1347. pool_stratum->n2size = pool->n2size;
  1348. pool_stratum->merkles = pool->merkles;
  1349. pool_stratum->swork.job_id = strdup(pool->swork.job_id);
  1350. pool_stratum->nonce1 = strdup(pool->nonce1);
  1351. memcpy(pool_stratum->ntime, pool->ntime, sizeof(pool_stratum->ntime));
  1352. memcpy(pool_stratum->header_bin, pool->header_bin, sizeof(pool_stratum->header_bin));
  1353. cg_wunlock(&pool_stratum->data_lock);
  1354. return 0;
  1355. }
  1356. static void avalonlc3_init_setting(struct cgpu_info *avalonlc3, int addr)
  1357. {
  1358. struct avalonlc3_pkg send_pkg;
  1359. uint32_t tmp;
  1360. memset(send_pkg.data, 0, AVALC3_P_DATA_LEN);
  1361. tmp = be32toh(opt_avalonlc3_freq_sel);
  1362. memcpy(send_pkg.data + 4, &tmp, 4);
  1363. tmp = 1;
  1364. if (!opt_avalonlc3_smart_speed)
  1365. tmp = 0;
  1366. tmp |= (opt_avalonlc3_nonce_check << 1);
  1367. tmp |= (opt_avalonlc3_roll_enable << 2);
  1368. send_pkg.data[8] = tmp & 0xff;
  1369. send_pkg.data[9] = opt_avalonlc3_nonce_mask & 0xff;
  1370. tmp = be32toh(opt_avalonlc3_mux_l2h);
  1371. memcpy(send_pkg.data + 10, &tmp, 4);
  1372. applog(LOG_DEBUG, "%s-%d-%d: avalonlc3 set mux l2h %u",
  1373. avalonlc3->drv->name, avalonlc3->device_id, addr,
  1374. opt_avalonlc3_mux_l2h);
  1375. tmp = be32toh(opt_avalonlc3_mux_h2l);
  1376. memcpy(send_pkg.data + 14, &tmp, 4);
  1377. applog(LOG_DEBUG, "%s-%d-%d: avalonlc3 set mux h2l %u",
  1378. avalonlc3->drv->name, avalonlc3->device_id, addr,
  1379. opt_avalonlc3_mux_h2l);
  1380. tmp = be32toh(opt_avalonlc3_h2ltime0_spd);
  1381. memcpy(send_pkg.data + 18, &tmp, 4);
  1382. applog(LOG_DEBUG, "%s-%d-%d: avalonlc3 set h2ltime0 spd %u",
  1383. avalonlc3->drv->name, avalonlc3->device_id, addr,
  1384. opt_avalonlc3_h2ltime0_spd);
  1385. tmp = be32toh(opt_avalonlc3_spdlow);
  1386. memcpy(send_pkg.data + 22, &tmp, 4);
  1387. applog(LOG_DEBUG, "%s-%d-%d: avalonlc3 set spdlow %u",
  1388. avalonlc3->drv->name, avalonlc3->device_id, addr,
  1389. opt_avalonlc3_spdlow);
  1390. tmp = be32toh(opt_avalonlc3_spdhigh);
  1391. memcpy(send_pkg.data + 26, &tmp, 4);
  1392. applog(LOG_DEBUG, "%s-%d-%d: avalonlc3 set spdhigh %u",
  1393. avalonlc3->drv->name, avalonlc3->device_id, addr,
  1394. opt_avalonlc3_spdhigh);
  1395. send_pkg.data[30] = opt_avalonlc3_tbase & 0xff;
  1396. applog(LOG_DEBUG, "%s-%d-%d: avalonlc3 set tbase %u",
  1397. avalonlc3->drv->name, avalonlc3->device_id, addr,
  1398. opt_avalonlc3_tbase);
  1399. /* Package the data */
  1400. avalonlc3_init_pkg(&send_pkg, AVALC3_P_SET, 1, 1);
  1401. if (addr == AVALC3_MODULE_BROADCAST)
  1402. avalonlc3_send_bc_pkgs(avalonlc3, &send_pkg);
  1403. else
  1404. avalonlc3_iic_xfer_pkg(avalonlc3, addr, &send_pkg, NULL);
  1405. }
  1406. static void avalonlc3_set_voltage_level(struct cgpu_info *avalonlc3, int addr, unsigned int voltage[])
  1407. {
  1408. struct avalonlc3_info *info = avalonlc3->device_data;
  1409. struct avalonlc3_pkg send_pkg;
  1410. uint32_t tmp;
  1411. uint8_t i;
  1412. memset(send_pkg.data, 0, AVALC3_P_DATA_LEN);
  1413. /* NOTE: miner_count should <= 8 */
  1414. for (i = 0; i < info->miner_count[addr]; i++) {
  1415. tmp = be32toh(encode_voltage(voltage[i] +
  1416. opt_avalonlc3_voltage_level_offset));
  1417. memcpy(send_pkg.data + i * 4, &tmp, 4);
  1418. }
  1419. applog(LOG_DEBUG, "%s-%d-%d: avalonlc3 set voltage miner %d, (%d-%d)",
  1420. avalonlc3->drv->name, avalonlc3->device_id, addr,
  1421. i, voltage[0], voltage[info->miner_count[addr] - 1]);
  1422. /* Package the data */
  1423. avalonlc3_init_pkg(&send_pkg, AVALC3_P_SET_VOLT, 1, 1);
  1424. if (addr == AVALC3_MODULE_BROADCAST)
  1425. avalonlc3_send_bc_pkgs(avalonlc3, &send_pkg);
  1426. else
  1427. avalonlc3_iic_xfer_pkg(avalonlc3, addr, &send_pkg, NULL);
  1428. }
  1429. static void avalonlc3_set_asic_otp(struct cgpu_info *avalonlc3, int addr, unsigned int asic[])
  1430. {
  1431. struct avalonlc3_info *info = avalonlc3->device_data;
  1432. struct avalonlc3_pkg send_pkg;
  1433. uint32_t tmp, core_sel;
  1434. uint8_t i;
  1435. memset(send_pkg.data, 0, AVALC3_P_DATA_LEN);
  1436. /* NOTE: miner_count should <= 8 */
  1437. for (i = 0; i < info->miner_count[addr]; i++) {
  1438. if (asic[i] < 0)
  1439. asic[i] = 0;
  1440. else if (asic[i] > (AVALC3_DEFAULT_ASIC_MAX -1))
  1441. asic[i] = AVALC3_DEFAULT_ASIC_MAX - 1;
  1442. tmp = be32toh(asic[i]);
  1443. memcpy(send_pkg.data + i * 4, &tmp, 4);
  1444. }
  1445. applog(LOG_DEBUG, "%s-%d-%d: avalonlc3 set asic for otp reading %d, (%d-%d)",
  1446. avalonlc3->drv->name, avalonlc3->device_id, addr,
  1447. i, asic[0], asic[info->miner_count[addr] - 1]);
  1448. /* Package the data */
  1449. avalonlc3_init_pkg(&send_pkg, AVALC3_P_SET_ASIC_OTP, 1, 1);
  1450. if (addr == AVALC3_MODULE_BROADCAST)
  1451. avalonlc3_send_bc_pkgs(avalonlc3, &send_pkg);
  1452. else
  1453. avalonlc3_iic_xfer_pkg(avalonlc3, addr, &send_pkg, NULL);
  1454. }
  1455. static void avalonlc3_set_freq(struct cgpu_info *avalonlc3, int addr, int miner_id, unsigned int freq[])
  1456. {
  1457. struct avalonlc3_info *info = avalonlc3->device_data;
  1458. struct avalonlc3_pkg send_pkg;
  1459. uint32_t tmp, f;
  1460. uint8_t i;
  1461. memset(send_pkg.data, 0, AVALC3_P_DATA_LEN);
  1462. for (i = 0; i < AVALC3_DEFAULT_PLL_CNT; i++) {
  1463. tmp = be32toh(api_get_cpm(freq[i]));
  1464. memcpy(send_pkg.data + i * 4, &tmp, 4);
  1465. }
  1466. f = freq[0];
  1467. for (i = 1; i < AVALC3_DEFAULT_PLL_CNT; i++)
  1468. f = f > freq[i] ? f : freq[i];
  1469. f = f ? f : 1;
  1470. /* TODO: adjust it according to frequency */
  1471. tmp = 100;
  1472. tmp = be32toh(tmp);
  1473. memcpy(send_pkg.data + AVALC3_DEFAULT_PLL_CNT * 4, &tmp, 4);
  1474. tmp = AVALC3_ASIC_TIMEOUT_CONST / f * 83 / 100;
  1475. tmp = be32toh(tmp);
  1476. memcpy(send_pkg.data + AVALC3_DEFAULT_PLL_CNT * 4 + 4, &tmp, 4);
  1477. applog(LOG_DEBUG, "%s-%d-%d: avalonlc3 set freq miner %x-%x",
  1478. avalonlc3->drv->name, avalonlc3->device_id, addr,
  1479. miner_id, be32toh(tmp));
  1480. /* Package the data */
  1481. avalonlc3_init_pkg(&send_pkg, AVALC3_P_SET_PLL, miner_id + 1, info->miner_count[addr]);
  1482. if (addr == AVALC3_MODULE_BROADCAST)
  1483. avalonlc3_send_bc_pkgs(avalonlc3, &send_pkg);
  1484. else
  1485. avalonlc3_iic_xfer_pkg(avalonlc3, addr, &send_pkg, NULL);
  1486. }
  1487. static void avalonlc3_set_factory_info(struct cgpu_info *avalonlc3, int addr, uint8_t value[])
  1488. {
  1489. struct avalonlc3_pkg send_pkg;
  1490. uint8_t i;
  1491. memset(send_pkg.data, 0, AVALC3_P_DATA_LEN);
  1492. for (i = 0; i < AVALC3_DEFAULT_FACTORY_INFO_CNT; i++)
  1493. send_pkg.data[i] = value[i];
  1494. /* Package the data */
  1495. avalonlc3_init_pkg(&send_pkg, AVALC3_P_SET_FAC, 1, 1);
  1496. if (addr == AVALC3_MODULE_BROADCAST)
  1497. avalonlc3_send_bc_pkgs(avalonlc3, &send_pkg);
  1498. else
  1499. avalonlc3_iic_xfer_pkg(avalonlc3, addr, &send_pkg, NULL);
  1500. }
  1501. static void avalonlc3_set_overclocking_info(struct cgpu_info *avalonlc3, int addr, uint8_t value[])
  1502. {
  1503. struct avalonlc3_pkg send_pkg;
  1504. uint8_t i;
  1505. memset(send_pkg.data, 0, AVALC3_P_DATA_LEN);
  1506. for (i = 0; i < AVALC3_DEFAULT_OVERCLOCKING_CNT; i++)
  1507. send_pkg.data[i] = value[i];
  1508. /* Package the data */
  1509. avalonlc3_init_pkg(&send_pkg, AVALC3_P_SET_OC, 1, 1);
  1510. if (addr == AVALC3_MODULE_BROADCAST)
  1511. avalonlc3_send_bc_pkgs(avalonlc3, &send_pkg);
  1512. else
  1513. avalonlc3_iic_xfer_pkg(avalonlc3, addr, &send_pkg, NULL);
  1514. }
  1515. static void avalonlc3_set_ss_param(struct cgpu_info *avalonlc3, int addr)
  1516. {
  1517. struct avalonlc3_pkg send_pkg;
  1518. uint32_t tmp;
  1519. if (!opt_avalonlc3_smart_speed)
  1520. return;
  1521. memset(send_pkg.data, 0, AVALC3_P_DATA_LEN);
  1522. tmp = be32toh(opt_avalonlc3_th_pass);
  1523. memcpy(send_pkg.data, &tmp, 4);
  1524. applog(LOG_DEBUG, "%s-%d-%d: avalonlc3 set th pass %u",
  1525. avalonlc3->drv->name, avalonlc3->device_id, addr,
  1526. opt_avalonlc3_th_pass);
  1527. tmp = be32toh(opt_avalonlc3_th_fail);
  1528. memcpy(send_pkg.data + 4, &tmp, 4);
  1529. applog(LOG_DEBUG, "%s-%d-%d: avalonlc3 set th fail %u",
  1530. avalonlc3->drv->name, avalonlc3->device_id, addr,
  1531. opt_avalonlc3_th_fail);
  1532. tmp = be32toh(opt_avalonlc3_th_init);
  1533. memcpy(send_pkg.data + 8, &tmp, 4);
  1534. applog(LOG_DEBUG, "%s-%d-%d: avalonlc3 set th init %u",
  1535. avalonlc3->drv->name, avalonlc3->device_id, addr,
  1536. opt_avalonlc3_th_init);
  1537. tmp = be32toh(opt_avalonlc3_th_ms);
  1538. memcpy(send_pkg.data + 12, &tmp, 4);
  1539. applog(LOG_DEBUG, "%s-%d-%d: avalonlc3 set th ms %u",
  1540. avalonlc3->drv->name, avalonlc3->device_id, addr,
  1541. opt_avalonlc3_th_ms);
  1542. tmp = be32toh(opt_avalonlc3_th_timeout);
  1543. memcpy(send_pkg.data + 16, &tmp, 4);
  1544. applog(LOG_DEBUG, "%s-%d-%d: avalonlc3 set th timeout %u",
  1545. avalonlc3->drv->name, avalonlc3->device_id, addr,
  1546. opt_avalonlc3_th_timeout);
  1547. tmp = be32toh(opt_avalonlc3_th_add);
  1548. memcpy(send_pkg.data + 20, &tmp, 4);
  1549. applog(LOG_DEBUG, "%s-%d-%d: avalonlc3 set th add %u",
  1550. avalonlc3->drv->name, avalonlc3->device_id, addr,
  1551. opt_avalonlc3_th_add);
  1552. /* Package the data */
  1553. avalonlc3_init_pkg(&send_pkg, AVALC3_P_SET_SS, 1, 1);
  1554. if (addr == AVALC3_MODULE_BROADCAST)
  1555. avalonlc3_send_bc_pkgs(avalonlc3, &send_pkg);
  1556. else
  1557. avalonlc3_iic_xfer_pkg(avalonlc3, addr, &send_pkg, NULL);
  1558. }
  1559. static void avalonlc3_stratum_finish(struct cgpu_info *avalonlc3)
  1560. {
  1561. struct avalonlc3_pkg send_pkg;
  1562. memset(send_pkg.data, 0, AVALC3_P_DATA_LEN);
  1563. avalonlc3_init_pkg(&send_pkg, AVALC3_P_JOB_FIN, 1, 1);
  1564. avalonlc3_send_bc_pkgs(avalonlc3, &send_pkg);
  1565. }
  1566. static void avalonlc3_set_finish(struct cgpu_info *avalonlc3, int addr)
  1567. {
  1568. struct avalonlc3_pkg send_pkg;
  1569. memset(send_pkg.data, 0, AVALC3_P_DATA_LEN);
  1570. avalonlc3_init_pkg(&send_pkg, AVALC3_P_SET_FIN, 1, 1);
  1571. avalonlc3_iic_xfer_pkg(avalonlc3, addr, &send_pkg, NULL);
  1572. }
  1573. static void avalonlc3_sswork_update(struct cgpu_info *avalonlc3)
  1574. {
  1575. struct avalonlc3_info *info = avalonlc3->device_data;
  1576. struct thr_info *thr = avalonlc3->thr[0];
  1577. struct pool *pool;
  1578. int coinbase_len_posthash, coinbase_len_prehash;
  1579. cgtime(&info->last_stratum);
  1580. /*
  1581. * NOTE: We need mark work_restart to private information,
  1582. * So that it cann't reset by hash_driver_work
  1583. */
  1584. if (thr->work_restart)
  1585. info->work_restart = thr->work_restart;
  1586. applog(LOG_NOTICE, "%s-%d: New stratum: restart: %d, update: %d, clean: %d",
  1587. avalonlc3->drv->name, avalonlc3->device_id,
  1588. thr->work_restart, thr->work_update, thr->clean_jobs);
  1589. /* Step 1: MM protocol check */
  1590. pool = current_pool();
  1591. if (!pool->has_stratum)
  1592. quit(1, "%s-%d: MM has to use stratum pools", avalonlc3->drv->name, avalonlc3->device_id);
  1593. coinbase_len_prehash = pool->nonce2_offset - (pool->nonce2_offset % SHA256_BLOCK_SIZE);
  1594. coinbase_len_posthash = pool->coinbase_len - coinbase_len_prehash;
  1595. if (coinbase_len_posthash + SHA256_BLOCK_SIZE > AVALC3_P_COINBASE_SIZE) {
  1596. applog(LOG_ERR, "%s-%d: MM pool modified coinbase length(%d) is more than %d",
  1597. avalonlc3->drv->name, avalonlc3->device_id,
  1598. coinbase_len_posthash + SHA256_BLOCK_SIZE, AVALC3_P_COINBASE_SIZE);
  1599. return;
  1600. }
  1601. if (pool->merkles > AVALC3_P_MERKLES_COUNT) {
  1602. applog(LOG_ERR, "%s-%d: MM merkles has to be less then %d", avalonlc3->drv->name, avalonlc3->device_id, AVALC3_P_MERKLES_COUNT);
  1603. return;
  1604. }
  1605. if (pool->n2size < 3) {
  1606. applog(LOG_ERR, "%s-%d: MM nonce2 size has to be >= 3 (%d)", avalonlc3->drv->name, avalonlc3->device_id, pool->n2size);
  1607. return;
  1608. }
  1609. cg_wlock(&info->update_lock);
  1610. /* Step 2: Send out stratum pkgs */
  1611. cg_rlock(&pool->data_lock);
  1612. copy_pool_stratum(&info->pool2, &info->pool1);
  1613. copy_pool_stratum(&info->pool1, &info->pool0);
  1614. if (copy_pool_stratum(&info->pool0, pool)) {
  1615. cg_runlock(&pool->data_lock);
  1616. cg_wunlock(&info->update_lock);
  1617. return;
  1618. } else {
  1619. info->pool_no = pool->pool_no;
  1620. avalonlc3_stratum_pkgs(avalonlc3, pool);
  1621. cg_runlock(&pool->data_lock);
  1622. }
  1623. /* Step 3: Send out finish pkg */
  1624. avalonlc3_stratum_finish(avalonlc3);
  1625. cg_wunlock(&info->update_lock);
  1626. }
  1627. static int64_t avalonlc3_scanhash(struct thr_info *thr)
  1628. {
  1629. struct cgpu_info *avalonlc3 = thr->cgpu;
  1630. struct avalonlc3_info *info = avalonlc3->device_data;
  1631. struct timeval current;
  1632. int i, j, k, count = 0;
  1633. int temp_max;
  1634. int64_t ret;
  1635. bool update_settings = false;
  1636. if ((info->connecter == AVALC3_CONNECTER_AUC) &&
  1637. (unlikely(avalonlc3->usbinfo.nodev))) {
  1638. applog(LOG_ERR, "%s-%d: Device disappeared, shutting down thread",
  1639. avalonlc3->drv->name, avalonlc3->device_id);
  1640. return -1;
  1641. }
  1642. /* Step 1: Stop polling and detach the device if there is no stratum in 3 minutes, network is down */
  1643. cgtime(&current);
  1644. if (tdiff(&current, &(info->last_stratum)) > 180.0) {
  1645. for (i = 1; i < AVALC3_DEFAULT_MODULARS; i++) {
  1646. if (!info->enable[i])
  1647. continue;
  1648. detach_module(avalonlc3, i);
  1649. }
  1650. info->mm_count = 0;
  1651. return 0;
  1652. }
  1653. /* Step 2: Try to detect new modules */
  1654. if ((tdiff(&current, &(info->last_detect)) > AVALC3_MODULE_DETECT_INTERVAL) ||
  1655. !info->mm_count) {
  1656. cgtime(&info->last_detect);
  1657. detect_modules(avalonlc3);
  1658. }
  1659. /* Step 3: ASIC configrations (voltage and frequency) */
  1660. for (i = 1; i < AVALC3_DEFAULT_MODULARS; i++) {
  1661. if (!info->enable[i])
  1662. continue;
  1663. update_settings = false;
  1664. /* Check temperautre */
  1665. temp_max = get_temp_max(info, i);
  1666. /* Enter too hot */
  1667. if (temp_max >= info->temp_overheat[i])
  1668. info->cutoff[i] = 1;
  1669. /* Exit too hot */
  1670. if (info->cutoff[i] && (temp_max <= (info->temp_overheat[i] - 10)))
  1671. info->cutoff[i] = 0;
  1672. switch (info->freq_mode[i]) {
  1673. case AVALC3_FREQ_INIT_MODE:
  1674. update_settings = true;
  1675. for (j = 0; j < info->miner_count[i]; j++) {
  1676. for (k = 0; k < AVALC3_DEFAULT_PLL_CNT; k++) {
  1677. if (opt_avalonlc3_freq[k] != AVALC3_DEFAULT_FREQUENCY)
  1678. info->set_frequency[i][j][k] = opt_avalonlc3_freq[k];
  1679. }
  1680. }
  1681. avalonlc3_init_setting(avalonlc3, i);
  1682. info->freq_mode[i] = AVALC3_FREQ_PLLADJ_MODE;
  1683. break;
  1684. case AVALC3_FREQ_PLLADJ_MODE:
  1685. if (opt_avalonlc3_smart_speed == AVALC3_DEFAULT_SMARTSPEED_OFF)
  1686. break;
  1687. /* AVALC3_DEFAULT_SMARTSPEED_MODE1: auto speed by A3210 chips */
  1688. break;
  1689. default:
  1690. applog(LOG_ERR, "%s-%d-%d: Invalid frequency mode %d",
  1691. avalonlc3->drv->name, avalonlc3->device_id, i, info->freq_mode[i]);
  1692. break;
  1693. }
  1694. if (update_settings) {
  1695. cg_wlock(&info->update_lock);
  1696. avalonlc3_set_voltage_level(avalonlc3, i, info->set_voltage_level[i]);
  1697. avalonlc3_set_asic_otp(avalonlc3, i, info->set_asic_otp[i]);
  1698. for (j = 0; j < info->miner_count[i]; j++)
  1699. avalonlc3_set_freq(avalonlc3, i, j, info->set_frequency[i][j]);
  1700. if (opt_avalonlc3_smart_speed)
  1701. avalonlc3_set_ss_param(avalonlc3, i);
  1702. avalonlc3_set_finish(avalonlc3, i);
  1703. cg_wunlock(&info->update_lock);
  1704. }
  1705. }
  1706. /* Step 4: Polling */
  1707. cg_rlock(&info->update_lock);
  1708. polling(avalonlc3);
  1709. cg_runlock(&info->update_lock);
  1710. /* Step 5: Calculate mm count */
  1711. for (i = 1; i < AVALC3_DEFAULT_MODULARS; i++) {
  1712. if (info->enable[i])
  1713. count++;
  1714. }
  1715. info->mm_count = count;
  1716. /* Step 6: Calculate hashes. Use the diff1 value which is scaled by
  1717. * device diff and is usually lower than pool diff which will give a
  1718. * more stable result, but remove diff rejected shares to more closely
  1719. * approximate diff accepted values. */
  1720. info->pending_diff1 += avalonlc3->diff1 - info->last_diff1;
  1721. info->last_diff1 = avalonlc3->diff1;
  1722. info->pending_diff1 -= avalonlc3->diff_rejected - info->last_rej;
  1723. info->last_rej = avalonlc3->diff_rejected;
  1724. if (info->pending_diff1 && !info->firsthash.tv_sec) {
  1725. cgtime(&info->firsthash);
  1726. copy_time(&(avalonlc3->dev_start_tv), &(info->firsthash));
  1727. }
  1728. if (info->pending_diff1 <= 0)
  1729. ret = 0;
  1730. else {
  1731. ret = info->pending_diff1;
  1732. info->pending_diff1 = 0;
  1733. }
  1734. return ret * 0xffffffffull;
  1735. }
  1736. static float avalonlc3_hash_cal(struct cgpu_info *avalonlc3, int modular_id)
  1737. {
  1738. struct avalonlc3_info *info = avalonlc3->device_data;
  1739. uint32_t tmp_freq[AVALC3_DEFAULT_PLL_CNT];
  1740. unsigned int i, j, k;
  1741. float mhsmm;
  1742. mhsmm = 0;
  1743. for (i = 0; i < info->miner_count[modular_id]; i++) {
  1744. for (j = 0; j < info->asic_count[modular_id]; j++) {
  1745. for (k = 0; k < AVALC3_DEFAULT_PLL_CNT; k++)
  1746. mhsmm += (info->get_asic[modular_id][i][j][2 + k] * info->get_frequency[modular_id][i][j][k]);
  1747. }
  1748. }
  1749. return mhsmm;
  1750. }
  1751. #define STATBUFLEN_WITHOUT_DBG (6 * 1024)
  1752. #define STATBUFLEN_WITH_DBG (6 * 7 * 1024)
  1753. static struct api_data *avalonlc3_api_stats(struct cgpu_info *avalonlc3)
  1754. {
  1755. struct api_data *root = NULL;
  1756. struct avalonlc3_info *info = avalonlc3->device_data;
  1757. int i, j, k, m;
  1758. char buf[256];
  1759. char *statbuf = NULL;
  1760. struct timeval current;
  1761. float mhsmm, auc_temp = 0.0;
  1762. double a, b, dh;
  1763. cgtime(&current);
  1764. if (opt_debug)
  1765. statbuf = cgcalloc(STATBUFLEN_WITH_DBG, 1);
  1766. else
  1767. statbuf = cgcalloc(STATBUFLEN_WITHOUT_DBG, 1);
  1768. for (i = 1; i < AVALC3_DEFAULT_MODULARS; i++) {
  1769. if (!info->enable[i])
  1770. continue;
  1771. sprintf(buf, "Ver[%s]", info->mm_version[i]);
  1772. strcpy(statbuf, buf);
  1773. sprintf(buf, " DNA[%02x%02x%02x%02x%02x%02x%02x%02x]",
  1774. info->mm_dna[i][0],
  1775. info->mm_dna[i][1],
  1776. info->mm_dna[i][2],
  1777. info->mm_dna[i][3],
  1778. info->mm_dna[i][4],
  1779. info->mm_dna[i][5],
  1780. info->mm_dna[i][6],
  1781. info->mm_dna[i][7]);
  1782. strcat(statbuf, buf);
  1783. sprintf(buf, " Elapsed[%.0f]", tdiff(&current, &(info->elapsed[i])));
  1784. strcat(statbuf, buf);
  1785. strcat(statbuf, " MW[");
  1786. info->local_works[i] = 0;
  1787. for (j = 0; j < info->miner_count[i]; j++) {
  1788. info->local_works[i] += info->local_works_i[i][j];
  1789. sprintf(buf, "%"PRIu64" ", info->local_works_i[i][j]);
  1790. strcat(statbuf, buf);
  1791. }
  1792. statbuf[strlen(statbuf) - 1] = ']';
  1793. sprintf(buf, " LW[%"PRIu64"]", info->local_works[i]);
  1794. strcat(statbuf, buf);
  1795. strcat(statbuf, " MH[");
  1796. info->hw_works[i] = 0;
  1797. for (j = 0; j < info->miner_count[i]; j++) {
  1798. info->hw_works[i] += info->hw_works_i[i][j];
  1799. sprintf(buf, "%"PRIu64" ", info->hw_works_i[i][j]);
  1800. strcat(statbuf, buf);
  1801. }
  1802. statbuf[strlen(statbuf) - 1] = ']';
  1803. sprintf(buf, " HW[%"PRIu64"]", info->hw_works[i]);
  1804. strcat(statbuf, buf);
  1805. a = 0;
  1806. b = 0;
  1807. for (j = 0; j < info->miner_count[i]; j++) {
  1808. for (k = 0; k < info->asic_count[i]; k++) {
  1809. a += info->get_asic[i][j][k][0];
  1810. b += info->get_asic[i][j][k][1];
  1811. }
  1812. }
  1813. dh = b ? (b / (a + b)) * 100 : 0;
  1814. sprintf(buf, " DH[%.3f%%]", dh);
  1815. strcat(statbuf, buf);
  1816. sprintf(buf, " Temp[%d]", info->temp_mm[i]);
  1817. strcat(statbuf, buf);
  1818. sprintf(buf, " TMax[%d]", get_temp_max(info, i));
  1819. strcat(statbuf, buf);
  1820. sprintf(buf, " Fan[%d]", info->fan_cpm[i]);
  1821. strcat(statbuf, buf);
  1822. sprintf(buf, " FanR[%d%%]", info->fan_pct[i]);
  1823. strcat(statbuf, buf);
  1824. sprintf(buf, " Vo[%d]", info->get_voltage[i][0]);
  1825. strcat(statbuf, buf);
  1826. sprintf(buf, " PS[");
  1827. strcat(statbuf, buf);
  1828. for (j = 0; j < AVALC3_DEFAULT_POWER_INFO_CNT; j++) {
  1829. sprintf(buf, "%d ", info->power_info[j]);
  1830. strcat(statbuf, buf);
  1831. }
  1832. statbuf[strlen(statbuf) - 1] = ']';
  1833. if (opt_debug) {
  1834. for (j = 0; j < info->miner_count[i]; j++) {
  1835. sprintf(buf, " PLL%d[", j);
  1836. strcat(statbuf, buf);
  1837. for (k = 0; k < AVALC3_DEFAULT_PLL_CNT; k++) {
  1838. sprintf(buf, "%d ", info->get_pll[i][j][k]);
  1839. strcat(statbuf, buf);
  1840. }
  1841. statbuf[strlen(statbuf) - 1] = ']';
  1842. }
  1843. }
  1844. mhsmm = avalonlc3_hash_cal(avalonlc3, i);
  1845. sprintf(buf, " GHSmm[%.2f] WU[%.2f] Freq[%.2f]", (float)mhsmm / 1000,
  1846. info->diff1[i] / tdiff(&current, &(info->elapsed[i])) * 60.0,
  1847. (float)mhsmm / (info->asic_count[i] * info->miner_count[i] * 172));
  1848. strcat(statbuf, buf);
  1849. sprintf(buf, " Led[%d]", info->led_indicator[i]);
  1850. strcat(statbuf, buf);
  1851. for (j = 0; j < info->miner_count[i]; j++) {
  1852. sprintf(buf, " MW%d[", j);
  1853. strcat(statbuf, buf);
  1854. for (k = 0; k < info->asic_count[i]; k++) {
  1855. sprintf(buf, "%"PRIu64" ", info->chip_matching_work[i][j][k]);
  1856. strcat(statbuf, buf);
  1857. }
  1858. statbuf[strlen(statbuf) - 1] = ']';
  1859. }
  1860. sprintf(buf, " TA[%d]", info->total_asics[i]);
  1861. strcat(statbuf, buf);
  1862. strcat(statbuf, " ECHU[");
  1863. for (j = 0; j < info->miner_count[i]; j++) {
  1864. sprintf(buf, "%d ", info->error_code[i][j]);
  1865. strcat(statbuf, buf);
  1866. }
  1867. statbuf[strlen(statbuf) - 1] = ']';
  1868. sprintf(buf, " ECMM[%d]", info->error_code[i][j]);
  1869. strcat(statbuf, buf);
  1870. if (opt_debug) {
  1871. sprintf(buf, " FAC0[%d]", info->factory_info[0]);
  1872. strcat(statbuf, buf);
  1873. sprintf(buf, " OC[%d]", info->overclocking_info[0]);
  1874. strcat(statbuf, buf);
  1875. for (j = 0; j < info->miner_count[i]; j++) {
  1876. sprintf(buf, " SF%d[", j);
  1877. strcat(statbuf, buf);
  1878. for (k = 0; k < AVALC3_DEFAULT_PLL_CNT; k++) {
  1879. sprintf(buf, "%d ", info->set_frequency[i][j][k]);
  1880. strcat(statbuf, buf);
  1881. }
  1882. statbuf[strlen(statbuf) - 1] = ']';
  1883. }
  1884. for (j = 0; j < info->miner_count[i]; j++) {
  1885. sprintf(buf, " PVT_T%d[", j);
  1886. strcat(statbuf, buf);
  1887. for (k = 0; k < info->asic_count[i]; k++) {
  1888. sprintf(buf, "%3d ", info->temp[i][j][k]);
  1889. strcat(statbuf, buf);
  1890. }
  1891. statbuf[strlen(statbuf) - 1] = ']';
  1892. statbuf[strlen(statbuf)] = '\0';
  1893. }
  1894. for (j = 0; j < info->miner_count[i]; j++) {
  1895. sprintf(buf, " PVT_V%d[", j);
  1896. strcat(statbuf, buf);
  1897. for (k = 0; k < info->asic_count[i]; k++) {
  1898. sprintf(buf, "%d ", info->core_volt[i][j][k][0]);
  1899. strcat(statbuf, buf);
  1900. }
  1901. statbuf[strlen(statbuf) - 1] = ']';
  1902. statbuf[strlen(statbuf)] = '\0';
  1903. }
  1904. for (j = 0; j < info->miner_count[i]; j++) {
  1905. sprintf(buf, " ERATIO%d[", j);
  1906. strcat(statbuf, buf);
  1907. for (k = 0; k < info->asic_count[i]; k++) {
  1908. if (info->get_asic[i][j][k][0])
  1909. sprintf(buf, "%6.2f%% ", (double)(info->get_asic[i][j][k][1] * 100.0 / (info->get_asic[i][j][k][0] + info->get_asic[i][j][k][1])));
  1910. else
  1911. sprintf(buf, "%6.2f%% ", 0.0);
  1912. strcat(statbuf, buf);
  1913. }
  1914. statbuf[strlen(statbuf) - 1] = ']';
  1915. }
  1916. int l;
  1917. /* i: modular, j: miner, k:asic, l:value */
  1918. for (l = 0; l < 2; l++) {
  1919. for (j = 0; j < info->miner_count[i]; j++) {
  1920. sprintf(buf, " C_%02d_%02d[", j, l);
  1921. strcat(statbuf, buf);
  1922. for (k = 0; k < info->asic_count[i]; k++) {
  1923. sprintf(buf, "%7d ", info->get_asic[i][j][k][l]);
  1924. strcat(statbuf, buf);
  1925. }
  1926. statbuf[strlen(statbuf) - 1] = ']';
  1927. }
  1928. }
  1929. for (j = 0; j < info->miner_count[i]; j++) {
  1930. sprintf(buf, " GHSmm%02d[", j);
  1931. strcat(statbuf, buf);
  1932. for (k = 0; k < info->asic_count[i]; k++) {
  1933. mhsmm = 0;
  1934. for (l = 2; l < 6; l++) {
  1935. mhsmm += (info->get_asic[i][j][k][l] * info->get_frequency[i][j][k][l - 2]);
  1936. }
  1937. sprintf(buf, "%7.2f ", mhsmm / 1000);
  1938. strcat(statbuf, buf);
  1939. }
  1940. statbuf[strlen(statbuf) - 1] = ']';
  1941. }
  1942. for (k = 0; k < info->miner_count[i]; k++) {
  1943. sprintf(buf, " CINFO%02d[", k);
  1944. strcat(statbuf, buf);
  1945. for (m = 0; m < 23; m++) {
  1946. sprintf(buf, "%02x", info->otp_info[i][k][m]);
  1947. strcat(statbuf, buf);
  1948. }
  1949. sprintf(buf, "]");
  1950. strcat(statbuf, buf);
  1951. }
  1952. }
  1953. sprintf(buf, " FM[%d]", info->freq_mode[i]);
  1954. strcat(statbuf, buf);
  1955. strcat(statbuf, " CRC[");
  1956. for (j = 0; j < info->miner_count[i]; j++) {
  1957. sprintf(buf, "%d ", info->error_crc[i][j]);
  1958. strcat(statbuf, buf);
  1959. }
  1960. statbuf[strlen(statbuf) - 1] = ']';
  1961. sprintf(buf, "MM ID%d", i);
  1962. root = api_add_string(root, buf, statbuf, true);
  1963. }
  1964. free(statbuf);
  1965. root = api_add_int(root, "MM Count", &(info->mm_count), true);
  1966. root = api_add_int(root, "Smart Speed", &opt_avalonlc3_smart_speed, true);
  1967. if (info->connecter == AVALC3_CONNECTER_IIC)
  1968. root = api_add_string(root, "Connecter", "IIC", true);
  1969. if (info->connecter == AVALC3_CONNECTER_AUC) {
  1970. root = api_add_string(root, "Connecter", "AUC", true);
  1971. root = api_add_string(root, "AUC VER", info->auc_version, false);
  1972. root = api_add_int(root, "AUC I2C Speed", &(info->auc_speed), true);
  1973. root = api_add_int(root, "AUC I2C XDelay", &(info->auc_xdelay), true);
  1974. root = api_add_int(root, "AUC Sensor", &(info->auc_sensor), true);
  1975. auc_temp = decode_auc_temp(info->auc_sensor);
  1976. root = api_add_temp(root, "AUC Temperature", &auc_temp, true);
  1977. }
  1978. root = api_add_bool(root, "Connection Overloaded", &info->conn_overloaded, true);
  1979. root = api_add_int(root, "Voltage Level Offset", &opt_avalonlc3_voltage_level_offset, true);
  1980. root = api_add_uint32(root, "Nonce Mask", &opt_avalonlc3_nonce_mask, true);
  1981. return root;
  1982. }
  1983. /* format: voltage[-addr[-miner]]
  1984. * addr[0, AVALC3_DEFAULT_MODULARS - 1], 0 means all modulars
  1985. * miner[0, miner_count], 0 means all miners
  1986. */
  1987. char *set_avalonlc3_device_voltage_level(struct cgpu_info *avalonlc3, char *arg)
  1988. {
  1989. struct avalonlc3_info *info = avalonlc3->device_data;
  1990. int val;
  1991. unsigned int addr = 0, i, j;
  1992. uint32_t miner_id = 0;
  1993. if (!(*arg))
  1994. return NULL;
  1995. sscanf(arg, "%d-%d-%d", &val, &addr, &miner_id);
  1996. if (val < AVALC3_DEFAULT_VOLTAGE_LEVEL_MIN || val > AVALC3_DEFAULT_VOLTAGE_LEVEL_MAX)
  1997. return "Invalid value passed to set_avalonlc3_device_voltage_level";
  1998. if (addr >= AVALC3_DEFAULT_MODULARS) {
  1999. applog(LOG_ERR, "invalid modular index: %d, valid range 0-%d", addr, (AVALC3_DEFAULT_MODULARS - 1));
  2000. return "Invalid modular index to set_avalonlc3_device_voltage_level";
  2001. }
  2002. if (!addr) {
  2003. for (i = 1; i < AVALC3_DEFAULT_MODULARS; i++) {
  2004. if (!info->enable[i])
  2005. continue;
  2006. if (miner_id > info->miner_count[i]) {
  2007. applog(LOG_ERR, "invalid miner index: %d, valid range 0-%d", miner_id, info->miner_count[i]);
  2008. return "Invalid miner index to set_avalonlc3_device_voltage_level";
  2009. }
  2010. if (miner_id)
  2011. info->set_voltage_level[i][miner_id - 1] = val;
  2012. else {
  2013. for (j = 0; j < info->miner_count[i]; j++)
  2014. info->set_voltage_level[i][j] = val;
  2015. }
  2016. avalonlc3_set_voltage_level(avalonlc3, i, info->set_voltage_level[i]);
  2017. }
  2018. } else {
  2019. if (!info->enable[addr]) {
  2020. applog(LOG_ERR, "Disabled modular:%d", addr);
  2021. return "Disabled modular to set_avalonlc3_device_voltage_level";
  2022. }
  2023. if (miner_id > info->miner_count[addr]) {
  2024. applog(LOG_ERR, "invalid miner index: %d, valid range 0-%d", miner_id, info->miner_count[addr]);
  2025. return "Invalid miner index to set_avalonlc3_device_voltage_level";
  2026. }
  2027. if (miner_id)
  2028. info->set_voltage_level[addr][miner_id - 1] = val;
  2029. else {
  2030. for (j = 0; j < info->miner_count[addr]; j++)
  2031. info->set_voltage_level[addr][j] = val;
  2032. }
  2033. avalonlc3_set_voltage_level(avalonlc3, addr, info->set_voltage_level[addr]);
  2034. }
  2035. applog(LOG_NOTICE, "%s-%d: Update voltage-level to %d", avalonlc3->drv->name, avalonlc3->device_id, val);
  2036. return NULL;
  2037. }
  2038. /*
  2039. * format: freq[-addr[-miner]]
  2040. * addr[0, AVALC3_DEFAULT_MODULARS - 1], 0 means all modulars
  2041. * miner[0, miner_count], 0 means all miners
  2042. */
  2043. char *set_avalonlc3_device_freq(struct cgpu_info *avalonlc3, char *arg)
  2044. {
  2045. struct avalonlc3_info *info = avalonlc3->device_data;
  2046. unsigned int val, addr = 0, i, j, k;
  2047. uint32_t miner_id = 0;
  2048. if (!(*arg))
  2049. return NULL;
  2050. sscanf(arg, "%d-%d-%d", &val, &addr, &miner_id);
  2051. if (val > AVALC3_DEFAULT_FREQUENCY_MAX)
  2052. return "Invalid value passed to set_avalonlc3_device_freq";
  2053. if (addr >= AVALC3_DEFAULT_MODULARS) {
  2054. applog(LOG_ERR, "invalid modular index: %d, valid range 0-%d", addr, (AVALC3_DEFAULT_MODULARS - 1));
  2055. return "Invalid modular index to set_avalonlc3_device_freq";
  2056. }
  2057. if (!addr) {
  2058. for (i = 1; i < AVALC3_DEFAULT_MODULARS; i++) {
  2059. if (!info->enable[i])
  2060. continue;
  2061. if (miner_id > info->miner_count[i]) {
  2062. applog(LOG_ERR, "invalid miner index: %d, valid range 0-%d", miner_id, info->miner_count[i]);
  2063. return "Invalid miner index to set_avalonlc3_device_freq";
  2064. }
  2065. if (miner_id) {
  2066. for (k = 0; k < AVALC3_DEFAULT_PLL_CNT; k++)
  2067. info->set_frequency[i][miner_id - 1][k] = val;
  2068. avalonlc3_set_freq(avalonlc3, i, miner_id - 1, info->set_frequency[i][miner_id - 1]);
  2069. } else {
  2070. for (j = 0; j < info->miner_count[i]; j++) {
  2071. for (k = 0; k < AVALC3_DEFAULT_PLL_CNT; k++)
  2072. info->set_frequency[i][j][k] = val;
  2073. avalonlc3_set_freq(avalonlc3, i, j, info->set_frequency[i][j]);
  2074. }
  2075. }
  2076. }
  2077. } else {
  2078. if (!info->enable[addr]) {
  2079. applog(LOG_ERR, "Disabled modular:%d", addr);
  2080. return "Disabled modular to set_avalonlc3_device_freq";
  2081. }
  2082. if (miner_id > info->miner_count[addr]) {
  2083. applog(LOG_ERR, "invalid miner index: %d, valid range 0-%d", miner_id, info->miner_count[addr]);
  2084. return "Invalid miner index to set_avalonlc3_device_freq";
  2085. }
  2086. if (miner_id) {
  2087. for (k = 0; k < AVALC3_DEFAULT_PLL_CNT; k++)
  2088. info->set_frequency[addr][miner_id - 1][k] = val;
  2089. avalonlc3_set_freq(avalonlc3, addr, miner_id - 1, info->set_frequency[addr][miner_id - 1]);
  2090. } else {
  2091. for (j = 0; j < info->miner_count[addr]; j++) {
  2092. for (k = 0; k < AVALC3_DEFAULT_PLL_CNT; k++)
  2093. info->set_frequency[addr][j][k] = val;
  2094. avalonlc3_set_freq(avalonlc3, addr, j, info->set_frequency[addr][j]);
  2095. }
  2096. }
  2097. }
  2098. applog(LOG_NOTICE, "%s-%d: Update frequency to %d",
  2099. avalonlc3->drv->name, avalonlc3->device_id, val);
  2100. return NULL;
  2101. }
  2102. char *set_avalonlc3_factory_info(struct cgpu_info *avalonlc3, char *arg)
  2103. {
  2104. struct avalonlc3_info *info = avalonlc3->device_data;
  2105. char type[AVALC3_DEFAULT_FACTORY_INFO_1_CNT];
  2106. int val;
  2107. if (!(*arg))
  2108. return NULL;
  2109. memset(type, 0, AVALC3_DEFAULT_FACTORY_INFO_1_CNT);
  2110. sscanf(arg, "%d-%s", &val, type);
  2111. if ((val != AVALC3_DEFAULT_FACTORY_INFO_0_IGNORE) &&
  2112. (val < AVALC3_DEFAULT_FACTORY_INFO_0_MIN || val > AVALC3_DEFAULT_FACTORY_INFO_0_MAX))
  2113. return "Invalid value passed to set_avalonlc3_factory_info";
  2114. info->factory_info[0] = val;
  2115. memcpy(&info->factory_info[1], type, AVALC3_DEFAULT_FACTORY_INFO_1_CNT);
  2116. avalonlc3_set_factory_info(avalonlc3, 0, (uint8_t *)info->factory_info);
  2117. applog(LOG_NOTICE, "%s-%d: Update factory info %d",
  2118. avalonlc3->drv->name, avalonlc3->device_id, val);
  2119. return NULL;
  2120. }
  2121. char *set_avalonlc3_overclocking_info(struct cgpu_info *avalonlc3, char *arg)
  2122. {
  2123. struct avalonlc3_info *info = avalonlc3->device_data;
  2124. int val;
  2125. if (!(*arg))
  2126. return NULL;
  2127. sscanf(arg, "%d", &val);
  2128. if (val != AVALC3_DEFAULT_OVERCLOCKING_OFF && val != AVALC3_DEFAULT_OVERCLOCKING_ON)
  2129. return "Invalid value passed to set_avalonlc3_overclocking_info";
  2130. info->overclocking_info[0] = val;
  2131. avalonlc3_set_overclocking_info(avalonlc3, 0, (uint8_t *)info->overclocking_info);
  2132. applog(LOG_NOTICE, "%s-%d: Update Overclocking info %d",
  2133. avalonlc3->drv->name, avalonlc3->device_id, val);
  2134. return NULL;
  2135. }
  2136. static char *avalonlc3_set_device(struct cgpu_info *avalonlc3, char *option, char *setting, char *replybuf)
  2137. {
  2138. unsigned int val;
  2139. struct avalonlc3_info *info = avalonlc3->device_data;
  2140. if (strcasecmp(option, "help") == 0) {
  2141. sprintf(replybuf, "pdelay|fan|frequency|led|voltage");
  2142. return replybuf;
  2143. }
  2144. if (strcasecmp(option, "pdelay") == 0) {
  2145. if (!setting || !*setting) {
  2146. sprintf(replybuf, "missing polling delay setting");
  2147. return replybuf;
  2148. }
  2149. val = (unsigned int)atoi(setting);
  2150. if (val < 1 || val > 65535) {
  2151. sprintf(replybuf, "invalid polling delay: %d, valid range 1-65535", val);
  2152. return replybuf;
  2153. }
  2154. opt_avalonlc3_polling_delay = val;
  2155. applog(LOG_NOTICE, "%s-%d: Update polling delay to: %d",
  2156. avalonlc3->drv->name, avalonlc3->device_id, val);
  2157. return NULL;
  2158. }
  2159. if (strcasecmp(option, "fan") == 0) {
  2160. if (!setting || !*setting) {
  2161. sprintf(replybuf, "missing fan value");
  2162. return replybuf;
  2163. }
  2164. if (set_avalonlc3_fan(setting)) {
  2165. sprintf(replybuf, "invalid fan value, valid range 0-100");
  2166. return replybuf;
  2167. }
  2168. applog(LOG_NOTICE, "%s-%d: Update fan to %d-%d",
  2169. avalonlc3->drv->name, avalonlc3->device_id,
  2170. opt_avalonlc3_fan_min, opt_avalonlc3_fan_max);
  2171. return NULL;
  2172. }
  2173. if (strcasecmp(option, "frequency") == 0) {
  2174. if (!setting || !*setting) {
  2175. sprintf(replybuf, "missing frequency value");
  2176. return replybuf;
  2177. }
  2178. return set_avalonlc3_device_freq(avalonlc3, setting);
  2179. }
  2180. if (strcasecmp(option, "led") == 0) {
  2181. int val_led = -1;
  2182. if (!setting || !*setting) {
  2183. sprintf(replybuf, "missing module_id setting");
  2184. return replybuf;
  2185. }
  2186. sscanf(setting, "%d-%d", &val, &val_led);
  2187. if (val < 1 || val >= AVALC3_DEFAULT_MODULARS) {
  2188. sprintf(replybuf, "invalid module_id: %d, valid range 1-%d", val, AVALC3_DEFAULT_MODULARS);
  2189. return replybuf;
  2190. }
  2191. if (!info->enable[val]) {
  2192. sprintf(replybuf, "the current module was disabled %d", val);
  2193. return replybuf;
  2194. }
  2195. if (val_led == -1)
  2196. info->led_indicator[val] = !info->led_indicator[val];
  2197. else {
  2198. if (val_led < 0 || val_led > 1) {
  2199. sprintf(replybuf, "invalid LED status: %d, valid value 0|1", val_led);
  2200. return replybuf;
  2201. }
  2202. if (val_led != info->led_indicator[val])
  2203. info->led_indicator[val] = val_led;
  2204. }
  2205. applog(LOG_NOTICE, "%s-%d: Module:%d, LED: %s",
  2206. avalonlc3->drv->name, avalonlc3->device_id,
  2207. val, info->led_indicator[val] ? "on" : "off");
  2208. return NULL;
  2209. }
  2210. if (strcasecmp(option, "voltage-level") == 0) {
  2211. if (!setting || !*setting) {
  2212. sprintf(replybuf, "missing voltage-level value");
  2213. return replybuf;
  2214. }
  2215. return set_avalonlc3_device_voltage_level(avalonlc3, setting);
  2216. }
  2217. if (strcasecmp(option, "factory") == 0) {
  2218. if (!setting || !*setting) {
  2219. sprintf(replybuf, "missing factory info");
  2220. return replybuf;
  2221. }
  2222. return set_avalonlc3_factory_info(avalonlc3, setting);
  2223. }
  2224. if (strcasecmp(option, "reboot") == 0) {
  2225. if (!setting || !*setting) {
  2226. sprintf(replybuf, "missing reboot value");
  2227. return replybuf;
  2228. }
  2229. sscanf(setting, "%d", &val);
  2230. if (val < 1 || val >= AVALC3_DEFAULT_MODULARS) {
  2231. sprintf(replybuf, "invalid module_id: %d, valid range 1-%d", val, AVALC3_DEFAULT_MODULARS);
  2232. return replybuf;
  2233. }
  2234. info->reboot[val] = true;
  2235. return NULL;
  2236. }
  2237. if (strcasecmp(option, "overclocking") == 0) {
  2238. if (!setting || !*setting) {
  2239. sprintf(replybuf, "missing overclocking info");
  2240. return replybuf;
  2241. }
  2242. return set_avalonlc3_overclocking_info(avalonlc3, setting);
  2243. }
  2244. sprintf(replybuf, "Unknown option: %s", option);
  2245. return replybuf;
  2246. }
  2247. static void avalonlc3_statline_before(char *buf, size_t bufsiz, struct cgpu_info *avalonlc3)
  2248. {
  2249. struct avalonlc3_info *info = avalonlc3->device_data;
  2250. int temp = -273;
  2251. int fanmin = AVALC3_DEFAULT_FAN_MAX;
  2252. int i, j, k;
  2253. uint32_t frequency = 0;
  2254. float ghs_sum = 0, mhsmm = 0;
  2255. double pass_num = 0.0, fail_num = 0.0;
  2256. for (i = 1; i < AVALC3_DEFAULT_MODULARS; i++) {
  2257. if (!info->enable[i])
  2258. continue;
  2259. if (fanmin >= info->fan_pct[i])
  2260. fanmin = info->fan_pct[i];
  2261. if (temp < get_temp_max(info, i))
  2262. temp = get_temp_max(info, i);
  2263. mhsmm = avalonlc3_hash_cal(avalonlc3, i);
  2264. frequency += (mhsmm / (info->asic_count[i] * info->miner_count[i] * 172));
  2265. ghs_sum += (mhsmm / 1000);
  2266. for (j = 0; j < info->miner_count[i]; j++) {
  2267. for (k = 0; k < info->asic_count[i]; k++) {
  2268. pass_num += info->get_asic[i][j][k][0];
  2269. fail_num += info->get_asic[i][j][k][1];
  2270. }
  2271. }
  2272. }
  2273. if (info->mm_count)
  2274. frequency /= info->mm_count;
  2275. tailsprintf(buf, bufsiz, "%4dMhz %.2fGHS %2dC %.2f%% %3d%%", frequency, ghs_sum, temp,
  2276. (fail_num + pass_num) ? fail_num * 100.0 / (fail_num + pass_num) : 0, fanmin);
  2277. }
  2278. struct device_drv avalonlc3_drv = {
  2279. .drv_id = DRIVER_avalonlc3,
  2280. .dname = "avalonlc3",
  2281. .name = "AVLC3",
  2282. .set_device = avalonlc3_set_device,
  2283. .get_api_stats = avalonlc3_api_stats,
  2284. .get_statline_before = avalonlc3_statline_before,
  2285. .drv_detect = avalonlc3_detect,
  2286. .thread_prepare = avalonlc3_prepare,
  2287. .hash_work = hash_driver_work,
  2288. .flush_work = avalonlc3_sswork_update,
  2289. .update_work = avalonlc3_sswork_update,
  2290. .scanwork = avalonlc3_scanhash,
  2291. .max_diff = AVALC3_DRV_DIFFMAX,
  2292. .genwork = true,
  2293. };