nvm.c 160 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661
  1. #include "headers.h"
  2. #define DWORD unsigned int
  3. static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter,
  4. unsigned int offset);
  5. static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter);
  6. static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter);
  7. static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter);
  8. static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter);
  9. static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter,
  10. unsigned int FlashSectorSizeSig,
  11. unsigned int FlashSectorSize);
  12. static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter);
  13. static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter);
  14. static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter);
  15. static enum bcm_nvm_type BcmGetNvmType(struct bcm_mini_adapter *Adapter);
  16. static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter,
  17. enum bcm_flash2x_section_val eFlash2xSectionVal);
  18. static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter,
  19. unsigned int uiOffset);
  20. static int IsSectionWritable(struct bcm_mini_adapter *Adapter,
  21. enum bcm_flash2x_section_val Section);
  22. static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter,
  23. enum bcm_flash2x_section_val section);
  24. static int ReadDSDPriority(struct bcm_mini_adapter *Adapter,
  25. enum bcm_flash2x_section_val dsd);
  26. static int ReadDSDSignature(struct bcm_mini_adapter *Adapter,
  27. enum bcm_flash2x_section_val dsd);
  28. static int ReadISOPriority(struct bcm_mini_adapter *Adapter,
  29. enum bcm_flash2x_section_val iso);
  30. static int ReadISOSignature(struct bcm_mini_adapter *Adapter,
  31. enum bcm_flash2x_section_val iso);
  32. static int CorruptDSDSig(struct bcm_mini_adapter *Adapter,
  33. enum bcm_flash2x_section_val eFlash2xSectionVal);
  34. static int CorruptISOSig(struct bcm_mini_adapter *Adapter,
  35. enum bcm_flash2x_section_val eFlash2xSectionVal);
  36. static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter,
  37. PUCHAR pBuff,
  38. unsigned int uiSectAlignAddr);
  39. static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
  40. PUINT pBuff,
  41. enum bcm_flash2x_section_val eFlash2xSectionVal,
  42. unsigned int uiOffset,
  43. unsigned int uiNumBytes);
  44. static enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter);
  45. static enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter);
  46. static int BeceemFlashBulkRead(
  47. struct bcm_mini_adapter *Adapter,
  48. PUINT pBuffer,
  49. unsigned int uiOffset,
  50. unsigned int uiNumBytes);
  51. static int BeceemFlashBulkWrite(
  52. struct bcm_mini_adapter *Adapter,
  53. PUINT pBuffer,
  54. unsigned int uiOffset,
  55. unsigned int uiNumBytes,
  56. bool bVerify);
  57. static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter);
  58. static int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, unsigned int dwAddress, unsigned int *pdwData, unsigned int dwNumData);
  59. /* Procedure: ReadEEPROMStatusRegister
  60. *
  61. * Description: Reads the standard EEPROM Status Register.
  62. *
  63. * Arguments:
  64. * Adapter - ptr to Adapter object instance
  65. * Returns:
  66. * OSAL_STATUS_CODE
  67. */
  68. static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter)
  69. {
  70. UCHAR uiData = 0;
  71. DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
  72. unsigned int uiStatus = 0;
  73. unsigned int value = 0;
  74. unsigned int value1 = 0;
  75. /* Read the EEPROM status register */
  76. value = EEPROM_READ_STATUS_REGISTER;
  77. wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
  78. while (dwRetries != 0) {
  79. value = 0;
  80. uiStatus = 0;
  81. rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
  82. if (Adapter->device_removed == TRUE) {
  83. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting....");
  84. break;
  85. }
  86. /* Wait for Avail bit to be set. */
  87. if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) {
  88. /* Clear the Avail/Full bits - which ever is set. */
  89. value = uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
  90. wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
  91. value = 0;
  92. rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
  93. uiData = (UCHAR)value;
  94. break;
  95. }
  96. dwRetries--;
  97. if (dwRetries == 0) {
  98. rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
  99. rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1));
  100. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x3004 = %x 0x3008 = %x, retries = %d failed.\n", value, value1, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY);
  101. return uiData;
  102. }
  103. if (!(dwRetries%RETRIES_PER_DELAY))
  104. udelay(1000);
  105. uiStatus = 0;
  106. }
  107. return uiData;
  108. } /* ReadEEPROMStatusRegister */
  109. /*
  110. * Procedure: ReadBeceemEEPROMBulk
  111. *
  112. * Description: This routine reads 16Byte data from EEPROM
  113. *
  114. * Arguments:
  115. * Adapter - ptr to Adapter object instance
  116. * dwAddress - EEPROM Offset to read the data from.
  117. * pdwData - Pointer to double word where data needs to be stored in. // dwNumWords - Number of words. Valid values are 4 ONLY.
  118. *
  119. * Returns:
  120. * OSAL_STATUS_CODE:
  121. */
  122. static int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter,
  123. DWORD dwAddress,
  124. DWORD *pdwData,
  125. DWORD dwNumWords)
  126. {
  127. DWORD dwIndex = 0;
  128. DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
  129. unsigned int uiStatus = 0;
  130. unsigned int value = 0;
  131. unsigned int value1 = 0;
  132. UCHAR *pvalue;
  133. /* Flush the read and cmd queue. */
  134. value = (EEPROM_READ_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH);
  135. wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
  136. value = 0;
  137. wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
  138. /* Clear the Avail/Full bits. */
  139. value = (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
  140. wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
  141. value = dwAddress | ((dwNumWords == 4) ? EEPROM_16_BYTE_PAGE_READ : EEPROM_4_BYTE_PAGE_READ);
  142. wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
  143. while (dwRetries != 0) {
  144. uiStatus = 0;
  145. rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
  146. if (Adapter->device_removed == TRUE) {
  147. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got Removed.hence exiting from loop...");
  148. return -ENODEV;
  149. }
  150. /* If we are reading 16 bytes we want to be sure that the queue
  151. * is full before we read. In the other cases we are ok if the
  152. * queue has data available
  153. */
  154. if (dwNumWords == 4) {
  155. if ((uiStatus & EEPROM_READ_DATA_FULL) != 0) {
  156. /* Clear the Avail/Full bits - which ever is set. */
  157. value = (uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL));
  158. wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
  159. break;
  160. }
  161. } else if (dwNumWords == 1) {
  162. if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) {
  163. /* We just got Avail and we have to read 32bits so we
  164. * need this sleep for Cardbus kind of devices.
  165. */
  166. if (Adapter->chip_id == 0xBECE0210)
  167. udelay(800);
  168. /* Clear the Avail/Full bits - which ever is set. */
  169. value = (uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL));
  170. wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
  171. break;
  172. }
  173. }
  174. uiStatus = 0;
  175. dwRetries--;
  176. if (dwRetries == 0) {
  177. value = 0;
  178. value1 = 0;
  179. rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
  180. rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1));
  181. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "dwNumWords %d 0x3004 = %x 0x3008 = %x retries = %d failed.\n",
  182. dwNumWords, value, value1, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY);
  183. return STATUS_FAILURE;
  184. }
  185. if (!(dwRetries%RETRIES_PER_DELAY))
  186. udelay(1000);
  187. }
  188. for (dwIndex = 0; dwIndex < dwNumWords; dwIndex++) {
  189. /* We get only a byte at a time - from LSB to MSB. We shift it into an integer. */
  190. pvalue = (PUCHAR)(pdwData + dwIndex);
  191. value = 0;
  192. rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
  193. pvalue[0] = value;
  194. value = 0;
  195. rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
  196. pvalue[1] = value;
  197. value = 0;
  198. rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
  199. pvalue[2] = value;
  200. value = 0;
  201. rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
  202. pvalue[3] = value;
  203. }
  204. return STATUS_SUCCESS;
  205. } /* ReadBeceemEEPROMBulk() */
  206. /*
  207. * Procedure: ReadBeceemEEPROM
  208. *
  209. * Description: This routine reads 4 data from EEPROM. It uses 1 or 2 page
  210. * reads to do this operation.
  211. *
  212. * Arguments:
  213. * Adapter - ptr to Adapter object instance
  214. * uiOffset - EEPROM Offset to read the data from.
  215. * pBuffer - Pointer to word where data needs to be stored in.
  216. *
  217. * Returns:
  218. * OSAL_STATUS_CODE:
  219. */
  220. int ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter,
  221. DWORD uiOffset,
  222. DWORD *pBuffer)
  223. {
  224. unsigned int uiData[8] = {0};
  225. unsigned int uiByteOffset = 0;
  226. unsigned int uiTempOffset = 0;
  227. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ====> ");
  228. uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
  229. uiByteOffset = uiOffset - uiTempOffset;
  230. ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4);
  231. /* A word can overlap at most over 2 pages. In that case we read the
  232. * next page too.
  233. */
  234. if (uiByteOffset > 12)
  235. ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4);
  236. memcpy((PUCHAR)pBuffer, (((PUCHAR)&uiData[0]) + uiByteOffset), 4);
  237. return STATUS_SUCCESS;
  238. } /* ReadBeceemEEPROM() */
  239. int ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter)
  240. {
  241. int Status;
  242. unsigned char puMacAddr[6];
  243. Status = BeceemNVMRead(Adapter,
  244. (PUINT)&puMacAddr[0],
  245. INIT_PARAMS_1_MACADDRESS_ADDRESS,
  246. MAC_ADDRESS_SIZE);
  247. if (Status == STATUS_SUCCESS)
  248. memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
  249. return Status;
  250. }
  251. /*
  252. * Procedure: BeceemEEPROMBulkRead
  253. *
  254. * Description: Reads the EEPROM and returns the Data.
  255. *
  256. * Arguments:
  257. * Adapter - ptr to Adapter object instance
  258. * pBuffer - Buffer to store the data read from EEPROM
  259. * uiOffset - Offset of EEPROM from where data should be read
  260. * uiNumBytes - Number of bytes to be read from the EEPROM.
  261. *
  262. * Returns:
  263. * OSAL_STATUS_SUCCESS - if EEPROM read is successful.
  264. * <FAILURE> - if failed.
  265. */
  266. int BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter,
  267. PUINT pBuffer,
  268. unsigned int uiOffset,
  269. unsigned int uiNumBytes)
  270. {
  271. unsigned int uiData[4] = {0};
  272. /* unsigned int uiAddress = 0; */
  273. unsigned int uiBytesRemaining = uiNumBytes;
  274. unsigned int uiIndex = 0;
  275. unsigned int uiTempOffset = 0;
  276. unsigned int uiExtraBytes = 0;
  277. unsigned int uiFailureRetries = 0;
  278. PUCHAR pcBuff = (PUCHAR)pBuffer;
  279. if (uiOffset % MAX_RW_SIZE && uiBytesRemaining) {
  280. uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
  281. uiExtraBytes = uiOffset - uiTempOffset;
  282. ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4);
  283. if (uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes)) {
  284. memcpy(pBuffer, (((PUCHAR)&uiData[0]) + uiExtraBytes), MAX_RW_SIZE - uiExtraBytes);
  285. uiBytesRemaining -= (MAX_RW_SIZE - uiExtraBytes);
  286. uiIndex += (MAX_RW_SIZE - uiExtraBytes);
  287. uiOffset += (MAX_RW_SIZE - uiExtraBytes);
  288. } else {
  289. memcpy(pBuffer, (((PUCHAR)&uiData[0]) + uiExtraBytes), uiBytesRemaining);
  290. uiIndex += uiBytesRemaining;
  291. uiOffset += uiBytesRemaining;
  292. uiBytesRemaining = 0;
  293. }
  294. }
  295. while (uiBytesRemaining && uiFailureRetries != 128) {
  296. if (Adapter->device_removed)
  297. return -1;
  298. if (uiBytesRemaining >= MAX_RW_SIZE) {
  299. /* For the requests more than or equal to 16 bytes, use bulk
  300. * read function to make the access faster.
  301. * We read 4 Dwords of data
  302. */
  303. if (ReadBeceemEEPROMBulk(Adapter, uiOffset, &uiData[0], 4) == 0) {
  304. memcpy(pcBuff + uiIndex, &uiData[0], MAX_RW_SIZE);
  305. uiOffset += MAX_RW_SIZE;
  306. uiBytesRemaining -= MAX_RW_SIZE;
  307. uiIndex += MAX_RW_SIZE;
  308. } else {
  309. uiFailureRetries++;
  310. mdelay(3); /* sleep for a while before retry... */
  311. }
  312. } else if (uiBytesRemaining >= 4) {
  313. if (ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0]) == 0) {
  314. memcpy(pcBuff + uiIndex, &uiData[0], 4);
  315. uiOffset += 4;
  316. uiBytesRemaining -= 4;
  317. uiIndex += 4;
  318. } else {
  319. uiFailureRetries++;
  320. mdelay(3); /* sleep for a while before retry... */
  321. }
  322. } else {
  323. /* Handle the reads less than 4 bytes... */
  324. PUCHAR pCharBuff = (PUCHAR)pBuffer;
  325. pCharBuff += uiIndex;
  326. if (ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0]) == 0) {
  327. memcpy(pCharBuff, &uiData[0], uiBytesRemaining); /* copy only bytes requested. */
  328. uiBytesRemaining = 0;
  329. } else {
  330. uiFailureRetries++;
  331. mdelay(3); /* sleep for a while before retry... */
  332. }
  333. }
  334. }
  335. return 0;
  336. }
  337. /*
  338. * Procedure: BeceemFlashBulkRead
  339. *
  340. * Description: Reads the FLASH and returns the Data.
  341. *
  342. * Arguments:
  343. * Adapter - ptr to Adapter object instance
  344. * pBuffer - Buffer to store the data read from FLASH
  345. * uiOffset - Offset of FLASH from where data should be read
  346. * uiNumBytes - Number of bytes to be read from the FLASH.
  347. *
  348. * Returns:
  349. * OSAL_STATUS_SUCCESS - if FLASH read is successful.
  350. * <FAILURE> - if failed.
  351. */
  352. static int BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter,
  353. PUINT pBuffer,
  354. unsigned int uiOffset,
  355. unsigned int uiNumBytes)
  356. {
  357. unsigned int uiIndex = 0;
  358. unsigned int uiBytesToRead = uiNumBytes;
  359. int Status = 0;
  360. unsigned int uiPartOffset = 0;
  361. int bytes;
  362. if (Adapter->device_removed) {
  363. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device Got Removed");
  364. return -ENODEV;
  365. }
  366. /* Adding flash Base address
  367. * uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
  368. */
  369. #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
  370. Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes);
  371. return Status;
  372. #endif
  373. Adapter->SelectedChip = RESET_CHIP_SELECT;
  374. if (uiOffset % MAX_RW_SIZE) {
  375. BcmDoChipSelect(Adapter, uiOffset);
  376. uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
  377. uiBytesToRead = MAX_RW_SIZE - (uiOffset % MAX_RW_SIZE);
  378. uiBytesToRead = MIN(uiNumBytes, uiBytesToRead);
  379. bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead);
  380. if (bytes < 0) {
  381. Status = bytes;
  382. Adapter->SelectedChip = RESET_CHIP_SELECT;
  383. return Status;
  384. }
  385. uiIndex += uiBytesToRead;
  386. uiOffset += uiBytesToRead;
  387. uiNumBytes -= uiBytesToRead;
  388. }
  389. while (uiNumBytes) {
  390. BcmDoChipSelect(Adapter, uiOffset);
  391. uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
  392. uiBytesToRead = MIN(uiNumBytes, MAX_RW_SIZE);
  393. bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead);
  394. if (bytes < 0) {
  395. Status = bytes;
  396. break;
  397. }
  398. uiIndex += uiBytesToRead;
  399. uiOffset += uiBytesToRead;
  400. uiNumBytes -= uiBytesToRead;
  401. }
  402. Adapter->SelectedChip = RESET_CHIP_SELECT;
  403. return Status;
  404. }
  405. /*
  406. * Procedure: BcmGetFlashSize
  407. *
  408. * Description: Finds the size of FLASH.
  409. *
  410. * Arguments:
  411. * Adapter - ptr to Adapter object instance
  412. *
  413. * Returns:
  414. * unsigned int - size of the FLASH Storage.
  415. *
  416. */
  417. static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter)
  418. {
  419. if (IsFlash2x(Adapter))
  420. return Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header);
  421. else
  422. return 32 * 1024;
  423. }
  424. /*
  425. * Procedure: BcmGetEEPROMSize
  426. *
  427. * Description: Finds the size of EEPROM.
  428. *
  429. * Arguments:
  430. * Adapter - ptr to Adapter object instance
  431. *
  432. * Returns:
  433. * unsigned int - size of the EEPROM Storage.
  434. *
  435. */
  436. static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter)
  437. {
  438. unsigned int uiData = 0;
  439. unsigned int uiIndex = 0;
  440. /*
  441. * if EEPROM is present and already Calibrated,it will have
  442. * 'BECM' string at 0th offset.
  443. * To find the EEPROM size read the possible boundaries of the
  444. * EEPROM like 4K,8K etc..accessing the EEPROM beyond its size will
  445. * result in wrap around. So when we get the End of the EEPROM we will
  446. * get 'BECM' string which is indeed at offset 0.
  447. */
  448. BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4);
  449. if (uiData == BECM) {
  450. for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) {
  451. BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4);
  452. if (uiData == BECM)
  453. return uiIndex * 1024;
  454. }
  455. } else {
  456. /*
  457. * EEPROM may not be present or not programmed
  458. */
  459. uiData = 0xBABEFACE;
  460. if (BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&uiData, 0, 4, TRUE) == 0) {
  461. uiData = 0;
  462. for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) {
  463. BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4);
  464. if (uiData == 0xBABEFACE)
  465. return uiIndex * 1024;
  466. }
  467. }
  468. }
  469. return 0;
  470. }
  471. /*
  472. * Procedure: FlashSectorErase
  473. *
  474. * Description: Finds the sector size of the FLASH.
  475. *
  476. * Arguments:
  477. * Adapter - ptr to Adapter object instance
  478. * addr - sector start address
  479. * numOfSectors - number of sectors to be erased.
  480. *
  481. * Returns:
  482. * OSAL_STATUS_CODE
  483. *
  484. */
  485. static int FlashSectorErase(struct bcm_mini_adapter *Adapter,
  486. unsigned int addr,
  487. unsigned int numOfSectors)
  488. {
  489. unsigned int iIndex = 0, iRetries = 0;
  490. unsigned int uiStatus = 0;
  491. unsigned int value;
  492. int bytes;
  493. for (iIndex = 0; iIndex < numOfSectors; iIndex++) {
  494. value = 0x06000000;
  495. wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
  496. value = (0xd8000000 | (addr & 0xFFFFFF));
  497. wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
  498. iRetries = 0;
  499. do {
  500. value = (FLASH_CMD_STATUS_REG_READ << 24);
  501. if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
  502. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
  503. return STATUS_FAILURE;
  504. }
  505. bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
  506. if (bytes < 0) {
  507. uiStatus = bytes;
  508. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
  509. return uiStatus;
  510. }
  511. iRetries++;
  512. /* After every try lets make the CPU free for 10 ms. generally time taken by the
  513. * the sector erase cycle is 500 ms to 40000 msec. hence sleeping 10 ms
  514. * won't hamper performance in any case.
  515. */
  516. mdelay(10);
  517. } while ((uiStatus & 0x1) && (iRetries < 400));
  518. if (uiStatus & 0x1) {
  519. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "iRetries crossing the limit of 80000\n");
  520. return STATUS_FAILURE;
  521. }
  522. addr += Adapter->uiSectorSize;
  523. }
  524. return 0;
  525. }
  526. /*
  527. * Procedure: flashByteWrite
  528. *
  529. * Description: Performs Byte by Byte write to flash
  530. *
  531. * Arguments:
  532. * Adapter - ptr to Adapter object instance
  533. * uiOffset - Offset of the flash where data needs to be written to.
  534. * pData - Address of Data to be written.
  535. * Returns:
  536. * OSAL_STATUS_CODE
  537. *
  538. */
  539. static int flashByteWrite(struct bcm_mini_adapter *Adapter,
  540. unsigned int uiOffset,
  541. PVOID pData)
  542. {
  543. unsigned int uiStatus = 0;
  544. int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
  545. unsigned int value;
  546. ULONG ulData = *(PUCHAR)pData;
  547. int bytes;
  548. /*
  549. * need not write 0xFF because write requires an erase and erase will
  550. * make whole sector 0xFF.
  551. */
  552. if (0xFF == ulData)
  553. return STATUS_SUCCESS;
  554. /* DumpDebug(NVM_RW,("flashWrite ====>\n")); */
  555. value = (FLASH_CMD_WRITE_ENABLE << 24);
  556. if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
  557. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails");
  558. return STATUS_FAILURE;
  559. }
  560. if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) {
  561. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DATA Write on FLASH_SPI_WRITEQ_REG fails");
  562. return STATUS_FAILURE;
  563. }
  564. value = (0x02000000 | (uiOffset & 0xFFFFFF));
  565. if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
  566. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programming of FLASH_SPI_CMDQ_REG fails");
  567. return STATUS_FAILURE;
  568. }
  569. /* __udelay(950); */
  570. do {
  571. value = (FLASH_CMD_STATUS_REG_READ << 24);
  572. if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
  573. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
  574. return STATUS_FAILURE;
  575. }
  576. /* __udelay(1); */
  577. bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
  578. if (bytes < 0) {
  579. uiStatus = bytes;
  580. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
  581. return uiStatus;
  582. }
  583. iRetries--;
  584. if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
  585. udelay(1000);
  586. } while ((uiStatus & 0x1) && (iRetries > 0));
  587. if (uiStatus & 0x1) {
  588. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times.");
  589. return STATUS_FAILURE;
  590. }
  591. return STATUS_SUCCESS;
  592. }
  593. /*
  594. * Procedure: flashWrite
  595. *
  596. * Description: Performs write to flash
  597. *
  598. * Arguments:
  599. * Adapter - ptr to Adapter object instance
  600. * uiOffset - Offset of the flash where data needs to be written to.
  601. * pData - Address of Data to be written.
  602. * Returns:
  603. * OSAL_STATUS_CODE
  604. *
  605. */
  606. static int flashWrite(struct bcm_mini_adapter *Adapter,
  607. unsigned int uiOffset,
  608. PVOID pData)
  609. {
  610. /* unsigned int uiStatus = 0;
  611. * int iRetries = 0;
  612. * unsigned int uiReadBack = 0;
  613. */
  614. unsigned int uiStatus = 0;
  615. int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
  616. unsigned int value;
  617. unsigned int uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
  618. int bytes;
  619. /*
  620. * need not write 0xFFFFFFFF because write requires an erase and erase will
  621. * make whole sector 0xFFFFFFFF.
  622. */
  623. if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE))
  624. return 0;
  625. value = (FLASH_CMD_WRITE_ENABLE << 24);
  626. if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
  627. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write Enable of FLASH_SPI_CMDQ_REG fails");
  628. return STATUS_FAILURE;
  629. }
  630. if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) {
  631. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails...");
  632. return STATUS_FAILURE;
  633. }
  634. /* __udelay(950); */
  635. do {
  636. value = (FLASH_CMD_STATUS_REG_READ << 24);
  637. if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
  638. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
  639. return STATUS_FAILURE;
  640. }
  641. /* __udelay(1); */
  642. bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
  643. if (bytes < 0) {
  644. uiStatus = bytes;
  645. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
  646. return uiStatus;
  647. }
  648. iRetries--;
  649. /* this will ensure that in there will be no changes in the current path.
  650. * currently one rdm/wrm takes 125 us.
  651. * Hence 125 *2 * FLASH_PER_RETRIES_DELAY > 3 ms(worst case delay)
  652. * Hence current implementation cycle will intoduce no delay in current path
  653. */
  654. if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
  655. udelay(1000);
  656. } while ((uiStatus & 0x1) && (iRetries > 0));
  657. if (uiStatus & 0x1) {
  658. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times.");
  659. return STATUS_FAILURE;
  660. }
  661. return STATUS_SUCCESS;
  662. }
  663. /*-----------------------------------------------------------------------------
  664. * Procedure: flashByteWriteStatus
  665. *
  666. * Description: Performs byte by byte write to flash with write done status check
  667. *
  668. * Arguments:
  669. * Adapter - ptr to Adapter object instance
  670. * uiOffset - Offset of the flash where data needs to be written to.
  671. * pData - Address of the Data to be written.
  672. * Returns:
  673. * OSAL_STATUS_CODE
  674. *
  675. */
  676. static int flashByteWriteStatus(struct bcm_mini_adapter *Adapter,
  677. unsigned int uiOffset,
  678. PVOID pData)
  679. {
  680. unsigned int uiStatus = 0;
  681. int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
  682. ULONG ulData = *(PUCHAR)pData;
  683. unsigned int value;
  684. int bytes;
  685. /*
  686. * need not write 0xFFFFFFFF because write requires an erase and erase will
  687. * make whole sector 0xFFFFFFFF.
  688. */
  689. if (0xFF == ulData)
  690. return STATUS_SUCCESS;
  691. /* DumpDebug(NVM_RW,("flashWrite ====>\n")); */
  692. value = (FLASH_CMD_WRITE_ENABLE << 24);
  693. if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
  694. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails");
  695. return STATUS_SUCCESS;
  696. }
  697. if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) {
  698. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DATA Write on FLASH_SPI_WRITEQ_REG fails");
  699. return STATUS_FAILURE;
  700. }
  701. value = (0x02000000 | (uiOffset & 0xFFFFFF));
  702. if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
  703. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programming of FLASH_SPI_CMDQ_REG fails");
  704. return STATUS_FAILURE;
  705. }
  706. /* msleep(1); */
  707. do {
  708. value = (FLASH_CMD_STATUS_REG_READ << 24);
  709. if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
  710. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
  711. return STATUS_FAILURE;
  712. }
  713. /* __udelay(1); */
  714. bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
  715. if (bytes < 0) {
  716. uiStatus = bytes;
  717. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
  718. return uiStatus;
  719. }
  720. iRetries--;
  721. if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
  722. udelay(1000);
  723. } while ((uiStatus & 0x1) && (iRetries > 0));
  724. if (uiStatus & 0x1) {
  725. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times.");
  726. return STATUS_FAILURE;
  727. }
  728. return STATUS_SUCCESS;
  729. }
  730. /*
  731. * Procedure: flashWriteStatus
  732. *
  733. * Description: Performs write to flash with write done status check
  734. *
  735. * Arguments:
  736. * Adapter - ptr to Adapter object instance
  737. * uiOffset - Offset of the flash where data needs to be written to.
  738. * pData - Address of the Data to be written.
  739. * Returns:
  740. * OSAL_STATUS_CODE
  741. *
  742. */
  743. static int flashWriteStatus(struct bcm_mini_adapter *Adapter,
  744. unsigned int uiOffset,
  745. PVOID pData)
  746. {
  747. unsigned int uiStatus = 0;
  748. int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
  749. /* unsigned int uiReadBack = 0; */
  750. unsigned int value;
  751. unsigned int uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
  752. int bytes;
  753. /*
  754. * need not write 0xFFFFFFFF because write requires an erase and erase will
  755. * make whole sector 0xFFFFFFFF.
  756. */
  757. if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE))
  758. return 0;
  759. value = (FLASH_CMD_WRITE_ENABLE << 24);
  760. if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
  761. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write Enable of FLASH_SPI_CMDQ_REG fails");
  762. return STATUS_FAILURE;
  763. }
  764. if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) {
  765. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails...");
  766. return STATUS_FAILURE;
  767. }
  768. /* __udelay(1); */
  769. do {
  770. value = (FLASH_CMD_STATUS_REG_READ << 24);
  771. if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
  772. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
  773. return STATUS_FAILURE;
  774. }
  775. /* __udelay(1); */
  776. bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
  777. if (bytes < 0) {
  778. uiStatus = bytes;
  779. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
  780. return uiStatus;
  781. }
  782. iRetries--;
  783. /* this will ensure that in there will be no changes in the current path.
  784. * currently one rdm/wrm takes 125 us.
  785. * Hence 125 *2 * FLASH_PER_RETRIES_DELAY >3 ms(worst case delay)
  786. * Hence current implementation cycle will intoduce no delay in current path
  787. */
  788. if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
  789. udelay(1000);
  790. } while ((uiStatus & 0x1) && (iRetries > 0));
  791. if (uiStatus & 0x1) {
  792. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times.");
  793. return STATUS_FAILURE;
  794. }
  795. return STATUS_SUCCESS;
  796. }
  797. /*
  798. * Procedure: BcmRestoreBlockProtectStatus
  799. *
  800. * Description: Restores the original block protection status.
  801. *
  802. * Arguments:
  803. * Adapter - ptr to Adapter object instance
  804. * ulWriteStatus -Original status
  805. * Returns:
  806. * <VOID>
  807. *
  808. */
  809. static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter, ULONG ulWriteStatus)
  810. {
  811. unsigned int value;
  812. value = (FLASH_CMD_WRITE_ENABLE << 24);
  813. wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
  814. udelay(20);
  815. value = (FLASH_CMD_STATUS_REG_WRITE << 24) | (ulWriteStatus << 16);
  816. wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
  817. udelay(20);
  818. }
  819. /*
  820. * Procedure: BcmFlashUnProtectBlock
  821. *
  822. * Description: UnProtects appropriate blocks for writing.
  823. *
  824. * Arguments:
  825. * Adapter - ptr to Adapter object instance
  826. * uiOffset - Offset of the flash where data needs to be written to. This should be Sector aligned.
  827. * Returns:
  828. * ULONG - Status value before UnProtect.
  829. *
  830. */
  831. static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, unsigned int uiOffset, unsigned int uiLength)
  832. {
  833. ULONG ulStatus = 0;
  834. ULONG ulWriteStatus = 0;
  835. unsigned int value;
  836. uiOffset = uiOffset&0x000FFFFF;
  837. /*
  838. * Implemented only for 1MB Flash parts.
  839. */
  840. if (FLASH_PART_SST25VF080B == Adapter->ulFlashID) {
  841. /*
  842. * Get Current BP status.
  843. */
  844. value = (FLASH_CMD_STATUS_REG_READ << 24);
  845. wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
  846. udelay(10);
  847. /*
  848. * Read status will be WWXXYYZZ. We have to take only WW.
  849. */
  850. rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulStatus, sizeof(ulStatus));
  851. ulStatus >>= 24;
  852. ulWriteStatus = ulStatus;
  853. /*
  854. * Bits [5-2] give current block level protection status.
  855. * Bit5: BP3 - DONT CARE
  856. * BP2-BP0: 0 - NO PROTECTION, 1 - UPPER 1/16, 2 - UPPER 1/8, 3 - UPPER 1/4
  857. * 4 - UPPER 1/2. 5 to 7 - ALL BLOCKS
  858. */
  859. if (ulStatus) {
  860. if ((uiOffset+uiLength) <= 0x80000) {
  861. /*
  862. * Offset comes in lower half of 1MB. Protect the upper half.
  863. * Clear BP1 and BP0 and set BP2.
  864. */
  865. ulWriteStatus |= (0x4<<2);
  866. ulWriteStatus &= ~(0x3<<2);
  867. } else if ((uiOffset + uiLength) <= 0xC0000) {
  868. /*
  869. * Offset comes below Upper 1/4. Upper 1/4 can be protected.
  870. * Clear BP2 and set BP1 and BP0.
  871. */
  872. ulWriteStatus |= (0x3<<2);
  873. ulWriteStatus &= ~(0x1<<4);
  874. } else if ((uiOffset + uiLength) <= 0xE0000) {
  875. /*
  876. * Offset comes below Upper 1/8. Upper 1/8 can be protected.
  877. * Clear BP2 and BP0 and set BP1
  878. */
  879. ulWriteStatus |= (0x1<<3);
  880. ulWriteStatus &= ~(0x5<<2);
  881. } else if ((uiOffset + uiLength) <= 0xF0000) {
  882. /*
  883. * Offset comes below Upper 1/16. Only upper 1/16 can be protected.
  884. * Set BP0 and Clear BP2,BP1.
  885. */
  886. ulWriteStatus |= (0x1<<2);
  887. ulWriteStatus &= ~(0x3<<3);
  888. } else {
  889. /*
  890. * Unblock all.
  891. * Clear BP2,BP1 and BP0.
  892. */
  893. ulWriteStatus &= ~(0x7<<2);
  894. }
  895. value = (FLASH_CMD_WRITE_ENABLE << 24);
  896. wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
  897. udelay(20);
  898. value = (FLASH_CMD_STATUS_REG_WRITE << 24) | (ulWriteStatus << 16);
  899. wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
  900. udelay(20);
  901. }
  902. }
  903. return ulStatus;
  904. }
  905. static int bulk_read_complete_sector(struct bcm_mini_adapter *ad,
  906. UCHAR read_bk[],
  907. PCHAR tmpbuff,
  908. unsigned int offset,
  909. unsigned int partoff)
  910. {
  911. unsigned int i;
  912. int j;
  913. int bulk_read_stat;
  914. FP_FLASH_WRITE_STATUS writef =
  915. ad->fpFlashWriteWithStatusCheck;
  916. for (i = 0; i < ad->uiSectorSize; i += MAX_RW_SIZE) {
  917. bulk_read_stat = BeceemFlashBulkRead(ad,
  918. (PUINT)read_bk,
  919. offset + i,
  920. MAX_RW_SIZE);
  921. if (bulk_read_stat != STATUS_SUCCESS)
  922. continue;
  923. if (ad->ulFlashWriteSize == 1) {
  924. for (j = 0; j < 16; j++) {
  925. if ((read_bk[j] != tmpbuff[i + j]) &&
  926. (STATUS_SUCCESS != (*writef)(ad, partoff + i + j, &tmpbuff[i + j]))) {
  927. return STATUS_FAILURE;
  928. }
  929. }
  930. } else {
  931. if ((memcmp(read_bk, &tmpbuff[i], MAX_RW_SIZE)) &&
  932. (STATUS_SUCCESS != (*writef)(ad, partoff + i, &tmpbuff[i]))) {
  933. return STATUS_FAILURE;
  934. }
  935. }
  936. }
  937. return STATUS_SUCCESS;
  938. }
  939. /*
  940. * Procedure: BeceemFlashBulkWrite
  941. *
  942. * Description: Performs write to the flash
  943. *
  944. * Arguments:
  945. * Adapter - ptr to Adapter object instance
  946. * pBuffer - Data to be written.
  947. * uiOffset - Offset of the flash where data needs to be written to.
  948. * uiNumBytes - Number of bytes to be written.
  949. * bVerify - read verify flag.
  950. * Returns:
  951. * OSAL_STATUS_CODE
  952. *
  953. */
  954. static int BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter,
  955. PUINT pBuffer,
  956. unsigned int uiOffset,
  957. unsigned int uiNumBytes,
  958. bool bVerify)
  959. {
  960. PCHAR pTempBuff = NULL;
  961. PUCHAR pcBuffer = (PUCHAR)pBuffer;
  962. unsigned int uiIndex = 0;
  963. unsigned int uiOffsetFromSectStart = 0;
  964. unsigned int uiSectAlignAddr = 0;
  965. unsigned int uiCurrSectOffsetAddr = 0;
  966. unsigned int uiSectBoundary = 0;
  967. unsigned int uiNumSectTobeRead = 0;
  968. UCHAR ucReadBk[16] = {0};
  969. ULONG ulStatus = 0;
  970. int Status = STATUS_SUCCESS;
  971. unsigned int uiTemp = 0;
  972. unsigned int index = 0;
  973. unsigned int uiPartOffset = 0;
  974. #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
  975. Status = bcmflash_raw_write((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes);
  976. return Status;
  977. #endif
  978. uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1);
  979. /* Adding flash Base address
  980. * uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
  981. */
  982. uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
  983. uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1);
  984. uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize;
  985. pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL);
  986. if (!pTempBuff)
  987. goto BeceemFlashBulkWrite_EXIT;
  988. /*
  989. * check if the data to be written is overlapped across sectors
  990. */
  991. if (uiOffset+uiNumBytes < uiSectBoundary) {
  992. uiNumSectTobeRead = 1;
  993. } else {
  994. /* Number of sectors = Last sector start address/First sector start address */
  995. uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize;
  996. if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize)
  997. uiNumSectTobeRead++;
  998. }
  999. /* Check whether Requested sector is writable or not in case of flash2x write. But if write call is
  1000. * for DSD calibration, allow it without checking of sector permission
  1001. */
  1002. if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == false)) {
  1003. index = 0;
  1004. uiTemp = uiNumSectTobeRead;
  1005. while (uiTemp) {
  1006. if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == false) {
  1007. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%X> is not writable",
  1008. (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
  1009. Status = SECTOR_IS_NOT_WRITABLE;
  1010. goto BeceemFlashBulkWrite_EXIT;
  1011. }
  1012. uiTemp = uiTemp - 1;
  1013. index = index + 1;
  1014. }
  1015. }
  1016. Adapter->SelectedChip = RESET_CHIP_SELECT;
  1017. while (uiNumSectTobeRead) {
  1018. /* do_gettimeofday(&tv1);
  1019. * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nTime In start of write :%ld ms\n",(tv1.tv_sec *1000 + tv1.tv_usec /1000));
  1020. */
  1021. uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
  1022. BcmDoChipSelect(Adapter, uiSectAlignAddr);
  1023. if (0 != BeceemFlashBulkRead(Adapter,
  1024. (PUINT)pTempBuff,
  1025. uiOffsetFromSectStart,
  1026. Adapter->uiSectorSize)) {
  1027. Status = -1;
  1028. goto BeceemFlashBulkWrite_EXIT;
  1029. }
  1030. /* do_gettimeofday(&tr);
  1031. * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Read :%ld ms\n", (tr.tv_sec *1000 + tr.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000));
  1032. */
  1033. ulStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize);
  1034. if (uiNumSectTobeRead > 1) {
  1035. memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr));
  1036. pcBuffer += ((uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)));
  1037. uiNumBytes -= (uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr));
  1038. } else {
  1039. memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiNumBytes);
  1040. }
  1041. if (IsFlash2x(Adapter))
  1042. SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart);
  1043. FlashSectorErase(Adapter, uiPartOffset, 1);
  1044. /* do_gettimeofday(&te);
  1045. * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Erase :%ld ms\n", (te.tv_sec *1000 + te.tv_usec/1000) - (tr.tv_sec *1000 + tr.tv_usec/1000));
  1046. */
  1047. for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) {
  1048. if (Adapter->device_removed) {
  1049. Status = -1;
  1050. goto BeceemFlashBulkWrite_EXIT;
  1051. }
  1052. if (STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter, uiPartOffset + uiIndex, (&pTempBuff[uiIndex]))) {
  1053. Status = -1;
  1054. goto BeceemFlashBulkWrite_EXIT;
  1055. }
  1056. }
  1057. /* do_gettimeofday(&tw);
  1058. * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash :%ld ms\n", (tw.tv_sec *1000 + tw.tv_usec/1000) - (te.tv_sec *1000 + te.tv_usec/1000));
  1059. */
  1060. if (STATUS_FAILURE == bulk_read_complete_sector(Adapter,
  1061. ucReadBk,
  1062. pTempBuff,
  1063. uiOffsetFromSectStart,
  1064. uiPartOffset)) {
  1065. Status = STATUS_FAILURE;
  1066. goto BeceemFlashBulkWrite_EXIT;
  1067. }
  1068. /* do_gettimeofday(&twv);
  1069. * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash verification :%ld ms\n", (twv.tv_sec *1000 + twv.tv_usec/1000) - (tw.tv_sec *1000 + tw.tv_usec/1000));
  1070. */
  1071. if (ulStatus) {
  1072. BcmRestoreBlockProtectStatus(Adapter, ulStatus);
  1073. ulStatus = 0;
  1074. }
  1075. uiCurrSectOffsetAddr = 0;
  1076. uiSectAlignAddr = uiSectBoundary;
  1077. uiSectBoundary += Adapter->uiSectorSize;
  1078. uiOffsetFromSectStart += Adapter->uiSectorSize;
  1079. uiNumSectTobeRead--;
  1080. }
  1081. /* do_gettimeofday(&tv2);
  1082. * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Time after Write :%ld ms\n",(tv2.tv_sec *1000 + tv2.tv_usec/1000));
  1083. * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by in Write is :%ld ms\n", (tv2.tv_sec *1000 + tv2.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000));
  1084. *
  1085. * Cleanup.
  1086. */
  1087. BeceemFlashBulkWrite_EXIT:
  1088. if (ulStatus)
  1089. BcmRestoreBlockProtectStatus(Adapter, ulStatus);
  1090. kfree(pTempBuff);
  1091. Adapter->SelectedChip = RESET_CHIP_SELECT;
  1092. return Status;
  1093. }
  1094. /*
  1095. * Procedure: BeceemFlashBulkWriteStatus
  1096. *
  1097. * Description: Writes to Flash. Checks the SPI status after each write.
  1098. *
  1099. * Arguments:
  1100. * Adapter - ptr to Adapter object instance
  1101. * pBuffer - Data to be written.
  1102. * uiOffset - Offset of the flash where data needs to be written to.
  1103. * uiNumBytes - Number of bytes to be written.
  1104. * bVerify - read verify flag.
  1105. * Returns:
  1106. * OSAL_STATUS_CODE
  1107. *
  1108. */
  1109. static int BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter,
  1110. PUINT pBuffer,
  1111. unsigned int uiOffset,
  1112. unsigned int uiNumBytes,
  1113. bool bVerify)
  1114. {
  1115. PCHAR pTempBuff = NULL;
  1116. PUCHAR pcBuffer = (PUCHAR)pBuffer;
  1117. unsigned int uiIndex = 0;
  1118. unsigned int uiOffsetFromSectStart = 0;
  1119. unsigned int uiSectAlignAddr = 0;
  1120. unsigned int uiCurrSectOffsetAddr = 0;
  1121. unsigned int uiSectBoundary = 0;
  1122. unsigned int uiNumSectTobeRead = 0;
  1123. UCHAR ucReadBk[16] = {0};
  1124. ULONG ulStatus = 0;
  1125. unsigned int Status = STATUS_SUCCESS;
  1126. unsigned int uiTemp = 0;
  1127. unsigned int index = 0;
  1128. unsigned int uiPartOffset = 0;
  1129. uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1);
  1130. /* uiOffset += Adapter->ulFlashCalStart;
  1131. * Adding flash Base address
  1132. * uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
  1133. */
  1134. uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
  1135. uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1);
  1136. uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize;
  1137. pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL);
  1138. if (!pTempBuff)
  1139. goto BeceemFlashBulkWriteStatus_EXIT;
  1140. /*
  1141. * check if the data to be written is overlapped across sectors
  1142. */
  1143. if (uiOffset+uiNumBytes < uiSectBoundary) {
  1144. uiNumSectTobeRead = 1;
  1145. } else {
  1146. /* Number of sectors = Last sector start address/First sector start address */
  1147. uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize;
  1148. if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize)
  1149. uiNumSectTobeRead++;
  1150. }
  1151. if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == false)) {
  1152. index = 0;
  1153. uiTemp = uiNumSectTobeRead;
  1154. while (uiTemp) {
  1155. if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == false) {
  1156. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%x> is not writable",
  1157. (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
  1158. Status = SECTOR_IS_NOT_WRITABLE;
  1159. goto BeceemFlashBulkWriteStatus_EXIT;
  1160. }
  1161. uiTemp = uiTemp - 1;
  1162. index = index + 1;
  1163. }
  1164. }
  1165. Adapter->SelectedChip = RESET_CHIP_SELECT;
  1166. while (uiNumSectTobeRead) {
  1167. uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
  1168. BcmDoChipSelect(Adapter, uiSectAlignAddr);
  1169. if (0 != BeceemFlashBulkRead(Adapter,
  1170. (PUINT)pTempBuff,
  1171. uiOffsetFromSectStart,
  1172. Adapter->uiSectorSize)) {
  1173. Status = -1;
  1174. goto BeceemFlashBulkWriteStatus_EXIT;
  1175. }
  1176. ulStatus = BcmFlashUnProtectBlock(Adapter, uiOffsetFromSectStart, Adapter->uiSectorSize);
  1177. if (uiNumSectTobeRead > 1) {
  1178. memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr));
  1179. pcBuffer += ((uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)));
  1180. uiNumBytes -= (uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr));
  1181. } else {
  1182. memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiNumBytes);
  1183. }
  1184. if (IsFlash2x(Adapter))
  1185. SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart);
  1186. FlashSectorErase(Adapter, uiPartOffset, 1);
  1187. for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) {
  1188. if (Adapter->device_removed) {
  1189. Status = -1;
  1190. goto BeceemFlashBulkWriteStatus_EXIT;
  1191. }
  1192. if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset+uiIndex, &pTempBuff[uiIndex])) {
  1193. Status = -1;
  1194. goto BeceemFlashBulkWriteStatus_EXIT;
  1195. }
  1196. }
  1197. if (bVerify) {
  1198. for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += MAX_RW_SIZE) {
  1199. if (STATUS_SUCCESS == BeceemFlashBulkRead(Adapter, (PUINT)ucReadBk, uiOffsetFromSectStart + uiIndex, MAX_RW_SIZE)) {
  1200. if (memcmp(ucReadBk, &pTempBuff[uiIndex], MAX_RW_SIZE)) {
  1201. Status = STATUS_FAILURE;
  1202. goto BeceemFlashBulkWriteStatus_EXIT;
  1203. }
  1204. }
  1205. }
  1206. }
  1207. if (ulStatus) {
  1208. BcmRestoreBlockProtectStatus(Adapter, ulStatus);
  1209. ulStatus = 0;
  1210. }
  1211. uiCurrSectOffsetAddr = 0;
  1212. uiSectAlignAddr = uiSectBoundary;
  1213. uiSectBoundary += Adapter->uiSectorSize;
  1214. uiOffsetFromSectStart += Adapter->uiSectorSize;
  1215. uiNumSectTobeRead--;
  1216. }
  1217. /*
  1218. * Cleanup.
  1219. */
  1220. BeceemFlashBulkWriteStatus_EXIT:
  1221. if (ulStatus)
  1222. BcmRestoreBlockProtectStatus(Adapter, ulStatus);
  1223. kfree(pTempBuff);
  1224. Adapter->SelectedChip = RESET_CHIP_SELECT;
  1225. return Status;
  1226. }
  1227. /*
  1228. * Procedure: PropagateCalParamsFromFlashToMemory
  1229. *
  1230. * Description: Dumps the calibration section of EEPROM to DDR.
  1231. *
  1232. * Arguments:
  1233. * Adapter - ptr to Adapter object instance
  1234. * Returns:
  1235. * OSAL_STATUS_CODE
  1236. *
  1237. */
  1238. int PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter)
  1239. {
  1240. PCHAR pBuff, pPtr;
  1241. unsigned int uiEepromSize = 0;
  1242. unsigned int uiBytesToCopy = 0;
  1243. /* unsigned int uiIndex = 0; */
  1244. unsigned int uiCalStartAddr = EEPROM_CALPARAM_START;
  1245. unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
  1246. unsigned int value;
  1247. int Status = 0;
  1248. /*
  1249. * Write the signature first. This will ensure firmware does not access EEPROM.
  1250. */
  1251. value = 0xbeadbead;
  1252. wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
  1253. value = 0xbeadbead;
  1254. wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
  1255. if (0 != BeceemNVMRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4))
  1256. return -1;
  1257. uiEepromSize = ntohl(uiEepromSize);
  1258. uiEepromSize >>= 16;
  1259. /*
  1260. * subtract the auto init section size
  1261. */
  1262. uiEepromSize -= EEPROM_CALPARAM_START;
  1263. if (uiEepromSize > 1024 * 1024)
  1264. return -1;
  1265. pBuff = kmalloc(uiEepromSize, GFP_KERNEL);
  1266. if (pBuff == NULL)
  1267. return -ENOMEM;
  1268. if (0 != BeceemNVMRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiEepromSize)) {
  1269. kfree(pBuff);
  1270. return -1;
  1271. }
  1272. pPtr = pBuff;
  1273. uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize);
  1274. while (uiBytesToCopy) {
  1275. Status = wrm(Adapter, uiMemoryLoc, (PCHAR)pPtr, uiBytesToCopy);
  1276. if (Status) {
  1277. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm failed with status :%d", Status);
  1278. break;
  1279. }
  1280. pPtr += uiBytesToCopy;
  1281. uiEepromSize -= uiBytesToCopy;
  1282. uiMemoryLoc += uiBytesToCopy;
  1283. uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize);
  1284. }
  1285. kfree(pBuff);
  1286. return Status;
  1287. }
  1288. /*
  1289. * Procedure: BeceemEEPROMReadBackandVerify
  1290. *
  1291. * Description: Read back the data written and verifies.
  1292. *
  1293. * Arguments:
  1294. * Adapter - ptr to Adapter object instance
  1295. * pBuffer - Data to be written.
  1296. * uiOffset - Offset of the flash where data needs to be written to.
  1297. * uiNumBytes - Number of bytes to be written.
  1298. * Returns:
  1299. * OSAL_STATUS_CODE
  1300. *
  1301. */
  1302. static int BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter,
  1303. PUINT pBuffer,
  1304. unsigned int uiOffset,
  1305. unsigned int uiNumBytes)
  1306. {
  1307. unsigned int uiRdbk = 0;
  1308. unsigned int uiIndex = 0;
  1309. unsigned int uiData = 0;
  1310. unsigned int auiData[4] = {0};
  1311. while (uiNumBytes) {
  1312. if (Adapter->device_removed)
  1313. return -1;
  1314. if (uiNumBytes >= MAX_RW_SIZE) {
  1315. /* for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster. */
  1316. BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE);
  1317. if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) {
  1318. /* re-write */
  1319. BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, MAX_RW_SIZE, false);
  1320. mdelay(3);
  1321. BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE);
  1322. if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE))
  1323. return -1;
  1324. }
  1325. uiOffset += MAX_RW_SIZE;
  1326. uiNumBytes -= MAX_RW_SIZE;
  1327. uiIndex += 4;
  1328. } else if (uiNumBytes >= 4) {
  1329. BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4);
  1330. if (uiData != pBuffer[uiIndex]) {
  1331. /* re-write */
  1332. BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, 4, false);
  1333. mdelay(3);
  1334. BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4);
  1335. if (uiData != pBuffer[uiIndex])
  1336. return -1;
  1337. }
  1338. uiOffset += 4;
  1339. uiNumBytes -= 4;
  1340. uiIndex++;
  1341. } else {
  1342. /* Handle the reads less than 4 bytes... */
  1343. uiData = 0;
  1344. memcpy(&uiData, ((PUCHAR)pBuffer) + (uiIndex * sizeof(unsigned int)), uiNumBytes);
  1345. BeceemEEPROMBulkRead(Adapter, &uiRdbk, uiOffset, 4);
  1346. if (memcmp(&uiData, &uiRdbk, uiNumBytes))
  1347. return -1;
  1348. uiNumBytes = 0;
  1349. }
  1350. }
  1351. return 0;
  1352. }
  1353. static VOID BcmSwapWord(unsigned int *ptr1)
  1354. {
  1355. unsigned int tempval = (unsigned int)*ptr1;
  1356. char *ptr2 = (char *)&tempval;
  1357. char *ptr = (char *)ptr1;
  1358. ptr[0] = ptr2[3];
  1359. ptr[1] = ptr2[2];
  1360. ptr[2] = ptr2[1];
  1361. ptr[3] = ptr2[0];
  1362. }
  1363. /*
  1364. * Procedure: BeceemEEPROMWritePage
  1365. *
  1366. * Description: Performs page write (16bytes) to the EEPROM
  1367. *
  1368. * Arguments:
  1369. * Adapter - ptr to Adapter object instance
  1370. * uiData - Data to be written.
  1371. * uiOffset - Offset of the EEPROM where data needs to be written to.
  1372. * Returns:
  1373. * OSAL_STATUS_CODE
  1374. *
  1375. */
  1376. static int BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, unsigned int uiData[], unsigned int uiOffset)
  1377. {
  1378. unsigned int uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
  1379. unsigned int uiStatus = 0;
  1380. UCHAR uiEpromStatus = 0;
  1381. unsigned int value = 0;
  1382. /* Flush the Write/Read/Cmd queues. */
  1383. value = (EEPROM_WRITE_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH | EEPROM_READ_QUEUE_FLUSH);
  1384. wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
  1385. value = 0;
  1386. wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
  1387. /* Clear the Empty/Avail/Full bits. After this it has been confirmed
  1388. * that the bit was cleared by reading back the register. See NOTE below.
  1389. * We also clear the Read queues as we do a EEPROM status register read
  1390. * later.
  1391. */
  1392. value = (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL | EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
  1393. wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
  1394. /* Enable write */
  1395. value = EEPROM_WRITE_ENABLE;
  1396. wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
  1397. /* We can write back to back 8bits * 16 into the queue and as we have
  1398. * checked for the queue to be empty we can write in a burst.
  1399. */
  1400. value = uiData[0];
  1401. BcmSwapWord(&value);
  1402. wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
  1403. value = uiData[1];
  1404. BcmSwapWord(&value);
  1405. wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
  1406. value = uiData[2];
  1407. BcmSwapWord(&value);
  1408. wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
  1409. value = uiData[3];
  1410. BcmSwapWord(&value);
  1411. wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
  1412. /* NOTE : After this write, on readback of EEPROM_SPI_Q_STATUS1_REG
  1413. * shows that we see 7 for the EEPROM data write. Which means that
  1414. * queue got full, also space is available as well as the queue is empty.
  1415. * This may happen in sequence.
  1416. */
  1417. value = EEPROM_16_BYTE_PAGE_WRITE | uiOffset;
  1418. wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
  1419. /* Ideally we should loop here without tries and eventually succeed.
  1420. * What we are checking if the previous write has completed, and this
  1421. * may take time. We should wait till the Empty bit is set.
  1422. */
  1423. uiStatus = 0;
  1424. rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
  1425. while ((uiStatus & EEPROM_WRITE_QUEUE_EMPTY) == 0) {
  1426. uiRetries--;
  1427. if (uiRetries == 0) {
  1428. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, %d retries failed.\n", uiStatus, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY);
  1429. return STATUS_FAILURE;
  1430. }
  1431. if (!(uiRetries%RETRIES_PER_DELAY))
  1432. udelay(1000);
  1433. uiStatus = 0;
  1434. rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
  1435. if (Adapter->device_removed == TRUE) {
  1436. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem got removed hence exiting from loop....");
  1437. return -ENODEV;
  1438. }
  1439. }
  1440. if (uiRetries != 0) {
  1441. /* Clear the ones that are set - either, Empty/Full/Avail bits */
  1442. value = (uiStatus & (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL));
  1443. wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
  1444. }
  1445. /* Here we should check if the EEPROM status register is correct before
  1446. * proceeding. Bit 0 in the EEPROM Status register should be 0 before
  1447. * we proceed further. A 1 at Bit 0 indicates that the EEPROM is busy
  1448. * with the previous write. Note also that issuing this read finally
  1449. * means the previous write to the EEPROM has completed.
  1450. */
  1451. uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
  1452. uiEpromStatus = 0;
  1453. while (uiRetries != 0) {
  1454. uiEpromStatus = ReadEEPROMStatusRegister(Adapter);
  1455. if (Adapter->device_removed == TRUE) {
  1456. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop...");
  1457. return -ENODEV;
  1458. }
  1459. if ((EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus) == 0) {
  1460. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM status register = %x tries = %d\n", uiEpromStatus, (MAX_EEPROM_RETRIES * RETRIES_PER_DELAY - uiRetries));
  1461. return STATUS_SUCCESS;
  1462. }
  1463. uiRetries--;
  1464. if (uiRetries == 0) {
  1465. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, for EEPROM status read %d retries failed.\n", uiEpromStatus, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY);
  1466. return STATUS_FAILURE;
  1467. }
  1468. uiEpromStatus = 0;
  1469. if (!(uiRetries%RETRIES_PER_DELAY))
  1470. udelay(1000);
  1471. }
  1472. return STATUS_SUCCESS;
  1473. } /* BeceemEEPROMWritePage */
  1474. /*
  1475. * Procedure: BeceemEEPROMBulkWrite
  1476. *
  1477. * Description: Performs write to the EEPROM
  1478. *
  1479. * Arguments:
  1480. * Adapter - ptr to Adapter object instance
  1481. * pBuffer - Data to be written.
  1482. * uiOffset - Offset of the EEPROM where data needs to be written to.
  1483. * uiNumBytes - Number of bytes to be written.
  1484. * bVerify - read verify flag.
  1485. * Returns:
  1486. * OSAL_STATUS_CODE
  1487. *
  1488. */
  1489. int BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter,
  1490. PUCHAR pBuffer,
  1491. unsigned int uiOffset,
  1492. unsigned int uiNumBytes,
  1493. bool bVerify)
  1494. {
  1495. unsigned int uiBytesToCopy = uiNumBytes;
  1496. /* unsigned int uiRdbk = 0; */
  1497. unsigned int uiData[4] = {0};
  1498. unsigned int uiIndex = 0;
  1499. unsigned int uiTempOffset = 0;
  1500. unsigned int uiExtraBytes = 0;
  1501. /* PUINT puiBuffer = (PUINT)pBuffer;
  1502. * int value;
  1503. */
  1504. if (uiOffset % MAX_RW_SIZE && uiBytesToCopy) {
  1505. uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
  1506. uiExtraBytes = uiOffset - uiTempOffset;
  1507. BeceemEEPROMBulkRead(Adapter, &uiData[0], uiTempOffset, MAX_RW_SIZE);
  1508. if (uiBytesToCopy >= (16 - uiExtraBytes)) {
  1509. memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, MAX_RW_SIZE - uiExtraBytes);
  1510. if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset))
  1511. return STATUS_FAILURE;
  1512. uiBytesToCopy -= (MAX_RW_SIZE - uiExtraBytes);
  1513. uiIndex += (MAX_RW_SIZE - uiExtraBytes);
  1514. uiOffset += (MAX_RW_SIZE - uiExtraBytes);
  1515. } else {
  1516. memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, uiBytesToCopy);
  1517. if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset))
  1518. return STATUS_FAILURE;
  1519. uiIndex += uiBytesToCopy;
  1520. uiOffset += uiBytesToCopy;
  1521. uiBytesToCopy = 0;
  1522. }
  1523. }
  1524. while (uiBytesToCopy) {
  1525. if (Adapter->device_removed)
  1526. return -1;
  1527. if (uiBytesToCopy >= MAX_RW_SIZE) {
  1528. if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, (PUINT) &pBuffer[uiIndex], uiOffset))
  1529. return STATUS_FAILURE;
  1530. uiIndex += MAX_RW_SIZE;
  1531. uiOffset += MAX_RW_SIZE;
  1532. uiBytesToCopy -= MAX_RW_SIZE;
  1533. } else {
  1534. /*
  1535. * To program non 16byte aligned data, read 16byte and then update.
  1536. */
  1537. BeceemEEPROMBulkRead(Adapter, &uiData[0], uiOffset, 16);
  1538. memcpy(&uiData[0], pBuffer + uiIndex, uiBytesToCopy);
  1539. if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiOffset))
  1540. return STATUS_FAILURE;
  1541. uiBytesToCopy = 0;
  1542. }
  1543. }
  1544. return 0;
  1545. }
  1546. /*
  1547. * Procedure: BeceemNVMRead
  1548. *
  1549. * Description: Reads n number of bytes from NVM.
  1550. *
  1551. * Arguments:
  1552. * Adapter - ptr to Adapter object instance
  1553. * pBuffer - Buffer to store the data read from NVM
  1554. * uiOffset - Offset of NVM from where data should be read
  1555. * uiNumBytes - Number of bytes to be read from the NVM.
  1556. *
  1557. * Returns:
  1558. * OSAL_STATUS_SUCCESS - if NVM read is successful.
  1559. * <FAILURE> - if failed.
  1560. */
  1561. int BeceemNVMRead(struct bcm_mini_adapter *Adapter,
  1562. PUINT pBuffer,
  1563. unsigned int uiOffset,
  1564. unsigned int uiNumBytes)
  1565. {
  1566. int Status = 0;
  1567. #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
  1568. unsigned int uiTemp = 0, value;
  1569. #endif
  1570. if (Adapter->eNVMType == NVM_FLASH) {
  1571. if (Adapter->bFlashRawRead == false) {
  1572. if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD))
  1573. return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes);
  1574. uiOffset = uiOffset + Adapter->ulFlashCalStart;
  1575. }
  1576. #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
  1577. Status = bcmflash_raw_read((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes);
  1578. #else
  1579. rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
  1580. value = 0;
  1581. wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
  1582. Status = BeceemFlashBulkRead(Adapter,
  1583. pBuffer,
  1584. uiOffset,
  1585. uiNumBytes);
  1586. wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
  1587. #endif
  1588. } else if (Adapter->eNVMType == NVM_EEPROM) {
  1589. Status = BeceemEEPROMBulkRead(Adapter,
  1590. pBuffer,
  1591. uiOffset,
  1592. uiNumBytes);
  1593. } else {
  1594. Status = -1;
  1595. }
  1596. return Status;
  1597. }
  1598. /*
  1599. * Procedure: BeceemNVMWrite
  1600. *
  1601. * Description: Writes n number of bytes to NVM.
  1602. *
  1603. * Arguments:
  1604. * Adapter - ptr to Adapter object instance
  1605. * pBuffer - Buffer contains the data to be written.
  1606. * uiOffset - Offset of NVM where data to be written to.
  1607. * uiNumBytes - Number of bytes to be written..
  1608. *
  1609. * Returns:
  1610. * OSAL_STATUS_SUCCESS - if NVM write is successful.
  1611. * <FAILURE> - if failed.
  1612. */
  1613. int BeceemNVMWrite(struct bcm_mini_adapter *Adapter,
  1614. PUINT pBuffer,
  1615. unsigned int uiOffset,
  1616. unsigned int uiNumBytes,
  1617. bool bVerify)
  1618. {
  1619. int Status = 0;
  1620. unsigned int uiTemp = 0;
  1621. unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
  1622. unsigned int uiIndex = 0;
  1623. #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
  1624. unsigned int value;
  1625. #endif
  1626. unsigned int uiFlashOffset = 0;
  1627. if (Adapter->eNVMType == NVM_FLASH) {
  1628. if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD))
  1629. Status = vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes, bVerify);
  1630. else {
  1631. uiFlashOffset = uiOffset + Adapter->ulFlashCalStart;
  1632. #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
  1633. Status = bcmflash_raw_write((uiFlashOffset / FLASH_PART_SIZE), (uiFlashOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes);
  1634. #else
  1635. rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
  1636. value = 0;
  1637. wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
  1638. if (Adapter->bStatusWrite == TRUE)
  1639. Status = BeceemFlashBulkWriteStatus(Adapter,
  1640. pBuffer,
  1641. uiFlashOffset,
  1642. uiNumBytes ,
  1643. bVerify);
  1644. else
  1645. Status = BeceemFlashBulkWrite(Adapter,
  1646. pBuffer,
  1647. uiFlashOffset,
  1648. uiNumBytes,
  1649. bVerify);
  1650. #endif
  1651. }
  1652. if (uiOffset >= EEPROM_CALPARAM_START) {
  1653. uiMemoryLoc += (uiOffset - EEPROM_CALPARAM_START);
  1654. while (uiNumBytes) {
  1655. if (uiNumBytes > BUFFER_4K) {
  1656. wrm(Adapter, (uiMemoryLoc+uiIndex), (PCHAR)(pBuffer + (uiIndex / 4)), BUFFER_4K);
  1657. uiNumBytes -= BUFFER_4K;
  1658. uiIndex += BUFFER_4K;
  1659. } else {
  1660. wrm(Adapter, uiMemoryLoc+uiIndex, (PCHAR)(pBuffer + (uiIndex / 4)), uiNumBytes);
  1661. uiNumBytes = 0;
  1662. break;
  1663. }
  1664. }
  1665. } else {
  1666. if ((uiOffset + uiNumBytes) > EEPROM_CALPARAM_START) {
  1667. ULONG ulBytesTobeSkipped = 0;
  1668. PUCHAR pcBuffer = (PUCHAR)pBuffer; /* char pointer to take care of odd byte cases. */
  1669. uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset);
  1670. ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset);
  1671. uiOffset += (EEPROM_CALPARAM_START - uiOffset);
  1672. while (uiNumBytes) {
  1673. if (uiNumBytes > BUFFER_4K) {
  1674. wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], BUFFER_4K);
  1675. uiNumBytes -= BUFFER_4K;
  1676. uiIndex += BUFFER_4K;
  1677. } else {
  1678. wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], uiNumBytes);
  1679. uiNumBytes = 0;
  1680. break;
  1681. }
  1682. }
  1683. }
  1684. }
  1685. /* restore the values. */
  1686. wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
  1687. } else if (Adapter->eNVMType == NVM_EEPROM) {
  1688. Status = BeceemEEPROMBulkWrite(Adapter,
  1689. (PUCHAR)pBuffer,
  1690. uiOffset,
  1691. uiNumBytes,
  1692. bVerify);
  1693. if (bVerify)
  1694. Status = BeceemEEPROMReadBackandVerify(Adapter, (PUINT)pBuffer, uiOffset, uiNumBytes);
  1695. } else {
  1696. Status = -1;
  1697. }
  1698. return Status;
  1699. }
  1700. /*
  1701. * Procedure: BcmUpdateSectorSize
  1702. *
  1703. * Description: Updates the sector size to FLASH.
  1704. *
  1705. * Arguments:
  1706. * Adapter - ptr to Adapter object instance
  1707. * uiSectorSize - sector size
  1708. *
  1709. * Returns:
  1710. * OSAL_STATUS_SUCCESS - if NVM write is successful.
  1711. * <FAILURE> - if failed.
  1712. */
  1713. int BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, unsigned int uiSectorSize)
  1714. {
  1715. int Status = -1;
  1716. struct bcm_flash_cs_info sFlashCsInfo = {0};
  1717. unsigned int uiTemp = 0;
  1718. unsigned int uiSectorSig = 0;
  1719. unsigned int uiCurrentSectorSize = 0;
  1720. unsigned int value;
  1721. rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
  1722. value = 0;
  1723. wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
  1724. /*
  1725. * Before updating the sector size in the reserved area, check if already present.
  1726. */
  1727. BeceemFlashBulkRead(Adapter, (PUINT)&sFlashCsInfo, Adapter->ulFlashControlSectionStart, sizeof(sFlashCsInfo));
  1728. uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig);
  1729. uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize);
  1730. if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) {
  1731. if ((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE)) {
  1732. if (uiSectorSize == uiCurrentSectorSize) {
  1733. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Provided sector size is same as programmed in Flash");
  1734. Status = STATUS_SUCCESS;
  1735. goto Restore;
  1736. }
  1737. }
  1738. }
  1739. if ((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE)) {
  1740. sFlashCsInfo.FlashSectorSize = htonl(uiSectorSize);
  1741. sFlashCsInfo.FlashSectorSizeSig = htonl(FLASH_SECTOR_SIZE_SIG);
  1742. Status = BeceemFlashBulkWrite(Adapter,
  1743. (PUINT)&sFlashCsInfo,
  1744. Adapter->ulFlashControlSectionStart,
  1745. sizeof(sFlashCsInfo),
  1746. TRUE);
  1747. }
  1748. Restore:
  1749. /* restore the values. */
  1750. wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
  1751. return Status;
  1752. }
  1753. /*
  1754. * Procedure: BcmGetFlashSectorSize
  1755. *
  1756. * Description: Finds the sector size of the FLASH.
  1757. *
  1758. * Arguments:
  1759. * Adapter - ptr to Adapter object instance
  1760. *
  1761. * Returns:
  1762. * unsigned int - sector size.
  1763. *
  1764. */
  1765. static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, unsigned int FlashSectorSizeSig, unsigned int FlashSectorSize)
  1766. {
  1767. unsigned int uiSectorSize = 0;
  1768. unsigned int uiSectorSig = 0;
  1769. if (Adapter->bSectorSizeOverride &&
  1770. (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
  1771. Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)) {
  1772. Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
  1773. } else {
  1774. uiSectorSig = FlashSectorSizeSig;
  1775. if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) {
  1776. uiSectorSize = FlashSectorSize;
  1777. /*
  1778. * If the sector size stored in the FLASH makes sense then use it.
  1779. */
  1780. if (uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE) {
  1781. Adapter->uiSectorSize = uiSectorSize;
  1782. } else if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
  1783. Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) {
  1784. /* No valid size in FLASH, check if Config file has it. */
  1785. Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
  1786. } else {
  1787. /* Init to Default, if none of the above works. */
  1788. Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
  1789. }
  1790. } else {
  1791. if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
  1792. Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)
  1793. Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
  1794. else
  1795. Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
  1796. }
  1797. }
  1798. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector size :%x\n", Adapter->uiSectorSize);
  1799. return Adapter->uiSectorSize;
  1800. }
  1801. /*
  1802. * Procedure: BcmInitEEPROMQueues
  1803. *
  1804. * Description: Initialization of EEPROM queues.
  1805. *
  1806. * Arguments:
  1807. * Adapter - ptr to Adapter object instance
  1808. *
  1809. * Returns:
  1810. * <OSAL_STATUS_CODE>
  1811. */
  1812. static int BcmInitEEPROMQueues(struct bcm_mini_adapter *Adapter)
  1813. {
  1814. unsigned int value = 0;
  1815. /* CHIP Bug : Clear the Avail bits on the Read queue. The default
  1816. * value on this register is supposed to be 0x00001102.
  1817. * But we get 0x00001122.
  1818. */
  1819. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Fixing reset value on 0x0f003004 register\n");
  1820. value = EEPROM_READ_DATA_AVAIL;
  1821. wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
  1822. /* Flush the all the EEPROM queues. */
  1823. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Flushing the queues\n");
  1824. value = EEPROM_ALL_QUEUE_FLUSH;
  1825. wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
  1826. value = 0;
  1827. wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
  1828. /* Read the EEPROM Status Register. Just to see, no real purpose. */
  1829. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "EEPROM Status register value = %x\n", ReadEEPROMStatusRegister(Adapter));
  1830. return STATUS_SUCCESS;
  1831. } /* BcmInitEEPROMQueues() */
  1832. /*
  1833. * Procedure: BcmInitNVM
  1834. *
  1835. * Description: Initialization of NVM, EEPROM size,FLASH size, sector size etc.
  1836. *
  1837. * Arguments:
  1838. * Adapter - ptr to Adapter object instance
  1839. *
  1840. * Returns:
  1841. * <OSAL_STATUS_CODE>
  1842. */
  1843. int BcmInitNVM(struct bcm_mini_adapter *ps_adapter)
  1844. {
  1845. BcmValidateNvmType(ps_adapter);
  1846. BcmInitEEPROMQueues(ps_adapter);
  1847. if (ps_adapter->eNVMType == NVM_AUTODETECT) {
  1848. ps_adapter->eNVMType = BcmGetNvmType(ps_adapter);
  1849. if (ps_adapter->eNVMType == NVM_UNKNOWN)
  1850. BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n");
  1851. } else if (ps_adapter->eNVMType == NVM_FLASH) {
  1852. BcmGetFlashCSInfo(ps_adapter);
  1853. }
  1854. BcmGetNvmSize(ps_adapter);
  1855. return STATUS_SUCCESS;
  1856. }
  1857. /* BcmGetNvmSize : set the EEPROM or flash size in Adapter.
  1858. *
  1859. * Input Parameter:
  1860. * Adapter data structure
  1861. * Return Value :
  1862. * 0. means success;
  1863. */
  1864. static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter)
  1865. {
  1866. if (Adapter->eNVMType == NVM_EEPROM)
  1867. Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter);
  1868. else if (Adapter->eNVMType == NVM_FLASH)
  1869. Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter);
  1870. return 0;
  1871. }
  1872. /*
  1873. * Procedure: BcmValidateNvm
  1874. *
  1875. * Description: Validates the NVM Type option selected against the device
  1876. *
  1877. * Arguments:
  1878. * Adapter - ptr to Adapter object instance
  1879. *
  1880. * Returns:
  1881. * <VOID>
  1882. */
  1883. static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter)
  1884. {
  1885. /*
  1886. * if forcing the FLASH through CFG file, we should ensure device really has a FLASH.
  1887. * Accessing the FLASH address without the FLASH being present can cause hang/freeze etc.
  1888. * So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice.
  1889. */
  1890. if (Adapter->eNVMType == NVM_FLASH &&
  1891. Adapter->chip_id < 0xBECE3300)
  1892. Adapter->eNVMType = NVM_AUTODETECT;
  1893. }
  1894. /*
  1895. * Procedure: BcmReadFlashRDID
  1896. *
  1897. * Description: Reads ID from Serial Flash
  1898. *
  1899. * Arguments:
  1900. * Adapter - ptr to Adapter object instance
  1901. *
  1902. * Returns:
  1903. * Flash ID
  1904. */
  1905. static ULONG BcmReadFlashRDID(struct bcm_mini_adapter *Adapter)
  1906. {
  1907. ULONG ulRDID = 0;
  1908. unsigned int value;
  1909. /*
  1910. * Read ID Instruction.
  1911. */
  1912. value = (FLASH_CMD_READ_ID << 24);
  1913. wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
  1914. /* Delay */
  1915. udelay(10);
  1916. /*
  1917. * Read SPI READQ REG. The output will be WWXXYYZZ.
  1918. * The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored.
  1919. */
  1920. rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulRDID, sizeof(ulRDID));
  1921. return ulRDID >> 8;
  1922. }
  1923. int BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter)
  1924. {
  1925. if (!psAdapter) {
  1926. BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL");
  1927. return -EINVAL;
  1928. }
  1929. psAdapter->psFlashCSInfo = kzalloc(sizeof(struct bcm_flash_cs_info), GFP_KERNEL);
  1930. if (psAdapter->psFlashCSInfo == NULL) {
  1931. BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 1.x");
  1932. return -ENOMEM;
  1933. }
  1934. psAdapter->psFlash2xCSInfo = kzalloc(sizeof(struct bcm_flash2x_cs_info), GFP_KERNEL);
  1935. if (!psAdapter->psFlash2xCSInfo) {
  1936. BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 2.x");
  1937. kfree(psAdapter->psFlashCSInfo);
  1938. return -ENOMEM;
  1939. }
  1940. psAdapter->psFlash2xVendorInfo = kzalloc(sizeof(struct bcm_flash2x_vendor_info), GFP_KERNEL);
  1941. if (!psAdapter->psFlash2xVendorInfo) {
  1942. BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate Vendor Info Memory for Flash 2.x");
  1943. kfree(psAdapter->psFlashCSInfo);
  1944. kfree(psAdapter->psFlash2xCSInfo);
  1945. return -ENOMEM;
  1946. }
  1947. return STATUS_SUCCESS;
  1948. }
  1949. int BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter)
  1950. {
  1951. if (!psAdapter) {
  1952. BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL");
  1953. return -EINVAL;
  1954. }
  1955. kfree(psAdapter->psFlashCSInfo);
  1956. kfree(psAdapter->psFlash2xCSInfo);
  1957. kfree(psAdapter->psFlash2xVendorInfo);
  1958. return STATUS_SUCCESS;
  1959. }
  1960. static int BcmDumpFlash2XCSStructure(struct bcm_flash2x_cs_info *psFlash2xCSInfo, struct bcm_mini_adapter *Adapter)
  1961. {
  1962. unsigned int Index = 0;
  1963. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************");
  1964. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x", (psFlash2xCSInfo->MagicNumber));
  1965. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Major Version :%d", MAJOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
  1966. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Minor Version :%d", MINOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
  1967. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ISOImageMajorVersion:0x%x", (psFlash2xCSInfo->ISOImageVersion));
  1968. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSIFirmwareMajorVersion :0x%x", (psFlash2xCSInfo->SCSIFirmwareVersion));
  1969. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart1ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage));
  1970. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForScsiFirmware :0x%x", (psFlash2xCSInfo->OffsetFromZeroForScsiFirmware));
  1971. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SizeOfScsiFirmware :0x%x", (psFlash2xCSInfo->SizeOfScsiFirmware));
  1972. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart2ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage));
  1973. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDStart));
  1974. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDEnd));
  1975. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAStart));
  1976. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAEnd));
  1977. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionStart));
  1978. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionData :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionData));
  1979. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CDLessInactivityTimeout :0x%x", (psFlash2xCSInfo->CDLessInactivityTimeout));
  1980. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "NewImageSignature :0x%x", (psFlash2xCSInfo->NewImageSignature));
  1981. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSizeSig :0x%x", (psFlash2xCSInfo->FlashSectorSizeSig));
  1982. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSize :0x%x", (psFlash2xCSInfo->FlashSectorSize));
  1983. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashWriteSupportSize :0x%x", (psFlash2xCSInfo->FlashWriteSupportSize));
  1984. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "TotalFlashSize :0x%X", (psFlash2xCSInfo->TotalFlashSize));
  1985. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashBaseAddr :0x%x", (psFlash2xCSInfo->FlashBaseAddr));
  1986. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashPartMaxSize :0x%x", (psFlash2xCSInfo->FlashPartMaxSize));
  1987. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "IsCDLessDeviceBootSig :0x%x", (psFlash2xCSInfo->IsCDLessDeviceBootSig));
  1988. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "MassStorageTimeout :0x%x", (psFlash2xCSInfo->MassStorageTimeout));
  1989. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1Start));
  1990. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1End));
  1991. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2Start));
  1992. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2End));
  1993. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3Start));
  1994. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3End));
  1995. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1Start));
  1996. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1End));
  1997. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2Start));
  1998. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2End));
  1999. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3Start));
  2000. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3End));
  2001. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromDSDStartForDSDHeader :0x%x", (psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader));
  2002. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1Start));
  2003. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1End));
  2004. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2Start));
  2005. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2End));
  2006. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1Start));
  2007. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1End));
  2008. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2Start));
  2009. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2End));
  2010. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :");
  2011. for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++)
  2012. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index,
  2013. (psFlash2xCSInfo->SectorAccessBitMap[Index]));
  2014. return STATUS_SUCCESS;
  2015. }
  2016. static int ConvertEndianOf2XCSStructure(struct bcm_flash2x_cs_info *psFlash2xCSInfo)
  2017. {
  2018. unsigned int Index = 0;
  2019. psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber);
  2020. psFlash2xCSInfo->FlashLayoutVersion = ntohl(psFlash2xCSInfo->FlashLayoutVersion);
  2021. /* psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion); */
  2022. psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion);
  2023. psFlash2xCSInfo->SCSIFirmwareVersion = ntohl(psFlash2xCSInfo->SCSIFirmwareVersion);
  2024. psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage);
  2025. psFlash2xCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
  2026. psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware);
  2027. psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage);
  2028. psFlash2xCSInfo->OffsetFromZeroForDSDStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDStart);
  2029. psFlash2xCSInfo->OffsetFromZeroForDSDEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
  2030. psFlash2xCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAStart);
  2031. psFlash2xCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
  2032. psFlash2xCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
  2033. psFlash2xCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionData);
  2034. psFlash2xCSInfo->CDLessInactivityTimeout = ntohl(psFlash2xCSInfo->CDLessInactivityTimeout);
  2035. psFlash2xCSInfo->NewImageSignature = ntohl(psFlash2xCSInfo->NewImageSignature);
  2036. psFlash2xCSInfo->FlashSectorSizeSig = ntohl(psFlash2xCSInfo->FlashSectorSizeSig);
  2037. psFlash2xCSInfo->FlashSectorSize = ntohl(psFlash2xCSInfo->FlashSectorSize);
  2038. psFlash2xCSInfo->FlashWriteSupportSize = ntohl(psFlash2xCSInfo->FlashWriteSupportSize);
  2039. psFlash2xCSInfo->TotalFlashSize = ntohl(psFlash2xCSInfo->TotalFlashSize);
  2040. psFlash2xCSInfo->FlashBaseAddr = ntohl(psFlash2xCSInfo->FlashBaseAddr);
  2041. psFlash2xCSInfo->FlashPartMaxSize = ntohl(psFlash2xCSInfo->FlashPartMaxSize);
  2042. psFlash2xCSInfo->IsCDLessDeviceBootSig = ntohl(psFlash2xCSInfo->IsCDLessDeviceBootSig);
  2043. psFlash2xCSInfo->MassStorageTimeout = ntohl(psFlash2xCSInfo->MassStorageTimeout);
  2044. psFlash2xCSInfo->OffsetISOImage1Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1Start);
  2045. psFlash2xCSInfo->OffsetISOImage1Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1End);
  2046. psFlash2xCSInfo->OffsetISOImage1Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2Start);
  2047. psFlash2xCSInfo->OffsetISOImage1Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2End);
  2048. psFlash2xCSInfo->OffsetISOImage1Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3Start);
  2049. psFlash2xCSInfo->OffsetISOImage1Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3End);
  2050. psFlash2xCSInfo->OffsetISOImage2Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1Start);
  2051. psFlash2xCSInfo->OffsetISOImage2Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1End);
  2052. psFlash2xCSInfo->OffsetISOImage2Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2Start);
  2053. psFlash2xCSInfo->OffsetISOImage2Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2End);
  2054. psFlash2xCSInfo->OffsetISOImage2Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3Start);
  2055. psFlash2xCSInfo->OffsetISOImage2Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3End);
  2056. psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader = ntohl(psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader);
  2057. psFlash2xCSInfo->OffsetFromZeroForDSD1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
  2058. psFlash2xCSInfo->OffsetFromZeroForDSD1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1End);
  2059. psFlash2xCSInfo->OffsetFromZeroForDSD2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
  2060. psFlash2xCSInfo->OffsetFromZeroForDSD2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2End);
  2061. psFlash2xCSInfo->OffsetFromZeroForVSA1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
  2062. psFlash2xCSInfo->OffsetFromZeroForVSA1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1End);
  2063. psFlash2xCSInfo->OffsetFromZeroForVSA2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
  2064. psFlash2xCSInfo->OffsetFromZeroForVSA2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2End);
  2065. for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++)
  2066. psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]);
  2067. return STATUS_SUCCESS;
  2068. }
  2069. static int ConvertEndianOfCSStructure(struct bcm_flash_cs_info *psFlashCSInfo)
  2070. {
  2071. /* unsigned int Index = 0; */
  2072. psFlashCSInfo->MagicNumber = ntohl(psFlashCSInfo->MagicNumber);
  2073. psFlashCSInfo->FlashLayoutVersion = ntohl(psFlashCSInfo->FlashLayoutVersion);
  2074. psFlashCSInfo->ISOImageVersion = ntohl(psFlashCSInfo->ISOImageVersion);
  2075. /* won't convert according to old assumption */
  2076. psFlashCSInfo->SCSIFirmwareVersion = (psFlashCSInfo->SCSIFirmwareVersion);
  2077. psFlashCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage);
  2078. psFlashCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware);
  2079. psFlashCSInfo->SizeOfScsiFirmware = ntohl(psFlashCSInfo->SizeOfScsiFirmware);
  2080. psFlashCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart2ISOImage);
  2081. psFlashCSInfo->OffsetFromZeroForCalibrationStart = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationStart);
  2082. psFlashCSInfo->OffsetFromZeroForCalibrationEnd = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationEnd);
  2083. psFlashCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlashCSInfo->OffsetFromZeroForVSAStart);
  2084. psFlashCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlashCSInfo->OffsetFromZeroForVSAEnd);
  2085. psFlashCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionStart);
  2086. psFlashCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionData);
  2087. psFlashCSInfo->CDLessInactivityTimeout = ntohl(psFlashCSInfo->CDLessInactivityTimeout);
  2088. psFlashCSInfo->NewImageSignature = ntohl(psFlashCSInfo->NewImageSignature);
  2089. psFlashCSInfo->FlashSectorSizeSig = ntohl(psFlashCSInfo->FlashSectorSizeSig);
  2090. psFlashCSInfo->FlashSectorSize = ntohl(psFlashCSInfo->FlashSectorSize);
  2091. psFlashCSInfo->FlashWriteSupportSize = ntohl(psFlashCSInfo->FlashWriteSupportSize);
  2092. psFlashCSInfo->TotalFlashSize = ntohl(psFlashCSInfo->TotalFlashSize);
  2093. psFlashCSInfo->FlashBaseAddr = ntohl(psFlashCSInfo->FlashBaseAddr);
  2094. psFlashCSInfo->FlashPartMaxSize = ntohl(psFlashCSInfo->FlashPartMaxSize);
  2095. psFlashCSInfo->IsCDLessDeviceBootSig = ntohl(psFlashCSInfo->IsCDLessDeviceBootSig);
  2096. psFlashCSInfo->MassStorageTimeout = ntohl(psFlashCSInfo->MassStorageTimeout);
  2097. return STATUS_SUCCESS;
  2098. }
  2099. static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section)
  2100. {
  2101. return (Adapter->uiVendorExtnFlag &&
  2102. (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) &&
  2103. (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS));
  2104. }
  2105. static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter)
  2106. {
  2107. B_UINT32 i = 0;
  2108. unsigned int uiSizeSection = 0;
  2109. Adapter->uiVendorExtnFlag = false;
  2110. for (i = 0; i < TOTAL_SECTIONS; i++)
  2111. Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS;
  2112. if (STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo))
  2113. return;
  2114. i = 0;
  2115. while (i < TOTAL_SECTIONS) {
  2116. if (!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT)) {
  2117. i++;
  2118. continue;
  2119. }
  2120. Adapter->uiVendorExtnFlag = TRUE;
  2121. uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd -
  2122. Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart);
  2123. switch (i) {
  2124. case DSD0:
  2125. if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) &&
  2126. (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
  2127. Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS;
  2128. else
  2129. Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS;
  2130. break;
  2131. case DSD1:
  2132. if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) &&
  2133. (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
  2134. Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS;
  2135. else
  2136. Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS;
  2137. break;
  2138. case DSD2:
  2139. if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) &&
  2140. (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
  2141. Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS;
  2142. else
  2143. Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS;
  2144. break;
  2145. case VSA0:
  2146. if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
  2147. Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS;
  2148. else
  2149. Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS;
  2150. break;
  2151. case VSA1:
  2152. if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
  2153. Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS;
  2154. else
  2155. Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS;
  2156. break;
  2157. case VSA2:
  2158. if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
  2159. Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS;
  2160. else
  2161. Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS;
  2162. break;
  2163. default:
  2164. break;
  2165. }
  2166. i++;
  2167. }
  2168. }
  2169. /*
  2170. * Procedure: BcmGetFlashCSInfo
  2171. *
  2172. * Description: Reads control structure and gets Cal section addresses.
  2173. *
  2174. * Arguments:
  2175. * Adapter - ptr to Adapter object instance
  2176. *
  2177. * Returns:
  2178. * <VOID>
  2179. */
  2180. static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter)
  2181. {
  2182. /* struct bcm_flash_cs_info sFlashCsInfo = {0}; */
  2183. #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
  2184. unsigned int value;
  2185. #endif
  2186. unsigned int uiFlashLayoutMajorVersion;
  2187. Adapter->uiFlashLayoutMinorVersion = 0;
  2188. Adapter->uiFlashLayoutMajorVersion = 0;
  2189. Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR;
  2190. Adapter->uiFlashBaseAdd = 0;
  2191. Adapter->ulFlashCalStart = 0;
  2192. memset(Adapter->psFlashCSInfo, 0 , sizeof(struct bcm_flash_cs_info));
  2193. memset(Adapter->psFlash2xCSInfo, 0 , sizeof(struct bcm_flash2x_cs_info));
  2194. if (!Adapter->bDDRInitDone) {
  2195. value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
  2196. wrmalt(Adapter, 0xAF00A080, &value, sizeof(value));
  2197. }
  2198. /* Reading first 8 Bytes to get the Flash Layout
  2199. * MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes)
  2200. */
  2201. BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, 8);
  2202. Adapter->psFlashCSInfo->FlashLayoutVersion = ntohl(Adapter->psFlashCSInfo->FlashLayoutVersion);
  2203. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion));
  2204. /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion)); */
  2205. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber));
  2206. if (FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber)) {
  2207. uiFlashLayoutMajorVersion = MAJOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
  2208. Adapter->uiFlashLayoutMinorVersion = MINOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
  2209. } else {
  2210. Adapter->uiFlashLayoutMinorVersion = 0;
  2211. uiFlashLayoutMajorVersion = 0;
  2212. }
  2213. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion);
  2214. if (uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER) {
  2215. BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, sizeof(struct bcm_flash_cs_info));
  2216. ConvertEndianOfCSStructure(Adapter->psFlashCSInfo);
  2217. Adapter->ulFlashCalStart = (Adapter->psFlashCSInfo->OffsetFromZeroForCalibrationStart);
  2218. if (!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
  2219. Adapter->ulFlashControlSectionStart = Adapter->psFlashCSInfo->OffsetFromZeroForControlSectionStart;
  2220. if ((FLASH_CONTROL_STRUCT_SIGNATURE == (Adapter->psFlashCSInfo->MagicNumber)) &&
  2221. (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlashCSInfo->SCSIFirmwareVersion)) &&
  2222. (FLASH_SECTOR_SIZE_SIG == (Adapter->psFlashCSInfo->FlashSectorSizeSig)) &&
  2223. (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize))) {
  2224. Adapter->ulFlashWriteSize = (Adapter->psFlashCSInfo->FlashWriteSupportSize);
  2225. Adapter->fpFlashWrite = flashByteWrite;
  2226. Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
  2227. } else {
  2228. Adapter->ulFlashWriteSize = MAX_RW_SIZE;
  2229. Adapter->fpFlashWrite = flashWrite;
  2230. Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
  2231. }
  2232. BcmGetFlashSectorSize(Adapter, (Adapter->psFlashCSInfo->FlashSectorSizeSig),
  2233. (Adapter->psFlashCSInfo->FlashSectorSize));
  2234. Adapter->uiFlashBaseAdd = Adapter->psFlashCSInfo->FlashBaseAddr & 0xFCFFFFFF;
  2235. } else {
  2236. if (BcmFlash2xBulkRead(Adapter, (PUINT)Adapter->psFlash2xCSInfo, NO_SECTION_VAL,
  2237. Adapter->ulFlashControlSectionStart, sizeof(struct bcm_flash2x_cs_info))) {
  2238. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure\n");
  2239. return STATUS_FAILURE;
  2240. }
  2241. ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo);
  2242. BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo, Adapter);
  2243. if ((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) &&
  2244. (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) &&
  2245. (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) &&
  2246. (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize)) {
  2247. Adapter->ulFlashWriteSize = Adapter->psFlash2xCSInfo->FlashWriteSupportSize;
  2248. Adapter->fpFlashWrite = flashByteWrite;
  2249. Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
  2250. } else {
  2251. Adapter->ulFlashWriteSize = MAX_RW_SIZE;
  2252. Adapter->fpFlashWrite = flashWrite;
  2253. Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
  2254. }
  2255. BcmGetFlashSectorSize(Adapter, Adapter->psFlash2xCSInfo->FlashSectorSizeSig,
  2256. Adapter->psFlash2xCSInfo->FlashSectorSize);
  2257. UpdateVendorInfo(Adapter);
  2258. BcmGetActiveDSD(Adapter);
  2259. BcmGetActiveISO(Adapter);
  2260. Adapter->uiFlashBaseAdd = Adapter->psFlash2xCSInfo->FlashBaseAddr & 0xFCFFFFFF;
  2261. Adapter->ulFlashControlSectionStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart;
  2262. }
  2263. /*
  2264. * Concerns: what if CS sector size does not match with this sector size ???
  2265. * what is the indication of AccessBitMap in CS in flash 2.x ????
  2266. */
  2267. Adapter->ulFlashID = BcmReadFlashRDID(Adapter);
  2268. Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion;
  2269. return STATUS_SUCCESS;
  2270. }
  2271. /*
  2272. * Procedure: BcmGetNvmType
  2273. *
  2274. * Description: Finds the type of NVM used.
  2275. *
  2276. * Arguments:
  2277. * Adapter - ptr to Adapter object instance
  2278. *
  2279. * Returns:
  2280. * NVM_TYPE
  2281. *
  2282. */
  2283. static enum bcm_nvm_type BcmGetNvmType(struct bcm_mini_adapter *Adapter)
  2284. {
  2285. unsigned int uiData = 0;
  2286. BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4);
  2287. if (uiData == BECM)
  2288. return NVM_EEPROM;
  2289. /*
  2290. * Read control struct and get cal addresses before accessing the flash
  2291. */
  2292. BcmGetFlashCSInfo(Adapter);
  2293. BeceemFlashBulkRead(Adapter, &uiData, 0x0 + Adapter->ulFlashCalStart, 4);
  2294. if (uiData == BECM)
  2295. return NVM_FLASH;
  2296. /*
  2297. * even if there is no valid signature on EEPROM/FLASH find out if they really exist.
  2298. * if exist select it.
  2299. */
  2300. if (BcmGetEEPROMSize(Adapter))
  2301. return NVM_EEPROM;
  2302. /* TBD for Flash. */
  2303. return NVM_UNKNOWN;
  2304. }
  2305. /*
  2306. * BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given
  2307. * @Adapter : Drivers Private Data structure
  2308. * @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val
  2309. *
  2310. * Return value:-
  2311. * On success it return the start offset of the provided section val
  2312. * On Failure -returns STATUS_FAILURE
  2313. */
  2314. int BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal)
  2315. {
  2316. /*
  2317. * Considering all the section for which end offset can be calculated or directly given
  2318. * in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section
  2319. * endoffset can't be calculated or given in CS Structure.
  2320. */
  2321. int SectStartOffset = 0;
  2322. SectStartOffset = INVALID_OFFSET;
  2323. if (IsSectionExistInVendorInfo(Adapter, eFlashSectionVal))
  2324. return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart;
  2325. switch (eFlashSectionVal) {
  2326. case ISO_IMAGE1:
  2327. if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
  2328. (IsNonCDLessDevice(Adapter) == false))
  2329. SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
  2330. break;
  2331. case ISO_IMAGE2:
  2332. if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
  2333. (IsNonCDLessDevice(Adapter) == false))
  2334. SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
  2335. break;
  2336. case DSD0:
  2337. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
  2338. SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart);
  2339. break;
  2340. case DSD1:
  2341. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
  2342. SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
  2343. break;
  2344. case DSD2:
  2345. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
  2346. SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
  2347. break;
  2348. case VSA0:
  2349. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
  2350. SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart);
  2351. break;
  2352. case VSA1:
  2353. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
  2354. SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
  2355. break;
  2356. case VSA2:
  2357. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
  2358. SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
  2359. break;
  2360. case SCSI:
  2361. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
  2362. SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
  2363. break;
  2364. case CONTROL_SECTION:
  2365. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
  2366. SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
  2367. break;
  2368. case ISO_IMAGE1_PART2:
  2369. if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS)
  2370. SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start);
  2371. break;
  2372. case ISO_IMAGE1_PART3:
  2373. if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS)
  2374. SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
  2375. break;
  2376. case ISO_IMAGE2_PART2:
  2377. if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS)
  2378. SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start);
  2379. break;
  2380. case ISO_IMAGE2_PART3:
  2381. if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS)
  2382. SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
  2383. break;
  2384. default:
  2385. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x");
  2386. SectStartOffset = INVALID_OFFSET;
  2387. }
  2388. return SectStartOffset;
  2389. }
  2390. /*
  2391. * BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given
  2392. * @Adapter : Drivers Private Data structure
  2393. * @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val
  2394. *
  2395. * Return value:-
  2396. * On success it return the end offset of the provided section val
  2397. * On Failure -returns STATUS_FAILURE
  2398. */
  2399. static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
  2400. {
  2401. int SectEndOffset = 0;
  2402. SectEndOffset = INVALID_OFFSET;
  2403. if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
  2404. return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd;
  2405. switch (eFlash2xSectionVal) {
  2406. case ISO_IMAGE1:
  2407. if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End != UNINIT_PTR_IN_CS) &&
  2408. (IsNonCDLessDevice(Adapter) == false))
  2409. SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End);
  2410. break;
  2411. case ISO_IMAGE2:
  2412. if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End != UNINIT_PTR_IN_CS) &&
  2413. (IsNonCDLessDevice(Adapter) == false))
  2414. SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End);
  2415. break;
  2416. case DSD0:
  2417. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS)
  2418. SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
  2419. break;
  2420. case DSD1:
  2421. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS)
  2422. SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End);
  2423. break;
  2424. case DSD2:
  2425. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS)
  2426. SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End);
  2427. break;
  2428. case VSA0:
  2429. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS)
  2430. SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
  2431. break;
  2432. case VSA1:
  2433. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS)
  2434. SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End);
  2435. break;
  2436. case VSA2:
  2437. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS)
  2438. SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End);
  2439. break;
  2440. case SCSI:
  2441. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
  2442. SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) +
  2443. (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware));
  2444. break;
  2445. case CONTROL_SECTION:
  2446. /* Not Clear So Putting failure. confirm and fix it. */
  2447. SectEndOffset = STATUS_FAILURE;
  2448. break;
  2449. case ISO_IMAGE1_PART2:
  2450. if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End != UNINIT_PTR_IN_CS)
  2451. SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End);
  2452. break;
  2453. case ISO_IMAGE1_PART3:
  2454. if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End != UNINIT_PTR_IN_CS)
  2455. SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End);
  2456. break;
  2457. case ISO_IMAGE2_PART2:
  2458. if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS)
  2459. SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End);
  2460. break;
  2461. case ISO_IMAGE2_PART3:
  2462. if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End != UNINIT_PTR_IN_CS)
  2463. SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End);
  2464. break;
  2465. default:
  2466. SectEndOffset = INVALID_OFFSET;
  2467. }
  2468. return SectEndOffset;
  2469. }
  2470. /*
  2471. * BcmFlash2xBulkRead:- Read API for Flash Map 2.x .
  2472. * @Adapter :Driver Private Data Structure
  2473. * @pBuffer : Buffer where data has to be put after reading
  2474. * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val
  2475. * @uiOffsetWithinSectionVal :- Offset with in provided section
  2476. * @uiNumBytes : Number of Bytes for Read
  2477. *
  2478. * Return value:-
  2479. * return true on success and STATUS_FAILURE on fail.
  2480. */
  2481. int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter,
  2482. PUINT pBuffer,
  2483. enum bcm_flash2x_section_val eFlash2xSectionVal,
  2484. unsigned int uiOffsetWithinSectionVal,
  2485. unsigned int uiNumBytes)
  2486. {
  2487. int Status = STATUS_SUCCESS;
  2488. int SectionStartOffset = 0;
  2489. unsigned int uiAbsoluteOffset = 0;
  2490. unsigned int uiTemp = 0, value = 0;
  2491. if (!Adapter) {
  2492. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
  2493. return -EINVAL;
  2494. }
  2495. if (Adapter->device_removed) {
  2496. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
  2497. return -ENODEV;
  2498. }
  2499. /* NO_SECTION_VAL means absolute offset is given. */
  2500. if (eFlash2xSectionVal == NO_SECTION_VAL)
  2501. SectionStartOffset = 0;
  2502. else
  2503. SectionStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal);
  2504. if (SectionStartOffset == STATUS_FAILURE) {
  2505. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exist in Flash 2.x Map ", eFlash2xSectionVal);
  2506. return -EINVAL;
  2507. }
  2508. if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
  2509. return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes);
  2510. /* calculating the absolute offset from FLASH; */
  2511. uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset;
  2512. rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
  2513. value = 0;
  2514. wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
  2515. Status = BeceemFlashBulkRead(Adapter, pBuffer, uiAbsoluteOffset, uiNumBytes);
  2516. wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
  2517. if (Status) {
  2518. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status);
  2519. return Status;
  2520. }
  2521. return Status;
  2522. }
  2523. /*
  2524. * BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x.
  2525. * @Adapter :Driver Private Data Structure
  2526. * @pBuffer : Buffer From where data has to taken for writing
  2527. * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val
  2528. * @uiOffsetWithinSectionVal :- Offset with in provided section
  2529. * @uiNumBytes : Number of Bytes for Write
  2530. *
  2531. * Return value:-
  2532. * return true on success and STATUS_FAILURE on fail.
  2533. *
  2534. */
  2535. int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter,
  2536. PUINT pBuffer,
  2537. enum bcm_flash2x_section_val eFlash2xSectVal,
  2538. unsigned int uiOffset,
  2539. unsigned int uiNumBytes,
  2540. unsigned int bVerify)
  2541. {
  2542. int Status = STATUS_SUCCESS;
  2543. unsigned int FlashSectValStartOffset = 0;
  2544. unsigned int uiTemp = 0, value = 0;
  2545. if (!Adapter) {
  2546. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
  2547. return -EINVAL;
  2548. }
  2549. if (Adapter->device_removed) {
  2550. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
  2551. return -ENODEV;
  2552. }
  2553. /* NO_SECTION_VAL means absolute offset is given. */
  2554. if (eFlash2xSectVal == NO_SECTION_VAL)
  2555. FlashSectValStartOffset = 0;
  2556. else
  2557. FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectVal);
  2558. if (FlashSectValStartOffset == STATUS_FAILURE) {
  2559. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exist in Flash Map 2.x", eFlash2xSectVal);
  2560. return -EINVAL;
  2561. }
  2562. if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectVal))
  2563. return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify);
  2564. /* calculating the absolute offset from FLASH; */
  2565. uiOffset = uiOffset + FlashSectValStartOffset;
  2566. rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
  2567. value = 0;
  2568. wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
  2569. Status = BeceemFlashBulkWrite(Adapter, pBuffer, uiOffset, uiNumBytes, bVerify);
  2570. wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
  2571. if (Status) {
  2572. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status);
  2573. return Status;
  2574. }
  2575. return Status;
  2576. }
  2577. /*
  2578. * BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR
  2579. * @Adapter :-Drivers private Data Structure
  2580. *
  2581. * Return Value:-
  2582. * Return STATUS_SUCESS if get success in setting the right DSD else negative error code
  2583. *
  2584. */
  2585. static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter)
  2586. {
  2587. enum bcm_flash2x_section_val uiHighestPriDSD = 0;
  2588. uiHighestPriDSD = getHighestPriDSD(Adapter);
  2589. Adapter->eActiveDSD = uiHighestPriDSD;
  2590. if (DSD0 == uiHighestPriDSD)
  2591. Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
  2592. if (DSD1 == uiHighestPriDSD)
  2593. Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
  2594. if (DSD2 == uiHighestPriDSD)
  2595. Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
  2596. if (Adapter->eActiveDSD)
  2597. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD);
  2598. if (Adapter->eActiveDSD == 0) {
  2599. /* if No DSD gets Active, Make Active the DSD with WR permission */
  2600. if (IsSectionWritable(Adapter, DSD2)) {
  2601. Adapter->eActiveDSD = DSD2;
  2602. Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
  2603. } else if (IsSectionWritable(Adapter, DSD1)) {
  2604. Adapter->eActiveDSD = DSD1;
  2605. Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
  2606. } else if (IsSectionWritable(Adapter, DSD0)) {
  2607. Adapter->eActiveDSD = DSD0;
  2608. Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
  2609. }
  2610. }
  2611. return STATUS_SUCCESS;
  2612. }
  2613. /*
  2614. * BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue
  2615. * @Adapter : Driver private Data Structure
  2616. *
  2617. * Return Value:-
  2618. * Sucsess:- STATUS_SUCESS
  2619. * Failure- : negative erro code
  2620. *
  2621. */
  2622. static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter)
  2623. {
  2624. int HighestPriISO = 0;
  2625. HighestPriISO = getHighestPriISO(Adapter);
  2626. Adapter->eActiveISO = HighestPriISO;
  2627. if (Adapter->eActiveISO == ISO_IMAGE2)
  2628. Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
  2629. else if (Adapter->eActiveISO == ISO_IMAGE1)
  2630. Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
  2631. if (Adapter->eActiveISO)
  2632. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active ISO :%x", Adapter->eActiveISO);
  2633. return STATUS_SUCCESS;
  2634. }
  2635. /*
  2636. * IsOffsetWritable :- it will tell the access permission of the sector having passed offset
  2637. * @Adapter : Drivers Private Data Structure
  2638. * @uiOffset : Offset provided in the Flash
  2639. *
  2640. * Return Value:-
  2641. * Success:-TRUE , offset is writable
  2642. * Failure:-false, offset is RO
  2643. *
  2644. */
  2645. static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset)
  2646. {
  2647. unsigned int uiSectorNum = 0;
  2648. unsigned int uiWordOfSectorPermission = 0;
  2649. unsigned int uiBitofSectorePermission = 0;
  2650. B_UINT32 permissionBits = 0;
  2651. uiSectorNum = uiOffset/Adapter->uiSectorSize;
  2652. /* calculating the word having this Sector Access permission from SectorAccessBitMap Array */
  2653. uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum / 16];
  2654. /* calculating the bit index inside the word for this sector */
  2655. uiBitofSectorePermission = 2 * (15 - uiSectorNum % 16);
  2656. /* Setting Access permission */
  2657. permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission);
  2658. permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3;
  2659. if (permissionBits == SECTOR_READWRITE_PERMISSION)
  2660. return TRUE;
  2661. else
  2662. return false;
  2663. }
  2664. static int BcmDumpFlash2xSectionBitMap(struct bcm_flash2x_bitmap *psFlash2xBitMap)
  2665. {
  2666. struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
  2667. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************");
  2668. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE1 :0X%x", psFlash2xBitMap->ISO_IMAGE1);
  2669. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE2 :0X%x", psFlash2xBitMap->ISO_IMAGE2);
  2670. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD0 :0X%x", psFlash2xBitMap->DSD0);
  2671. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD1 :0X%x", psFlash2xBitMap->DSD1);
  2672. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD2 :0X%x", psFlash2xBitMap->DSD2);
  2673. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA0 :0X%x", psFlash2xBitMap->VSA0);
  2674. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA1 :0X%x", psFlash2xBitMap->VSA1);
  2675. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA2 :0X%x", psFlash2xBitMap->VSA2);
  2676. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSI :0X%x", psFlash2xBitMap->SCSI);
  2677. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CONTROL_SECTION :0X%x", psFlash2xBitMap->CONTROL_SECTION);
  2678. return STATUS_SUCCESS;
  2679. }
  2680. /*
  2681. * BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash
  2682. * 8bit has been assigned to every section.
  2683. * bit[0] :Section present or not
  2684. * bit[1] :section is valid or not
  2685. * bit[2] : Secton is read only or has write permission too.
  2686. * bit[3] : Active Section -
  2687. * bit[7...4] = Reserved .
  2688. *
  2689. * @Adapter:-Driver private Data Structure
  2690. *
  2691. * Return value:-
  2692. * Success:- STATUS_SUCESS
  2693. * Failure:- negative error code
  2694. */
  2695. int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_bitmap *psFlash2xBitMap)
  2696. {
  2697. struct bcm_flash2x_cs_info *psFlash2xCSInfo = Adapter->psFlash2xCSInfo;
  2698. enum bcm_flash2x_section_val uiHighestPriDSD = 0;
  2699. enum bcm_flash2x_section_val uiHighestPriISO = 0;
  2700. bool SetActiveDSDDone = false;
  2701. bool SetActiveISODone = false;
  2702. /* For 1.x map all the section except DSD0 will be shown as not present
  2703. * This part will be used by calibration tool to detect the number of DSD present in Flash.
  2704. */
  2705. if (IsFlash2x(Adapter) == false) {
  2706. psFlash2xBitMap->ISO_IMAGE2 = 0;
  2707. psFlash2xBitMap->ISO_IMAGE1 = 0;
  2708. psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; /* 0xF; 0000(Reseved)1(Active)0(RW)1(valid)1(present) */
  2709. psFlash2xBitMap->DSD1 = 0;
  2710. psFlash2xBitMap->DSD2 = 0;
  2711. psFlash2xBitMap->VSA0 = 0;
  2712. psFlash2xBitMap->VSA1 = 0;
  2713. psFlash2xBitMap->VSA2 = 0;
  2714. psFlash2xBitMap->CONTROL_SECTION = 0;
  2715. psFlash2xBitMap->SCSI = 0;
  2716. psFlash2xBitMap->Reserved0 = 0;
  2717. psFlash2xBitMap->Reserved1 = 0;
  2718. psFlash2xBitMap->Reserved2 = 0;
  2719. return STATUS_SUCCESS;
  2720. }
  2721. uiHighestPriDSD = getHighestPriDSD(Adapter);
  2722. uiHighestPriISO = getHighestPriISO(Adapter);
  2723. /*
  2724. * IS0 IMAGE 2
  2725. */
  2726. if ((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS) {
  2727. /* Setting the 0th Bit representing the Section is present or not. */
  2728. psFlash2xBitMap->ISO_IMAGE2 = psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT;
  2729. if (ReadISOSignature(Adapter, ISO_IMAGE2) == ISO_IMAGE_MAGIC_NUMBER)
  2730. psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID;
  2731. /* Calculation for extrating the Access permission */
  2732. if (IsSectionWritable(Adapter, ISO_IMAGE2) == false)
  2733. psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO;
  2734. if (SetActiveISODone == false && uiHighestPriISO == ISO_IMAGE2) {
  2735. psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT;
  2736. SetActiveISODone = TRUE;
  2737. }
  2738. }
  2739. /*
  2740. * IS0 IMAGE 1
  2741. */
  2742. if ((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS) {
  2743. /* Setting the 0th Bit representing the Section is present or not. */
  2744. psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT;
  2745. if (ReadISOSignature(Adapter, ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER)
  2746. psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID;
  2747. /* Calculation for extrating the Access permission */
  2748. if (IsSectionWritable(Adapter, ISO_IMAGE1) == false)
  2749. psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO;
  2750. if (SetActiveISODone == false && uiHighestPriISO == ISO_IMAGE1) {
  2751. psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT;
  2752. SetActiveISODone = TRUE;
  2753. }
  2754. }
  2755. /*
  2756. * DSD2
  2757. */
  2758. if ((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS) {
  2759. /* Setting the 0th Bit representing the Section is present or not. */
  2760. psFlash2xBitMap->DSD2 = psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT;
  2761. if (ReadDSDSignature(Adapter, DSD2) == DSD_IMAGE_MAGIC_NUMBER)
  2762. psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID;
  2763. /* Calculation for extrating the Access permission */
  2764. if (IsSectionWritable(Adapter, DSD2) == false) {
  2765. psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO;
  2766. } else {
  2767. /* Means section is writable */
  2768. if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD2)) {
  2769. psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT;
  2770. SetActiveDSDDone = TRUE;
  2771. }
  2772. }
  2773. }
  2774. /*
  2775. * DSD 1
  2776. */
  2777. if ((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS) {
  2778. /* Setting the 0th Bit representing the Section is present or not. */
  2779. psFlash2xBitMap->DSD1 = psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT;
  2780. if (ReadDSDSignature(Adapter, DSD1) == DSD_IMAGE_MAGIC_NUMBER)
  2781. psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID;
  2782. /* Calculation for extrating the Access permission */
  2783. if (IsSectionWritable(Adapter, DSD1) == false) {
  2784. psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO;
  2785. } else {
  2786. /* Means section is writable */
  2787. if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD1)) {
  2788. psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT;
  2789. SetActiveDSDDone = TRUE;
  2790. }
  2791. }
  2792. }
  2793. /*
  2794. * For DSD 0
  2795. */
  2796. if ((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS) {
  2797. /* Setting the 0th Bit representing the Section is present or not. */
  2798. psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT;
  2799. if (ReadDSDSignature(Adapter, DSD0) == DSD_IMAGE_MAGIC_NUMBER)
  2800. psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID;
  2801. /* Setting Access permission */
  2802. if (IsSectionWritable(Adapter, DSD0) == false) {
  2803. psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO;
  2804. } else {
  2805. /* Means section is writable */
  2806. if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD0)) {
  2807. psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT;
  2808. SetActiveDSDDone = TRUE;
  2809. }
  2810. }
  2811. }
  2812. /*
  2813. * VSA 0
  2814. */
  2815. if ((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS) {
  2816. /* Setting the 0th Bit representing the Section is present or not. */
  2817. psFlash2xBitMap->VSA0 = psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT;
  2818. /* Setting the Access Bit. Map is not defined hece setting it always valid */
  2819. psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID;
  2820. /* Calculation for extrating the Access permission */
  2821. if (IsSectionWritable(Adapter, VSA0) == false)
  2822. psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_RO;
  2823. /* By Default section is Active */
  2824. psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT;
  2825. }
  2826. /*
  2827. * VSA 1
  2828. */
  2829. if ((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS) {
  2830. /* Setting the 0th Bit representing the Section is present or not. */
  2831. psFlash2xBitMap->VSA1 = psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT;
  2832. /* Setting the Access Bit. Map is not defined hece setting it always valid */
  2833. psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_VALID;
  2834. /* Checking For Access permission */
  2835. if (IsSectionWritable(Adapter, VSA1) == false)
  2836. psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO;
  2837. /* By Default section is Active */
  2838. psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT;
  2839. }
  2840. /*
  2841. * VSA 2
  2842. */
  2843. if ((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS) {
  2844. /* Setting the 0th Bit representing the Section is present or not. */
  2845. psFlash2xBitMap->VSA2 = psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT;
  2846. /* Setting the Access Bit. Map is not defined hece setting it always valid */
  2847. psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID;
  2848. /* Checking For Access permission */
  2849. if (IsSectionWritable(Adapter, VSA2) == false)
  2850. psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO;
  2851. /* By Default section is Active */
  2852. psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT;
  2853. }
  2854. /*
  2855. * SCSI Section
  2856. */
  2857. if ((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS) {
  2858. /* Setting the 0th Bit representing the Section is present or not. */
  2859. psFlash2xBitMap->SCSI = psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT;
  2860. /* Setting the Access Bit. Map is not defined hece setting it always valid */
  2861. psFlash2xBitMap->SCSI |= FLASH2X_SECTION_VALID;
  2862. /* Checking For Access permission */
  2863. if (IsSectionWritable(Adapter, SCSI) == false)
  2864. psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO;
  2865. /* By Default section is Active */
  2866. psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT;
  2867. }
  2868. /*
  2869. * Control Section
  2870. */
  2871. if ((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS) {
  2872. /* Setting the 0th Bit representing the Section is present or not. */
  2873. psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT);
  2874. /* Setting the Access Bit. Map is not defined hece setting it always valid */
  2875. psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID;
  2876. /* Checking For Access permission */
  2877. if (IsSectionWritable(Adapter, CONTROL_SECTION) == false)
  2878. psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO;
  2879. /* By Default section is Active */
  2880. psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT;
  2881. }
  2882. /*
  2883. * For Reserved Sections
  2884. */
  2885. psFlash2xBitMap->Reserved0 = 0;
  2886. psFlash2xBitMap->Reserved0 = 0;
  2887. psFlash2xBitMap->Reserved0 = 0;
  2888. BcmDumpFlash2xSectionBitMap(psFlash2xBitMap);
  2889. return STATUS_SUCCESS;
  2890. }
  2891. /*
  2892. * BcmSetActiveSection :- Set Active section is used to make priority field highest over other
  2893. * section of same type.
  2894. *
  2895. * @Adapater :- Bcm Driver Private Data Structure
  2896. * @eFlash2xSectionVal :- Flash section val whose priority has to be made highest.
  2897. *
  2898. * Return Value:- Make the priorit highest else return erorr code
  2899. *
  2900. */
  2901. int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectVal)
  2902. {
  2903. unsigned int SectImagePriority = 0;
  2904. int Status = STATUS_SUCCESS;
  2905. /* struct bcm_dsd_header sDSD = {0};
  2906. * struct bcm_iso_header sISO = {0};
  2907. */
  2908. int HighestPriDSD = 0;
  2909. int HighestPriISO = 0;
  2910. Status = IsSectionWritable(Adapter, eFlash2xSectVal);
  2911. if (Status != TRUE) {
  2912. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Provided Section <%d> is not writable", eFlash2xSectVal);
  2913. return STATUS_FAILURE;
  2914. }
  2915. Adapter->bHeaderChangeAllowed = TRUE;
  2916. switch (eFlash2xSectVal) {
  2917. case ISO_IMAGE1:
  2918. case ISO_IMAGE2:
  2919. if (ReadISOSignature(Adapter, eFlash2xSectVal) == ISO_IMAGE_MAGIC_NUMBER) {
  2920. HighestPriISO = getHighestPriISO(Adapter);
  2921. if (HighestPriISO == eFlash2xSectVal) {
  2922. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal);
  2923. Status = STATUS_SUCCESS;
  2924. break;
  2925. }
  2926. SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1;
  2927. if ((SectImagePriority == 0) && IsSectionWritable(Adapter, HighestPriISO)) {
  2928. /* This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF.
  2929. * We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO
  2930. * by user
  2931. */
  2932. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal);
  2933. SectImagePriority = htonl(0x1);
  2934. Status = BcmFlash2xBulkWrite(Adapter,
  2935. &SectImagePriority,
  2936. HighestPriISO,
  2937. 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority),
  2938. SIGNATURE_SIZE,
  2939. TRUE);
  2940. if (Status) {
  2941. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
  2942. Status = STATUS_FAILURE;
  2943. break;
  2944. }
  2945. HighestPriISO = getHighestPriISO(Adapter);
  2946. if (HighestPriISO == eFlash2xSectVal) {
  2947. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal);
  2948. Status = STATUS_SUCCESS;
  2949. break;
  2950. }
  2951. SectImagePriority = 2;
  2952. }
  2953. SectImagePriority = htonl(SectImagePriority);
  2954. Status = BcmFlash2xBulkWrite(Adapter,
  2955. &SectImagePriority,
  2956. eFlash2xSectVal,
  2957. 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority),
  2958. SIGNATURE_SIZE,
  2959. TRUE);
  2960. if (Status) {
  2961. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
  2962. break;
  2963. }
  2964. } else {
  2965. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
  2966. Status = STATUS_FAILURE;
  2967. break;
  2968. }
  2969. break;
  2970. case DSD0:
  2971. case DSD1:
  2972. case DSD2:
  2973. if (ReadDSDSignature(Adapter, eFlash2xSectVal) == DSD_IMAGE_MAGIC_NUMBER) {
  2974. HighestPriDSD = getHighestPriDSD(Adapter);
  2975. if (HighestPriDSD == eFlash2xSectVal) {
  2976. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given DSD<%x> already has highest priority", eFlash2xSectVal);
  2977. Status = STATUS_SUCCESS;
  2978. break;
  2979. }
  2980. SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1;
  2981. if (SectImagePriority == 0) {
  2982. /* This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF.
  2983. * We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD
  2984. * by user
  2985. */
  2986. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal);
  2987. SectImagePriority = htonl(0x1);
  2988. Status = BcmFlash2xBulkWrite(Adapter,
  2989. &SectImagePriority,
  2990. HighestPriDSD,
  2991. Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority),
  2992. SIGNATURE_SIZE,
  2993. TRUE);
  2994. if (Status) {
  2995. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
  2996. break;
  2997. }
  2998. HighestPriDSD = getHighestPriDSD(Adapter);
  2999. if (HighestPriDSD == eFlash2xSectVal) {
  3000. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal);
  3001. Status = STATUS_SUCCESS;
  3002. break;
  3003. }
  3004. SectImagePriority = htonl(0x2);
  3005. Status = BcmFlash2xBulkWrite(Adapter,
  3006. &SectImagePriority,
  3007. HighestPriDSD,
  3008. Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority),
  3009. SIGNATURE_SIZE,
  3010. TRUE);
  3011. if (Status) {
  3012. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
  3013. break;
  3014. }
  3015. HighestPriDSD = getHighestPriDSD(Adapter);
  3016. if (HighestPriDSD == eFlash2xSectVal) {
  3017. Status = STATUS_SUCCESS;
  3018. break;
  3019. }
  3020. SectImagePriority = 3;
  3021. }
  3022. SectImagePriority = htonl(SectImagePriority);
  3023. Status = BcmFlash2xBulkWrite(Adapter,
  3024. &SectImagePriority,
  3025. eFlash2xSectVal,
  3026. Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority),
  3027. SIGNATURE_SIZE,
  3028. TRUE);
  3029. if (Status) {
  3030. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
  3031. Status = STATUS_FAILURE;
  3032. break;
  3033. }
  3034. } else {
  3035. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
  3036. Status = STATUS_FAILURE;
  3037. break;
  3038. }
  3039. break;
  3040. case VSA0:
  3041. case VSA1:
  3042. case VSA2:
  3043. /* Has to be decided */
  3044. break;
  3045. default:
  3046. Status = STATUS_FAILURE;
  3047. break;
  3048. }
  3049. Adapter->bHeaderChangeAllowed = false;
  3050. return Status;
  3051. }
  3052. /*
  3053. * BcmCopyISO - Used only for copying the ISO section
  3054. * @Adapater :- Bcm Driver Private Data Structure
  3055. * @sCopySectStrut :- Section copy structure
  3056. *
  3057. * Return value:- SUCCESS if copies successfully else negative error code
  3058. *
  3059. */
  3060. int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section sCopySectStrut)
  3061. {
  3062. PCHAR Buff = NULL;
  3063. enum bcm_flash2x_section_val eISOReadPart = 0, eISOWritePart = 0;
  3064. unsigned int uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0;
  3065. unsigned int uiTotalDataToCopy = 0;
  3066. bool IsThisHeaderSector = false;
  3067. unsigned int sigOffset = 0;
  3068. unsigned int ISOLength = 0;
  3069. unsigned int Status = STATUS_SUCCESS;
  3070. unsigned int SigBuff[MAX_RW_SIZE];
  3071. unsigned int i = 0;
  3072. if (ReadISOSignature(Adapter, sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER) {
  3073. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
  3074. return STATUS_FAILURE;
  3075. }
  3076. Status = BcmFlash2xBulkRead(Adapter, &ISOLength,
  3077. sCopySectStrut.SrcSection,
  3078. 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageSize),
  3079. 4);
  3080. if (Status) {
  3081. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n");
  3082. return Status;
  3083. }
  3084. ISOLength = htonl(ISOLength);
  3085. if (ISOLength % Adapter->uiSectorSize)
  3086. ISOLength = Adapter->uiSectorSize * (1 + ISOLength/Adapter->uiSectorSize);
  3087. sigOffset = FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber);
  3088. Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL);
  3089. if (!Buff) {
  3090. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for section size");
  3091. return -ENOMEM;
  3092. }
  3093. if (sCopySectStrut.SrcSection == ISO_IMAGE1 && sCopySectStrut.DstSection == ISO_IMAGE2) {
  3094. eISOReadPart = ISO_IMAGE1;
  3095. eISOWritePart = ISO_IMAGE2;
  3096. uiReadOffsetWithinPart = 0;
  3097. uiWriteOffsetWithinPart = 0;
  3098. uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
  3099. (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) +
  3100. (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
  3101. (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) +
  3102. (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
  3103. (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
  3104. if (uiTotalDataToCopy < ISOLength) {
  3105. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
  3106. Status = STATUS_FAILURE;
  3107. goto out;
  3108. }
  3109. uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
  3110. (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) +
  3111. (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
  3112. (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) +
  3113. (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
  3114. (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
  3115. if (uiTotalDataToCopy < ISOLength) {
  3116. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size");
  3117. Status = STATUS_FAILURE;
  3118. goto out;
  3119. }
  3120. uiTotalDataToCopy = ISOLength;
  3121. CorruptISOSig(Adapter, ISO_IMAGE2);
  3122. while (uiTotalDataToCopy) {
  3123. if (uiTotalDataToCopy == Adapter->uiSectorSize) {
  3124. /* Setting for write of first sector. First sector is assumed to be written in last */
  3125. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector");
  3126. eISOReadPart = ISO_IMAGE1;
  3127. uiReadOffsetWithinPart = 0;
  3128. eISOWritePart = ISO_IMAGE2;
  3129. uiWriteOffsetWithinPart = 0;
  3130. IsThisHeaderSector = TRUE;
  3131. } else {
  3132. uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize;
  3133. uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize;
  3134. if ((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) {
  3135. eISOReadPart = ISO_IMAGE1_PART2;
  3136. uiReadOffsetWithinPart = 0;
  3137. }
  3138. if ((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) {
  3139. eISOReadPart = ISO_IMAGE1_PART3;
  3140. uiReadOffsetWithinPart = 0;
  3141. }
  3142. if ((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) {
  3143. eISOWritePart = ISO_IMAGE2_PART2;
  3144. uiWriteOffsetWithinPart = 0;
  3145. }
  3146. if ((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) {
  3147. eISOWritePart = ISO_IMAGE2_PART3;
  3148. uiWriteOffsetWithinPart = 0;
  3149. }
  3150. }
  3151. Status = BcmFlash2xBulkRead(Adapter,
  3152. (PUINT)Buff,
  3153. eISOReadPart,
  3154. uiReadOffsetWithinPart,
  3155. Adapter->uiSectorSize);
  3156. if (Status) {
  3157. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
  3158. break;
  3159. }
  3160. if (IsThisHeaderSector == TRUE) {
  3161. /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */
  3162. memcpy(SigBuff, Buff + sigOffset, sizeof(SigBuff));
  3163. for (i = 0; i < MAX_RW_SIZE; i++)
  3164. *(Buff + sigOffset + i) = 0xFF;
  3165. }
  3166. Adapter->bHeaderChangeAllowed = TRUE;
  3167. Status = BcmFlash2xBulkWrite(Adapter,
  3168. (PUINT)Buff,
  3169. eISOWritePart,
  3170. uiWriteOffsetWithinPart,
  3171. Adapter->uiSectorSize,
  3172. TRUE);
  3173. if (Status) {
  3174. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
  3175. break;
  3176. }
  3177. Adapter->bHeaderChangeAllowed = false;
  3178. if (IsThisHeaderSector == TRUE) {
  3179. WriteToFlashWithoutSectorErase(Adapter,
  3180. SigBuff,
  3181. eISOWritePart,
  3182. sigOffset,
  3183. MAX_RW_SIZE);
  3184. IsThisHeaderSector = false;
  3185. }
  3186. /* subtracting the written Data */
  3187. uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize;
  3188. }
  3189. }
  3190. if (sCopySectStrut.SrcSection == ISO_IMAGE2 && sCopySectStrut.DstSection == ISO_IMAGE1) {
  3191. eISOReadPart = ISO_IMAGE2;
  3192. eISOWritePart = ISO_IMAGE1;
  3193. uiReadOffsetWithinPart = 0;
  3194. uiWriteOffsetWithinPart = 0;
  3195. uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
  3196. (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) +
  3197. (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
  3198. (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) +
  3199. (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
  3200. (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
  3201. if (uiTotalDataToCopy < ISOLength) {
  3202. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
  3203. Status = STATUS_FAILURE;
  3204. goto out;
  3205. }
  3206. uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
  3207. (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) +
  3208. (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
  3209. (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) +
  3210. (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
  3211. (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
  3212. if (uiTotalDataToCopy < ISOLength) {
  3213. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size");
  3214. Status = STATUS_FAILURE;
  3215. goto out;
  3216. }
  3217. uiTotalDataToCopy = ISOLength;
  3218. CorruptISOSig(Adapter, ISO_IMAGE1);
  3219. while (uiTotalDataToCopy) {
  3220. if (uiTotalDataToCopy == Adapter->uiSectorSize) {
  3221. /* Setting for write of first sector. First sector is assumed to be written in last */
  3222. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector");
  3223. eISOReadPart = ISO_IMAGE2;
  3224. uiReadOffsetWithinPart = 0;
  3225. eISOWritePart = ISO_IMAGE1;
  3226. uiWriteOffsetWithinPart = 0;
  3227. IsThisHeaderSector = TRUE;
  3228. } else {
  3229. uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize;
  3230. uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize;
  3231. if ((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) {
  3232. eISOReadPart = ISO_IMAGE2_PART2;
  3233. uiReadOffsetWithinPart = 0;
  3234. }
  3235. if ((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) {
  3236. eISOReadPart = ISO_IMAGE2_PART3;
  3237. uiReadOffsetWithinPart = 0;
  3238. }
  3239. if ((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) {
  3240. eISOWritePart = ISO_IMAGE1_PART2;
  3241. uiWriteOffsetWithinPart = 0;
  3242. }
  3243. if ((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) {
  3244. eISOWritePart = ISO_IMAGE1_PART3;
  3245. uiWriteOffsetWithinPart = 0;
  3246. }
  3247. }
  3248. Status = BcmFlash2xBulkRead(Adapter,
  3249. (PUINT)Buff,
  3250. eISOReadPart,
  3251. uiReadOffsetWithinPart,
  3252. Adapter->uiSectorSize);
  3253. if (Status) {
  3254. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
  3255. break;
  3256. }
  3257. if (IsThisHeaderSector == TRUE) {
  3258. /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */
  3259. memcpy(SigBuff, Buff + sigOffset, sizeof(SigBuff));
  3260. for (i = 0; i < MAX_RW_SIZE; i++)
  3261. *(Buff + sigOffset + i) = 0xFF;
  3262. }
  3263. Adapter->bHeaderChangeAllowed = TRUE;
  3264. Status = BcmFlash2xBulkWrite(Adapter,
  3265. (PUINT)Buff,
  3266. eISOWritePart,
  3267. uiWriteOffsetWithinPart,
  3268. Adapter->uiSectorSize,
  3269. TRUE);
  3270. if (Status) {
  3271. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
  3272. break;
  3273. }
  3274. Adapter->bHeaderChangeAllowed = false;
  3275. if (IsThisHeaderSector == TRUE) {
  3276. WriteToFlashWithoutSectorErase(Adapter,
  3277. SigBuff,
  3278. eISOWritePart,
  3279. sigOffset,
  3280. MAX_RW_SIZE);
  3281. IsThisHeaderSector = false;
  3282. }
  3283. /* subtracting the written Data */
  3284. uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize;
  3285. }
  3286. }
  3287. out:
  3288. kfree(Buff);
  3289. return Status;
  3290. }
  3291. /*
  3292. * BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section.
  3293. * It will corrupt the sig, if Section is writable, by making first bytes as zero.
  3294. * @Adapater :- Bcm Driver Private Data Structure
  3295. * @eFlash2xSectionVal :- Flash section val which has header
  3296. *
  3297. * Return Value :-
  3298. * Success :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS
  3299. * Failure :-Return negative error code
  3300. */
  3301. int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
  3302. {
  3303. int Status = STATUS_SUCCESS;
  3304. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Value :%x\n", eFlash2xSectionVal);
  3305. if ((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2)) {
  3306. Status = CorruptDSDSig(Adapter, eFlash2xSectionVal);
  3307. } else if (eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2) {
  3308. Status = CorruptISOSig(Adapter, eFlash2xSectionVal);
  3309. } else {
  3310. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given Section <%d>does not have Header", eFlash2xSectionVal);
  3311. return STATUS_SUCCESS;
  3312. }
  3313. return Status;
  3314. }
  3315. /*
  3316. *BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has
  3317. * header and Write Permission.
  3318. * @Adapater :- Bcm Driver Private Data Structure
  3319. * @eFlashSectionVal :- Flash section val which has header
  3320. *
  3321. * Return Value :-
  3322. * Success :- If Section is present and writable write the sig and return STATUS_SUCCESS
  3323. * Failure :-Return negative error code
  3324. */
  3325. int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal)
  3326. {
  3327. unsigned int uiSignature = 0;
  3328. unsigned int uiOffset = 0;
  3329. /* struct bcm_dsd_header dsdHeader = {0}; */
  3330. if (Adapter->bSigCorrupted == false) {
  3331. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is not corrupted by driver, hence not restoring\n");
  3332. return STATUS_SUCCESS;
  3333. }
  3334. if (Adapter->bAllDSDWriteAllow == false) {
  3335. if (IsSectionWritable(Adapter, eFlashSectionVal) == false) {
  3336. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Write signature");
  3337. return SECTOR_IS_NOT_WRITABLE;
  3338. }
  3339. }
  3340. if ((eFlashSectionVal == DSD0) || (eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2)) {
  3341. uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER);
  3342. uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader;
  3343. uiOffset += FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber);
  3344. if ((ReadDSDSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) {
  3345. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Corrupted Pattern is not there. Hence won't write sig");
  3346. return STATUS_FAILURE;
  3347. }
  3348. } else if ((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2)) {
  3349. uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER);
  3350. /* uiOffset = 0; */
  3351. uiOffset = FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber);
  3352. if ((ReadISOSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) {
  3353. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Currupted Pattern is not there. Hence won't write sig");
  3354. return STATUS_FAILURE;
  3355. }
  3356. } else {
  3357. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal);
  3358. return STATUS_FAILURE;
  3359. }
  3360. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature");
  3361. Adapter->bHeaderChangeAllowed = TRUE;
  3362. Adapter->bSigCorrupted = false;
  3363. BcmFlash2xBulkWrite(Adapter, &uiSignature, eFlashSectionVal, uiOffset, SIGNATURE_SIZE, TRUE);
  3364. Adapter->bHeaderChangeAllowed = false;
  3365. return STATUS_SUCCESS;
  3366. }
  3367. /*
  3368. * validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write.
  3369. * if requested Bytes goes beyond the Requested section, it reports error.
  3370. * @Adapater :- Bcm Driver Private Data Structure
  3371. * @psFlash2xReadWrite :-Flash2x Read/write structure pointer
  3372. *
  3373. * Return values:-Return TRUE is request is valid else false.
  3374. */
  3375. int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite)
  3376. {
  3377. unsigned int uiNumOfBytes = 0;
  3378. unsigned int uiSectStartOffset = 0;
  3379. unsigned int uiSectEndOffset = 0;
  3380. uiNumOfBytes = psFlash2xReadWrite->numOfBytes;
  3381. if (IsSectionExistInFlash(Adapter, psFlash2xReadWrite->Section) != TRUE) {
  3382. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%x> does not exist in Flash", psFlash2xReadWrite->Section);
  3383. return false;
  3384. }
  3385. uiSectStartOffset = BcmGetSectionValStartOffset(Adapter, psFlash2xReadWrite->Section);
  3386. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n", uiSectStartOffset, psFlash2xReadWrite->Section);
  3387. if ((psFlash2xReadWrite->Section == ISO_IMAGE1) || (psFlash2xReadWrite->Section == ISO_IMAGE2)) {
  3388. if (psFlash2xReadWrite->Section == ISO_IMAGE1) {
  3389. uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1) -
  3390. BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) +
  3391. BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART2) -
  3392. BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART2) +
  3393. BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART3) -
  3394. BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART3);
  3395. } else if (psFlash2xReadWrite->Section == ISO_IMAGE2) {
  3396. uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2) -
  3397. BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2) +
  3398. BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART2) -
  3399. BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART2) +
  3400. BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART3) -
  3401. BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART3);
  3402. }
  3403. /* since this uiSectEndoffset is the size of iso Image. hence for calculating the virtual endoffset
  3404. * it should be added in startoffset. so that check done in last of this function can be valued.
  3405. */
  3406. uiSectEndOffset = uiSectStartOffset + uiSectEndOffset;
  3407. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Total size of the ISO Image :%x", uiSectEndOffset);
  3408. } else
  3409. uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, psFlash2xReadWrite->Section);
  3410. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x\n", uiSectEndOffset);
  3411. /* psFlash2xReadWrite->offset and uiNumOfBytes are user controlled and can lead to integer overflows */
  3412. if (psFlash2xReadWrite->offset > uiSectEndOffset) {
  3413. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request....");
  3414. return false;
  3415. }
  3416. if (uiNumOfBytes > uiSectEndOffset) {
  3417. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request....");
  3418. return false;
  3419. }
  3420. /* Checking the boundary condition */
  3421. if ((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset)
  3422. return TRUE;
  3423. else {
  3424. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request....");
  3425. return false;
  3426. }
  3427. }
  3428. /*
  3429. * IsFlash2x :- check for Flash 2.x
  3430. * Adapater :- Bcm Driver Private Data Structure
  3431. *
  3432. * Return value:-
  3433. * return TRUE if flah2.x of hgher version else return false.
  3434. */
  3435. int IsFlash2x(struct bcm_mini_adapter *Adapter)
  3436. {
  3437. if (Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER)
  3438. return TRUE;
  3439. else
  3440. return false;
  3441. }
  3442. /*
  3443. * GetFlashBaseAddr :- Calculate the Flash Base address
  3444. * @Adapater :- Bcm Driver Private Data Structure
  3445. *
  3446. * Return Value:-
  3447. * Success :- Base Address of the Flash
  3448. */
  3449. static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter)
  3450. {
  3451. unsigned int uiBaseAddr = 0;
  3452. if (Adapter->bDDRInitDone) {
  3453. /*
  3454. * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
  3455. * In case of Raw Read... use the default value
  3456. */
  3457. if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == false) &&
  3458. !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
  3459. uiBaseAddr = Adapter->uiFlashBaseAdd;
  3460. else
  3461. uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT;
  3462. } else {
  3463. /*
  3464. * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
  3465. * In case of Raw Read... use the default value
  3466. */
  3467. if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == false) &&
  3468. !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
  3469. uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
  3470. else
  3471. uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
  3472. }
  3473. return uiBaseAddr;
  3474. }
  3475. /*
  3476. * BcmCopySection :- This API is used to copy the One section in another. Both section should
  3477. * be contiuous and of same size. Hence this Will not be applicabe to copy ISO.
  3478. *
  3479. * @Adapater :- Bcm Driver Private Data Structure
  3480. * @SrcSection :- Source section From where data has to be copied
  3481. * @DstSection :- Destination section to which data has to be copied
  3482. * @offset :- Offset from/to where data has to be copied from one section to another.
  3483. * @numOfBytes :- number of byes that has to be copyed from one section to another at given offset.
  3484. * in case of numofBytes equal zero complete section will be copied.
  3485. * Return Values-
  3486. * Success : Return STATUS_SUCCESS
  3487. * Faillure :- return negative error code
  3488. */
  3489. int BcmCopySection(struct bcm_mini_adapter *Adapter,
  3490. enum bcm_flash2x_section_val SrcSection,
  3491. enum bcm_flash2x_section_val DstSection,
  3492. unsigned int offset,
  3493. unsigned int numOfBytes)
  3494. {
  3495. unsigned int BuffSize = 0;
  3496. unsigned int BytesToBeCopied = 0;
  3497. PUCHAR pBuff = NULL;
  3498. int Status = STATUS_SUCCESS;
  3499. if (SrcSection == DstSection) {
  3500. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source and Destination should be different ...try again");
  3501. return -EINVAL;
  3502. }
  3503. if ((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2)) {
  3504. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source should be DSD subsection");
  3505. return -EINVAL;
  3506. }
  3507. if ((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2)) {
  3508. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destination should be DSD subsection");
  3509. return -EINVAL;
  3510. }
  3511. /* if offset zero means have to copy complete secton */
  3512. if (numOfBytes == 0) {
  3513. numOfBytes = BcmGetSectionValEndOffset(Adapter, SrcSection)
  3514. - BcmGetSectionValStartOffset(Adapter, SrcSection);
  3515. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Section Size :0x%x", numOfBytes);
  3516. }
  3517. if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, SrcSection)
  3518. - BcmGetSectionValStartOffset(Adapter, SrcSection)) {
  3519. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, " Input parameters going beyond the section offS: %x numB: %x of Source Section\n",
  3520. offset, numOfBytes);
  3521. return -EINVAL;
  3522. }
  3523. if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, DstSection)
  3524. - BcmGetSectionValStartOffset(Adapter, DstSection)) {
  3525. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Input parameters going beyond the section offS: %x numB: %x of Destination Section\n",
  3526. offset, numOfBytes);
  3527. return -EINVAL;
  3528. }
  3529. if (numOfBytes > Adapter->uiSectorSize)
  3530. BuffSize = Adapter->uiSectorSize;
  3531. else
  3532. BuffSize = numOfBytes;
  3533. pBuff = kzalloc(BuffSize, GFP_KERNEL);
  3534. if (!pBuff) {
  3535. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed.. ");
  3536. return -ENOMEM;
  3537. }
  3538. BytesToBeCopied = Adapter->uiSectorSize;
  3539. if (offset % Adapter->uiSectorSize)
  3540. BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize);
  3541. if (BytesToBeCopied > numOfBytes)
  3542. BytesToBeCopied = numOfBytes;
  3543. Adapter->bHeaderChangeAllowed = TRUE;
  3544. do {
  3545. Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset, BytesToBeCopied);
  3546. if (Status) {
  3547. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection, BytesToBeCopied);
  3548. break;
  3549. }
  3550. Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pBuff, DstSection, offset, BytesToBeCopied, false);
  3551. if (Status) {
  3552. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection, BytesToBeCopied);
  3553. break;
  3554. }
  3555. offset = offset + BytesToBeCopied;
  3556. numOfBytes = numOfBytes - BytesToBeCopied;
  3557. if (numOfBytes) {
  3558. if (numOfBytes > Adapter->uiSectorSize)
  3559. BytesToBeCopied = Adapter->uiSectorSize;
  3560. else
  3561. BytesToBeCopied = numOfBytes;
  3562. }
  3563. } while (numOfBytes > 0);
  3564. kfree(pBuff);
  3565. Adapter->bHeaderChangeAllowed = false;
  3566. return Status;
  3567. }
  3568. /*
  3569. * SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write
  3570. * @Adapater :- Bcm Driver Private Data Structure
  3571. * @pBuff :- Data buffer that has to be written in sector having the header map.
  3572. * @uiOffset :- Flash offset that has to be written.
  3573. *
  3574. * Return value :-
  3575. * Success :- On success return STATUS_SUCCESS
  3576. * Faillure :- Return negative error code
  3577. */
  3578. static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiOffset)
  3579. {
  3580. unsigned int offsetToProtect = 0, HeaderSizeToProtect = 0;
  3581. bool bHasHeader = false;
  3582. PUCHAR pTempBuff = NULL;
  3583. unsigned int uiSectAlignAddr = 0;
  3584. unsigned int sig = 0;
  3585. /* making the offset sector aligned */
  3586. uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
  3587. if ((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD2) - Adapter->uiSectorSize) ||
  3588. (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD1) - Adapter->uiSectorSize) ||
  3589. (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD0) - Adapter->uiSectorSize)) {
  3590. /* offset from the sector boundary having the header map */
  3591. offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize;
  3592. HeaderSizeToProtect = sizeof(struct bcm_dsd_header);
  3593. bHasHeader = TRUE;
  3594. }
  3595. if (uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) ||
  3596. uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2)) {
  3597. offsetToProtect = 0;
  3598. HeaderSizeToProtect = sizeof(struct bcm_iso_header);
  3599. bHasHeader = TRUE;
  3600. }
  3601. /* If Header is present overwrite passed buffer with this */
  3602. if (bHasHeader && (Adapter->bHeaderChangeAllowed == false)) {
  3603. pTempBuff = kzalloc(HeaderSizeToProtect, GFP_KERNEL);
  3604. if (!pTempBuff) {
  3605. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed");
  3606. return -ENOMEM;
  3607. }
  3608. /* Read header */
  3609. BeceemFlashBulkRead(Adapter, (PUINT)pTempBuff, (uiSectAlignAddr + offsetToProtect), HeaderSizeToProtect);
  3610. BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pTempBuff, HeaderSizeToProtect);
  3611. /* Replace Buffer content with Header */
  3612. memcpy(pBuff + offsetToProtect, pTempBuff, HeaderSizeToProtect);
  3613. kfree(pTempBuff);
  3614. }
  3615. if (bHasHeader && Adapter->bSigCorrupted) {
  3616. sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber)));
  3617. sig = ntohl(sig);
  3618. if ((sig & 0xFF000000) != CORRUPTED_PATTERN) {
  3619. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Desired pattern is not at sig offset. Hence won't restore");
  3620. Adapter->bSigCorrupted = false;
  3621. return STATUS_SUCCESS;
  3622. }
  3623. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Corrupted sig is :%X", sig);
  3624. *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber))) = htonl(DSD_IMAGE_MAGIC_NUMBER);
  3625. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature in Header Write only");
  3626. Adapter->bSigCorrupted = false;
  3627. }
  3628. return STATUS_SUCCESS;
  3629. }
  3630. /*
  3631. * BcmDoChipSelect : This will selcet the appropriate chip for writing.
  3632. * @Adapater :- Bcm Driver Private Data Structure
  3633. *
  3634. * OutPut:-
  3635. * Select the Appropriate chip and retrn status Success
  3636. */
  3637. static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset)
  3638. {
  3639. unsigned int FlashConfig = 0;
  3640. int ChipNum = 0;
  3641. unsigned int GPIOConfig = 0;
  3642. unsigned int PartNum = 0;
  3643. ChipNum = offset / FLASH_PART_SIZE;
  3644. /*
  3645. * Chip Select mapping to enable flash0.
  3646. * To select flash 0, we have to OR with (0<<12).
  3647. * ORing 0 will have no impact so not doing that part.
  3648. * In future if Chip select value changes from 0 to non zero,
  3649. * That needs be taken care with backward comaptibility. No worries for now.
  3650. */
  3651. /*
  3652. * SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured
  3653. * if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken)
  3654. * Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from
  3655. * power down modes (Idle mode/shutdown mode), the values in the register will be different.
  3656. */
  3657. if (Adapter->SelectedChip == ChipNum)
  3658. return STATUS_SUCCESS;
  3659. /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum); */
  3660. Adapter->SelectedChip = ChipNum;
  3661. /* bit[13..12] will select the appropriate chip */
  3662. rdmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4);
  3663. rdmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
  3664. {
  3665. switch (ChipNum) {
  3666. case 0:
  3667. PartNum = 0;
  3668. break;
  3669. case 1:
  3670. PartNum = 3;
  3671. GPIOConfig |= (0x4 << CHIP_SELECT_BIT12);
  3672. break;
  3673. case 2:
  3674. PartNum = 1;
  3675. GPIOConfig |= (0x1 << CHIP_SELECT_BIT12);
  3676. break;
  3677. case 3:
  3678. PartNum = 2;
  3679. GPIOConfig |= (0x2 << CHIP_SELECT_BIT12);
  3680. break;
  3681. }
  3682. }
  3683. /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired,
  3684. * nothing to do... can return immediately.
  3685. * ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG.
  3686. * Even if the chip goes to low power mode, it should wake with values in each register in sync with each other.
  3687. * These values are not written by host other than during CHIP_SELECT.
  3688. */
  3689. if (PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3))
  3690. return STATUS_SUCCESS;
  3691. /* clearing the bit[13..12] */
  3692. FlashConfig &= 0xFFFFCFFF;
  3693. FlashConfig = (FlashConfig | (PartNum<<CHIP_SELECT_BIT12)); /* 00 */
  3694. wrmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
  3695. udelay(100);
  3696. wrmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4);
  3697. udelay(100);
  3698. return STATUS_SUCCESS;
  3699. }
  3700. static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
  3701. {
  3702. unsigned int uiDSDsig = 0;
  3703. /* unsigned int sigoffsetInMap = 0;
  3704. * struct bcm_dsd_header dsdHeader = {0};
  3705. */
  3706. /* sigoffsetInMap =(PUCHAR)&(dsdHeader.DSDImageMagicNumber) -(PUCHAR)&dsdHeader; */
  3707. if (dsd != DSD0 && dsd != DSD1 && dsd != DSD2) {
  3708. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for DSDs");
  3709. return STATUS_FAILURE;
  3710. }
  3711. BcmFlash2xBulkRead(Adapter,
  3712. &uiDSDsig,
  3713. dsd,
  3714. Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber),
  3715. SIGNATURE_SIZE);
  3716. uiDSDsig = ntohl(uiDSDsig);
  3717. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD SIG :%x", uiDSDsig);
  3718. return uiDSDsig;
  3719. }
  3720. static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
  3721. {
  3722. /* unsigned int priOffsetInMap = 0 ; */
  3723. unsigned int uiDSDPri = STATUS_FAILURE;
  3724. /* struct bcm_dsd_header dsdHeader = {0};
  3725. * priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader;
  3726. */
  3727. if (IsSectionWritable(Adapter, dsd)) {
  3728. if (ReadDSDSignature(Adapter, dsd) == DSD_IMAGE_MAGIC_NUMBER) {
  3729. BcmFlash2xBulkRead(Adapter,
  3730. &uiDSDPri,
  3731. dsd,
  3732. Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority),
  3733. 4);
  3734. uiDSDPri = ntohl(uiDSDPri);
  3735. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD<%x> Priority :%x", dsd, uiDSDPri);
  3736. }
  3737. }
  3738. return uiDSDPri;
  3739. }
  3740. static enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter)
  3741. {
  3742. int DSDHighestPri = STATUS_FAILURE;
  3743. int DsdPri = 0;
  3744. enum bcm_flash2x_section_val HighestPriDSD = 0;
  3745. if (IsSectionWritable(Adapter, DSD2)) {
  3746. DSDHighestPri = ReadDSDPriority(Adapter, DSD2);
  3747. HighestPriDSD = DSD2;
  3748. }
  3749. if (IsSectionWritable(Adapter, DSD1)) {
  3750. DsdPri = ReadDSDPriority(Adapter, DSD1);
  3751. if (DSDHighestPri < DsdPri) {
  3752. DSDHighestPri = DsdPri;
  3753. HighestPriDSD = DSD1;
  3754. }
  3755. }
  3756. if (IsSectionWritable(Adapter, DSD0)) {
  3757. DsdPri = ReadDSDPriority(Adapter, DSD0);
  3758. if (DSDHighestPri < DsdPri) {
  3759. DSDHighestPri = DsdPri;
  3760. HighestPriDSD = DSD0;
  3761. }
  3762. }
  3763. if (HighestPriDSD)
  3764. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest DSD :%x , and its Pri :%x", HighestPriDSD, DSDHighestPri);
  3765. return HighestPriDSD;
  3766. }
  3767. static int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
  3768. {
  3769. unsigned int uiISOsig = 0;
  3770. /* unsigned int sigoffsetInMap = 0;
  3771. * struct bcm_iso_header ISOHeader = {0};
  3772. * sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader;
  3773. */
  3774. if (iso != ISO_IMAGE1 && iso != ISO_IMAGE2) {
  3775. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for ISOs");
  3776. return STATUS_FAILURE;
  3777. }
  3778. BcmFlash2xBulkRead(Adapter,
  3779. &uiISOsig,
  3780. iso,
  3781. 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber),
  3782. SIGNATURE_SIZE);
  3783. uiISOsig = ntohl(uiISOsig);
  3784. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO SIG :%x", uiISOsig);
  3785. return uiISOsig;
  3786. }
  3787. static int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
  3788. {
  3789. unsigned int ISOPri = STATUS_FAILURE;
  3790. if (IsSectionWritable(Adapter, iso)) {
  3791. if (ReadISOSignature(Adapter, iso) == ISO_IMAGE_MAGIC_NUMBER) {
  3792. BcmFlash2xBulkRead(Adapter,
  3793. &ISOPri,
  3794. iso,
  3795. 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority),
  3796. 4);
  3797. ISOPri = ntohl(ISOPri);
  3798. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO<%x> Priority :%x", iso, ISOPri);
  3799. }
  3800. }
  3801. return ISOPri;
  3802. }
  3803. static enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter)
  3804. {
  3805. int ISOHighestPri = STATUS_FAILURE;
  3806. int ISOPri = 0;
  3807. enum bcm_flash2x_section_val HighestPriISO = NO_SECTION_VAL;
  3808. if (IsSectionWritable(Adapter, ISO_IMAGE2)) {
  3809. ISOHighestPri = ReadISOPriority(Adapter, ISO_IMAGE2);
  3810. HighestPriISO = ISO_IMAGE2;
  3811. }
  3812. if (IsSectionWritable(Adapter, ISO_IMAGE1)) {
  3813. ISOPri = ReadISOPriority(Adapter, ISO_IMAGE1);
  3814. if (ISOHighestPri < ISOPri) {
  3815. ISOHighestPri = ISOPri;
  3816. HighestPriISO = ISO_IMAGE1;
  3817. }
  3818. }
  3819. if (HighestPriISO)
  3820. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest ISO :%x and its Pri :%x", HighestPriISO, ISOHighestPri);
  3821. return HighestPriISO;
  3822. }
  3823. static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
  3824. PUINT pBuff,
  3825. enum bcm_flash2x_section_val eFlash2xSectionVal,
  3826. unsigned int uiOffset,
  3827. unsigned int uiNumBytes)
  3828. {
  3829. #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
  3830. unsigned int uiTemp = 0, value = 0;
  3831. unsigned int i = 0;
  3832. unsigned int uiPartOffset = 0;
  3833. #endif
  3834. unsigned int uiStartOffset = 0;
  3835. /* Adding section start address */
  3836. int Status = STATUS_SUCCESS;
  3837. PUCHAR pcBuff = (PUCHAR)pBuff;
  3838. if (uiNumBytes % Adapter->ulFlashWriteSize) {
  3839. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes);
  3840. return STATUS_FAILURE;
  3841. }
  3842. uiStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal);
  3843. if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
  3844. return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes);
  3845. uiOffset = uiOffset + uiStartOffset;
  3846. #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
  3847. Status = bcmflash_raw_writenoerase((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), pcBuff, uiNumBytes);
  3848. #else
  3849. rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
  3850. value = 0;
  3851. wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
  3852. Adapter->SelectedChip = RESET_CHIP_SELECT;
  3853. BcmDoChipSelect(Adapter, uiOffset);
  3854. uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
  3855. for (i = 0; i < uiNumBytes; i += Adapter->ulFlashWriteSize) {
  3856. if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
  3857. Status = flashByteWrite(Adapter, uiPartOffset, pcBuff);
  3858. else
  3859. Status = flashWrite(Adapter, uiPartOffset, pcBuff);
  3860. if (Status != STATUS_SUCCESS)
  3861. break;
  3862. pcBuff = pcBuff + Adapter->ulFlashWriteSize;
  3863. uiPartOffset = uiPartOffset + Adapter->ulFlashWriteSize;
  3864. }
  3865. wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
  3866. Adapter->SelectedChip = RESET_CHIP_SELECT;
  3867. #endif
  3868. return Status;
  3869. }
  3870. bool IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section)
  3871. {
  3872. bool SectionPresent = false;
  3873. switch (section) {
  3874. case ISO_IMAGE1:
  3875. if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
  3876. (IsNonCDLessDevice(Adapter) == false))
  3877. SectionPresent = TRUE;
  3878. break;
  3879. case ISO_IMAGE2:
  3880. if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
  3881. (IsNonCDLessDevice(Adapter) == false))
  3882. SectionPresent = TRUE;
  3883. break;
  3884. case DSD0:
  3885. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
  3886. SectionPresent = TRUE;
  3887. break;
  3888. case DSD1:
  3889. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
  3890. SectionPresent = TRUE;
  3891. break;
  3892. case DSD2:
  3893. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
  3894. SectionPresent = TRUE;
  3895. break;
  3896. case VSA0:
  3897. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
  3898. SectionPresent = TRUE;
  3899. break;
  3900. case VSA1:
  3901. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
  3902. SectionPresent = TRUE;
  3903. break;
  3904. case VSA2:
  3905. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
  3906. SectionPresent = TRUE;
  3907. break;
  3908. case SCSI:
  3909. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
  3910. SectionPresent = TRUE;
  3911. break;
  3912. case CONTROL_SECTION:
  3913. if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
  3914. SectionPresent = TRUE;
  3915. break;
  3916. default:
  3917. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x");
  3918. SectionPresent = false;
  3919. }
  3920. return SectionPresent;
  3921. }
  3922. static int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section)
  3923. {
  3924. int offset = STATUS_FAILURE;
  3925. int Status = false;
  3926. if (IsSectionExistInFlash(Adapter, Section) == false) {
  3927. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section <%d> does not exist", Section);
  3928. return false;
  3929. }
  3930. offset = BcmGetSectionValStartOffset(Adapter, Section);
  3931. if (offset == INVALID_OFFSET) {
  3932. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%d> does not exist", Section);
  3933. return false;
  3934. }
  3935. if (IsSectionExistInVendorInfo(Adapter, Section))
  3936. return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO);
  3937. Status = IsOffsetWritable(Adapter, offset);
  3938. return Status;
  3939. }
  3940. static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
  3941. {
  3942. PUCHAR pBuff = NULL;
  3943. unsigned int sig = 0;
  3944. unsigned int uiOffset = 0;
  3945. unsigned int BlockStatus = 0;
  3946. unsigned int uiSectAlignAddr = 0;
  3947. Adapter->bSigCorrupted = false;
  3948. if (Adapter->bAllDSDWriteAllow == false) {
  3949. if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) {
  3950. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature");
  3951. return SECTOR_IS_NOT_WRITABLE;
  3952. }
  3953. }
  3954. pBuff = kzalloc(MAX_RW_SIZE, GFP_KERNEL);
  3955. if (!pBuff) {
  3956. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
  3957. return -ENOMEM;
  3958. }
  3959. uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header);
  3960. uiOffset -= MAX_RW_SIZE;
  3961. BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE);
  3962. sig = *((PUINT)(pBuff + 12));
  3963. sig = ntohl(sig);
  3964. BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE);
  3965. /* Now corrupting the sig by corrupting 4th last Byte. */
  3966. *(pBuff + 12) = 0;
  3967. if (sig == DSD_IMAGE_MAGIC_NUMBER) {
  3968. Adapter->bSigCorrupted = TRUE;
  3969. if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) {
  3970. uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
  3971. BlockStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize);
  3972. WriteToFlashWithoutSectorErase(Adapter, (PUINT)(pBuff + 12), eFlash2xSectionVal,
  3973. (uiOffset + 12), BYTE_WRITE_SUPPORT);
  3974. if (BlockStatus) {
  3975. BcmRestoreBlockProtectStatus(Adapter, BlockStatus);
  3976. BlockStatus = 0;
  3977. }
  3978. } else {
  3979. WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal,
  3980. uiOffset, MAX_RW_SIZE);
  3981. }
  3982. } else {
  3983. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header");
  3984. kfree(pBuff);
  3985. return STATUS_FAILURE;
  3986. }
  3987. kfree(pBuff);
  3988. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature");
  3989. return STATUS_SUCCESS;
  3990. }
  3991. static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
  3992. {
  3993. PUCHAR pBuff = NULL;
  3994. unsigned int sig = 0;
  3995. unsigned int uiOffset = 0;
  3996. Adapter->bSigCorrupted = false;
  3997. if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) {
  3998. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature");
  3999. return SECTOR_IS_NOT_WRITABLE;
  4000. }
  4001. pBuff = kzalloc(MAX_RW_SIZE, GFP_KERNEL);
  4002. if (!pBuff) {
  4003. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
  4004. return -ENOMEM;
  4005. }
  4006. uiOffset = 0;
  4007. BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE);
  4008. sig = *((PUINT)pBuff);
  4009. sig = ntohl(sig);
  4010. /* corrupt signature */
  4011. *pBuff = 0;
  4012. if (sig == ISO_IMAGE_MAGIC_NUMBER) {
  4013. Adapter->bSigCorrupted = TRUE;
  4014. WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal,
  4015. uiOffset, Adapter->ulFlashWriteSize);
  4016. } else {
  4017. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header");
  4018. kfree(pBuff);
  4019. return STATUS_FAILURE;
  4020. }
  4021. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature");
  4022. BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE);
  4023. kfree(pBuff);
  4024. return STATUS_SUCCESS;
  4025. }
  4026. bool IsNonCDLessDevice(struct bcm_mini_adapter *Adapter)
  4027. {
  4028. if (Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG)
  4029. return TRUE;
  4030. else
  4031. return false;
  4032. }