123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680 |
- /*
- * Copyright 2017-2021 vh
- * Copyright 2021-2022 sidehack
- * Copyright 2021-2023 kano
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 3 of the License, or (at your option)
- * any later version. See COPYING for more details.
- */
- #include "driver-gekko.h"
- #include "crc.h"
- #include "compat.h"
- #include <unistd.h>
- #ifdef __GNUC__
- #if __GNUC__ >= 7
- #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
- #endif
- #endif
- // usleep reliability
- #if defined(__APPLE__)
- #define USLEEPMIN 2000
- #define USLEEPPLUS 200
- #elif defined (WIN32)
- #define USLEEPMIN 250
- #define USLEEPPLUS 100
- #else
- #define USLEEPMIN 200
- #define USLEEPPLUS 50
- #endif
- static bool compac_prepare(struct thr_info *thr);
- static pthread_mutex_t static_lock = PTHREAD_MUTEX_INITIALIZER;
- static bool last_widescreen;
- static uint8_t dev_init_count[0xffff] = {0};
- static uint8_t *init_count;
- static uint32_t stat_len;
- static uint32_t chip_max;
- #define MS2US(_n) ((_n) * 1000)
- // report averages and how far they overrun the requested time
- // linux would appear to be unable to handle less than 55us
- // on the RPi4 it would regularly sleep 3 times as long
- // thus code in general ignores sleeping anything less than 200us
- #define TUNE_CODE 1
- static void gekko_usleep(struct COMPAC_INFO *info, int usec)
- {
- #if TUNE_CODE
- struct timeval stt, fin;
- double td, fac;
- #endif
- // error for usleep()
- if (usec >= 1000000)
- {
- cgsleep_ms(usec / 1000);
- #if TUNE_CODE
- mutex_lock(&info->slock);
- info->inv++;
- mutex_unlock(&info->slock);
- #endif
- return;
- }
- #if TUNE_CODE
- cgtime(&stt);
- #endif
- usleep(usec);
- #if TUNE_CODE
- cgtime(&fin);
- td = us_tdiff(&fin, &stt);
- fac = (td / (double)usec);
- mutex_lock(&info->slock);
- if (td < usec)
- info->num0++;
- if (fac >= 1.5)
- {
- info->req1_5 += usec;
- info->fac1_5 += fac;
- info->num1_5++;
- }
- else
- {
- if (fac >= 1.1)
- {
- info->req1_1 += usec;
- info->fac1_1 += fac;
- info->num1_1++;
- }
- else
- {
- info->req += usec;
- info->fac += fac;
- info->num++;
- }
- }
- mutex_unlock(&info->slock);
- #endif
- }
- static float fbound(float value, float lower_bound, float upper_bound)
- {
- if (value < lower_bound)
- return lower_bound;
- if (value > upper_bound)
- return upper_bound;
- return value;
- }
- uint32_t bmcrc(unsigned char *ptr, uint32_t len)
- {
- unsigned char c[5] = {1, 1, 1, 1, 1};
- uint32_t i, c1, ptr_idx = 0;
- for (i = 0; i < len; i++) {
- c1 = c[1];
- c[1] = c[0];
- c[0] = c[4] ^ ((ptr[ptr_idx] & (0x80 >> (i % 8))) ? 1 : 0);
- c[4] = c[3];
- c[3] = c[2];
- c[2] = c1 ^ c[0];
- if (((i + 1) % 8) == 0)
- ptr_idx++;
- }
- return (c[4] * 0x10) | (c[3] * 0x08) | (c[2] * 0x04) | (c[1] * 0x02) | (c[0] * 0x01);
- }
- void dumpbuffer(struct cgpu_info *compac, int LOG_LEVEL, char *note, unsigned char *ptr, uint32_t len)
- {
- if (opt_log_output || LOG_LEVEL <= opt_log_level) {
- char str[2048];
- const char * hex = "0123456789ABCDEF";
- char * pout = str;
- unsigned int i = 0;
- for(; i < 768 && i < len - 1; ++i) {
- *pout++ = hex[(*ptr>>4)&0xF];
- *pout++ = hex[(*ptr++)&0xF];
- if (i % 42 == 41) {
- *pout = 0;
- pout = str;
- applog(LOG_LEVEL, "%i: %s %s: %s", compac->cgminer_id, compac->drv->name, note, str);
- } else {
- *pout++ = ':';
- }
- }
- *pout++ = hex[(*ptr>>4)&0xF];
- *pout++ = hex[(*ptr)&0xF];
- *pout = 0;
- applog(LOG_LEVEL, "%d: %s %d - %s: %s", compac->cgminer_id, compac->drv->name, compac->device_id, note, str);
- }
- }
- static int compac_micro_send(struct cgpu_info *compac, uint8_t cmd, uint8_t channel, uint8_t value)
- {
- struct COMPAC_INFO *info = compac->device_data;
- int bytes = 1;
- int read_bytes = 1;
- int micro_temp;
- uint8_t temp;
- unsigned short usb_val;
- __maybe_unused char null[255];
- // synchronous : safe to run in the listen thread.
- if (!info->micro_found) {
- return 0;
- }
- // Baud Rate : 500,000
- usb_val = (FTDI_BITMODE_CBUS << 8) | 0xF3; // low byte: bitmask - 1111 0011 - CB1(HI), CB0(HI)
- usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BITMODE, usb_val, info->interface, C_SETMODEM);
- gekko_usleep(info, MS2US(2));
- //usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, 0x06, (FTDI_INDEX_BAUD_BTS & 0xff00) | info->interface, C_SETBAUD);
- info->cmd[0] = cmd | channel;
- info->cmd[1] = value;
- if (value != 0x00 || cmd == M2_SET_VCORE) {
- bytes = 2;
- }
- usb_read_timeout(compac, (char *)info->rx, 255, &read_bytes, 1, C_GETRESULTS);
- dumpbuffer(compac, LOG_INFO, "(micro) TX", info->cmd, bytes);
- usb_write(compac, (char *)info->cmd, bytes, &read_bytes, C_REQUESTRESULTS);
- memset(info->rx, 0, info->rx_len);
- usb_read_timeout(compac, (char *)info->rx, 1, &read_bytes, 5, C_GETRESULTS);
- if (read_bytes > 0) {
- dumpbuffer(compac, LOG_INFO, "(micro) RX", info->rx, read_bytes);
- switch (cmd) {
- case 0x20:
- temp = info->rx[0];
- micro_temp = 32 + 1.8 * temp;
- if (micro_temp != info->micro_temp) {
- info->micro_temp = micro_temp;
- applog(LOG_WARNING, "%d: %s %d - micro temp changed to %d°C / %.1f°F",
- compac->cgminer_id, compac->drv->name, compac->device_id, temp, info->micro_temp);
- }
- break;
- default:
- break;
- }
- }
- // Restore Baud Rate
- //usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, (info->bauddiv + 1), (FTDI_INDEX_BAUD_BTS & 0xff00) | info->interface, C_SETBAUD);
- usb_val = (FTDI_BITMODE_CBUS << 8) | 0xF2; // low byte: bitmask - 1111 0010 - CB1(HI), CB0(LO)
- usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BITMODE, usb_val, info->interface, C_SETMODEM);
- gekko_usleep(info, MS2US(2));
- return read_bytes;
- }
- #define compac_send(_c, _r, _b, _crc) compac_send2(_c, _r, _b, _crc, NULL)
- static void compac_send2(struct cgpu_info *compac, unsigned char *req_tx, uint32_t bytes, uint32_t crc_bits, __maybe_unused char *msg)
- {
- struct COMPAC_INFO *info = compac->device_data;
- int read_bytes = 1;
- unsigned int i, off = 0;
- // leave original buffer intact
- if (info->asic_type == BM1397)
- {
- info->cmd[0] = 0x55;
- info->cmd[1] = 0xAA;
- off = 2;
- }
- for (i = 0; i < bytes; i++)
- info->cmd[i+off] = req_tx[i];
- bytes += off;
- info->cmd[bytes-1] |= bmcrc(req_tx, crc_bits);
- #if 0
- if (msg == NULL)
- msg = "null";
- applog(LOG_ERR, "%s() %d: %s %d - Send len %3u (%s)", __func__,
- compac->cgminer_id, compac->drv->name, compac->device_id, bytes, msg);
- applog(LOG_ERR, "%s() [%02x %02x %02x %02x %02x %02x %02x %02x]", __func__,
- info->cmd[0], info->cmd[1], info->cmd[2], info->cmd[3], info->cmd[4], info->cmd[5], info->cmd[6], info->cmd[7]);
- applog(LOG_ERR, "%s() [%02x %02x %02x %02x %02x %02x %02x %02x]", __func__,
- info->cmd[8], info->cmd[9], info->cmd[10], info->cmd[11], info->cmd[12], info->cmd[13], info->cmd[14], info->cmd[15]);
- #endif
- int log_level = (bytes < info->task_len) ? LOG_INFO : LOG_INFO;
- dumpbuffer(compac, log_level, "TX", info->cmd, bytes);
- usb_write(compac, (char *)(info->cmd), bytes, &read_bytes, C_REQUESTRESULTS);
- //let the usb frame propagate
- if (info->asic_type == BM1397)
- gekko_usleep(info, info->usb_prop);
- else
- gekko_usleep(info, MS2US(1));
- }
- static float limit_freq(struct COMPAC_INFO *info, float freq, bool zero)
- {
- switch(info->ident)
- {
- case IDENT_BSC:
- case IDENT_GSC:
- case IDENT_BSD:
- case IDENT_GSD:
- case IDENT_BSE:
- case IDENT_GSE:
- freq = fbound(freq, info->freq_base, 500);
- break;
- case IDENT_GSH:
- case IDENT_BAX:
- case IDENT_GSI:
- freq = fbound(freq, 50, 900);
- break;
- case IDENT_GSF:
- case IDENT_GSFM:
- // allow 0 also if zero is true - coded obviously
- if (zero && freq == 0)
- freq = 0;
- else
- freq = fbound(freq, 100, 800);
- break;
- default:
- // 'should' never happen ...
- freq = fbound(freq, 100, 300);
- break;
- }
- return freq;
- }
- static void ping_freq(struct cgpu_info *compac, int asic)
- {
- struct COMPAC_INFO *info = compac->device_data;
- bool ping = false;
- if (info->asic_type == BM1397)
- {
- unsigned char pingall[] = {0x52, 0x05, 0x00, BM1397FREQ, 0x00};
- compac_send2(compac, pingall, sizeof(pingall), 8 * sizeof(pingall) - 8, "pingfreq");
- ping = true;
- }
- else if (info->asic_type == BM1387)
- {
- unsigned char buffer[] = {0x44, 0x05, 0x00, 0x0C, 0x00}; // PLL_PARAMETER
- buffer[2] = (0x100 / info->chips) * asic;
- compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8);
- ping = true;
- }
- else if (info->asic_type == BM1384)
- {
- unsigned char buffer[] = {0x04, 0x00, 0x04, 0x00};
- buffer[1] = (0x100 / info->chips) * asic;
- compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
- ping = true;
- }
- if (ping)
- {
- cgtime(&info->last_frequency_ping);
- cgtime(&(info->asics[asic].last_frequency_ping));
- }
- }
- static void gsf_calc_nb2c(struct cgpu_info *compac)
- {
- struct COMPAC_INFO *info = compac->device_data;
- int c, i, j;
- double fac;
- if (info->chips == 1)
- {
- // default all 0 is correct
- info->nb2c_setup = true;
- }
- else if (info->chips == 6)
- {
- // groups of 4
- fac = CHIPPY1397(info, 1) / 4.0;
- for (i = 0; i < 256; i += 64)
- {
- for (j = 0; j < 64; j++)
- {
- c = (int)((double)j / fac);
- if (c >= (int)(info->chips))
- c = info->chips - 1;
- info->nb2chip[i + j] = c;
- }
- }
- info->nb2c_setup = true;
- }
- }
- static void gc_wipe(struct GEKKOCHIP *gc, struct timeval *now)
- {
- // clear out everything
- gc->zerosec = now->tv_sec;
- gc->offset = 0;
- memset(gc->noncenum, 0, sizeof(gc->noncenum));
- gc->noncesum = 0;
- gc->last = 0;
- }
- static void gc_wipe_all(struct COMPAC_INFO *info, struct timeval *now, bool locked)
- {
- int i;
- if (!locked)
- mutex_lock(&info->ghlock);
- for (i = 0; i < (int)(info->chips); i++)
- gc_wipe(&(info->asics[i].gc), now);
- if (!locked)
- mutex_unlock(&info->ghlock);
- }
- // update asic->gc offset as at 'now' and correct values
- // info must be locked, wipe creates a new data set
- static void gc_offset(struct COMPAC_INFO *info, struct ASIC_INFO *asic, struct timeval *now, bool wipe, bool locked)
- {
- struct GEKKOCHIP *gc = &(asic->gc);
- time_t delta;
- if (!locked)
- mutex_lock(&info->ghlock);
- // wipe or delta != 0
- if (wipe || !CHCMP(gc->zerosec, now->tv_sec))
- {
- // clear some/all delta data
- delta = CHBASE(now->tv_sec) - CHBASE(gc->zerosec);
- // if time goes back, also reset everything
- // a forward jump of CHNUM will reset the whole buffer
- if (wipe || delta < 0 || delta >= CHNUM)
- gc_wipe(gc, now);
- else
- {
- // delta is > 0, but usually always 1 unless,
- // due to asic failure, a 10 minutes had no nonces
- // however the loop will total 1 iteration each
- // 10 minutes elapsed real time e.g. if not called
- // for 30 minutes, it will loop 3 times
- // there is also a CHNUM-1 limit on that
- gc->zerosec = now->tv_sec;
- // clear out the old values
- do
- {
- gc->offset = CHOFF(gc->offset+1);
- gc->noncesum -= gc->noncenum[CHOFF(gc->offset)];
- gc->noncenum[CHOFF(gc->offset)] = 0;
- if (gc->last < (CHNUM-1))
- gc->last++;
- }
- while (--delta > 0);
- }
- }
- // if there's been no nonces up to now, history must already be all zero
- // so just remove history
- if (gc->noncesum == 0 && gc->last > 0)
- gc->last = 0;
- if (!locked)
- mutex_unlock(&info->ghlock);
- }
- // update info->gh offset as at 'now' and correct values
- // info must be locked, wipe creates a new data set and also wipes all asic->gc
- static void gh_offset(struct COMPAC_INFO *info, struct timeval *now, bool wipe, bool locked)
- {
- struct GEKKOHASH *gh = &(info->gh);
- time_t delta;
- int i;
- if (!locked)
- mutex_lock(&info->ghlock);
- // first time in, wipe is ignored (it's already all zero)
- if (gh->zerosec == 0)
- {
- gh->zerosec = now->tv_sec;
- for (i = 0; i < (int)(info->chips); i++)
- info->asics[i].gc.zerosec = now->tv_sec;
- }
- else
- {
- if (wipe)
- gc_wipe_all(info, now, true);
- // wipe or delta != 0
- if (wipe || gh->zerosec != now->tv_sec)
- {
- // clear some/all delta data
- delta = now->tv_sec - gh->zerosec;
- // if time goes back, also reset everything
- // N.B. a forward time jump between 2 and GHLIMsec
- // seconds will reduce the hash rate value
- // but GHLIMsec or more will reset the whole buffer
- if (wipe || delta < 0 || delta >= GHLIMsec)
- {
- // clear out everything
- gh->zerosec = now->tv_sec;
- gh->offset = 0;
- memset(gh->diff, 0, sizeof(gh->diff));
- memset(gh->firstt, 0, sizeof(gh->firstt));
- memset(gh->firstd, 0, sizeof(gh->firstd));
- memset(gh->lastt, 0, sizeof(gh->lastt));
- memset(gh->noncenum, 0, sizeof(gh->noncenum));
- gh->diffsum = 0;
- gh->noncesum = 0;
- gh->last = 0;
- }
- else
- {
- // delta is > 0, but usually always 1 unless,
- // due to asic failure, a second had no nonces
- // however the loop will total 1 iteration each
- // second elapsed real time e.g. if not called
- // for 3 seconds, it will loop 3 times
- // there is also a GHLIMsec-1 limit on that
- gh->zerosec = now->tv_sec;
- // clear out the old values
- do
- {
- gh->offset = GHOFF(gh->offset+1);
- gh->diffsum -= gh->diff[GHOFF(gh->offset)];
- gh->diff[GHOFF(gh->offset)] = 0;
- gh->noncesum -= gh->noncenum[GHOFF(gh->offset)];
- gh->noncenum[GHOFF(gh->offset)] = 0;
- gh->firstt[GHOFF(gh->offset)].tv_sec = 0;
- gh->firstt[GHOFF(gh->offset)].tv_usec = 0;
- gh->firstd[GHOFF(gh->offset)] = 0;
- gh->lastt[GHOFF(gh->offset)].tv_sec = 0;
- gh->lastt[GHOFF(gh->offset)].tv_usec = 0;
- if (gh->last < (GHNUM-1))
- gh->last++;
- }
- while (--delta > 0);
- }
- }
- }
- // if there's been no nonces up to now, history must already be all zero
- // so just remove history
- if (gh->noncesum == 0 && gh->last > 0)
- gh->last = 0;
- // this also handles the issue of a nonce-less wipe with a high
- // now->tv_usec and if the first nonce comes in during the next second.
- // without setting 'last=0' the previous empty full second(s) will
- // always be included in the elapsed time used to calc the hash rate
- if (!locked)
- mutex_unlock(&info->ghlock);
- }
- // update info->gh with a new nonce as at 'now' (diff=info->difficulty)
- // info must be locked, wipe creates a new data set with the single nonce
- static void add_gekko_nonce(struct COMPAC_INFO *info, struct ASIC_INFO *asic, struct timeval *now)
- {
- struct GEKKOHASH *gh = &(info->gh);
- mutex_lock(&info->ghlock);
- gh_offset(info, now, false, true);
- if (gh->diff[gh->offset] == 0)
- {
- gh->firstt[gh->offset].tv_sec = now->tv_sec;
- gh->firstt[gh->offset].tv_usec = now->tv_usec;
- gh->firstd[gh->offset] = info->difficulty;
- }
- gh->lastt[gh->offset].tv_sec = now->tv_sec;
- gh->lastt[gh->offset].tv_usec = now->tv_usec;
- gh->diff[gh->offset] += info->difficulty;
- gh->diffsum += info->difficulty;
- (gh->noncenum[gh->offset])++;
- (gh->noncesum)++;
- if (asic != NULL)
- {
- struct GEKKOCHIP *gc = &(asic->gc);
- gc_offset(info, asic, now, false, true);
- (gc->noncenum[gc->offset])++;
- (gc->noncesum)++;
- }
- mutex_unlock(&info->ghlock);
- }
- // calculate MH/s hashrate, info must be locked
- // value is 0.0 if there's no useful data
- // caller check info->gh.last for history size used and info->gh.noncesum-1
- // for the amount of data used (i.e. accuracy of the hash rate)
- static double gekko_gh_hashrate(struct COMPAC_INFO *info, struct timeval *now, bool locked)
- {
- struct GEKKOHASH *gh = &(info->gh);
- struct timeval age, end;
- int zero, last;
- uint64_t delta;
- double ghr, old;
- ghr = 0.0;
- if (!locked)
- mutex_lock(&info->ghlock);
- // can't be calculated with only one nonce
- if (gh->diffsum > 0 && gh->noncesum > 1)
- {
- gh_offset(info, now, false, true);
- if (gh->diffsum > 0 && gh->noncesum > 1)
- {
- // offset of 'now'
- zero = gh->offset;
- // offset of oldest nonce
- last = GHOFF(zero - gh->last);
- if (gh->diff[last] != 0)
- {
- // from the oldest nonce, excluding it's diff
- delta = gh->firstd[last];
- age.tv_sec = gh->firstt[last].tv_sec;
- age.tv_usec = gh->firstt[last].tv_usec;
- }
- else
- {
- // if last is empty, use the start time of last
- delta = 0;
- age.tv_sec = gh->zerosec - (GHNUM - 1);
- age.tv_usec = 0;
- }
- // up to the time of the newest nonce as long as it
- // was curr or prev second, otherwise use now
- if (gh->diff[zero] != 0)
- {
- // time of the newest nonce found this second
- end.tv_sec = gh->lastt[zero].tv_sec;
- end.tv_usec = gh->lastt[zero].tv_usec;
- }
- else
- {
- // unexpected ... no recent nonces ...
- if (gh->diff[GHOFF(zero-1)] == 0)
- {
- end.tv_sec = now->tv_sec;
- end.tv_usec = now->tv_usec;
- }
- else
- {
- // time of the newest nonce found this second-1
- end.tv_sec = gh->lastt[GHOFF(zero-1)].tv_sec;
- end.tv_usec = gh->lastt[GHOFF(zero-1)].tv_usec;
- }
- }
- old = tdiff(&end, &age);
- if (old > 0.0)
- {
- ghr = (double)(gh->diffsum - delta)
- * (pow(2.0, 32.0) / old) / 1.0e6;
- }
- }
- }
- if (!locked)
- mutex_unlock(&info->ghlock);
- return ghr;
- }
- static void job_offset(struct COMPAC_INFO *info, struct timeval *now, bool wipe, bool locked)
- {
- struct GEKKOJOB *job = &(info->job);
- time_t delta;
- int jobnow;
- jobnow = JOBTIME(now->tv_sec);
- if (!locked)
- mutex_lock(&info->joblock);
- // first time in, wipe is ignored (it's already all zero)
- if (job->zeromin == 0)
- job->zeromin = jobnow;
- else
- {
- // wipe or delta != 0
- if (wipe || job->zeromin != jobnow)
- {
- // clear some/all delta data
- delta = jobnow - job->zeromin;
- // if time goes back, also reset everything
- // N.B. a forward time jump between 2 and JOBLIMn
- // seconds will reduce the job rate value
- // but JOBLIMn or more will reset the whole buffer
- if (wipe || delta < 0 || delta >= JOBLIMn)
- {
- // clear out everything
- job->zeromin = jobnow;
- job->lastjob.tv_sec = 0;
- job->lastjob.tv_usec = 0;
- job->offset = 0;
- memset(job->firstj, 0, sizeof(job->firstj));
- memset(job->lastj, 0, sizeof(job->lastj));
- memset(job->jobnum, 0, sizeof(job->jobnum));
- memset(job->avgms, 0, sizeof(job->avgms));
- memset(job->minms, 0, sizeof(job->minms));
- memset(job->maxms, 0, sizeof(job->maxms));
- job->jobsnum = 0;
- job->last = 0;
- }
- else
- {
- // delta is > 0, but usually always 1 unless,
- // due to asic or pool failure, a minute had no jobs
- // however the loop will total 1 iteration each
- // minute elapsed real time e.g. if not called
- // for 2 minutes, it will loop 2 times
- // there is also a JOBLIMn-1 limit on that
- job->zeromin = jobnow;
- // clear out the old values
- do
- {
- job->offset = JOBOFF(job->offset+1);
- job->firstj[JOBOFF(job->offset)].tv_sec = 0;
- job->firstj[JOBOFF(job->offset)].tv_usec = 0;
- job->lastj[JOBOFF(job->offset)].tv_sec = 0;
- job->lastj[JOBOFF(job->offset)].tv_usec = 0;
- job->jobsnum -= job->jobnum[JOBOFF(job->offset)];
- job->jobnum[JOBOFF(job->offset)] = 0;
- job->avgms[JOBOFF(job->offset)] = 0;
- job->minms[JOBOFF(job->offset)] = 0;
- job->maxms[JOBOFF(job->offset)] = 0;
- if (job->last < (JOBMIN-1))
- job->last++;
- }
- while (--delta > 0);
- }
- }
- }
- // if there's been no jobs up to now, history must already be all zero
- // so just remove history
- if (job->jobsnum == 0 && job->last > 0)
- job->last = 0;
- // this also handles the issue of a job-less wipe with a high
- // now->tv_usec and if the first job comes in during the next minute.
- // without setting 'last=0' the previous empty full minute will
- // always be included in the elapsed time used to calc the job rate
- if (!locked)
- mutex_unlock(&info->joblock);
- }
- // update info->job with a job as at 'now'
- // info must be locked, wipe creates a new empty data set
- static void add_gekko_job(struct COMPAC_INFO *info, struct timeval *now, bool wipe)
- {
- struct GEKKOJOB *job = &(info->job);
- bool firstjob;
- double avg;
- double ms;
- mutex_lock(&info->joblock);
- job_offset(info, now, wipe, true);
- if (!wipe)
- {
- if (job->jobnum[job->offset] == 0)
- {
- job->firstj[job->offset].tv_sec = now->tv_sec;
- job->firstj[job->offset].tv_usec = now->tv_usec;
- firstjob = true;
- }
- else
- firstjob = false;
- job->lastj[job->offset].tv_sec = now->tv_sec;
- job->lastj[job->offset].tv_usec = now->tv_usec;
- // first job time in each offset gets ignored
- // this is only necessary for the very first job,
- // but easier to do it for every offset group
- if (firstjob)
- {
- // already true
- // job->avgms[job->offset] = 0.0;
- // job->minms[job->offset] = 0.0;
- // job->maxms[job->offset] = 0.0;
- }
- else
- {
- avg = job->avgms[job->offset] * (double)(job->jobnum[job->offset] - 1);
- ms = (double)(now->tv_sec - job->lastjob.tv_sec) * 1000.0;
- ms += (double)(now->tv_usec - job->lastjob.tv_usec) / 1000.0;
- // jobnum[] must be > 0
- job->avgms[job->offset] = (avg + ms) / (double)(job->jobnum[job->offset]);
- if (job->minms[job->offset] == 0.0)
- {
- job->minms[job->offset] = ms;
- job->maxms[job->offset] = ms;
- }
- else
- {
- if (ms < job->minms[job->offset])
- job->minms[job->offset] = ms;
- if (job->maxms[job->offset] < ms)
- job->maxms[job->offset] = ms;
- }
- }
- (job->jobnum[job->offset])++;
- (job->jobsnum)++;
- job->lastjob.tv_sec = now->tv_sec;
- job->lastjob.tv_usec = now->tv_usec;
- }
- mutex_unlock(&info->joblock);
- }
- // ignore nonces for this many work items after the ticket change
- #define TICKET_DELAY 8
- // allow this many nonces below the ticket value in case of work swap delays
- // N.B. if the chip mask is half the wanted value,
- // roughly 85% of shares will be low since CDF 190% = 0.850
- // with the lowest nonce_count of 150 below for diff 2,
- // TICKET_BLOW_LIM 4 will always be exceeded if incorrectly set to diff 1
- #define TICKET_BELOW_LIM 4
- struct TICKET_INFO {
- uint32_t diff; // work diff value
- uint32_t ticket_mask; // ticket mask to ensure work diff
- int nonce_count; // CDF[Erl] nonces must have 1 below low_limit
- double low_limit; // must be a diff below this or ticket is too hi
- double hi_limit; // a diff below this means ticket is too low
- // set to .1 below diff to avoid any rounding
- uint32_t cclimit; // chips x cores limit i.e. required to go above 16
- };
- // ticket restart checks allowed before forced to diff=1
- #define MAX_TICKET_CHECK 3
- // ticket values, diff descending. List values rather than calc them
- // end comments are how long at given task/sec (15 ~= 60 1diff nonce/sec = ~260GH/s)
- // testing should take and chance of failure
- // though it will retry MAX_TICKET_CHECK times so shouldn't give up in the
- // exceedingly rare occasion where it fails once due to bad luck
- // limit to max diff of 16 unless the chips x cores is a bit better than a GSF/GSFM
- // to ensure enough nonces are coming back to identify status changes/issues
- // the luck calculation is the chance all nonce diff values will be above low_limit
- // after nonce_count nonces i.e. after nonce_count nonces there should be a nonce
- // below low_limit, or the ticket mask is actually higher than it was set to
- // the gsl function is cdf_gamma_Q(nonces, nonces, low_limit/diff)
- static struct TICKET_INFO ticket_1397[] =
- {
- { 64, 0xfc, 20000, 65.9, 63.9, 2600 }, // 90 59.3m Erlang=1.6x10-5 <- 64+ nonces
- { 32, 0xf8, 10000, 33.3, 31.9, 1300 }, // 45 29.6m Erlang=3.0x10-5 <- 32+ nonces
- { 16, 0xf0, 5000, 16.9, 15.9, 0 }, // 15 22.2m Erlang=4.6x10-5 <- 16+ nonces
- { 8, 0xe0, 1250, 8.9, 7.9, 0 }, // 15 166s Erlang=6.0x10-5
- { 4, 0xc0, 450, 4.9, 3.9, 0 }, // 15 30s Erlang=3.9x10-6
- { 2, 0x80, 150, 2.9, 1.9, 0 }, // 15 5s Erlang=5.4x10-7
- { 1, 0x00, 50, 1.9, 0.0, 0 }, // 15 0.8s Erlang=1.5x10-7 <- all nonces
- { 0 }
- };
- // force=true to allow setting it if it may not have taken before
- // force also delays longer after sending the ticket mask
- // diff=0.0 mean set the highest valid
- static void set_ticket(struct cgpu_info *compac, float diff, bool force, bool locked)
- {
- struct COMPAC_INFO *info = compac->device_data;
- struct timeval now;
- bool got = false;
- uint32_t udiff, new_diff = 0, new_mask = 0, cc;
- int i;
- if (diff == 0.0)
- {
- // above max will get the highest valid for cc
- diff = 128;
- }
- // if (!force && info->last_work_diff == diff)
- // return;
- // closest uint diff equal or below
- udiff = (uint32_t)floor(diff);
- cc = info->chips * info->cores;
- for (i = 0; ticket_1397[i].diff > 0; i++)
- {
- if (udiff >= ticket_1397[i].diff && cc > ticket_1397[i].cclimit)
- {
- // if ticket is already the same
- if (!force && info->difficulty == ticket_1397[i].diff)
- return;
- if (!locked)
- mutex_lock(&info->lock);
- new_diff = info->difficulty = ticket_1397[i].diff;
- new_mask = info->ticket_mask = ticket_1397[i].ticket_mask;
- info->last_work_diff = diff;
- cgtime(&info->last_ticket_attempt);
- info->ticket_number = i;
- info->ticket_work = 0;
- info->ticket_nonces = 0;
- info->below_nonces = 0;
- info->ticket_ok = false;
- info->ticket_got_low = false;
- if (!locked)
- mutex_unlock(&info->lock);
- got = true;
- break;
- }
- }
- // code failure
- if (!got)
- return;
- // set them all the same 0x51 .... 0x00
- unsigned char ticket[] = {0x51, 0x09, 0x00, BM1397TICKET, 0x00, 0x00, 0x00, 0xC0, 0x00};
- ticket[7] = info->ticket_mask;
- compac_send2(compac, ticket, sizeof(ticket), 8 * sizeof(ticket) - 8, "ticket");
- if (!force)
- gekko_usleep(info, MS2US(10));
- else
- gekko_usleep(info, MS2US(20));
- applog(LOG_ERR, "%d: %s %d - set ticket to 0x%02x/%u work %u/%.1f",
- compac->cgminer_id, compac->drv->name, compac->device_id,
- new_mask, new_diff, udiff, diff);
- // wipe info->gh/asic->gc
- cgtime(&now);
- gh_offset(info, &now, true, false);
- job_offset(info, &now, true, false);
- // reset P:
- info->frequency_computed = 0;
- }
- // expected nonces for GEKKOCHIP - MUST already be locked AND gc_offset()
- // full 50 mins + current offset in 10 mins - N.B. uses CLOCK_MONOTONIC
- // it will grow from 0% to ~100% between 50 & 60 mins if the chip
- // is performing at 100% - random variance of course also applies
- static double noncepercent(struct COMPAC_INFO *info, int chip, struct timeval *now)
- {
- double sec, hashpersec, noncepersec, nonceexpect;
- if (info->asic_type != BM1397)
- return 0.0;
- sec = CHTIME * (CHNUM-1) + (now->tv_sec % CHTIME) + ((double)now->tv_usec / 1000000.0);
- hashpersec = info->asics[chip].frequency * info->cores * info->hr_scale * 1000000.0;
- noncepersec = (hashpersec / (double)0xffffffffull)
- / (double)(ticket_1397[info->ticket_number].diff);
- nonceexpect = noncepersec * sec;
- return 100.0 * (double)(info->asics[chip].gc.noncesum) / nonceexpect;
- }
- // GSF/GSFM any chip count
- static void calc_gsf_freq(struct cgpu_info *compac, float frequency, int chip)
- {
- struct COMPAC_INFO *info = compac->device_data;
- char chipn[8];
- bool doall;
- if (info->asic_type != BM1397)
- return;
- if (chip == -1)
- doall = true;
- else
- {
- if (chip < 0 || chip >= (int)(info->chips))
- {
- applog(LOG_ERR, "%d: %s %d - invalid set chip [%d] -> freq %.2fMHz",
- compac->cgminer_id, compac->drv->name, compac->device_id, chip, frequency);
- return;
- }
- doall = false;
- }
- // if attempting the same frequency that previously failed ...
- if (frequency != 0 && frequency == info->freq_fail)
- return;
- unsigned char prefreqall[] = {0x51, 0x09, 0x00, 0x70, 0x0F, 0x0F, 0x0F, 0x00, 0x00};
- unsigned char prefreqch[] = {0x41, 0x09, 0x00, 0x70, 0x0F, 0x0F, 0x0F, 0x00, 0x00};
- // default 200Mhz if it fails
- unsigned char freqbufall[] = {0x51, 0x09, 0x00, BM1397FREQ, 0x40, 0xF0, 0x02, 0x35, 0x00};
- unsigned char freqbufch[] = {0x41, 0x09, 0x00, BM1397FREQ, 0x40, 0xF0, 0x02, 0x35, 0x00};
- float deffreq = 200.0;
- float fa, fb, fc1, fc2, newf;
- float f1, basef, famax = 0xf0, famin = 0x10;
- uint16_t c;
- int i;
- // allow a frequency 'power down'
- if (frequency == 0)
- {
- doall = true;
- basef = fa = 0;
- fb = fc1 = fc2 = 1;
- }
- else
- {
- f1 = limit_freq(info, frequency, false);
- fb = 2; fc1 = 1; fc2 = 5; // initial multiplier of 10
- if (f1 >= 500)
- {
- // halv down to '250-400'
- fb = 1;
- }
- else if (f1 <= 150)
- {
- // tiple up to '300-450'
- fc1 = 3;
- }
- else if (f1 <= 250)
- {
- // double up to '300-500'
- fc1 = 2;
- }
- // else f1 is 250-500
- // f1 * fb * fc1 * fc2 is between 2500 and 5000
- // - so round up to the next 25 (freq_mult)
- basef = info->freq_mult * ceil(f1 * fb * fc1 * fc2 / info->freq_mult);
- // fa should be between 100 (0x64) and 200 (0xC8)
- fa = basef / info->freq_mult;
- }
- // code failure ... basef isn't 400 to 6000
- if (frequency != 0 && (fa < famin || fa > famax))
- {
- info->freq_fail = frequency;
- newf = deffreq;
- }
- else
- {
- if (doall)
- {
- freqbufall[5] = (int)fa;
- freqbufall[6] = (int)fb;
- // fc1, fc2 'should' already be 1..15
- freqbufall[7] = (((int)fc1 & 0xf) << 4) + ((int)fc2 & 0xf);
- }
- else
- {
- freqbufch[5] = (int)fa;
- freqbufch[6] = (int)fb;
- // fc1, fc2 'should' already be 1..15
- freqbufch[7] = (((int)fc1 & 0xf) << 4) + ((int)fc2 & 0xf);
- }
- newf = basef / ((float)fb * (float)fc1 * (float)fc2);
- }
- if (doall)
- {
- // i.e. -1 means no reply since last set
- for (c = 0; c < info->chips; c++)
- info->asics[c].frequency_reply = -1;
- for (i = 0; i < 2; i++)
- {
- gekko_usleep(info, MS2US(10));
- compac_send2(compac, prefreqall, sizeof(prefreqall), 8 * sizeof(prefreqall) - 8, "prefreq");
- }
- for (i = 0; i < 2; i++)
- {
- gekko_usleep(info, MS2US(10));
- compac_send2(compac, freqbufall, sizeof(freqbufall), 8 * sizeof(freqbufall) - 8, "freq");
- }
- // the freq wanted, which 'should' be the same
- for (c = 0; c < info->chips; c++)
- info->asics[c].frequency = frequency;
- }
- else
- {
- // just setting 1 chip
- prefreqch[2] = freqbufch[2] = CHIPPY1397(info, chip);
- // i.e. -1 means no reply since last set
- info->asics[chip].frequency_reply = -1;
- for (i = 0; i < 2; i++)
- {
- gekko_usleep(info, MS2US(10));
- compac_send2(compac, prefreqch, sizeof(prefreqch), 8 * sizeof(prefreqch) - 8, "prefreq");
- }
- for (i = 0; i < 2; i++)
- {
- gekko_usleep(info, MS2US(10));
- compac_send2(compac, freqbufch, sizeof(freqbufch), 8 * sizeof(freqbufch) - 8, "freq");
- }
- // the freq wanted, which 'should' be the same
- info->asics[chip].frequency = frequency;
- }
- if (doall)
- info->frequency = frequency;
- gekko_usleep(info, MS2US(10));
- if (doall)
- snprintf(chipn, sizeof(chipn), "all");
- else
- snprintf(chipn, sizeof(chipn), "%d", chip);
- // applog(LOG_INFO, "%d: %s %d - setting frequency to %.2fMHz (%.2f)" " (%.0f/%.0f/%.0f/%.0f)",
- applog(LOG_ERR, "%d: %s %d - setting [%s] frequency to %.2fMHz (%.2f)" " (%.0f/%.0f/%.0f/%.0f)",
- compac->cgminer_id, compac->drv->name, compac->device_id, chipn, frequency, newf, fa, fb, fc1, fc2);
- ping_freq(compac, 0);
- }
- static void compac_send_chain_inactive(struct cgpu_info *compac)
- {
- struct COMPAC_INFO *info = compac->device_data;
- unsigned int i, j;
- applog(LOG_INFO,"%d: %s %d - sending chain inactive for %d chip(s)",
- compac->cgminer_id, compac->drv->name, compac->device_id, info->chips);
- if (info->asic_type == BM1397)
- {
- // chain inactive
- unsigned char chainin[5] = {0x53, 0x05, 0x00, 0x00, 0x00};
- for (i = 0; i < 3; i++)
- {
- compac_send2(compac, chainin, sizeof(chainin), 8 * sizeof(chainin) - 8, "chin");
- gekko_usleep(info, MS2US(100));
- }
- unsigned char chippy[] = {0x40, 0x05, 0x00, 0x00, 0x00};
- for (i = 0; i < info->chips; i++)
- {
- chippy[2] = CHIPPY1397(info, i);
- compac_send2(compac, chippy, sizeof(chippy), 8 * sizeof(chippy) - 8, "chippy");
- gekko_usleep(info, MS2US(10));
- }
- unsigned char init1[] = {0x51, 0x09, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00};
- unsigned char init2[] = {0x51, 0x09, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00};
- unsigned char init3[] = {0x51, 0x09, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00};
- unsigned char init4[] = {0x51, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x80, 0x74, 0x00};
- compac_send2(compac, init1, sizeof(init1), 8 * sizeof(init1) - 8, "init1");
- gekko_usleep(info, MS2US(10));
- compac_send2(compac, init2, sizeof(init2), 8 * sizeof(init2) - 8, "init2");
- gekko_usleep(info, MS2US(100));
- compac_send2(compac, init3, sizeof(init3), 8 * sizeof(init3) - 8, "init3");
- gekko_usleep(info, MS2US(50));
- compac_send2(compac, init4, sizeof(init4), 8 * sizeof(init4) - 8, "init4");
- gekko_usleep(info, MS2US(100));
- // set ticket based on chips, pool will be above this anyway
- set_ticket(compac, 0.0, true, false);
- unsigned char init5[] = {0x51, 0x09, 0x00, 0x68, 0xC0, 0x70, 0x01, 0x11, 0x00};
- unsigned char init6[] = {0x51, 0x09, 0x00, 0x28, 0x06, 0x00, 0x00, 0x0F, 0x00};
- for (j = 0; j < 2; j++)
- {
- compac_send2(compac, init5, sizeof(init5), 8 * sizeof(init5) - 8, "init5");
- gekko_usleep(info, MS2US(50));
- }
- compac_send2(compac, init6, sizeof(init6), 8 * sizeof(init6) - 8, "init6");
- gekko_usleep(info, MS2US(100));
- unsigned char baudrate[] = { 0x51, 0x09, 0x00, 0x18, 0x00, 0x00, 0x61, 0x31, 0x00 }; // lo 1.51M
- info->bauddiv = 1; // 1.5M
- #ifdef WIN32___fixme_zzz
- if (info->midstates == 4)
- {
- // 4 mid = slow it down on windows 116K
- baudrate[5] = 0x00;
- baudrate[6] = 0x7A;
- // 3.125M/27
- info->bauddiv = 26;
- }
- #endif
- applog(LOG_ERR, "%d: %s %d - setting bauddiv : %02x %02x (ftdi/%d)",
- compac->cgminer_id, compac->drv->name, compac->device_id, baudrate[5], baudrate[6], info->bauddiv + 1);
- compac_send2(compac, baudrate, sizeof(baudrate), 8 * sizeof(baudrate) - 8, "baud");
- gekko_usleep(info, MS2US(10));
- usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, info->bauddiv + 1,
- (FTDI_INDEX_BAUD_BTS & 0xff00) | info->interface, C_SETBAUD);
- gekko_usleep(info, MS2US(10));
- calc_gsf_freq(compac, info->frequency, -1);
- gekko_usleep(info, MS2US(20));
- } else if (info->asic_type == BM1387) {
- unsigned char buffer[5] = {0x55, 0x05, 0x00, 0x00, 0x00};
- compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8); // chain inactive
- gekko_usleep(info, MS2US(5));
- compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8); // chain inactive
- gekko_usleep(info, MS2US(5));
- compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8); // chain inactive
- for (i = 0; i < info->chips; i++) {
- buffer[0] = 0x41;
- buffer[1] = 0x05;
- buffer[2] = (0x100 / info->chips) * i;
- gekko_usleep(info, MS2US(5));
- compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8);
- }
- gekko_usleep(info, MS2US(10));
- unsigned char baudrate[] = { 0x58, 0x09, 0x00, 0x1C, 0x00, 0x20, 0x07, 0x00, 0x19 };
- if (opt_gekko_bauddiv) {
- info->bauddiv = opt_gekko_bauddiv;
- } else {
- info->bauddiv = 0x01; // 1.5Mbps baud.
- #ifdef WIN32
- if (info->midstates == 4)
- info->bauddiv = 0x0D; // 214Kbps baud.
- #endif
- }
- applog(LOG_INFO, "%d: %s %d - setting bauddiv : %02x",
- compac->cgminer_id, compac->drv->name, compac->device_id, info->bauddiv);
- baudrate[6] = info->bauddiv;
- compac_send(compac, baudrate, sizeof(baudrate), 8 * sizeof(baudrate) - 8);
- gekko_usleep(info, MS2US(10));
- usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, (info->bauddiv + 1),
- (FTDI_INDEX_BAUD_BTS & 0xff00) | info->interface, C_SETBAUD);
- gekko_usleep(info, MS2US(10));
- unsigned char gateblk[9] = {0x58, 0x09, 0x00, 0x1C, 0x40, 0x20, 0x99, 0x80, 0x01};
- gateblk[6] = 0x80 | info->bauddiv;
- compac_send(compac, gateblk, sizeof(gateblk), 8 * sizeof(gateblk) - 8); // chain inactive
- } else if (info->asic_type == BM1384) {
- unsigned char buffer[] = {0x85, 0x00, 0x00, 0x00};
- compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5); // chain inactive
- for (i = 0; i < info->chips; i++) {
- buffer[0] = 0x01;
- buffer[1] = (0x100 / info->chips) * i;
- compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
- }
- buffer[0] = 0x86; // GATEBLK
- buffer[1] = 0x00;
- buffer[2] = 0x9a; // 0x80 | 0x1a;
- //compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
- }
- if (info->mining_state == MINER_CHIP_COUNT_OK) {
- applog(LOG_INFO, "%d: %s %d - open cores",
- compac->cgminer_id, compac->drv->name, compac->device_id);
- info->zero_check = 0;
- info->task_hcn = 0;
- info->mining_state = MINER_OPEN_CORE;
- }
- }
- static void compac_update_rates(struct cgpu_info *compac)
- {
- struct COMPAC_INFO *info = compac->device_data;
- struct ASIC_INFO *asic;
- float average_frequency = 0, est;
- unsigned int i;
- cgtime(&(info->last_update_rates));
- if (info->chips == 0 || info->frequency == 0)
- return;
- for (i = 0; i < info->chips; i++)
- {
- if (info->asics[i].frequency == 0)
- return;
- }
- info->frequency_asic = 0;
- for (i = 0; i < info->chips; i++) {
- asic = &info->asics[i];
- asic->hashrate = asic->frequency * info->cores * 1000000 * info->hr_scale;
- asic->fullscan_ms = 1000.0 * info->hr_scale * 0xffffffffull / asic->hashrate;
- asic->fullscan_us = 1000.0 * info->hr_scale * 1000.0 * 0xffffffffull / asic->hashrate;
- average_frequency += asic->frequency;
- info->frequency_asic = (asic->frequency > info->frequency_asic ) ? asic->frequency : info->frequency_asic;
- }
- average_frequency = average_frequency / info->chips;
- if (average_frequency != info->frequency) {
- applog(LOG_INFO,"%d: %s %d - frequency updated %.2fMHz -> %.2fMHz",
- compac->cgminer_id, compac->drv->name, compac->device_id, info->frequency, average_frequency);
- info->frequency = average_frequency;
- info->wu_max = 0;
- }
- info->wu = (info->chips * info->frequency * info->cores / 71.6) * info->hr_scale;
- info->hashrate = info->chips * info->frequency * info->cores * 1000000 * info->hr_scale;
- info->fullscan_ms = 1000.0 * info->hr_scale * 0xffffffffull / info->hashrate;
- info->fullscan_us = 1000.0 * info->hr_scale * 1000.0 * 0xffffffffull / info->hashrate;
- if (info->asic_type != BM1397)
- {
- info->ticket_mask = bound(pow(2, ceil(log(info->hashrate / (2.0 * 0xffffffffull)) / log(2))) - 1, 0, 4000);
- info->ticket_mask = (info->asic_type == BM1387) ? 0 : info->ticket_mask;
- info->difficulty = info->ticket_mask + 1;
- }
- info->wait_factor = info->wait_factor0;
- if (!opt_gekko_noboost && info->vmask && (info->asic_type == BM1387 || info->asic_type == BM1397))
- info->wait_factor *= info->midstates;
- est = info->wait_factor * (float)(info->fullscan_us);
- info->max_task_wait = bound((uint64_t)est, 1, 3 * info->fullscan_us);
- if (info->asic_type == BM1387)
- {
- if (opt_gekko_tune_up > 95)
- info->tune_up = 100.0 * ((info->frequency - info->freq_base * (600 / info->frequency)) / info->frequency);
- else
- info->tune_up = opt_gekko_tune_up;
- }
- else if (info->asic_type == BM1397)
- {
- // 90% will always allow at least 2 freq steps
- if (opt_gekko_tune_up > 90)
- opt_gekko_tune_up = 90;
- else
- info->tune_up = opt_gekko_tune_up;
- }
- else
- info->tune_up = 99;
- // shouldn't happen, but next call should fix it
- if (info->difficulty == 0)
- info->nonce_expect = 0;
- else
- {
- // expected ms per nonce for PT_NONONCE
- info->nonce_expect = info->fullscan_ms * info->difficulty;
- // BM1397 check is per miner, not per chip, fullscan_ms is sum of chips
- if (info->asic_type != BM1397 && info->chips > 1)
- info->nonce_expect *= (float)info->chips;
- // CDF >2000% is avg once in 485165205.1 nonces
- info->nonce_limit = info->nonce_expect * 20.0;
- // N.B. this ignores info->ghrequire since
- // that should be an independent test
- }
- applog(LOG_INFO, "%d: %s %d - Rates: ms %.2f tu %.2f td %.2f",
- compac->cgminer_id, compac->drv->name, compac->device_id,
- info->fullscan_ms, info->tune_up, info->tune_down);
- }
- static void compac_set_frequency_single(struct cgpu_info *compac, float frequency, int asic_id)
- {
- struct COMPAC_INFO *info = compac->device_data;
- struct ASIC_INFO *asic = &info->asics[asic_id];
- struct timeval now;
- if (info->asic_type == BM1387) {
- unsigned char buffer[] = {0x48, 0x09, 0x00, 0x0C, 0x00, 0x50, 0x02, 0x41, 0x00}; //250MHz -- osc of 25MHz
- frequency = bound(frequency, 50, 1200);
- frequency = FREQ_BASE(frequency);
- if (frequency < 400) {
- buffer[7] = 0x41;
- buffer[5] = (frequency * 8) / info->freq_mult;
- } else {
- buffer[7] = 0x21;
- buffer[5] = (frequency * 4) / info->freq_mult;
- }
- buffer[2] = (0x100 / info->chips) * asic_id;
- //asic->frequency = frequency;
- asic->frequency_set = frequency;
- asic->frequency_attempt++;
- applog(LOG_INFO, "%d: %s %d - setting chip[%d] frequency (%d) %.2fMHz -> %.2fMHz",
- compac->cgminer_id, compac->drv->name, compac->device_id,
- asic_id, asic->frequency_attempt, asic->frequency, frequency);
- compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8);
- //unsigned char gateblk[9] = {0x48, 0x09, 0x00, 0x1C, 0x40, 0x20, 0x99, 0x80, 0x01};
- //gateblk[6] = 0x80 | info->bauddiv;
- //gateblk[2] = (0x100 / info->chips) * id;
- //compac_send(compac, gateblk, sizeof(gateblk), 8 * sizeof(gateblk) - 8); // chain inactive
- // wipe info->gh/asic->gc
- cgtime(&now);
- gh_offset(info, &now, true, false);
- // reset P:
- info->frequency_computed = 0;
- }
- }
- static void compac_set_frequency(struct cgpu_info *compac, float frequency)
- {
- struct COMPAC_INFO *info = compac->device_data;
- uint32_t i, r, r1, r2, r3, p1, p2, pll;
- struct timeval now;
- if (info->asic_type == BM1397) {
- calc_gsf_freq(compac, frequency, -1);
- } else if (info->asic_type == BM1387) {
- unsigned char buffer[] = {0x58, 0x09, 0x00, 0x0C, 0x00, 0x50, 0x02, 0x41, 0x00}; //250MHz -- osc of 25MHz
- frequency = bound(frequency, 50, 1200);
- frequency = FREQ_BASE(frequency);
- if (frequency < 400) {
- buffer[7] = 0x41;
- buffer[5] = (frequency * 8) / info->freq_mult;
- } else {
- buffer[7] = 0x21;
- buffer[5] = (frequency * 4) / info->freq_mult;
- }
- /*
- } else {
- buffer[7] = 0x11;
- buffer[5] = (frequency * 2) / info->freq_mult;
- }
- */
- applog(LOG_INFO, "%d: %s %d - setting frequency to %.2fMHz",
- compac->cgminer_id, compac->drv->name, compac->device_id, frequency);
- compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8);
- info->frequency = frequency;
- for (i = 0; i < info->chips; i++)
- info->asics[i].frequency = frequency;
- } else if (info->asic_type == BM1384) {
- unsigned char buffer[] = {0x82, 0x0b, 0x83, 0x00};
- frequency = bound(frequency, 6, 500);
- frequency = FREQ_BASE(frequency);
- info->frequency = frequency;
- r = floor(log(info->frequency/info->freq_mult) / log(2));
- r1 = 0x0785 - r;
- r2 = 0x200 / pow(2, r);
- r3 = info->freq_mult * pow(2, r);
- p1 = r1 + r2 * (info->frequency - r3) / info->freq_base;
- p2 = p1 * 2 + (0x7f + r);
- pll = (((uint32_t)(info->frequency) % (uint32_t)(info->freq_mult)) == 0 ? p1 : p2);
- if (info->frequency < 100) {
- pll = 0x0783 - 0x80 * (100 - info->frequency) / info->freq_base;
- }
- buffer[1] = (pll >> 8) & 0xff;
- buffer[2] = (pll) & 0xff;
- applog(LOG_INFO, "%d: %s %d - setting frequency to %.2fMHz",
- compac->cgminer_id, compac->drv->name, compac->device_id, frequency);
- compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
- buffer[0] = 0x84;
- buffer[1] = 0x00;
- buffer[2] = 0x00;
- // compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
- buffer[2] = 0x04;
- compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
- for (i = 0; i < info->chips; i++)
- info->asics[i].frequency = frequency;
- }
- compac_update_rates(compac);
- // wipe info->gh/asic->gc
- cgtime(&now);
- gh_offset(info, &now, true, false);
- // reset P:
- info->frequency_computed = 0;
- }
- static void compac_update_work(struct cgpu_info *compac)
- {
- struct COMPAC_INFO *info = compac->device_data;
- int i;
- for (i = 0; i < JOB_MAX; i++) {
- info->active_work[i] = false;
- }
- info->update_work = 1;
- }
- static void compac_flush_buffer(struct cgpu_info *compac)
- {
- int read_bytes = 1;
- unsigned char resp[32];
- while (read_bytes) {
- usb_read_timeout(compac, (char *)resp, 32, &read_bytes, 1, C_REQUESTRESULTS);
- }
- }
- static void compac_flush_work(struct cgpu_info *compac)
- {
- compac_flush_buffer(compac);
- compac_update_work(compac);
- }
- static void compac_toggle_reset(struct cgpu_info *compac)
- {
- struct COMPAC_INFO *info = compac->device_data;
- unsigned short usb_val;
- applog(info->log_wide,"%d: %s %d - Toggling ASIC nRST to reset",
- compac->cgminer_id, compac->drv->name, compac->device_id);
- usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_RESET, FTDI_VALUE_RESET, info->interface, C_RESET);
- usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_DATA, FTDI_VALUE_DATA_BTS, info->interface, C_SETDATA);
- usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, FTDI_VALUE_BAUD_BTS, (FTDI_INDEX_BAUD_BTS & 0xff00) | info->interface, C_SETBAUD);
- usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_FLOW, FTDI_VALUE_FLOW, info->interface, C_SETFLOW);
- usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_RESET, FTDI_VALUE_PURGE_TX, info->interface, C_PURGETX);
- usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_RESET, FTDI_VALUE_PURGE_RX, info->interface, C_PURGERX);
- usb_val = (FTDI_BITMODE_CBUS << 8) | 0xF2; // low byte: bitmask - 1111 0010 - CB1(HI)
- usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BITMODE, usb_val, info->interface, C_SETMODEM);
- gekko_usleep(info, MS2US(30));
- usb_val = (FTDI_BITMODE_CBUS << 8) | 0xF0; // low byte: bitmask - 1111 0000 - CB1(LO)
- usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BITMODE, usb_val, info->interface, C_SETMODEM);
- if (info->asic_type == BM1397)
- gekko_usleep(info, MS2US(1000));
- else
- gekko_usleep(info, MS2US(30));
- usb_val = (FTDI_BITMODE_CBUS << 8) | 0xF2; // low byte: bitmask - 1111 0010 - CB1(HI)
- usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BITMODE, usb_val, info->interface, C_SETMODEM);
- gekko_usleep(info, MS2US(200));
- cgtime(&info->last_reset);
- }
- static void compac_gsf_nonce(struct cgpu_info *compac, K_ITEM *item)
- {
- struct COMPAC_INFO *info = compac->device_data;
- unsigned char *rx = DATA_NONCE(item)->rx;
- int hwe = compac->hw_errors;
- struct work *work = NULL;
- bool active_work = false;
- uint32_t job_id = 0;
- uint32_t nonce = 0;
- int domid, midnum = 0;
- double diff = 0.0;
- bool boost, ok;
- int asic_id, i;
- if (info->asic_type != BM1397)
- return;
- job_id = rx[7] & 0xff;
- nonce = (rx[5] << 0) | (rx[4] << 8) | (rx[3] << 16) | (rx[2] << 24);
- // N.B. busy work (0xff) never returns a nonce
- mutex_lock(&info->lock);
- info->nonces++;
- info->nonceless = 0;
- info->noncebyte[rx[3]]++;
- mutex_unlock(&info->lock);
- if (info->nb2c_setup)
- asic_id = info->nb2chip[rx[3]];
- else
- asic_id = floor((double)(rx[4]) / ((double)0x100 / (double)(info->chips)));
- if (asic_id >= (int)(info->chips))
- {
- applog(LOG_ERR, "%d: %s %d - nonce %08x @ %02x rx[4] %02x invalid asic_id (0..%d)",
- compac->cgminer_id, compac->drv->name, compac->device_id, nonce, job_id,
- rx[4], (int)(info->chips)-1);
- asic_id = (info->chips - 1);
- }
- #if 0
- else
- {
- applog(LOG_ERR, "%d: %s %d - gotnonce %08x @ %02x rx[2] %02x id %d(%u)",
- compac->cgminer_id, compac->drv->name, compac->device_id, nonce, job_id,
- rx[2], asic_id, info->chips);
- applog(LOG_ERR, " N:[%02x %02x %02x %02x %02x %02x %02x]",
- rx[0], rx[1], rx[2], rx[3], rx[4], rx[5], rx[6]);
- }
- #endif
- struct ASIC_INFO *asic = &info->asics[asic_id];
- if (nonce == asic->prev_nonce)
- {
- applog(LOG_INFO, "%d: %s %d - Duplicate Nonce : %08x @ %02x [%02x %02x %02x %02x %02x %02x %02x]",
- compac->cgminer_id, compac->drv->name, compac->device_id, nonce, job_id,
- rx[0], rx[1], rx[2], rx[3], rx[4], rx[5], rx[6]);
- mutex_lock(&info->lock);
- info->dups++;
- info->dupsall++;
- info->dupsreset++;
- asic->dups++;
- asic->dupsall++;
- cgtime(&info->last_dup_time);
- if (info->dups == 1)
- info->mining_state = MINER_MINING_DUPS;
- mutex_unlock(&info->lock);
- return;
- }
- mutex_lock(&info->lock);
- info->prev_nonce = nonce;
- asic->prev_nonce = nonce;
- applog(LOG_INFO, "%d: %s %d - Device reported nonce: %08x @ %02x (%d)",
- compac->cgminer_id, compac->drv->name, compac->device_id, nonce, job_id, info->tracker);
- if (!opt_gekko_noboost && info->vmask)
- {
- domid = info->midstates;
- boost = true;
- }
- else
- {
- domid = 1;
- boost = false;
- }
- ok = false;
- // test the exact jobid/midnum
- uint32_t w_job_id = job_id & 0xfc;
- if (w_job_id <= info->max_job_id)
- {
- work = info->work[w_job_id];
- active_work = info->active_work[w_job_id];
- if (work && active_work)
- {
- if (boost)
- {
- midnum = job_id & 0x03;
- work->micro_job_id = pow(2, midnum);
- memcpy(work->data, &(work->pool->vmask_001[work->micro_job_id]), 4);
- }
- if ((diff = test_nonce_value(work, nonce)) != 0.0)
- {
- ok = true;
- if (midnum > 0)
- info->boosted = true;
- }
- }
- }
- if (!ok)
- {
- // not found, try each cur_attempt
- for (i = 0; !ok && i < (int)CUR_ATTEMPT; i++)
- {
- w_job_id = JOB_ID_ROLL(info->job_id, cur_attempt[i], info) & 0xfc;
- work = info->work[w_job_id];
- active_work = info->active_work[w_job_id];
- if (work && active_work)
- {
- for (midnum = 0; !ok && midnum < domid; midnum++)
- {
- // failed original job_id already tested
- if ((w_job_id | midnum) == job_id)
- continue;
- if (boost)
- {
- work->micro_job_id = pow(2, midnum);
- memcpy(work->data, &(work->pool->vmask_001[work->micro_job_id]), 4);
- }
- if ((diff = test_nonce_value(work, nonce)) != 0)
- {
- if (midnum > 0)
- info->boosted = true;
- info->cur_off[i]++;
- ok = true;
- applog(LOG_INFO, "%d: %s %d - Nonce Recovered : %08x @ job[%02x]->fix[%02x] len %u prelen %u",
- compac->cgminer_id, compac->drv->name, compac->device_id,
- nonce, job_id, w_job_id, (uint32_t)(DATA_NONCE(item)->len),
- (uint32_t)(DATA_NONCE(item)->prelen));
- }
- }
- }
- }
- if (!ok)
- {
- applog(LOG_INFO, "%d: %s %d - Nonce Dumped : %08x @ job[%02x] cur[%02x] diff %u",
- compac->cgminer_id, compac->drv->name, compac->device_id,
- nonce, job_id, info->job_id, info->difficulty);
- inc_hw_errors_n(info->thr, info->difficulty);
- cgtime(&info->last_hwerror);
- mutex_unlock(&info->lock);
- return;
- }
- }
- // verify the ticket mask is correct
- if (!info->ticket_ok && diff > 0)
- {
- do // so we can break out
- {
- if (++(info->ticket_work) > TICKET_DELAY)
- {
- int i = info->ticket_number;
- info->ticket_nonces++;
- // nonce below ticket setting - redo ticket - chip must be too low
- // check this for all nonces until ticket_ok
- if (diff < ticket_1397[i].hi_limit)
- {
- if (++(info->below_nonces) < TICKET_BELOW_LIM)
- break;
- // redo ticket to return fewer nonces
- if (info->ticket_failures > MAX_TICKET_CHECK)
- {
- // give up - just set it to max
- applog(LOG_ERR, "%d: %s %d - ticket %u failed too many times setting to max",
- compac->cgminer_id, compac->drv->name, compac->device_id, ticket_1397[i].diff);
- //set_ticket(compac, 1.0, true, true);
- set_ticket(compac, 0.0, true, true);
- info->ticket_ok = true;
- break;
- }
- applog(LOG_ERR, "%d: %s %d - ticket %u failure (%"PRId64") diff %.1f below lim %.1f - retry %d",
- compac->cgminer_id, compac->drv->name, compac->device_id,
- ticket_1397[i].diff, info->below_nonces, diff, ticket_1397[i].hi_limit, info->ticket_failures+1);
- // try again ...
- //set_ticket(compac, ticket_1397[i].diff, true, true);
- set_ticket(compac, 0.0, true, true);
- info->ticket_failures++;
- break;
- }
- // after nonce_count, CDF[Erlang] chance of NOT being below
- if (diff < ticket_1397[i].low_limit)
- info->ticket_got_low = true;
- if (info->ticket_work >= (ticket_1397[i].nonce_count + TICKET_DELAY))
- {
- // we should have got a 'low' by now
- if (info->ticket_got_low)
- {
- info->ticket_ok = true;
- info->ticket_failures = 0;
- applog(LOG_ERR, "%d: %s %d - ticket value confirmed 0x%02x/%u after %"PRId64" nonces",
- compac->cgminer_id, compac->drv->name, compac->device_id,
- info->ticket_mask, info->difficulty, info->ticket_nonces);
- break;
- }
- // chip ticket must be too high means lost shares
- if (info->ticket_failures > MAX_TICKET_CHECK)
- {
- // give up - just set it to 1.0
- applog(LOG_ERR, "%d: %s %d - ticket %u failed too many times setting to max",
- compac->cgminer_id, compac->drv->name, compac->device_id, ticket_1397[i].diff);
- //set_ticket(compac, 1.0, true, true);
- set_ticket(compac, 0.0, true, true);
- info->ticket_ok = true;
- break;
- }
- applog(LOG_ERR, "%d: %s %d - ticket %u failure no low < %.1f after %d - retry %d",
- compac->cgminer_id, compac->drv->name, compac->device_id,
- ticket_1397[i].diff, ticket_1397[i].low_limit, info->ticket_work, info->ticket_failures+1);
- // try again ...
- //set_ticket(compac, ticket_1397[i].diff, true, true);
- set_ticket(compac, 0.0, true, true);
- info->ticket_failures++;
- break;
- }
- }
- }
- while (0);
- }
- if (active_work && work)
- work->device_diff = info->difficulty;
- mutex_unlock(&info->lock);
- if (active_work && work && submit_nonce(info->thr, work, nonce))
- {
- mutex_lock(&info->lock);
- cgtime(&info->last_nonce);
- cgtime(&asic->last_nonce);
- // count of valid nonces
- asic->nonces++; // info only
- if (midnum > 0)
- {
- applog(LOG_INFO, "%d: %s %d - AsicBoost nonce found : midstate %d",
- compac->cgminer_id, compac->drv->name, compac->device_id, midnum);
- }
- // if work diff < info->dificulty, 'accept' hash rate will be low
- info->hashes += info->difficulty * 0xffffffffull;
- info->xhashes += info->difficulty;
- info->accepted++;
- info->failing = false;
- info->dups = 0;
- asic->dups = 0;
- mutex_unlock(&info->lock);
- if (info->nb2c_setup)
- add_gekko_nonce(info, asic, &(DATA_NONCE(item)->when));
- else
- add_gekko_nonce(info, NULL, &(DATA_NONCE(item)->when));
- }
- else
- {
- // shouldn't be possible since diff has already been checked
- if (hwe != compac->hw_errors)
- {
- mutex_lock(&info->lock);
- cgtime(&info->last_hwerror);
- mutex_unlock(&info->lock);
- }
- }
- }
- static uint64_t compac_check_nonce(struct cgpu_info *compac)
- {
- struct COMPAC_INFO *info = compac->device_data;
- uint32_t nonce = 0;
- int hwe = compac->hw_errors;
- uint32_t job_id = 0;
- uint64_t hashes = 0;
- struct timeval now;
- int i;
- if (info->asic_type == BM1387) {
- job_id = info->rx[5] & 0xff;
- nonce = (info->rx[3] << 0) | (info->rx[2] << 8) | (info->rx[1] << 16) | (info->rx[0] << 24);
- } else if (info->asic_type == BM1384) {
- job_id = info->rx[4] ^ 0x80;
- nonce = (info->rx[3] << 0) | (info->rx[2] << 8) | (info->rx[1] << 16) | (info->rx[0] << 24);
- } else if (info->asic_type == BM1397) {
- // should never call here
- return hashes;
- }
- if ((info->rx[0] == 0x72 && info->rx[1] == 0x03 && info->rx[2] == 0xEA && info->rx[3] == 0x83)
- || (info->rx[0] == 0xE1 && info->rx[1] == 0x6B && info->rx[2] == 0xF8 && info->rx[3] == 0x09))
- {
- //busy work nonces
- return hashes;
- }
- if (job_id > info->max_job_id
- || (abs((int)(info->job_id) - (int)job_id) > 3 && abs((int)(info->max_job_id) - (int)job_id + (int)(info->job_id)) > 3))
- {
- return hashes;
- }
- if (!info->active_work[job_id]
- && !(job_id > 0 && info->active_work[job_id - 1])
- && !(job_id > 1 && info->active_work[job_id - 2])
- && !(job_id > 2 && info->active_work[job_id - 3]))
- {
- return hashes;
- }
- cgtime(&now);
- info->nonces++;
- info->nonceless = 0;
- int asic_id = (int)floor((double)(info->rx[0]) / ((double)0x100 / (double)(info->chips)));
- struct ASIC_INFO *asic = &info->asics[asic_id];
- if (nonce == asic->prev_nonce) {
- applog(LOG_INFO, "%d: %s %d - Duplicate Nonce : %08x @ %02x [%02x %02x %02x %02x %02x %02x]",
- compac->cgminer_id, compac->drv->name, compac->device_id, nonce, job_id,
- info->rx[0], info->rx[1], info->rx[2], info->rx[3], info->rx[4], info->rx[5]);
- info->dups++;
- info->dupsall++;
- info->dupsreset++;
- asic->dups++;
- asic->dupsall++;
- cgtime(&info->last_dup_time);
- if (info->dups == 1) {
- info->mining_state = MINER_MINING_DUPS;
- }
- return hashes;
- }
- info->prev_nonce = nonce;
- asic->prev_nonce = nonce;
- applog(LOG_INFO, "%d: %s %d - Device reported nonce: %08x @ %02x (%d)",
- compac->cgminer_id, compac->drv->name, compac->device_id, nonce, job_id, info->tracker);
- struct work *work = info->work[job_id];
- bool active_work = info->active_work[job_id];
- int midnum = 0;
- if (!opt_gekko_noboost && info->vmask)
- {
- // force check last few nonces by [job_id - 1]
- // doesn't handle job_id roll over
- if (info->asic_type == BM1387)
- {
- for (i = 0; i < info->midstates; i++)
- {
- if ((int)job_id >= i)
- {
- if (info->active_work[job_id - i])
- {
- work = info->work[job_id - i];
- active_work = info->active_work[job_id - i];
- if (active_work && work)
- {
- work->micro_job_id = pow(2, i);
- memcpy(work->data, &(work->pool->vmask_001[work->micro_job_id]), 4);
- if (test_nonce(work, nonce))
- {
- midnum = i;
- if (i > 0)
- info->boosted = true;
- break;
- }
- }
- }
- }
- }
- }
- }
- if (!active_work || !work) {
- return hashes;
- }
- work->device_diff = info->difficulty;
- if (submit_nonce(info->thr, work, nonce)) {
- cgtime(&info->last_nonce);
- cgtime(&asic->last_nonce);
- // count of valid nonces
- asic->nonces++; // info only
- if (midnum > 0) {
- applog(LOG_INFO, "%d: %s %d - AsicBoost nonce found : midstate%d",
- compac->cgminer_id, compac->drv->name, compac->device_id, midnum);
- }
- hashes = info->difficulty * 0xffffffffull;
- info->xhashes += info->difficulty;
- info->accepted++;
- info->failing = false;
- info->dups = 0;
- asic->dups = 0;
- add_gekko_nonce(info, asic, &now);
- } else {
- if (hwe != compac->hw_errors) {
- cgtime(&info->last_hwerror);
- }
- }
- return hashes;
- }
- static void busy_work(struct COMPAC_INFO *info)
- {
- memset(info->task, 0, info->task_len);
- if (info->asic_type == BM1387 || info->asic_type == BM1397) {
- info->task[0] = 0x21;
- info->task[1] = info->task_len;
- info->task[2] = info->job_id & 0xff;
- info->task[3] = ((!opt_gekko_noboost && info->vmask) ? 0x04 : 0x01);
- memset(info->task + 8, 0xff, 12);
- unsigned short crc = crc16_false(info->task, info->task_len - 2);
- info->task[info->task_len - 2] = (crc >> 8) & 0xff;
- info->task[info->task_len - 1] = crc & 0xff;
- } else if (info->asic_type == BM1384) {
- if (info->mining_state == MINER_MINING) {
- info->task[39] = info->ticket_mask & 0xff;
- stuff_msb(info->task + 40, info->task_hcn);
- }
- info->task[51] = info->job_id & 0xff;
- }
- }
- static void init_task(struct COMPAC_INFO *info)
- {
- struct work *work = info->work[info->job_id];
- memset(info->task, 0, info->task_len);
- if (info->asic_type == BM1387 || info->asic_type == BM1397) {
- info->task[0] = 0x21;
- info->task[1] = info->task_len;
- info->task[2] = info->job_id & 0xff;
- info->task[3] = ((!opt_gekko_noboost && info->vmask) ? info->midstates : 0x01);
- if (info->mining_state == MINER_MINING) {
- stuff_reverse(info->task + 8, work->data + 64, 12);
- stuff_reverse(info->task + 20, work->midstate, 32);
- if (!opt_gekko_noboost && info->vmask) {
- if (info->midstates > 1)
- stuff_reverse(info->task + 20 + 32, work->midstate1, 32);
- if (info->midstates > 2)
- stuff_reverse(info->task + 20 + 32 + 32, work->midstate2, 32);
- if (info->midstates > 3)
- stuff_reverse(info->task + 20 + 32 + 32 + 32, work->midstate3, 32);
- }
- } else {
- memset(info->task + 8, 0xff, 12);
- }
- unsigned short crc = crc16_false(info->task, info->task_len - 2);
- info->task[info->task_len - 2] = (crc >> 8) & 0xff;
- info->task[info->task_len - 1] = crc & 0xff;
- } else if (info->asic_type == BM1384) {
- if (info->mining_state == MINER_MINING) {
- stuff_reverse(info->task, work->midstate, 32);
- stuff_reverse(info->task + 52, work->data + 64, 12);
- info->task[39] = info->ticket_mask & 0xff;
- stuff_msb(info->task + 40, info->task_hcn);
- }
- info->task[51] = info->job_id & 0xff;
- }
- }
- static void change_freq_any(struct cgpu_info *compac, float new_freq)
- {
- struct COMPAC_INFO *info = compac->device_data;
- unsigned int i;
- float old_freq;
- old_freq = info->frequency;
- for (i = 0; i < info->chips; i++)
- {
- struct ASIC_INFO *asic = &info->asics[i];
- cgtime(&info->last_frequency_adjust);
- cgtime(&asic->last_frequency_adjust);
- cgtime(&info->monitor_time);
- asic->frequency_updated = 1;
- if (info->asic_type == BM1397)
- {
- if (i == 0)
- compac_set_frequency(compac, new_freq);
- }
- else if (info->asic_type == BM1387)
- {
- compac_set_frequency_single(compac, new_freq, i);
- info->frequency = new_freq;
- }
- else if (info->asic_type == BM1384)
- {
- if (i == 0)
- {
- compac_set_frequency(compac, new_freq);
- compac_send_chain_inactive(compac);
- info->frequency = new_freq;
- }
- }
- }
- applog(LOG_WARNING,"%d: %s %d - new frequency %.2fMHz -> %.2fMHz",
- compac->cgminer_id, compac->drv->name, compac->device_id,
- old_freq, new_freq);
- }
- // compac_mine() with long term adjustments
- static void *compac_mine2(void *object)
- {
- struct cgpu_info *compac = (struct cgpu_info *)object;
- struct COMPAC_INFO *info = compac->device_data;
- struct work *work = NULL;
- struct work *old_work = NULL;
- struct timeval now;
- struct timeval last_rolling = (struct timeval){0};
- struct timeval last_movement = (struct timeval){0};
- struct timeval last_plateau_check = (struct timeval){0};
- struct timeval last_frequency_check = (struct timeval){0};
- struct sched_param param;
- int sent_bytes, sleep_us, use_us, policy, ret_nice;
- double diff_us, left_us;
- unsigned int i, j;
- uint32_t err = 0;
- uint64_t hashrate_gs;
- double dev_runtime, wu;
- float frequency_computed;
- bool frequency_updated;
- bool has_freq;
- bool job_added;
- bool last_was_busy = false;
- int plateau_type = 0;
- #ifndef WIN32
- ret_nice = nice(-15);
- #else /* WIN32 */
- pthread_getschedparam(pthread_self(), &policy, ¶m);
- param.sched_priority = sched_get_priority_max(policy);
- pthread_setschedparam(pthread_self(), policy, ¶m);
- ret_nice = param.sched_priority;
- #endif /* WIN32 */
- applog(LOG_INFO, "%d: %s %d - work thread niceness (%d)",
- compac->cgminer_id, compac->drv->name, compac->device_id, ret_nice);
- sleep_us = 100;
- cgtime(&last_plateau_check);
- while (info->mining_state != MINER_SHUTDOWN)
- {
- if (old_work)
- {
- mutex_lock(&info->lock);
- work_completed(compac, old_work);
- mutex_unlock(&info->lock);
- old_work = NULL;
- }
- if (info->chips == 0
- || compac->deven == DEV_DISABLED
- || compac->usbinfo.nodev
- || (info->mining_state != MINER_MINING && info->mining_state != MINER_MINING_DUPS))
- {
- gekko_usleep(info, MS2US(10));
- continue;
- }
- cgtime(&now);
- if (!info->update_work)
- {
- diff_us = us_tdiff(&now, &info->last_task);
- left_us = info->max_task_wait - diff_us;
- if (left_us > 0)
- {
- // allow 300us from here to next sleep
- left_us -= 300;
- use_us = sleep_us;
- if (use_us > left_us)
- use_us = left_us;
- // 1ms is more than enough
- if (use_us > 1000)
- use_us = 1000;
- if (use_us >= USLEEPMIN)
- {
- gekko_usleep(info, use_us);
- continue;
- }
- }
- }
- frequency_updated = 0;
- info->update_work = 0;
- sleep_us = bound(ceil(info->max_task_wait / 20), 1, 100 * 1000); // 1us .. 100ms
- dev_runtime = cgpu_runtime(compac);
- wu = compac->diff1 / dev_runtime * 60;
- if (wu > info->wu_max)
- {
- info->wu_max = wu;
- cgtime(&info->last_wu_increase);
- }
- // don't change anything until we have 10s of data since a reset
- if (ms_tdiff(&now, &info->last_reset) > MS_SECOND_10)
- {
- if (ms_tdiff(&now, &last_rolling) >= MS_SECOND_1)
- {
- mutex_lock(&info->ghlock);
- if (info->gh.noncesum > (GHNONCENEEDED+1))
- {
- cgtime(&last_rolling);
- info->rolling = gekko_gh_hashrate(info, &last_rolling, true);
- }
- mutex_unlock(&info->ghlock);
- }
- hashrate_gs = (double)info->rolling * 1000000ull;
- info->eff_gs = 100.0 * (1.0 * hashrate_gs / info->hashrate);
- info->eff_wu = 100.0 * (1.0 * wu / info->wu);
- if (info->eff_gs > 100)
- info->eff_gs = 100;
- if (info->eff_wu > 100)
- info->eff_wu = 100;
- frequency_computed = ((hashrate_gs / 1.0e6) / info->cores) / info->chips;
- frequency_computed = limit_freq(info, frequency_computed, true);
- if (frequency_computed > info->frequency_computed
- && frequency_computed <= info->frequency)
- {
- info->frequency_computed = frequency_computed;
- cgtime(&info->last_computed_increase);
- applog(LOG_INFO, "%d: %s %d - new comp=%.2f (gs=%.2f)",
- compac->cgminer_id, compac->drv->name, compac->device_id, frequency_computed,
- ((double)hashrate_gs)/1.0e6);
- }
- plateau_type = 0;
- // search for plateau
- if (ms_tdiff(&now, &last_plateau_check) > MS_SECOND_5)
- {
- has_freq = false;
- for (i = 0; i < info->chips; i++)
- {
- if (info->asics[i].frequency != 0)
- {
- has_freq = true;
- break;
- }
- }
- cgtime(&last_plateau_check);
- for (i = 0; i < info->chips; i++)
- {
- struct ASIC_INFO *asic = &info->asics[i];
- // missing nonces
- if (info->asic_type == BM1397)
- {
- if (has_freq && i == 0 && info->nonce_limit > 0.0
- && ms_tdiff(&now, &info->last_nonce) > info->nonce_limit)
- {
- plateau_type = PT_NONONCE;
- applog(LOG_ERR, "%d: %s %d - plateau_type PT_NONONCE [%u] %d > %.2f (lock=%d)",
- compac->cgminer_id, compac->drv->name, compac->device_id, i,
- ms_tdiff(&now, &info->last_nonce), info->nonce_limit, info->lock_freq);
- if (info->lock_freq)
- info->lock_freq = false;
- }
- }
- else
- {
- if (has_freq && info->nonce_limit > 0.0
- && ms_tdiff(&now, &asic->last_nonce) > info->nonce_limit)
- {
- plateau_type = PT_NONONCE;
- applog(LOG_ERR, "%d: %s %d - plateau_type PT_NONONCE [%u] %d > %.2f (lock=%d)",
- compac->cgminer_id, compac->drv->name, compac->device_id, i,
- ms_tdiff(&now, &asic->last_nonce), info->nonce_limit, info->lock_freq);
- if (info->lock_freq)
- info->lock_freq = false;
- }
- }
- // asic check-in failed
- if (!info->lock_freq
- && info->asic_type != BM1397)
- {
- if (ms_tdiff(&asic->last_frequency_ping, &asic->last_frequency_reply) > MS_SECOND_30
- && ms_tdiff(&now, &asic->last_frequency_reply) > MS_SECOND_30)
- {
- plateau_type = PT_FREQNR;
- applog(LOG_INFO, "%d: %s %d - plateau_type PT_FREQNR [%u] %d > %d",
- compac->cgminer_id, compac->drv->name, compac->device_id, i,
- ms_tdiff(&now, &asic->last_frequency_reply), MS_SECOND_30);
- }
- }
- // set frequency requests not honored
- if (!info->lock_freq
- && asic->frequency_attempt > 3)
- {
- plateau_type = PT_FREQSET;
- applog(LOG_INFO, "%d: %s %d - plateau_type PT_FREQSET [%u] %u > 3",
- compac->cgminer_id, compac->drv->name, compac->device_id, i, asic->frequency_attempt);
- }
- if (plateau_type)
- {
- float old_frequency, new_frequency;
- new_frequency = info->frequency_requested;
- bool didmsg, doreset;
- char *reason;
- char freq_buf[512];
- char freq_chip_buf[15];
- memset(freq_buf, 0, sizeof(freq_buf));
- memset(freq_chip_buf, 0, sizeof(freq_chip_buf));
- for (j = 0; j < info->chips; j++)
- {
- struct ASIC_INFO *asjc = &info->asics[j];
- sprintf(freq_chip_buf, "[%d:%.2f]", j, asjc->frequency);
- strcat(freq_buf, freq_chip_buf);
- }
- applog(LOG_INFO,"%d: %s %d - %s",
- compac->cgminer_id, compac->drv->name, compac->device_id, freq_buf);
- if (info->plateau_reset < 3)
- {
- // Capture failure high frequency using first three resets
- if ((info->frequency - info->freq_base) > info->frequency_fail_high)
- info->frequency_fail_high = (info->frequency - info->freq_base);
- applog(LOG_WARNING,"%d: %s %d - asic plateau: [%u] (%d/3) %.2fMHz",
- compac->cgminer_id, compac->drv->name, compac->device_id,
- i, info->plateau_reset + 1, info->frequency_fail_high);
- }
- if (info->plateau_reset >= 2) {
- if (ms_tdiff(&now, &info->last_frequency_adjust) > MS_MINUTE_30) {
- // Been running for 30 minutes, possible plateau
- // Overlook the incident
- } else {
- // Step back frequency
- info->frequency_fail_high -= info->freq_base;
- }
- new_frequency = limit_freq(info, FREQ_BASE(info->frequency_fail_high), true);
- }
- info->plateau_reset++;
- asic->last_state = asic->state;
- asic->state = ASIC_HALFDEAD;
- cgtime(&asic->state_change_time);
- cgtime(&info->monitor_time);
- switch (plateau_type)
- {
- case PT_FREQNR:
- applog(info->log_wide,"%d: %s %d - no frequency reply from chip[%u] - %.2fMHz",
- compac->cgminer_id, compac->drv->name, compac->device_id, i, info->frequency);
- asic->frequency_attempt = 0;
- reason = " FREQNR";
- break;
- case PT_FREQSET:
- applog(info->log_wide,"%d: %s %d - frequency set fail to chip[%u] - %.2fMHz",
- compac->cgminer_id, compac->drv->name, compac->device_id, i, info->frequency);
- asic->frequency_attempt = 0;
- reason = " FREQSET";
- break;
- case PT_NONONCE:
- applog(info->log_wide,"%d: %s %d - missing nonces from chip[%u] - %.2fMHz",
- compac->cgminer_id, compac->drv->name, compac->device_id, i, info->frequency);
- reason = " NONONCE";
- break;
- default:
- reason = NULL;
- break;
- }
- if (plateau_type == PT_NONONCE || info->asic_type == BM1387 || info->asic_type == BM1397)
- {
- // BM1384 is less tolerant to sudden drops in frequency.
- // Ignore other indicators except no nonce.
- doreset = true;
- }
- else
- doreset = false;
- didmsg = false;
- old_frequency = info->frequency_requested;
- if (new_frequency != old_frequency)
- {
- info->frequency_requested = new_frequency;
- applog(LOG_WARNING,"%d: %s %d - plateau%s [%u] adjust:%s target frequency %.2fMHz -> %.2fMHz",
- compac->cgminer_id, compac->drv->name, compac->device_id,
- reason ? : "", i, doreset ? " RESET" : "", old_frequency, new_frequency);
- didmsg = true;
- }
- if (doreset)
- {
- if (didmsg == false)
- {
- applog(LOG_WARNING,"%d: %s %d - plateau%s [%u] RESET at %.2fMHz",
- compac->cgminer_id, compac->drv->name, compac->device_id,
- reason ? : "", i, old_frequency);
- }
- info->mining_state = MINER_RESET;
- }
- // any plateau on 1 chip means no need to check the rest
- break;
- }
- }
- }
- if (!info->lock_freq
- && ms_tdiff(&now, &info->last_reset) < info->ramp_time)
- {
- // move running frequency towards target every second
- // initially or for up to ramp_time after a reset
- if ((plateau_type == 0)
- && (ms_tdiff(&now, &last_movement) > MS_SECOND_1)
- && (info->frequency < info->frequency_requested)
- && (info->gh.noncesum > GHNONCENEEDED))
- {
- float new_frequency = info->frequency + info->step_freq;
- if (new_frequency > info->frequency_requested)
- new_frequency = info->frequency_requested;
- frequency_updated = 1;
- change_freq_any(compac, new_frequency);
- cgtime(&last_movement);
- }
- }
- else
- {
- // after ramp_time regularly check the frequency vs hashrate
- // when we have enough nonces or gh is full
- if (!info->lock_freq
- && (info->gh.last == (GHNUM-1) || info->gh.noncesum > GHNONCES)
- && (ms_tdiff(&now, &info->tune_limit) >= MS_MINUTE_2))
- {
- float new_freq, prev_freq;
- double hash_for_freq, curr_hr;
- int nonces, last;
- prev_freq = info->frequency;
- mutex_lock(&info->ghlock);
- curr_hr = gekko_gh_hashrate(info, &now, true);
- nonces = info->gh.noncesum;
- last = info->gh.last;
- mutex_unlock(&info->ghlock);
- // verify with locked values
- if ((last == (GHNUM-1)) || (nonces > GHNONCES))
- {
- hash_for_freq = info->frequency * (double)(info->cores * info->chips);
- // a low hash rate means frequency may be too high
- if (curr_hr < (hash_for_freq * info->ghrequire))
- {
- new_freq = FREQ_BASE(info->frequency - (info->freq_base * 2));
- if (new_freq < info->min_freq)
- new_freq = FREQ_BASE(info->min_freq);
- if (info->frequency_requested > new_freq)
- info->frequency_requested = new_freq;
- if (info->frequency_start > new_freq)
- info->frequency_start = new_freq;
- applog(LOG_WARNING,"%d: %s %d - %.2fGH/s low [%.2f/%.2f/%d] reset limit %.2fMHz -> %.2fMHz",
- compac->cgminer_id, compac->drv->name, compac->device_id,
- curr_hr/1.0e3, hash_for_freq/1.0e3, hash_for_freq*info->ghrequire/1.0e3,
- nonces, prev_freq, new_freq);
- mutex_lock(&info->lock);
- frequency_updated = 1;
- change_freq_any(compac, info->frequency_start);
- // reset from start
- info->mining_state = MINER_RESET;
- mutex_unlock(&info->lock);
- continue;
- }
- cgtime(&info->tune_limit);
- // step the freq up one - environment may have changed to allow it
- if (opt_gekko_tune2 != 0
- && (info->frequency_requested < info->frequency_selected)
- && (tdiff(&now, &info->last_reset) >= ((double)opt_gekko_tune2 * 60.0))
- && (tdiff(&now, &info->last_tune_up) >= ((double)opt_gekko_tune2 * 60.0)))
- {
- new_freq = FREQ_BASE(info->frequency + info->freq_base);
- if (new_freq <= info->frequency_selected)
- {
- if (info->frequency_requested < new_freq)
- info->frequency_requested = new_freq;
- applog(LOG_WARNING,"%d: %s %d - tune up attempt (%.1fGH/s) %.2fMHz -> %.2fMHz",
- compac->cgminer_id, compac->drv->name, compac->device_id,
- curr_hr/1.0e3, prev_freq, new_freq);
- // will reset if it doesn't improve,
- // as soon as it has enough nonces
- frequency_updated = 1;
- change_freq_any(compac, new_freq);
- }
- cgtime(&info->last_tune_up);
- }
- }
- }
- }
- if (!info->lock_freq
- && !frequency_updated
- && ms_tdiff(&now, &last_frequency_check) > 20)
- {
- cgtime(&last_frequency_check);
- for (i = 0; i < info->chips; i++)
- {
- struct ASIC_INFO *asic = &info->asics[i];
- if (asic->frequency_updated)
- {
- asic->frequency_updated = 0;
- info->frequency_of = i;
- if (info->asic_type != BM1397)
- ping_freq(compac, i);
- break;
- }
- }
- }
- }
- has_freq = false;
- for (i = 0; i < info->chips; i++)
- {
- if (info->asics[i].frequency != 0)
- {
- has_freq = true;
- break;
- }
- }
- // don't bother with work if it's not mining
- if (!has_freq)
- {
- gekko_usleep(info, MS2US(10));
- continue;
- }
- struct timeval stt, fin;
- double wd;
- // don't delay work updates when doing busy work
- if (info->work_usec_num > 1 && !last_was_busy)
- {
- // check if we got here early
- // and sleep almost the entire delay required
- cgtime(&now);
- diff_us = us_tdiff(&now, &info->last_task);
- left_us = info->max_task_wait - diff_us;
- if (left_us > 0)
- {
- // allow time for get_queued() + a bit
- left_us -= (info->work_usec_avg + USLEEPPLUS);
- if (left_us >= USLEEPMIN)
- gekko_usleep(info, left_us);
- }
- else
- {
- #if TUNE_CODE
- // ran over by 10us or more
- if (left_us <= -10)
- {
- info->over1num++;
- info->over1amt -= left_us;
- }
- #endif
- }
- }
- cgtime(&stt);
- work = get_queued(compac);
- if (work)
- {
- cgtime(&fin);
- wd = us_tdiff(&fin, &stt);
- if (info->work_usec_num == 0)
- info->work_usec_avg = wd;
- else
- {
- // fast work times should have a higher effect
- if (wd < (info->work_usec_avg / 2.0))
- info->work_usec_avg = (info->work_usec_avg + wd) / 2.0;
- else
- {
- // ignore extra long work times after we get a few
- if (info->work_usec_num > 5
- && (wd / 3.0) < info->work_usec_avg)
- {
- info->work_usec_avg =
- (info->work_usec_avg * 9.0 + wd) / 10.0;
- }
- }
- }
- info->work_usec_num++;
- if (last_was_busy)
- last_was_busy = false;
- #if TUNE_CODE
- diff_us = us_tdiff(&fin, &info->last_task);
- // stats if we got here too fast ...
- left_us = info->max_task_wait - diff_us;
- if (left_us < 0)
- {
- // ran over by 10us or more
- if (left_us <= -10)
- {
- info->over2num++;
- info->over2amt -= left_us;
- }
- }
- #endif
- if (opt_gekko_noboost)
- work->pool->vmask = 0;
- info->job_id += info->add_job_id;
- if (info->job_id > info->max_job_id)
- info->job_id = info->min_job_id;
- old_work = info->work[info->job_id];
- info->work[info->job_id] = work;
- info->active_work[info->job_id] = 1;
- info->vmask = work->pool->vmask;
- if (info->asic_type == BM1387 || info->asic_type == BM1397)
- {
- if (!opt_gekko_noboost && info->vmask)
- info->task_len = 54 + 32 * (info->midstates - 1);
- else
- info->task_len = 54;
- }
- init_task(info);
- }
- else
- {
- struct pool *cp;
- cp = current_pool();
- if (!cp->stratum_active)
- cgtime(&info->last_pool_lost);
- if (cp->stratum_active
- && (info->asic_type == BM1387 || info->asic_type == BM1397))
- {
- // get Dups instead of sending busy work
- // sleep 1ms then fast loop back
- gekko_usleep(info, MS2US(1));
- last_was_busy = true;
- continue;
- }
- busy_work(info);
- info->busy_work++;
- last_was_busy = true;
- cgtime(&info->monitor_time);
- applog(LOG_INFO, "%d: %s %d - Busy",
- compac->cgminer_id, compac->drv->name, compac->device_id);
- }
- int task_len = info->task_len;
- #if 0
- unsigned char jid = info->task[2];
- #endif
- if (info->asic_type == BM1397)
- {
- int k;
- for (k = (info->task_len - 1); k >= 0; k--)
- {
- info->task[k+2] = info->task[k];
- }
- info->task[0] = 0x55;
- info->task[1] = 0xaa;
- task_len += 2;
- }
- #if 0
- applog(LOG_ERR, "%s() %d: %s %d - Task [%02x] len %3u", __func__,
- compac->cgminer_id, compac->drv->name, compac->device_id, jid, task_len);
- applog(LOG_ERR, " [%02x %02x %02x %02x %02x %02x %02x %02x]",
- info->task[0], info->task[1], info->task[2], info->task[3], info->task[4], info->task[5], info->task[6], info->task[7]);
- applog(LOG_ERR, " [%02x %02x %02x %02x %02x %02x %02x %02x]",
- info->task[8], info->task[9], info->task[10], info->task[11], info->task[12], info->task[13], info->task[14], info->task[15]);
- applog(LOG_ERR, " [%02x %02x %02x %02x %02x %02x %02x %02x]",
- info->task[16], info->task[17], info->task[18], info->task[19], info->task[20], info->task[21], info->task[22], info->task[23]);
- applog(LOG_ERR, " [%02x %02x %02x %02x %02x %02x %02x %02x]",
- info->task[24], info->task[25], info->task[26], info->task[27], info->task[28], info->task[29], info->task[30], info->task[31]);
- #endif
- cgtime(&now); // set the time we actually sent it
- err = usb_write(compac, (char *)info->task, task_len, &sent_bytes, C_SENDWORK);
- //dumpbuffer(compac, LOG_WARNING, "TASK.TX", info->task, task_len);
- if (err != LIBUSB_SUCCESS)
- {
- applog(LOG_WARNING,"%d: %s %d - usb failure (%d)", compac->cgminer_id, compac->drv->name, compac->device_id, err);
- info->mining_state = MINER_RESET;
- continue;
- }
- if (sent_bytes != task_len)
- {
- if (ms_tdiff(&now, &info->last_write_error) > (5 * 1000)) {
- applog(LOG_WARNING,"%d: %s %d - usb write error [%d:%d]",
- compac->cgminer_id, compac->drv->name, compac->device_id, sent_bytes, task_len);
- cgtime(&info->last_write_error);
- }
- job_added = false;
- }
- else
- {
- // successfully sent work
- add_gekko_job(info, &now, false);
- job_added = true;
- }
- //let the usb frame propagate
- if (info->asic_type == BM1397 && info->usb_prop != 1000)
- gekko_usleep(info, info->usb_prop);
- else
- gekko_usleep(info, MS2US(1));
- info->task_ms = (info->task_ms * 9 + ms_tdiff(&now, &info->last_task)) / 10;
- info->last_task.tv_sec = now.tv_sec;
- info->last_task.tv_usec = now.tv_usec;
- if (info->first_task.tv_sec == 0L)
- {
- info->first_task.tv_sec = now.tv_sec;
- info->first_task.tv_usec = now.tv_usec;
- }
- info->tasks++;
- // work source changes can affect this e.g. 1 vs 4 midstates
- if (work && job_added
- && ms_tdiff(&now, &info->last_update_rates) > MS_SECOND_5)
- {
- compac_update_rates(compac);
- }
- }
- return NULL;
- }
- // not called by BM1397
- static void *compac_handle_rx(void *object, int read_bytes, int path)
- {
- struct cgpu_info *compac = (struct cgpu_info *)object;
- struct COMPAC_INFO *info = compac->device_data;
- struct ASIC_INFO *asic;
- int cmd_resp;
- unsigned int i;
- struct timeval now;
- cgtime(&now);
- cmd_resp = 0;
- if (info->rx[read_bytes-1] <= 0x1f)
- {
- if (bmcrc(info->rx, 8 * read_bytes - 5) == info->rx[read_bytes-1])
- cmd_resp = 1;
- }
- int log_level = (cmd_resp) ? LOG_INFO : LOG_INFO;
- if (path) {
- dumpbuffer(compac, log_level, "RX1", info->rx, read_bytes);
- } else {
- dumpbuffer(compac, log_level, "RX0", info->rx, read_bytes);
- }
- if (cmd_resp && info->rx[0] == 0x80 && info->frequency_of != (int)(info->chips)) {
- float frequency = 0.0;
- int frequency_of = info->frequency_of;
- info->frequency_of = info->chips;
- cgtime(&info->last_frequency_report);
- if (info->asic_type == BM1387 && (info->rx[2] == 0 || (info->rx[3] >> 4) == 0 || (info->rx[3] & 0x0f) != 1 || (info->rx[4]) != 0 || (info->rx[5]) != 0)) {
- cgtime(&info->last_frequency_invalid);
- applog(LOG_INFO,"%d: %s %d - invalid frequency report", compac->cgminer_id, compac->drv->name, compac->device_id);
- } else {
- if (info->asic_type == BM1387) {
- frequency = info->freq_mult * info->rx[1] / (info->rx[2] * (info->rx[3] >> 4) * (info->rx[3] & 0x0f));
- } else if (info->asic_type == BM1384) {
- frequency = (info->rx[1] + 1) * info->freq_base / ((1 + info->rx[2]) & 0x0f) * pow(2, (3 - info->rx[3])) + ((info->rx[2] >> 4) * info->freq_base);
- }
- if (frequency_of != (int)(info->chips)) {
- asic = &info->asics[frequency_of];
- cgtime(&asic->last_frequency_reply);
- if (frequency != asic->frequency) {
- bool syncd = 1;
- if (frequency < asic->frequency && frequency != info->frequency_requested) {
- applog(LOG_INFO,"%d: %s %d - chip[%d] reported frequency at %.2fMHz", compac->cgminer_id, compac->drv->name, compac->device_id, info->frequency_of, frequency);
- } else {
- applog(LOG_INFO,"%d: %s %d - chip[%d] reported new frequency of %.2fMHz", compac->cgminer_id, compac->drv->name, compac->device_id, info->frequency_of, frequency);
- }
- asic->frequency = frequency;
- if (asic->frequency == asic->frequency_set) {
- asic->frequency_attempt = 0;
- }
- for (i = 1; i < info->chips; i++) {
- if (info->asics[i].frequency != info->asics[i - 1].frequency) {
- syncd = 0;
- }
- }
- if (info->frequency_syncd != syncd) {
- info->frequency_syncd = syncd;
- applog(LOG_INFO,"%d: %s %d - syncd [%d]", compac->cgminer_id, compac->drv->name, compac->device_id, syncd);
- }
- } else {
- applog(LOG_INFO,"%d: %s %d - chip[%d] reported frequency of %.2fMHz", compac->cgminer_id, compac->drv->name, compac->device_id, info->frequency_of, frequency);
- }
- } else {
- //applog(LOG_INFO,"%d: %s %d - [-1] reported frequency of %.2fMHz", compac->cgminer_id, compac->drv->name, compac->device_id, frequency);
- //if (frequency != info->frequency) {
- // info->frequency = frequency;
- //}
- }
- compac_update_rates(compac);
- }
- }
- switch (info->mining_state) {
- case MINER_CHIP_COUNT:
- case MINER_CHIP_COUNT_XX:
- if (cmd_resp && (info->rx[0] == 0x13 ||
- (info->rx[0] == 0xaa && info->rx[1] == 0x55 && info->rx[2] == 0x13))) { // BM1397
- struct ASIC_INFO *asic = &info->asics[info->chips];
- memset(asic, 0, sizeof(struct ASIC_INFO));
- asic->frequency = info->frequency_default;
- asic->frequency_attempt = 0;
- asic->last_frequency_ping = (struct timeval){0};
- asic->last_frequency_reply = (struct timeval){0};
- cgtime(&asic->last_nonce);
- info->chips++;
- info->mining_state = MINER_CHIP_COUNT_XX;
- compac_update_rates(compac);
- }
- break;
- case MINER_OPEN_CORE:
- if ((info->rx[0] == 0x72 && info->rx[1] == 0x03 && info->rx[2] == 0xEA && info->rx[3] == 0x83) ||
- (info->rx[0] == 0xE1 && info->rx[1] == 0x6B && info->rx[2] == 0xF8 && info->rx[3] == 0x09)) {
- //open core nonces = healthy chips.
- info->zero_check++;
- }
- break;
- case MINER_MINING:
- if (!cmd_resp) {
- #ifdef __APPLE__
- if (opt_mac_yield)
- sched_yield();
- #else
- selective_yield();
- #endif
- mutex_lock(&info->lock);
- info->hashes += compac_check_nonce(compac);
- mutex_unlock(&info->lock);
- }
- break;
- default:
- break;
- }
- return NULL;
- }
- static void *compac_gsf_nonce_que(void *object)
- {
- struct cgpu_info *compac = (struct cgpu_info *)object;
- struct COMPAC_INFO *info = compac->device_data;
- struct timespec abstime, addtime;
- K_ITEM *item;
- int rc;
- if (info->asic_type != BM1397)
- return NULL;
- // wait at most 42ms for a nonce
- ms_to_timespec(&addtime, 42);
- while (info->mining_state != MINER_SHUTDOWN)
- {
- K_WLOCK(info->nlist);
- item = k_unlink_head(info->nstore);
- K_WUNLOCK(info->nlist);
- if (item)
- {
- compac_gsf_nonce(compac, item);
- K_WLOCK(info->nlist);
- k_add_head(info->nlist, item);
- K_WUNLOCK(info->nlist);
- }
- else
- {
- cgcond_time(&abstime);
- timeraddspec(&abstime, &addtime);
- mutex_lock(&info->nlock);
- rc = pthread_cond_timedwait(&info->ncond, &info->nlock, &abstime);
- mutex_unlock(&info->nlock);
- if (rc == ETIMEDOUT)
- info->ntimeout++;
- else
- info->ntrigger++;
- }
- }
- return NULL;
- }
- static bool gsf_reply(struct COMPAC_INFO *info, unsigned char *rx, int len, struct timeval *now)
- {
- unsigned char fa, fb, fc1, fc2;
- bool used = false;
- if (len == (int)(info->rx_len) && rx[7] == BM1397FREQ)
- {
- int chip = TOCHIPPY1397(info, rx[6]);
- if (chip >= 0 && chip < (int)(info->chips))
- {
- struct ASIC_INFO *asic = &info->asics[chip];
- fa = rx[3];
- fb = rx[4];
- fc1 = (rx[5] & 0xf0) >> 4;
- fc2 = rx[5] & 0x0f;
- // only allow a valid reply
- if (fa >= 0 && fb > 0 && fc1 > 0 && fc2 > 0)
- {
- asic->frequency_reply = info->freq_mult * fa / fb / fc1 / fc2;
- asic->last_frequency_reply.tv_sec = now->tv_sec;
- asic->last_frequency_reply.tv_usec = now->tv_usec;
- used = true;
- }
- }
- }
- return used;
- }
- static void *compac_listen2(struct cgpu_info *compac, struct COMPAC_INFO *info)
- {
- unsigned char rx[BUFFER_MAX];
- struct timeval now;
- int read_bytes, tmo, pos = 0, len, i, prelen;
- bool okcrc, used, chipped;
- K_ITEM *item;
- memset(rx, 0, sizeof(rx));
- while (info->mining_state != MINER_SHUTDOWN)
- {
- tmo = 20;
- if (info->mining_state == MINER_CHIP_COUNT)
- {
- unsigned char chippy[] = {0x52, 0x05, 0x00, 0x00, 0x0A};
- compac_send2(compac, chippy, sizeof(chippy), 8 * sizeof(chippy) - 8, "CHIPPY");
- info->mining_state = MINER_CHIP_COUNT_XX;
- // initial config reply allow much longer
- tmo = 1000;
- }
- usb_read_timeout(compac, ((char *)rx)+pos, BUFFER_MAX-pos, &read_bytes, tmo, C_GETRESULTS);
- pos += read_bytes;
- cgtime(&now);
- // all replies should be info->rx_len
- while (read_bytes > 0 && pos >= (int)(info->rx_len))
- {
- #if 0
- applog(LOG_ERR, "%d: %s %d - READ %3d pos %3d state %2d first 16: [%02x %02x %02x %02x %02x %02x %02x %02x]",
- compac->cgminer_id, compac->drv->name, compac->device_id, read_bytes, pos, info->mining_state,
- rx[0], rx[1], rx[2], rx[3], rx[4], rx[5], rx[6], rx[7]);
- applog(LOG_ERR, " [%02x %02x %02x %02x %02x %02x %02x %02x]",
- rx[8], rx[9], rx[10], rx[11], rx[12], rx[13], rx[14], rx[15]);
- #endif
- // rubbish - skip over it to next 0xaa
- if (rx[0] != 0xaa || rx[1] != 0x55)
- {
- for (i = 1; i < pos; i++)
- {
- if (rx[i] == 0xaa)
- {
- // next read could be 0x55 or i+1=0x55
- if (i == (pos - 1) || rx[i+1] == 0x55)
- break;
- }
- }
- // no 0xaa dump it and wait for more data
- if (i >= pos)
- {
- #if 0
- applog(LOG_ERR, " %s %d no 0xaa = dump all (%d) [%02x %02x %02x %02x ...]",
- compac->drv->name, compac->device_id, pos, rx[0], rx[1], rx[2], rx[3]);
- #endif
- pos = 0;
- continue;
- }
- #if 0
- applog(LOG_ERR, " %s %d dump before %d=0xaa [%02x %02x %02x %02x ...]",
- compac->drv->name, compac->device_id, i, rx[0], rx[1], rx[2], rx[3]);
- #endif
- // i=0xaa dump up to i-1
- memmove(rx, rx+i, pos-i);
- pos -= i;
- if (pos < (int)(info->rx_len))
- continue;
- }
- // find next 0xaa 0x55
- for (len = info->rx_len; len < pos; len++)
- {
- if (rx[len] == 0xaa
- && (len == (pos-1) || rx[len+1] == 0x55))
- break;
- }
- prelen = len;
- // a reply followed by only 0xaa but no 0x55 yet
- if (len == pos && (len == 8 || len == 10) && rx[pos-1] == 0xaa)
- len--;
- // try it as a nonce
- if (len != (int)(info->rx_len))
- len = info->rx_len;
- #if 0
- if (info->asic_type == BM1397 &&
- bmcrc(&rx[i+2], 8 * (info->rx_len-2) - 5) == (rx[i + info->rx_len - 1] & 0x1f)) {
- // crc checksum is good
- crc_match = true;
- rx_okay = true;
- }
- if (info->asic_type == BM1397 && rx[0] >= 0xaa && rx[1] <= 0x55) {
- // bm1397 response
- rx_okay = true;
- }
- #endif
- if (rx[len-1] <= 0x1f
- && bmcrc(rx+2, 8 * (len-2) - 5) == rx[len-1])
- okcrc = true;
- else
- okcrc = false;
- switch (info->mining_state)
- {
- case MINER_CHIP_COUNT:
- case MINER_CHIP_COUNT_XX:
- // BM1397
- chipped = false;
- if (rx[2] == 0x13 && rx[3] == 0x97)
- {
- struct ASIC_INFO *asic = &info->asics[info->chips];
- memset(asic, 0, sizeof(struct ASIC_INFO));
- asic->frequency = info->frequency_default;
- asic->frequency_attempt = 0;
- asic->last_frequency_ping = (struct timeval){0};
- asic->frequency_reply = -1;
- asic->last_frequency_reply = (struct timeval){0};
- cgtime(&asic->last_nonce);
- info->chips++;
- info->mining_state = MINER_CHIP_COUNT_XX;
- compac_update_rates(compac);
- chipped = true;
- }
- // ignore all data until we get at least 1 chip reply
- if (!chipped && info->mining_state == MINER_CHIP_COUNT_XX)
- {
- // we found some chips then it replied with other data ...
- if (info->chips > 0)
- {
- info->mining_state = MINER_CHIP_COUNT_OK;
- mutex_lock(&static_lock);
- (*init_count) = 0;
- info->init_count = 0;
- mutex_unlock(&static_lock);
- // don't discard the data
- if (len == (int)(info->rx_len) && okcrc)
- gsf_reply(info, rx, info->rx_len, &now);
- }
- else
- info->mining_state = MINER_RESET;
- }
- break;
- case MINER_MINING:
- used = false;
- if (len == (int)(info->rx_len) && okcrc)
- {
- used = gsf_reply(info, rx, info->rx_len, &now);
- #if 0
- if (!used)
- {
- applog(LOG_ERR, "%d: %s %d - ? len %3d state %2d first 12:",
- compac->cgminer_id, compac->drv->name, compac->device_id, len, info->mining_state);
- applog(LOG_ERR, " [%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x]",
- rx[0], rx[1], rx[2], rx[3], rx[4], rx[5], rx[6], rx[7], rx[8], rx[9], rx[10], rx[11]);
- }
- #endif
- }
- // also try unidentifed crc's as a nonce
- if (!used)
- {
- K_WLOCK(info->nlist);
- item = k_unlink_head(info->nlist);
- K_WUNLOCK(info->nlist);
- DATA_NONCE(item)->asic = 0;
- // should never be true ...
- if (len > (int)sizeof(DATA_NONCE(item)->rx))
- len = (int)sizeof(DATA_NONCE(item)->rx);
- memcpy(DATA_NONCE(item)->rx, rx, len);
- DATA_NONCE(item)->len = len;
- DATA_NONCE(item)->prelen = prelen;
- DATA_NONCE(item)->when.tv_sec = now.tv_sec;
- DATA_NONCE(item)->when.tv_usec = now.tv_usec;
- K_WLOCK(info->nlist);
- k_add_tail(info->nstore, item);
- K_WUNLOCK(info->nlist);
- mutex_lock(&info->nlock);
- pthread_cond_signal(&info->ncond);
- mutex_unlock(&info->nlock);
- }
- break;
- default:
- used = false;
- if (len == (int)(info->rx_len) && okcrc)
- used = gsf_reply(info, rx, info->rx_len, &now);
- #if 0
- if (!used)
- {
- applog(LOG_ERR, "%d: %s %d - unhandled, len %3d state %2d first 12:",
- compac->cgminer_id, compac->drv->name, compac->device_id, len, info->mining_state);
- applog(LOG_ERR, " [%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x]",
- rx[0], rx[1], rx[2], rx[3], rx[4], rx[5], rx[6], rx[7], rx[8], rx[9], rx[10], rx[11]);
- }
- #endif
- break;
- }
- // we've used up 0..len-1
- if (pos > len)
- memmove(rx, rx+len, pos-len);
- pos -= len;
- }
- if (read_bytes == 0 || pos < 6)
- {
- if (info->mining_state == MINER_CHIP_COUNT_XX)
- {
- if (info->chips < info->expected_chips)
- info->mining_state = MINER_RESET;
- else
- {
- if (info->chips > 0)
- {
- info->mining_state = MINER_CHIP_COUNT_OK;
- mutex_lock(&static_lock);
- (*init_count) = 0;
- info->init_count = 0;
- mutex_unlock(&static_lock);
- }
- else
- info->mining_state = MINER_RESET;
- }
- }
- }
- }
- return NULL;
- }
- static void *compac_listen(void *object)
- {
- struct cgpu_info *compac = (struct cgpu_info *)object;
- struct COMPAC_INFO *info = compac->device_data;
- if (info->asic_type == BM1397)
- return compac_listen2(compac, info);
- struct timeval now;
- unsigned char rx[BUFFER_MAX];
- unsigned char *prx = rx;
- int read_bytes, cmd_resp, pos;
- unsigned int i, rx_bytes;
- memset(rx, 0, sizeof(rx));
- memset(info->rx, 0, sizeof(info->rx));
- pos = 0;
- rx_bytes = 0;
- while (info->mining_state != MINER_SHUTDOWN) {
- cgtime(&now);
- if (info->mining_state == MINER_CHIP_COUNT) {
- if (info->asic_type == BM1387) {
- unsigned char buffer[] = {0x54, 0x05, 0x00, 0x00, 0x00};
- compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8);
- } else if (info->asic_type == BM1384) {
- unsigned char buffer[] = {0x84, 0x00, 0x00, 0x00};
- compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
- }
- usb_read_timeout(compac, (char *)rx, BUFFER_MAX, &read_bytes, 1000, C_GETRESULTS);
- dumpbuffer(compac, LOG_INFO, "CMD.RX", rx, read_bytes);
- rx_bytes = (unsigned int)read_bytes;
- info->mining_state = MINER_CHIP_COUNT_XX;
- } else {
- if (rx_bytes >= (BUFFER_MAX - info->rx_len)) {
- applog(LOG_INFO, "%d: %s %d - Buffer not useful, dumping (b) %d bytes", compac->cgminer_id, compac->drv->name, compac->device_id, rx_bytes);
- dumpbuffer(compac, LOG_INFO, "NO-CRC-RX", rx, rx_bytes);
- pos = 0;
- rx_bytes = 0;
- }
- usb_read_timeout(compac, (char *)(&rx[pos]), info->rx_len, &read_bytes, 20, C_GETRESULTS);
- rx_bytes += read_bytes;
- pos = rx_bytes;
- }
- if (read_bytes > 0) {
- if (rx_bytes < info->rx_len) {
- applog(LOG_INFO, "%d: %s %d - Buffered %d bytes", compac->cgminer_id, compac->drv->name, compac->device_id, rx_bytes);
- dumpbuffer(compac, LOG_INFO, "Partial-RX", rx, rx_bytes);
- continue;
- }
- if (rx_bytes >= info->rx_len)
- cmd_resp = (rx[read_bytes - 1] <= 0x1f && bmcrc(prx, 8 * read_bytes - 5) == rx[read_bytes - 1]) ? 1 : 0;
- if (info->mining_state == MINER_CHIP_COUNT_XX || cmd_resp) {
- if (rx_bytes % info->rx_len == 2) {
- // fix up trial 1
- int shift = 0;
- int extra = 0;
- for (i = 0; i < (rx_bytes - shift); i++) {
- if (rx[i] == 0x01) {
- shift = 2;
- extra = rx[i + 1];
- }
- rx[i] = rx[i + shift];
- }
- rx_bytes -= shift;
- pos = rx_bytes;
- applog(LOG_INFO, "%d: %s %d - Extra Data - 0x01 0x%02x", compac->cgminer_id, compac->drv->name, compac->device_id, extra & 0xff);
- }
- }
- if (rx_bytes >= info->rx_len) {
- bool crc_match = false;
- unsigned int new_pos = 0;
- for (i = 0; i <= (rx_bytes - info->rx_len); i++) {
- bool rx_okay = false;
- if (bmcrc(&rx[i], 8 * info->rx_len - 5) == (rx[i + info->rx_len - 1] & 0x1f)) {
- // crc checksum is good
- crc_match = true;
- rx_okay = true;
- }
- if (info->asic_type == BM1384 && rx[i + info->rx_len - 1] >= 0x80 && rx[i + info->rx_len - 1] <= 0x9f) {
- // bm1384 nonce
- rx_okay = true;
- }
- if (rx_okay) {
- memcpy(info->rx, &rx[i], info->rx_len);
- compac_handle_rx(compac, info->rx_len, 0);
- new_pos = i + info->rx_len;
- }
- }
- if (new_pos > rx_bytes) {
- rx_bytes = 0;
- pos = 0;
- } else if (new_pos > 0) {
- for (i = new_pos; i < rx_bytes; i++) {
- rx[i - new_pos] = rx[i];
- }
- rx_bytes -= new_pos;
- pos = rx_bytes;
- }
- }
- /*
- if (bmcrc(&rx[rx_bytes - info->rx_len], 8 * info->rx_len - 5) != info->rx[rx_bytes - 1]) {
- int n_read_bytes;
- pos = rx_bytes;
- usb_read_timeout(compac, &rx[pos], BUFFER_MAX - pos, &n_read_bytes, 5, C_GETRESULTS);
- rx_bytes += n_read_bytes;
- if (rx_bytes % info->rx_len != 0 && rx_bytes >= info->rx_len) {
- int extra_bytes = rx_bytes % info->rx_len;
- for (i = extra_bytes; i < rx_bytes; i++) {
- rx[i - extra_bytes] = rx[i];
- }
- rx_bytes -= extra_bytes;
- applog(LOG_INFO, "%d: %s %d - Fixing buffer alignment, dumping initial %d bytes", compac->cgminer_id, compac->drv->name, compac->device_id, extra_bytes);
- }
- }
- if (rx_bytes % info->rx_len == 0) {
- for (i = 0; i < rx_bytes; i += info->rx_len) {
- memcpy(info->rx, &rx[i], info->rx_len);
- compac_handle_rx(compac, info->rx_len, 1);
- }
- pos = 0;
- rx_bytes = 0;
- }
- */
- } else {
- if (rx_bytes > 0) {
- applog(LOG_INFO, "%d: %s %d - Second read, no data dumping (c) %d bytes", compac->cgminer_id, compac->drv->name, compac->device_id, rx_bytes);
- dumpbuffer(compac, LOG_INFO, "EXTRA-RX", rx, rx_bytes);
- }
- pos = 0;
- rx_bytes = 0;
- // RX line is idle, let's squeeze in a command to the micro if needed.
- if (info->asic_type == BM1387) {
- if (ms_tdiff(&now, &info->last_micro_ping) > MS_SECOND_5 && ms_tdiff(&now, &info->last_task) > 1 && ms_tdiff(&now, &info->last_task) < 3) {
- compac_micro_send(compac, M1_GET_TEMP, 0x00, 0x00);
- cgtime(&info->last_micro_ping);
- }
- }
- switch (info->mining_state) {
- case MINER_CHIP_COUNT_XX:
- if (info->chips < info->expected_chips) {
- applog(LOG_INFO, "%d: %s %d - found %d/%d chip(s)", compac->cgminer_id, compac->drv->name, compac->device_id, info->chips, info->expected_chips);
- info->mining_state = MINER_RESET;
- } else {
- applog(LOG_INFO, "%d: %s %d - found %d chip(s)", compac->cgminer_id, compac->drv->name, compac->device_id, info->chips);
- if (info->chips > 0) {
- info->mining_state = MINER_CHIP_COUNT_OK;
- mutex_lock(&static_lock);
- (*init_count) = 0;
- info->init_count = 0;
- mutex_unlock(&static_lock);
- } else {
- info->mining_state = MINER_RESET;
- }
- }
- break;
- default:
- break;
- }
- }
- }
- return NULL;
- }
- static bool compac_init(struct thr_info *thr)
- {
- int i;
- struct cgpu_info *compac = thr->cgpu;
- struct COMPAC_INFO *info = compac->device_data;
- float step_freq;
- // all are currently this value
- info->freq_mult = 25.0;
- // most are this value (6.25)
- info->freq_base = info->freq_mult / 4.0;
- // correct some options
- if (opt_gekko_tune_down > 100)
- opt_gekko_tune_down = 100;
- if (opt_gekko_tune_up > 99)
- opt_gekko_tune_up = 99;
- opt_gekko_wait_factor = fbound(opt_gekko_wait_factor, 0.01, 2.0);
- info->wait_factor0 = opt_gekko_wait_factor;
- if (opt_gekko_start_freq < 25)
- opt_gekko_start_freq = 25;
- if (opt_gekko_step_freq < 1)
- opt_gekko_step_freq = 1;
- if (opt_gekko_step_delay < 1)
- opt_gekko_step_delay = 1;
- // must limit it to allow tune downs before trying again
- if (opt_gekko_tune2 < 30 && opt_gekko_tune2 != 0)
- opt_gekko_tune2 = 30;
- info->boosted = false;
- info->prev_nonce = 0;
- info->fail_count = 0;
- info->busy_work = 0;
- info->log_wide = (opt_widescreen) ? LOG_WARNING : LOG_INFO;
- info->plateau_reset = 0;
- info->low_eff_resets = 0;
- info->frequency_fail_high = 0;
- info->frequency_fail_low = 999;
- info->frequency_fo = info->chips;
- info->first_task.tv_sec = 0L;
- info->first_task.tv_usec = 0L;
- info->tasks = 0;
- info->tune_limit.tv_sec = 0L;
- info->tune_limit.tv_usec = 0L;
- info->last_tune_up.tv_sec = 0L;
- info->last_tune_up.tv_usec = 0L;
- memset(info->rx, 0, sizeof(info->rx));
- memset(info->tx, 0, sizeof(info->tx));
- memset(info->cmd, 0, sizeof(info->cmd));
- memset(info->end, 0, sizeof(info->end));
- memset(info->task, 0, sizeof(info->task));
- for (i = 0; i < JOB_MAX; i++) {
- info->active_work[i] = false;
- info->work[i] = NULL;
- }
- memset(&(info->gh), 0, sizeof(info->gh));
- cgtime(&info->last_write_error);
- cgtime(&info->last_frequency_adjust);
- cgtime(&info->last_computed_increase);
- cgtime(&info->last_low_eff_reset);
- info->last_frequency_invalid = (struct timeval){0};
- cgtime(&info->last_micro_ping);
- cgtime(&info->last_scanhash);
- cgtime(&info->last_reset);
- cgtime(&info->last_task);
- cgtime(&info->start_time);
- cgtime(&info->monitor_time);
- info->step_freq = FREQ_BASE(opt_gekko_step_freq);
- // if it can't mine at this freq the hardware has failed
- info->min_freq = info->freq_mult;
- // most should only take this long
- info->ramp_time = MS_MINUTE_3;
- info->ghrequire = GHREQUIRE;
- info->freq_fail = 0.0;
- info->hr_scale = 1.0;
- info->usb_prop = 1000;
- switch (info->ident)
- {
- case IDENT_BSC:
- case IDENT_GSC:
- info->frequency_requested = limit_freq(info, opt_gekko_gsc_freq, false);
- info->frequency_start = limit_freq(info, opt_gekko_start_freq, false);
- break;
- case IDENT_BSD:
- case IDENT_GSD:
- info->frequency_requested = limit_freq(info, opt_gekko_gsd_freq, false);
- info->frequency_start = limit_freq(info, opt_gekko_start_freq, false);
- break;
- case IDENT_BSE:
- case IDENT_GSE:
- info->frequency_requested = limit_freq(info, opt_gekko_gse_freq, false);
- info->frequency_start = limit_freq(info, opt_gekko_start_freq, false);
- break;
- case IDENT_GSH:
- info->frequency_requested = limit_freq(info, opt_gekko_gsh_freq, false);
- info->frequency_start = limit_freq(info, opt_gekko_start_freq, false);
- break;
- case IDENT_BAX:
- info->frequency_requested = limit_freq(info, opt_gekko_bax_freq, false);
- info->frequency_start = limit_freq(info, opt_gekko_start_freq, false);
- break;
- case IDENT_GSI:
- info->frequency_requested = limit_freq(info, opt_gekko_gsi_freq, false);
- info->frequency_start = limit_freq(info, opt_gekko_start_freq, false);
- // default to 550
- if (info->frequency_start == 100)
- info->frequency_start = 550;
- if (info->frequency_start < 100)
- info->frequency_start = 100;
- // due to higher freq allow longer
- info->ramp_time = MS_MINUTE_4;
- break;
- case IDENT_GSF:
- case IDENT_GSFM:
- if (info->ident == IDENT_GSF)
- info->frequency_requested = limit_freq(info, opt_gekko_gsf_freq, false);
- else
- info->frequency_requested = limit_freq(info, opt_gekko_r909_freq, false);
- info->frequency_start = limit_freq(info, opt_gekko_start_freq, false);
- if (info->frequency_start < 100)
- info->frequency_start = 100;
- if (info->frequency_start == 100)
- {
- if (info->ident == IDENT_GSF)
- {
- // default to 200
- info->frequency_start = 200;
- }
- else // (info->ident == IDENT_GSFM)
- {
- // default to 400
- info->frequency_start = 400;
- }
- }
- // ensure request is >= start
- if (info->frequency_requested < info->frequency_start)
- info->frequency_requested = info->frequency_start;
- // correct the defaults:
- info->freq_base = info->freq_mult / 5.0;
- step_freq = opt_gekko_step_freq;
- if (step_freq == 6.25)
- step_freq = 5.0;
- info->step_freq = FREQ_BASE(step_freq);
- // IDENT_GSFM runs at the more reliable higher frequencies
- if (info->ident == IDENT_GSF)
- {
- // chips can get lower than the calculated 67.2 at lower freq
- info->hr_scale = 52.5 / 67.2;
- }
- // due to ticket mask allow longer
- info->ramp_time = MS_MINUTE_5;
- break;
- default:
- info->frequency_requested = 200;
- info->frequency_start = info->frequency_requested;
- break;
- }
- if (info->frequency_start > info->frequency_requested) {
- info->frequency_start = info->frequency_requested;
- }
- info->frequency_requested = FREQ_BASE(info->frequency_requested);
- info->frequency_selected = info->frequency_requested;
- info->frequency_start = FREQ_BASE(info->frequency_start);
- info->frequency = info->frequency_start;
- info->frequency_default = info->frequency_start;
- if (!info->rthr.pth) {
- pthread_mutex_init(&info->lock, NULL);
- pthread_mutex_init(&info->wlock, NULL);
- pthread_mutex_init(&info->rlock, NULL);
- pthread_mutex_init(&info->ghlock, NULL);
- pthread_mutex_init(&info->joblock, NULL);
- if (info->ident == IDENT_GSF || info->ident == IDENT_GSFM)
- {
- info->nlist = k_new_list("GekkoNonces", sizeof(struct COMPAC_NONCE),
- ALLOC_NLIST_ITEMS, LIMIT_NLIST_ITEMS, true);
- info->nstore = k_new_store(info->nlist);
- }
- if (thr_info_create(&(info->rthr), NULL, compac_listen, (void *)compac)) {
- applog(LOG_ERR, "%d: %s %d - read thread create failed", compac->cgminer_id, compac->drv->name, compac->device_id);
- return false;
- } else {
- applog(LOG_INFO, "%d: %s %d - read thread created", compac->cgminer_id, compac->drv->name, compac->device_id);
- }
- pthread_detach(info->rthr.pth);
- gekko_usleep(info, MS2US(100));
- if (thr_info_create(&(info->wthr), NULL, compac_mine2, (void *)compac)) {
- applog(LOG_ERR, "%d: %s %d - write thread create failed", compac->cgminer_id, compac->drv->name, compac->device_id);
- return false;
- } else {
- applog(LOG_INFO, "%d: %s %d - write thread created", compac->cgminer_id, compac->drv->name, compac->device_id);
- }
- pthread_detach(info->wthr.pth);
- if (info->ident == IDENT_GSF || info->ident == IDENT_GSFM)
- {
- gekko_usleep(info, MS2US(10));
- if (pthread_mutex_init(&info->nlock, NULL))
- {
- applog(LOG_ERR, "%d: %s %d - nonce mutex create failed",
- compac->cgminer_id, compac->drv->name, compac->device_id);
- return false;
- }
- if (pthread_cond_init(&info->ncond, NULL))
- {
- applog(LOG_ERR, "%d: %s %d - nonce cond create failed",
- compac->cgminer_id, compac->drv->name, compac->device_id);
- return false;
- }
- if (thr_info_create(&(info->nthr), NULL, compac_gsf_nonce_que, (void *)compac))
- {
- applog(LOG_ERR, "%d: %s %d - nonce thread create failed",
- compac->cgminer_id, compac->drv->name, compac->device_id);
- return false;
- }
- else
- {
- applog(LOG_INFO, "%d: %s %d - nonce thread created",
- compac->cgminer_id, compac->drv->name, compac->device_id);
- }
- pthread_detach(info->nthr.pth);
- }
- }
- return true;
- }
- static int64_t compac_scanwork(struct thr_info *thr)
- {
- struct cgpu_info *compac = thr->cgpu;
- struct COMPAC_INFO *info = compac->device_data;
- struct timeval now;
- int read_bytes;
- // uint64_t hashes = 0;
- uint64_t xhashes = 0;
- if (info->chips == 0)
- gekko_usleep(info, MS2US(10));
- if (compac->usbinfo.nodev)
- return -1;
- #ifdef __APPLE__
- if (opt_mac_yield)
- sched_yield();
- #else
- selective_yield();
- #endif
- cgtime(&now);
- switch (info->mining_state) {
- case MINER_INIT:
- gekko_usleep(info, MS2US(50));
- compac_flush_buffer(compac);
- info->chips = 0;
- info->ramping = 0;
- info->frequency_syncd = 1;
- if (info->frequency_start > info->frequency_requested) {
- info->frequency_start = info->frequency_requested;
- }
- info->mining_state = MINER_CHIP_COUNT;
- return 0;
- break;
- case MINER_CHIP_COUNT:
- if (ms_tdiff(&now, &info->last_reset) > MS_SECOND_5) {
- applog(LOG_INFO, "%d: %s %d - found 0 chip(s)", compac->cgminer_id, compac->drv->name, compac->device_id);
- info->mining_state = MINER_RESET;
- return 0;
- }
- gekko_usleep(info, MS2US(10));
- break;
- case MINER_CHIP_COUNT_OK:
- gekko_usleep(info, MS2US(50));
- //compac_set_frequency(compac, info->frequency_start);
- compac_send_chain_inactive(compac);
- if (info->asic_type == BM1397)
- info->mining_state = MINER_OPEN_CORE_OK;
- return 0;
- break;
- case MINER_OPEN_CORE:
- info->job_id = info->ramping % (info->max_job_id + 1);
- //info->task_hcn = (0xffffffff / info->chips) * (1 + info->ramping) / info->cores;
- init_task(info);
- dumpbuffer(compac, LOG_DEBUG, "RAMP", info->task, info->task_len);
- usb_write(compac, (char *)info->task, info->task_len, &read_bytes, C_SENDWORK);
- if (info->ramping > (info->cores * info->add_job_id)) {
- //info->job_id = 0;
- info->mining_state = MINER_OPEN_CORE_OK;
- info->task_hcn = (0xffffffff / info->chips);
- return 0;
- }
- info->ramping += info->add_job_id;
- info->task_ms = (info->task_ms * 9 + ms_tdiff(&now, &info->last_task)) / 10;
- cgtime(&info->last_task);
- gekko_usleep(info, MS2US(10));
- return 0;
- break;
- case MINER_OPEN_CORE_OK:
- applog(LOG_INFO, "%d: %s %d - start work", compac->cgminer_id, compac->drv->name, compac->device_id);
- if (info->asic_type == BM1397)
- gsf_calc_nb2c(compac);
- cgtime(&info->start_time);
- cgtime(&info->monitor_time);
- cgtime(&info->last_frequency_adjust);
- info->last_dup_time = (struct timeval){0};
- cgtime(&info->last_frequency_report);
- cgtime(&info->last_micro_ping);
- cgtime(&info->last_nonce);
- compac_flush_buffer(compac);
- compac_update_rates(compac);
- info->update_work = 1;
- info->mining_state = MINER_MINING;
- return 0;
- break;
- case MINER_MINING:
- break;
- case MINER_RESET:
- compac_flush_work(compac);
- if (info->asic_type == BM1387 || info->asic_type == BM1397) {
- compac_toggle_reset(compac);
- } else if (info->asic_type == BM1384) {
- compac_set_frequency(compac, info->frequency_default);
- //compac_send_chain_inactive(compac);
- }
- compac_prepare(thr);
- info->fail_count++;
- info->dupsreset = 0;
- info->mining_state = MINER_INIT;
- cgtime(&info->last_reset);
- // in case clock jumps back ...
- cgtime(&info->tune_limit);
- // wipe info->gh/asic->gc
- gh_offset(info, &now, true, false);
- // wipe info->job
- job_offset(info, &now, true, false);
- // reset P:
- info->frequency_computed = 0;
- return 0;
- break;
- case MINER_MINING_DUPS:
- info->mining_state = MINER_MINING;
- break;
- default:
- break;
- }
- mutex_lock(&info->lock);
- // hashes = info->hashes;
- xhashes = info->xhashes;
- info->hashes = 0;
- info->xhashes = 0;
- mutex_unlock(&info->lock);
- gekko_usleep(info, MS2US(1));
- return xhashes * 0xffffffffull;
- //return hashes;
- }
- static struct cgpu_info *compac_detect_one(struct libusb_device *dev, struct usb_find_devices *found)
- {
- struct cgpu_info *compac;
- struct COMPAC_INFO *info;
- int i;
- bool exclude_me = 0;
- uint32_t baudrate = CP210X_DATA_BAUD;
- unsigned int bits = CP210X_BITS_DATA_8 | CP210X_BITS_PARITY_MARK;
- compac = usb_alloc_cgpu(&gekko_drv, 1);
- if (!usb_init(compac, dev, found))
- {
- applog(LOG_INFO, "failed usb_init");
- compac = usb_free_cgpu(compac);
- return NULL;
- }
- // all zero
- info = cgcalloc(1, sizeof(struct COMPAC_INFO));
- #if TUNE_CODE
- pthread_mutex_init(&info->slock, NULL);
- #endif
- compac->device_data = (void *)info;
- info->ident = usb_ident(compac);
- if (opt_gekko_gsc_detect || opt_gekko_gsd_detect || opt_gekko_gse_detect
- || opt_gekko_gsh_detect || opt_gekko_bax_detect || opt_gekko_gsi_detect
- || opt_gekko_gsf_detect || opt_gekko_r909_detect)
- {
- exclude_me = (info->ident == IDENT_BSC && !opt_gekko_gsc_detect);
- exclude_me |= (info->ident == IDENT_GSC && !opt_gekko_gsc_detect);
- exclude_me |= (info->ident == IDENT_BSD && !opt_gekko_gsd_detect);
- exclude_me |= (info->ident == IDENT_GSD && !opt_gekko_gsd_detect);
- exclude_me |= (info->ident == IDENT_BSE && !opt_gekko_gse_detect);
- exclude_me |= (info->ident == IDENT_GSE && !opt_gekko_gse_detect);
- exclude_me |= (info->ident == IDENT_GSH && !opt_gekko_gsh_detect);
- exclude_me |= (info->ident == IDENT_BAX && !opt_gekko_gsh_detect);
- exclude_me |= (info->ident == IDENT_GSI && !opt_gekko_gsi_detect);
- exclude_me |= (info->ident == IDENT_GSF && !opt_gekko_gsf_detect);
- exclude_me |= (info->ident == IDENT_GSFM && !opt_gekko_r909_detect);
- }
- if (opt_gekko_serial != NULL
- && (strstr(opt_gekko_serial, compac->usbdev->serial_string) == NULL))
- {
- exclude_me = true;
- }
- if (exclude_me)
- {
- usb_uninit(compac);
- free(info);
- compac->device_data = NULL;
- return NULL;
- }
- switch (info->ident)
- {
- case IDENT_BSC:
- case IDENT_GSC:
- case IDENT_BSD:
- case IDENT_GSD:
- case IDENT_BSE:
- case IDENT_GSE:
- info->asic_type = BM1384;
- usb_transfer_data(compac, CP210X_TYPE_OUT, CP210X_REQUEST_IFC_ENABLE,
- CP210X_VALUE_UART_ENABLE, info->interface, NULL, 0, C_ENABLE_UART);
- usb_transfer_data(compac, CP210X_TYPE_OUT, CP210X_REQUEST_DATA,
- CP210X_VALUE_DATA, info->interface, NULL, 0, C_SETDATA);
- usb_transfer_data(compac, CP210X_TYPE_OUT, CP210X_REQUEST_BAUD,
- 0, info->interface, &baudrate, sizeof (baudrate), C_SETBAUD);
- usb_transfer_data(compac, CP210X_TYPE_OUT, CP210X_SET_LINE_CTL,
- bits, info->interface, NULL, 0, C_SETPARITY);
- break;
- case IDENT_GSH:
- info->asic_type = BM1387;
- info->expected_chips = 2;
- break;
- case IDENT_BAX:
- info->asic_type = BM1387;
- info->expected_chips = 2;
- break;
- case IDENT_GSI:
- info->asic_type = BM1387;
- info->expected_chips = 12;
- break;
- case IDENT_GSF:
- case IDENT_GSFM:
- info->asic_type = BM1397;
- // at least 1
- info->expected_chips = 1;
- break;
- default:
- quit(1, "%d: %s compac_detect_one() invalid %s ident=%d",
- compac->cgminer_id, compac->drv->dname, compac->drv->dname, info->ident);
- }
- info->min_job_id = 0x10;
- switch (info->asic_type)
- {
- case BM1384:
- info->rx_len = 5;
- info->task_len = 64;
- info->cores = 55;
- info->add_job_id = 1;
- info->max_job_id = 0x1f;
- info->midstates = 1;
- info->can_boost = false;
- break;
- case BM1387:
- info->rx_len = 7;
- info->task_len = 54;
- info->cores = 114;
- info->add_job_id = 1;
- info->max_job_id = 0x7f;
- info->midstates = (opt_gekko_lowboost) ? 2 : 4;
- info->can_boost = true;
- compac_toggle_reset(compac);
- break;
- case BM1397:
- info->rx_len = 9;
- info->task_len = 54;
- info->cores = 672;
- info->add_job_id = 4;
- info->max_job_id = 0x7f;
- // ignore lowboost
- info->midstates = 4;
- info->can_boost = true;
- compac_toggle_reset(compac);
- break;
- default:
- break;
- }
- info->interface = usb_interface(compac);
- info->mining_state = MINER_INIT;
- applog(LOG_DEBUG, "Using interface %d", info->interface);
- if (!add_cgpu(compac))
- quit(1, "Failed to add_cgpu in compac_detect_one");
- update_usb_stats(compac);
- for (i = 0; i < 8; i++)
- compac->unique_id[i] = compac->unique_id[i+3];
- compac->unique_id[8] = 0;
- info->wait_factor = info->wait_factor0;
- if (!opt_gekko_noboost && info->vmask && (info->asic_type == BM1387 || info->asic_type == BM1397))
- info->wait_factor *= info->midstates;
- return compac;
- }
- static void compac_detect(bool __maybe_unused hotplug)
- {
- usb_detect(&gekko_drv, compac_detect_one);
- }
- static bool compac_prepare(struct thr_info *thr)
- {
- struct cgpu_info *compac = thr->cgpu;
- struct COMPAC_INFO *info = compac->device_data;
- int device = (compac->usbinfo.bus_number * 0xff + compac->usbinfo.device_address) % 0xffff;
- mutex_lock(&static_lock);
- init_count = &dev_init_count[device];
- (*init_count)++;
- info->init_count = (*init_count);
- mutex_unlock(&static_lock);
- if (info->init_count == 1) {
- applog(LOG_WARNING, "%d: %s %d - %s (%s)",
- compac->cgminer_id, compac->drv->name, compac->device_id,
- compac->usbdev->prod_string, compac->unique_id);
- } else {
- applog(LOG_INFO, "%d: %s %d - init_count %d",
- compac->cgminer_id, compac->drv->name, compac->device_id,
- info->init_count);
- }
- info->thr = thr;
- info->bauddiv = 0x19; // 115200
- //info->bauddiv = 0x0D; // 214286
- //info->bauddiv = 0x07; // 375000
- //Sanity check and abort to prevent miner thread from being created.
- if (info->asic_type == BM1387) {
- // Ping Micro
- info->micro_found = 0;
- /*
- if (info->asic_type == BM1387) {
- info->vcore = bound(opt_gekko_gsh_vcore, 300, 810);
- info->micro_found = 1;
- if (!compac_micro_send(compac, M1_GET_TEMP, 0x00, 0x00)) {
- info->micro_found = 0;
- applog(LOG_INFO, "%d: %s %d - micro not found : dummy mode", compac->cgminer_id, compac->drv->name, compac->device_id);
- } else {
- uint8_t vcc = (info->vcore / 1000.0 - 0.3) / 0.002;
- applog(LOG_INFO, "%d: %s %d - requesting vcore of %dmV (%x)", compac->cgminer_id, compac->drv->name, compac->device_id, info->vcore, vcc);
- compac_micro_send(compac, M2_SET_VCORE, 0x00, vcc); // Default 400mV
- }
- }
- */
- }
- if (info->init_count != 0 && info->init_count % 5 == 0) {
- applog(LOG_INFO, "%d: %s %d - forcing usb_nodev()", compac->cgminer_id, compac->drv->name, compac->device_id);
- usb_nodev(compac);
- } else if (info->init_count > 1) {
- if (info->init_count > 10) {
- compac->deven = DEV_DISABLED;
- } else {
- cgsleep_ms(MS_SECOND_5);
- }
- }
- return true;
- }
- static void compac_statline(char *buf, size_t bufsiz, struct cgpu_info *compac)
- {
- struct COMPAC_INFO *info = compac->device_data;
- struct timeval now;
- unsigned int i;
- char ab[2];
- char asic_stat[64];
- char asic_statline[512];
- char ms_stat[64];
- char eff_stat[64];
- uint32_t len = 0;
- memset(asic_statline, 0, sizeof(asic_statline));
- memset(asic_stat, 0, sizeof(asic_stat));
- memset(ms_stat, 0, sizeof(ms_stat));
- memset(eff_stat, 0, sizeof(eff_stat));
- if (info->chips == 0) {
- if (info->init_count > 1) {
- sprintf(asic_statline, "found 0 chip(s)");
- }
- for (i = strlen(asic_statline); i < stat_len + 15; i++)
- asic_statline[i] = ' ';
- tailsprintf(buf, bufsiz, "%s", asic_statline);
- return;
- }
- ab[0] = (info->boosted) ? '+' : 0;
- ab[1] = 0;
- if (info->chips > chip_max)
- chip_max = info->chips;
- cgtime(&now);
- if (opt_widescreen) {
- asic_stat[0] = '[';
- for (i = 1; i <= info->chips; i++) {
- struct ASIC_INFO *asic = &info->asics[i - 1];
- switch (asic->state) {
- case ASIC_HEALTHY:
- asic_stat[i] = 'o';
- break;
- case ASIC_HALFDEAD:
- asic_stat[i] = '-';
- break;
- case ASIC_ALMOST_DEAD:
- asic_stat[i] = '!';
- break;
- case ASIC_DEAD:
- asic_stat[i] = 'x';
- break;
- }
- }
- asic_stat[info->chips + 1] = ']';
- for (i = 1; i <= (chip_max - info->chips) + 1; i++)
- asic_stat[info->chips + 1 + i] = ' ';
- }
- sprintf(ms_stat, "(%.0f:%.0f)", info->task_ms, info->fullscan_ms);
- uint8_t wuc = (ms_tdiff(&now, &info->last_wu_increase) > MS_MINUTE_1) ? 32 : 94;
- if (info->eff_gs >= 99.9 && info->eff_wu >= 98.9) {
- sprintf(eff_stat, "| 100%% WU:100%%");
- } else if (info->eff_gs >= 99.9) {
- sprintf(eff_stat, "| 100%% WU:%c%2.0f%%", wuc, info->eff_wu);
- } else if (info->eff_wu >= 98.9) {
- sprintf(eff_stat, "| %4.1f%% WU:100%%", info->eff_gs);
- } else {
- sprintf(eff_stat, "| %4.1f%% WU:%c%2.0f%%", info->eff_gs, wuc, info->eff_wu);
- }
- if (info->asic_type == BM1387 || info->asic_type == BM1397) {
- char *chipnam = ((info->asic_type == BM1387) ? "BM1387" : "BM1397");
- if (info->micro_found) {
- sprintf(asic_statline, "%s:%02d%-1s %.2fMHz T:%.0f P:%.0f %s %.0fF",
- chipnam, info->chips, ab, info->frequency, info->frequency_requested,
- info->frequency_computed, ms_stat, info->micro_temp);
- } else {
- if (opt_widescreen) {
- sprintf(asic_statline, "%s:%02d%-1s %.0f/%.0f/%3.0f %s %s",
- chipnam, info->chips, ab, info->frequency, info->frequency_requested,
- info->frequency_computed, ms_stat, asic_stat);
- } else {
- sprintf(asic_statline, "%s:%02d%-1s %.2fMHz T:%-3.0f P:%-3.0f %s %s",
- chipnam, info->chips, ab, info->frequency, info->frequency_requested,
- info->frequency_computed, ms_stat, asic_stat);
- }
- }
- } else {
- if (opt_widescreen) {
- sprintf(asic_statline, "BM1384:%02d %.0f/%.0f/%.0f %s %s",
- info->chips, info->frequency, info->frequency_requested,
- info->frequency_computed, ms_stat, asic_stat);
- } else {
- sprintf(asic_statline, "BM1384:%02d %.2fMHz T:%-3.0f P:%-3.0f %s %s",
- info->chips, info->frequency, info->frequency_requested,
- info->frequency_computed, ms_stat, asic_stat);
- }
- }
- len = strlen(asic_statline);
- if (len > stat_len || opt_widescreen != last_widescreen) {
- mutex_lock(&static_lock);
- stat_len = len;
- last_widescreen = opt_widescreen;
- mutex_unlock(&static_lock);
- }
- for (i = len; i < stat_len; i++)
- asic_statline[i] = ' ';
- strcat(asic_statline, eff_stat);
- asic_statline[63] = 0;
- tailsprintf(buf, bufsiz, "%s", asic_statline);
- }
- static struct api_data *compac_api_stats(struct cgpu_info *compac)
- {
- struct COMPAC_INFO *info = compac->device_data;
- struct api_data *root = NULL;
- struct timeval now;
- char nambuf[64], buf256[256];
- double taskdiff, tps, ghs, off;
- time_t secs;
- size_t len;
- int i, j, k;
- cgtime(&now);
- taskdiff = tdiff(&now, &(info->first_task));
- if (taskdiff == 0 || info->tasks < 2)
- tps = 0;
- else
- tps = (double)(info->tasks - 1) / taskdiff;
- root = api_add_string(root, "Serial", compac->usbdev->serial_string, false);
- root = api_add_int(root, "Nonces", &info->nonces, false);
- root = api_add_int(root, "Accepted", &info->accepted, false);
- root = api_add_double(root, "TasksPerSec", &tps, true);
- root = api_add_uint64(root, "Tasks", &info->tasks, false);
- root = api_add_uint64(root, "BusyWork", &info->busy_work, false);
- root = api_add_int(root, "Midstates", &info->midstates, false);
- root = api_add_uint64(root, "MaxTaskWait", &info->max_task_wait, false);
- root = api_add_float(root, "WaitFactor0", &info->wait_factor0, false);
- root = api_add_float(root, "WaitFactor", &info->wait_factor, false);
- root = api_add_float(root, "FreqBase", &info->freq_base, false);
- root = api_add_float(root, "FreqFail", &info->freq_fail, false);
- root = api_add_uint32(root, "TicketDiff", &info->difficulty, false);
- root = api_add_hex32(root, "TicketMask", &info->ticket_mask, false);
- root = api_add_int64(root, "TicketNonces", &info->ticket_nonces, false);
- root = api_add_int64(root, "TicketBelow", &info->below_nonces, false);
- root = api_add_bool(root, "TicketOK", &info->ticket_ok, false);
- root = api_add_float(root, "NonceExpect", &info->nonce_expect, false);
- root = api_add_float(root, "NonceLimit", &info->nonce_limit, false);
- // info->gh access must be under lock
- mutex_lock(&info->ghlock);
- ghs = gekko_gh_hashrate(info, &now, true) / 1.0e3;
- secs = now.tv_sec - info->gh.zerosec;
- root = api_add_time(root, "GHZeroDelta", &secs, true);
- root = api_add_int(root, "GHLast", &info->gh.last, true);
- root = api_add_int(root, "GHNonces", &info->gh.noncesum, true);
- root = api_add_int64(root, "GHDiff", &info->gh.diffsum, true);
- root = api_add_double(root, "GHGHs", &ghs, true);
- mutex_unlock(&info->ghlock);
- root = api_add_float(root, "Require", &info->ghrequire, true);
- ghs = info->frequency * (double)(info->cores * info->chips) * info->ghrequire / 1.0e3;
- root = api_add_double(root, "RequireGH", &ghs, true);
- // info->job access must be under lock
- // N.B. this is as at the last job sent, not 'now'
- mutex_lock(&info->joblock);
- off = tdiff(&now, &(info->job.lastjob));
- root = api_add_double(root, "JobDataAge", &off, true);
- buf256[0] = '\0';
- for (i = 0; i < JOBMIN; i++)
- {
- j = JOBOFF(info->job.offset - i);
- len = strlen(buf256);
- // /, digit, null = 3
- if ((len - sizeof(buf256)) < 3)
- break;
- snprintf(buf256+len, sizeof(buf256)-len, "/%d", info->job.jobnum[j]);
- }
- root = api_add_string(root, "Jobs", buf256+1, true);
- buf256[0] = '\0';
- for (i = 0; i < JOBMIN; i++)
- {
- double elap;
- j = JOBOFF(info->job.offset - i);
- elap = tdiff(&(info->job.lastj[j]), &(info->job.firstj[j]));
- len = strlen(buf256);
- // /, digit, null = 3
- if ((len - sizeof(buf256)) < 3)
- break;
- snprintf(buf256+len, sizeof(buf256)-len, "/%.2f", elap);
- }
- root = api_add_string(root, "JobElapsed", buf256+1, true);
- buf256[0] = '\0';
- for (i = 0; i < JOBMIN; i++)
- {
- double jps, elap;
- j = JOBOFF(info->job.offset - i);
- elap = tdiff(&(info->job.lastj[j]), &(info->job.firstj[j]));
- if (elap == 0)
- jps = 0;
- else
- jps = (double)(info->job.jobnum[j] - 1) / elap;
- len = strlen(buf256);
- // /, digit, null = 3
- if ((len - sizeof(buf256)) < 3)
- break;
- snprintf(buf256+len, sizeof(buf256)-len, "/%.2f", jps);
- }
- root = api_add_string(root, "JobsPerSec", buf256+1, true);
- buf256[0] = '\0';
- for (i = 0; i < JOBMIN; i++)
- {
- j = JOBOFF(info->job.offset - i);
- len = strlen(buf256);
- // /, digit, null = 3
- if ((len - sizeof(buf256)) < 3)
- break;
- snprintf(buf256+len, sizeof(buf256)-len, "/%.2f", info->job.avgms[j]);
- }
- root = api_add_string(root, "JobsAvgms", buf256+1, true);
- buf256[0] = '\0';
- for (i = 0; i < JOBMIN; i++)
- {
- j = JOBOFF(info->job.offset - i);
- len = strlen(buf256);
- // /, digit, null = 3
- if ((len - sizeof(buf256)) < 3)
- break;
- snprintf(buf256+len, sizeof(buf256)-len, "/%.2f:%.2f",
- info->job.minms[j], info->job.maxms[j]);
- }
- root = api_add_string(root, "JobsMinMaxms", buf256+1, true);
- mutex_unlock(&info->joblock);
- for (i = 0; i < (int)CUR_ATTEMPT; i++)
- {
- snprintf(nambuf, sizeof(nambuf), "cur_off_%d_%d", i, cur_attempt[i]);
- root = api_add_uint64(root, nambuf, &info->cur_off[i], true);
- }
- root = api_add_double(root, "Rolling", &info->rolling, false);
- root = api_add_int(root, "Resets", &info->fail_count, false);
- root = api_add_float(root, "Frequency", &info->frequency, false);
- root = api_add_float(root, "FreqComp", &info->frequency_computed, false);
- root = api_add_float(root, "FreqReq", &info->frequency_requested, false);
- root = api_add_float(root, "FreqStart", &info->frequency_start, false);
- root = api_add_float(root, "FreqSel", &info->frequency_selected, false);
- //root = api_add_temp(root, "Temp", &info->micro_temp, false);
- root = api_add_int(root, "Dups", &info->dupsall, true);
- root = api_add_int(root, "DupsReset", &info->dupsreset, true);
- root = api_add_uint(root, "Chips", &info->chips, false);
- root = api_add_bool(root, "FreqLocked", &info->lock_freq, false);
- if (info->asic_type == BM1397)
- root = api_add_int(root, "USBProp", &info->usb_prop, false);
- mutex_lock(&info->ghlock);
- for (i = 0; i < (int)info->chips; i++)
- {
- struct ASIC_INFO *asic = &info->asics[i];
- snprintf(nambuf, sizeof(nambuf), "Chip%dNonces", i);
- root = api_add_int(root, nambuf, &asic->nonces, true);
- snprintf(nambuf, sizeof(nambuf), "Chip%dDups", i);
- root = api_add_uint(root, nambuf, &asic->dupsall, true);
- gc_offset(info, asic, &now, false, true);
- snprintf(nambuf, sizeof(nambuf), "Chip%dRanges", i);
- buf256[0] = '\0';
- for (j = 0; j < CHNUM; j++)
- {
- len = strlen(buf256);
- // slash, digit, null = 3
- if ((len - sizeof(buf256)) < 3)
- break;
- k = CHOFF(asic->gc.offset - j);
- snprintf(buf256+len, sizeof(buf256)-len, "/%d", asic->gc.noncenum[k]);
- }
- len = strlen(buf256);
- if ((len - sizeof(buf256)) >= 3)
- snprintf(buf256+len, sizeof(buf256)-len, "/%d", asic->gc.noncesum);
- len = strlen(buf256);
- if ((len - sizeof(buf256)) >= 3)
- snprintf(buf256+len, sizeof(buf256)-len, "/%.2f%%", noncepercent(info, i, &now));
- root = api_add_string(root, nambuf, buf256+1, true);
- snprintf(nambuf, sizeof(nambuf), "Chip%dFreqSend", i);
- root = api_add_float(root, nambuf, &asic->frequency, true);
- snprintf(nambuf, sizeof(nambuf), "Chip%dFreqReply", i);
- root = api_add_float(root, nambuf, &asic->frequency_reply, true);
- }
- mutex_unlock(&info->ghlock);
- for (i = 0; i < 16; i++)
- {
- snprintf(nambuf, sizeof(nambuf), "NonceByte-%1X0", i);
- buf256[0] = '\0';
- for (j = 0; j < 16; j++)
- {
- len = strlen(buf256);
- // dot, digit, null = 3
- if ((len - sizeof(buf256)) < 3)
- break;
- snprintf(buf256+len, sizeof(buf256)-len, ".%"PRId64, info->noncebyte[i*16+j]);
- }
- root = api_add_string(root, nambuf, buf256+1, true);
- }
- for (i = 0; i < 16; i++)
- {
- snprintf(nambuf, sizeof(nambuf), "nb2c-%1X0", i);
- buf256[0] = '\0';
- for (j = 0; j < 16; j++)
- {
- len = strlen(buf256);
- // dot, digit, null = 3
- if ((len - sizeof(buf256)) < 3)
- break;
- snprintf(buf256+len, sizeof(buf256)-len, ".%u", info->nb2chip[i*16+j]);
- }
- root = api_add_string(root, nambuf, buf256+1, true);
- }
- root = api_add_uint64(root, "NTimeout", &info->ntimeout, false);
- root = api_add_uint64(root, "NTrigger", &info->ntrigger, false);
- #if TUNE_CODE
- mutex_lock(&info->slock);
- uint64_t num = info->num;
- double req = info->req;
- double fac = info->fac;
- uint64_t num1_1 = info->num1_1;
- double req1_1 = info->req1_1;
- double fac1_1 = info->fac1_1;
- uint64_t num1_5 = info->num1_5;
- double req1_5 = info->req1_5;
- double fac1_5 = info->fac1_5;
- uint64_t inv = info->inv;
- mutex_unlock(&info->slock);
- double avg, res, avg1_1, res1_1, avg1_5, res1_5;
- if (num == 0)
- avg = res = 0.0;
- else
- {
- avg = req / (double)num;
- res = fac / (double)num;
- }
- if (num1_1 == 0)
- avg1_1 = res1_1 = 0.0;
- else
- {
- avg1_1 = req1_1 / (double)num1_1;
- res1_1 = fac1_1 / (double)num1_1;
- }
- if (num1_5 == 0)
- avg1_5 = res1_5 = 0.0;
- else
- {
- avg1_5 = req1_5 / (double)num1_5;
- res1_5 = fac1_5 / (double)num1_5;
- }
- root = api_add_uint64(root, "SleepN", &num, true);
- root = api_add_double(root, "SleepAvgReq", &avg, true);
- root = api_add_double(root, "SleepAvgRes", &res, true);
- root = api_add_uint64(root, "SleepN1_1", &num1_1, true);
- root = api_add_double(root, "SleepAvgReq1_1", &avg1_1, true);
- root = api_add_double(root, "SleepAvgRes1_1", &res1_1, true);
- root = api_add_uint64(root, "SleepN1_5", &num1_5, true);
- root = api_add_double(root, "SleepAvgReq1_5", &avg1_5, true);
- root = api_add_double(root, "SleepAvgRes1_5", &res1_5, true);
- root = api_add_uint64(root, "SleepInv", &inv, true);
- root = api_add_uint64(root, "WorkGenNum", &info->work_usec_num, true);
- root = api_add_double(root, "WorkGenAvg", &info->work_usec_avg, true);
- if (info->over1num == 0)
- avg = 0.0;
- else
- avg = info->over1amt / (double)(info->over1num);
- root = api_add_int64(root, "Over1N", &info->over1num, true);
- root = api_add_double(root, "Over1Avg", &avg, true);
- if (info->over2num == 0)
- avg = 0.0;
- else
- avg = info->over2amt / (double)(info->over2num);
- root = api_add_int64(root, "Over2N", &info->over2num, true);
- root = api_add_double(root, "Over2Avg", &avg, true);
- #endif
- #if STRATUM_WORK_TIMING
- cg_rlock(&swt_lock);
- uint64_t swc = stratum_work_count;
- uint64_t swt = stratum_work_time;
- uint64_t swmin = stratum_work_min;
- uint64_t swmax = stratum_work_max;
- uint64_t swt0 = stratum_work_time0;
- uint64_t swt10 = stratum_work_time10;
- uint64_t swt100 = stratum_work_time100;
- cg_runlock(&swt_lock);
- double sw_avg;
- if (swc == 0)
- sw_avg = 0.0;
- else
- sw_avg = (double)swt / (double)swc;
- root = api_add_uint64(root, "SWCount", &swc, true);
- root = api_add_double(root, "SWAvg", &sw_avg, true);
- root = api_add_uint64(root, "SWMin", &swmin, true);
- root = api_add_uint64(root, "SWMax", &swmax, true);
- root = api_add_uint64(root, "SW0Count", &swt0, true);
- root = api_add_uint64(root, "SW10Count", &swt10, true);
- root = api_add_uint64(root, "SW100Count", &swt100, true);
- #endif
- return root;
- }
- static void compac_shutdown(struct thr_info *thr)
- {
- struct cgpu_info *compac = thr->cgpu;
- struct COMPAC_INFO *info = compac->device_data;
- applog(LOG_INFO, "%d: %s %d - shutting down", compac->cgminer_id, compac->drv->name, compac->device_id);
- if (!compac->usbinfo.nodev) {
- if (info->asic_type == BM1387) {
- compac_micro_send(compac, M2_SET_VCORE, 0x00, 0x00); // 300mV
- compac_toggle_reset(compac);
- } else if (info->asic_type == BM1397) {
- calc_gsf_freq(compac, 0, -1);
- compac_toggle_reset(compac);
- } else if (info->asic_type == BM1384 && info->frequency != info->frequency_default) {
- float frequency = info->frequency - info->freq_mult;
- while (frequency > info->frequency_default) {
- compac_set_frequency(compac, frequency);
- frequency -= info->freq_mult;
- cgsleep_ms(100);
- }
- compac_set_frequency(compac, info->frequency_default);
- compac_send_chain_inactive(compac);
- }
- }
- info->mining_state = MINER_SHUTDOWN;
- pthread_join(info->rthr.pth, NULL); // Let thread close.
- pthread_join(info->wthr.pth, NULL); // Let thread close.
- if (info->asic_type == BM1397)
- pthread_join(info->nthr.pth, NULL); // Let thread close.
- PTH(thr) = 0L;
- }
- uint64_t bound(uint64_t value, uint64_t lower_bound, uint64_t upper_bound)
- {
- if (value < lower_bound)
- return lower_bound;
- if (value > upper_bound)
- return upper_bound;
- return value;
- }
- void stuff_reverse(unsigned char *dst, unsigned char *src, uint32_t len)
- {
- uint32_t i;
- for (i = 0; i < len; i++) {
- dst[i] = src[len - i - 1];
- }
- }
- void stuff_lsb(unsigned char *dst, uint32_t x)
- {
- dst[0] = (x >> 0) & 0xff;
- dst[1] = (x >> 8) & 0xff;
- dst[2] = (x >> 16) & 0xff;
- dst[3] = (x >> 24) & 0xff;
- }
- void stuff_msb(unsigned char *dst, uint32_t x)
- {
- dst[0] = (x >> 24) & 0xff;
- dst[1] = (x >> 16) & 0xff;
- dst[2] = (x >> 8) & 0xff;
- dst[3] = (x >> 0) & 0xff;
- }
- static char *compac_api_set(struct cgpu_info *compac, char *option, char *setting, char *replybuf, size_t siz)
- {
- struct COMPAC_INFO *info = compac->device_data;
- float freq;
- if (strcasecmp(option, "help") == 0)
- {
- // freq: all of the drivers automatically fix the value
- // BM1397 0 is a special case, since it 'works'
- if (info->asic_type == BM1397)
- {
- snprintf(replybuf, siz, "reset freq: 0-1200 chip: N:0-800 target: 0-1200"
- " lockfreq unlockfreq waitfactor: 0.01-2.0"
- " usbprop: %d-1000 require: 0.0-0.8", USLEEPMIN);
- }
- else
- {
- snprintf(replybuf, siz, "reset freq: 0-1200 chip: N:0-800 target: 0-1200"
- " lockfreq unlockfreq waitfactor: 0.01-2.0"
- " require: 0.0-0.8");
- }
- return replybuf;
- }
- if (strcasecmp(option, "reset") == 0)
- {
- // will cause various problems ...
- info->mining_state = MINER_RESET;
- return NULL;
- }
- // set all chips to freq
- if (strcasecmp(option, "freq") == 0)
- {
- if (!setting || !*setting)
- {
- snprintf(replybuf, siz, "missing freq");
- return replybuf;
- }
- freq = limit_freq(info, atof(setting), true);
- freq = FREQ_BASE(freq);
- change_freq_any(compac, freq);
- return NULL;
- }
- // set chip:freq
- if (strcasecmp(option, "chip") == 0)
- {
- char *fpos;
- int chip;
- if (!setting || !*setting)
- {
- snprintf(replybuf, siz, "missing chip:freq");
- return replybuf;
- }
- if (info->asic_type != BM1397)
- {
- snprintf(replybuf, siz, "chip:freq only valid for BM1397");
- return replybuf;
- }
- fpos = strchr(setting, ':');
- if (!fpos || fpos == setting || *(fpos+1) == '\0')
- {
- snprintf(replybuf, siz, "not chip:freq");
- return replybuf;
- }
- // atoi will stop at the ':'
- chip = atoi(setting);
- if (chip < 0 || chip >= (int)(info->chips))
- {
- snprintf(replybuf, siz, "invalid chip %d", chip);
- return replybuf;
- }
- freq = limit_freq(info, atof(fpos+1), true);
- freq = FREQ_BASE(freq);
- calc_gsf_freq(compac, freq, chip);
- return NULL;
- }
- if (strcasecmp(option, "target") == 0)
- {
- if (!setting || !*setting)
- {
- snprintf(replybuf, siz, "missing freq");
- return replybuf;
- }
- freq = limit_freq(info, atof(setting), true);
- freq = FREQ_BASE(freq);
- info->frequency_requested = freq;
- return NULL;
- }
- if (strcasecmp(option, "lockfreq") == 0)
- {
- info->lock_freq = true;
- return NULL;
- }
- if (strcasecmp(option, "unlockfreq") == 0)
- {
- info->lock_freq = false;
- return NULL;
- }
- // set wait-factor
- if (strcasecmp(option, "waitfactor") == 0)
- {
- if (!setting || !*setting)
- {
- snprintf(replybuf, siz, "missing value");
- return replybuf;
- }
- info->wait_factor0 = fbound(atof(setting), 0.01, 2.0);
- compac_update_rates(compac);
- return NULL;
- }
- // set work propagation time
- if (strcasecmp(option, "usbprop") == 0)
- {
- if (info->asic_type != BM1397)
- {
- snprintf(replybuf, siz, "usbprop only for BM1397");
- return replybuf;
- }
- if (!setting || !*setting)
- {
- snprintf(replybuf, siz, "missing usec");
- return replybuf;
- }
- info->usb_prop = (int)bound(atoi(setting), USLEEPMIN, 1000);
- return NULL;
- }
- // set ghrequire
- if (strcasecmp(option, "require") == 0)
- {
- if (!setting || !*setting)
- {
- snprintf(replybuf, siz, "missing value");
- return replybuf;
- }
- info->ghrequire = fbound(atof(setting), 0.0, 0.8);
- compac_update_rates(compac);
- return NULL;
- }
- snprintf(replybuf, siz, "Unknown option: %s", option);
- return replybuf;
- }
- struct device_drv gekko_drv = {
- .drv_id = DRIVER_gekko,
- .dname = "GekkoScience",
- .name = "GSX",
- .hash_work = hash_queued_work,
- .get_api_stats = compac_api_stats,
- .get_statline_before = compac_statline,
- .set_device = compac_api_set,
- .drv_detect = compac_detect,
- .scanwork = compac_scanwork,
- .flush_work = compac_flush_work,
- .update_work = compac_update_work,
- .thread_prepare = compac_prepare,
- .thread_init = compac_init,
- .thread_shutdown = compac_shutdown,
- };
|