cpqfcTScontrol.c 73 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231
  1. /* Copyright 2000, Compaq Computer Corporation
  2. * Fibre Channel Host Bus Adapter
  3. * 64-bit, 66MHz PCI
  4. * Originally developed and tested on:
  5. * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ...
  6. * SP# P225CXCBFIEL6T, Rev XC
  7. * SP# 161290-001, Rev XD
  8. * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5
  9. *
  10. * This program is free software; you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License as published by the
  12. * Free Software Foundation; either version 2, or (at your option) any
  13. * later version.
  14. *
  15. * This program is distributed in the hope that it will be useful, but
  16. * WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * General Public License for more details.
  19. * Written by Don Zimmerman
  20. */
  21. /* These functions control the host bus adapter (HBA) hardware. The main chip
  22. control takes place in the interrupt handler where we process the IMQ
  23. (Inbound Message Queue). The IMQ is Tachyon's way of communicating FC link
  24. events and state information to the driver. The Single Frame Queue (SFQ)
  25. buffers incoming FC frames for processing by the driver. References to
  26. "TL/TS UG" are for:
  27. "HP HPFC-5100/5166 Tachyon TL/TS ICs User Guide", August 16, 1999, 1st Ed.
  28. Hewlitt Packard Manual Part Number 5968-1083E.
  29. */
  30. #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
  31. #include <linux/blkdev.h>
  32. #include <linux/kernel.h>
  33. #include <linux/string.h>
  34. #include <linux/ioport.h> // request_region() prototype
  35. #include <linux/sched.h>
  36. #include <linux/slab.h> // need "kfree" for ext. S/G pages
  37. #include <linux/types.h>
  38. #include <linux/pci.h>
  39. #include <linux/delay.h>
  40. #include <linux/unistd.h>
  41. #include <asm/io.h> // struct pt_regs for IRQ handler & Port I/O
  42. #include <asm/irq.h>
  43. #include <linux/spinlock.h>
  44. #include "scsi.h"
  45. #include <scsi/scsi_host.h> // Scsi_Host definition for INT handler
  46. #include "cpqfcTSchip.h"
  47. #include "cpqfcTSstructs.h"
  48. //#define IMQ_DEBUG 1
  49. static void fcParseLinkStatusCounters(TACHYON * fcChip);
  50. static void CpqTsGetSFQEntry(TACHYON * fcChip,
  51. USHORT pi, ULONG * buffr, BOOLEAN UpdateChip);
  52. static void
  53. cpqfc_free_dma_consistent(CPQFCHBA *cpqfcHBAdata)
  54. {
  55. // free up the primary EXCHANGES struct and Link Q
  56. PTACHYON fcChip = &cpqfcHBAdata->fcChip;
  57. if (fcChip->Exchanges != NULL)
  58. pci_free_consistent(cpqfcHBAdata->PciDev, sizeof(FC_EXCHANGES),
  59. fcChip->Exchanges, fcChip->exch_dma_handle);
  60. fcChip->Exchanges = NULL;
  61. if (cpqfcHBAdata->fcLQ != NULL)
  62. pci_free_consistent(cpqfcHBAdata->PciDev, sizeof(FC_LINK_QUE),
  63. cpqfcHBAdata->fcLQ, cpqfcHBAdata->fcLQ_dma_handle);
  64. cpqfcHBAdata->fcLQ = NULL;
  65. }
  66. // Note special requirements for Q alignment! (TL/TS UG pg. 190)
  67. // We place critical index pointers at end of QUE elements to assist
  68. // in non-symbolic (i.e. memory dump) debugging
  69. // opcode defines placement of Queues (e.g. local/external RAM)
  70. int CpqTsCreateTachLiteQues( void* pHBA, int opcode)
  71. {
  72. CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA;
  73. PTACHYON fcChip = &cpqfcHBAdata->fcChip;
  74. int iStatus=0;
  75. unsigned long ulAddr;
  76. dma_addr_t ERQdma, IMQdma, SPQdma, SESTdma;
  77. int i;
  78. // NOTE! fcMemManager() will return system virtual addresses.
  79. // System (kernel) virtual addresses, though non-paged, still
  80. // aren't physical addresses. Convert to PHYSICAL_ADDRESS for Tachyon's
  81. // DMA use.
  82. ENTER("CreateTachLiteQues");
  83. // Allocate primary EXCHANGES array...
  84. fcChip->Exchanges = NULL;
  85. cpqfcHBAdata->fcLQ = NULL;
  86. /* printk("Allocating %u for %u Exchanges ",
  87. (ULONG)sizeof(FC_EXCHANGES), TACH_MAX_XID); */
  88. fcChip->Exchanges = pci_alloc_consistent(cpqfcHBAdata->PciDev,
  89. sizeof(FC_EXCHANGES), &fcChip->exch_dma_handle);
  90. /* printk("@ %p\n", fcChip->Exchanges); */
  91. if( fcChip->Exchanges == NULL ) // fatal error!!
  92. {
  93. printk("pci_alloc_consistent failure on Exchanges: fatal error\n");
  94. return -1;
  95. }
  96. // zero out the entire EXCHANGE space
  97. memset( fcChip->Exchanges, 0, sizeof( FC_EXCHANGES));
  98. /* printk("Allocating %u for LinkQ ", (ULONG)sizeof(FC_LINK_QUE)); */
  99. cpqfcHBAdata->fcLQ = pci_alloc_consistent(cpqfcHBAdata->PciDev,
  100. sizeof( FC_LINK_QUE), &cpqfcHBAdata->fcLQ_dma_handle);
  101. /* printk("@ %p (%u elements)\n", cpqfcHBAdata->fcLQ, FC_LINKQ_DEPTH); */
  102. if( cpqfcHBAdata->fcLQ == NULL ) // fatal error!!
  103. {
  104. cpqfc_free_dma_consistent(cpqfcHBAdata);
  105. printk("pci_alloc_consistent() failure on fc Link Que: fatal error\n");
  106. return -1;
  107. }
  108. // zero out the entire EXCHANGE space
  109. memset( cpqfcHBAdata->fcLQ, 0, sizeof( FC_LINK_QUE));
  110. // Verify that basic Tach I/O registers are not NULL
  111. if( !fcChip->Registers.ReMapMemBase )
  112. {
  113. cpqfc_free_dma_consistent(cpqfcHBAdata);
  114. printk("HBA base address NULL: fatal error\n");
  115. return -1;
  116. }
  117. // Initialize the fcMemManager memory pairs (stores allocated/aligned
  118. // pairs for future freeing)
  119. memset( cpqfcHBAdata->dynamic_mem, 0, sizeof(cpqfcHBAdata->dynamic_mem));
  120. // Allocate Tach's Exchange Request Queue (each ERQ entry 32 bytes)
  121. fcChip->ERQ = fcMemManager( cpqfcHBAdata->PciDev,
  122. &cpqfcHBAdata->dynamic_mem[0],
  123. sizeof( TachLiteERQ ), 32*(ERQ_LEN), 0L, &ERQdma);
  124. if( !fcChip->ERQ )
  125. {
  126. cpqfc_free_dma_consistent(cpqfcHBAdata);
  127. printk("pci_alloc_consistent/alignment failure on ERQ: fatal error\n");
  128. return -1;
  129. }
  130. fcChip->ERQ->length = ERQ_LEN-1;
  131. ulAddr = (ULONG) ERQdma;
  132. #if BITS_PER_LONG > 32
  133. if( (ulAddr >> 32) )
  134. {
  135. cpqfc_free_dma_consistent(cpqfcHBAdata);
  136. printk(" FATAL! ERQ ptr %p exceeds Tachyon's 32-bit register size\n",
  137. (void*)ulAddr);
  138. return -1; // failed
  139. }
  140. #endif
  141. fcChip->ERQ->base = (ULONG)ulAddr; // copy for quick reference
  142. // Allocate Tach's Inbound Message Queue (32 bytes per entry)
  143. fcChip->IMQ = fcMemManager( cpqfcHBAdata->PciDev,
  144. &cpqfcHBAdata->dynamic_mem[0],
  145. sizeof( TachyonIMQ ), 32*(IMQ_LEN), 0L, &IMQdma );
  146. if( !fcChip->IMQ )
  147. {
  148. cpqfc_free_dma_consistent(cpqfcHBAdata);
  149. printk("pci_alloc_consistent/alignment failure on IMQ: fatal error\n");
  150. return -1;
  151. }
  152. fcChip->IMQ->length = IMQ_LEN-1;
  153. ulAddr = IMQdma;
  154. #if BITS_PER_LONG > 32
  155. if( (ulAddr >> 32) )
  156. {
  157. cpqfc_free_dma_consistent(cpqfcHBAdata);
  158. printk(" FATAL! IMQ ptr %p exceeds Tachyon's 32-bit register size\n",
  159. (void*)ulAddr);
  160. return -1; // failed
  161. }
  162. #endif
  163. fcChip->IMQ->base = (ULONG)ulAddr; // copy for quick reference
  164. // Allocate Tach's Single Frame Queue (64 bytes per entry)
  165. fcChip->SFQ = fcMemManager( cpqfcHBAdata->PciDev,
  166. &cpqfcHBAdata->dynamic_mem[0],
  167. sizeof( TachLiteSFQ ), 64*(SFQ_LEN),0L, &SPQdma );
  168. if( !fcChip->SFQ )
  169. {
  170. cpqfc_free_dma_consistent(cpqfcHBAdata);
  171. printk("pci_alloc_consistent/alignment failure on SFQ: fatal error\n");
  172. return -1;
  173. }
  174. fcChip->SFQ->length = SFQ_LEN-1; // i.e. Que length [# entries -
  175. // min. 32; max. 4096 (0xffff)]
  176. ulAddr = SPQdma;
  177. #if BITS_PER_LONG > 32
  178. if( (ulAddr >> 32) )
  179. {
  180. cpqfc_free_dma_consistent(cpqfcHBAdata);
  181. printk(" FATAL! SFQ ptr %p exceeds Tachyon's 32-bit register size\n",
  182. (void*)ulAddr);
  183. return -1; // failed
  184. }
  185. #endif
  186. fcChip->SFQ->base = (ULONG)ulAddr; // copy for quick reference
  187. // Allocate SCSI Exchange State Table; aligned nearest @sizeof
  188. // power-of-2 boundary
  189. // LIVE DANGEROUSLY! Assume the boundary for SEST mem will
  190. // be on physical page (e.g. 4k) boundary.
  191. /* printk("Allocating %u for TachSEST for %u Exchanges\n",
  192. (ULONG)sizeof(TachSEST), TACH_SEST_LEN); */
  193. fcChip->SEST = fcMemManager( cpqfcHBAdata->PciDev,
  194. &cpqfcHBAdata->dynamic_mem[0],
  195. sizeof(TachSEST), 4, 0L, &SESTdma );
  196. // sizeof(TachSEST), 64*TACH_SEST_LEN, 0L );
  197. if( !fcChip->SEST )
  198. {
  199. cpqfc_free_dma_consistent(cpqfcHBAdata);
  200. printk("pci_alloc_consistent/alignment failure on SEST: fatal error\n");
  201. return -1;
  202. }
  203. for( i=0; i < TACH_SEST_LEN; i++) // for each exchange
  204. fcChip->SEST->sgPages[i] = NULL;
  205. fcChip->SEST->length = TACH_SEST_LEN; // e.g. DON'T subtract one
  206. // (TL/TS UG, pg 153)
  207. ulAddr = SESTdma;
  208. #if BITS_PER_LONG > 32
  209. if( (ulAddr >> 32) )
  210. {
  211. cpqfc_free_dma_consistent(cpqfcHBAdata);
  212. printk(" FATAL! SFQ ptr %p exceeds Tachyon's 32-bit register size\n",
  213. (void*)ulAddr);
  214. return -1; // failed
  215. }
  216. #endif
  217. fcChip->SEST->base = (ULONG)ulAddr; // copy for quick reference
  218. // Now that structures are defined,
  219. // fill in Tachyon chip registers...
  220. // EEEEEEEE EXCHANGE REQUEST QUEUE
  221. writel( fcChip->ERQ->base,
  222. (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_BASE));
  223. writel( fcChip->ERQ->length,
  224. (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_LENGTH));
  225. fcChip->ERQ->producerIndex = 0L;
  226. writel( fcChip->ERQ->producerIndex,
  227. (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_PRODUCER_INDEX));
  228. // NOTE! write consumer index last, since the write
  229. // causes Tachyon to process the other registers
  230. ulAddr = ((unsigned long)&fcChip->ERQ->consumerIndex -
  231. (unsigned long)fcChip->ERQ) + (unsigned long) ERQdma;
  232. // NOTE! Tachyon DMAs to the ERQ consumer Index host
  233. // address; must be correctly aligned
  234. writel( (ULONG)ulAddr,
  235. (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_CONSUMER_INDEX_ADR));
  236. // IIIIIIIIIIIII INBOUND MESSAGE QUEUE
  237. // Tell Tachyon where the Que starts
  238. // set the Host's pointer for Tachyon to access
  239. /* printk(" cpqfcTS: writing IMQ BASE %Xh ", fcChip->IMQ->base ); */
  240. writel( fcChip->IMQ->base,
  241. (fcChip->Registers.ReMapMemBase + IMQ_BASE));
  242. writel( fcChip->IMQ->length,
  243. (fcChip->Registers.ReMapMemBase + IMQ_LENGTH));
  244. writel( fcChip->IMQ->consumerIndex,
  245. (fcChip->Registers.ReMapMemBase + IMQ_CONSUMER_INDEX));
  246. // NOTE: TachLite DMAs to the producerIndex host address
  247. // must be correctly aligned with address bits 1-0 cleared
  248. // Writing the BASE register clears the PI register, so write it last
  249. ulAddr = ((unsigned long)&fcChip->IMQ->producerIndex -
  250. (unsigned long)fcChip->IMQ) + (unsigned long) IMQdma;
  251. #if BITS_PER_LONG > 32
  252. if( (ulAddr >> 32) )
  253. {
  254. cpqfc_free_dma_consistent(cpqfcHBAdata);
  255. printk(" FATAL! IMQ ptr %p exceeds Tachyon's 32-bit register size\n",
  256. (void*)ulAddr);
  257. return -1; // failed
  258. }
  259. #endif
  260. #if DBG
  261. printk(" PI %Xh\n", (ULONG)ulAddr );
  262. #endif
  263. writel( (ULONG)ulAddr,
  264. (fcChip->Registers.ReMapMemBase + IMQ_PRODUCER_INDEX));
  265. // SSSSSSSSSSSSSSS SINGLE FRAME SEQUENCE
  266. // Tell TachLite where the Que starts
  267. writel( fcChip->SFQ->base,
  268. (fcChip->Registers.ReMapMemBase + TL_MEM_SFQ_BASE));
  269. writel( fcChip->SFQ->length,
  270. (fcChip->Registers.ReMapMemBase + TL_MEM_SFQ_LENGTH));
  271. // tell TachLite where SEST table is & how long
  272. writel( fcChip->SEST->base,
  273. (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_BASE));
  274. /* printk(" cpqfcTS: SEST %p(virt): Wrote base %Xh @ %p\n",
  275. fcChip->SEST, fcChip->SEST->base,
  276. fcChip->Registers.ReMapMemBase + TL_MEM_SEST_BASE); */
  277. writel( fcChip->SEST->length,
  278. (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_LENGTH));
  279. writel( (TL_EXT_SG_PAGE_COUNT-1),
  280. (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_SG_PAGE));
  281. LEAVE("CreateTachLiteQues");
  282. return iStatus;
  283. }
  284. // function to return TachLite to Power On state
  285. // 1st - reset tachyon ('SOFT' reset)
  286. // others - future
  287. int CpqTsResetTachLite(void *pHBA, int type)
  288. {
  289. CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA;
  290. PTACHYON fcChip = &cpqfcHBAdata->fcChip;
  291. ULONG ulBuff, i;
  292. int ret_status=0; // def. success
  293. ENTER("ResetTach");
  294. switch(type)
  295. {
  296. case CLEAR_FCPORTS:
  297. // in case he was running previously, mask Tach's interrupt
  298. writeb( 0, (fcChip->Registers.ReMapMemBase + IINTEN));
  299. // de-allocate mem for any Logged in ports
  300. // (e.g., our module is unloading)
  301. // search the forward linked list, de-allocating
  302. // the memory we allocated when the port was initially logged in
  303. {
  304. PFC_LOGGEDIN_PORT pLoggedInPort = fcChip->fcPorts.pNextPort;
  305. PFC_LOGGEDIN_PORT ptr;
  306. // printk("checking for allocated LoggedInPorts...\n");
  307. while( pLoggedInPort )
  308. {
  309. ptr = pLoggedInPort;
  310. pLoggedInPort = ptr->pNextPort;
  311. // printk("kfree(%p) on FC LoggedInPort port_id 0x%06lX\n",
  312. // ptr, ptr->port_id);
  313. kfree( ptr );
  314. }
  315. }
  316. // (continue resetting hardware...)
  317. case 1: // RESTART Tachyon (power-up state)
  318. // in case he was running previously, mask Tach's interrupt
  319. writeb( 0, (fcChip->Registers.ReMapMemBase + IINTEN));
  320. // turn OFF laser (NOTE: laser is turned
  321. // off during reset, because GPIO4 is cleared
  322. // to 0 by reset action - see TLUM, sec 7.22)
  323. // However, CPQ 64-bit HBAs have a "health
  324. // circuit" which keeps laser ON for a brief
  325. // period after it is turned off ( < 1s)
  326. fcChip->LaserControl( fcChip->Registers.ReMapMemBase, 0);
  327. // soft reset timing constraints require:
  328. // 1. set RST to 1
  329. // 2. read SOFTRST register
  330. // (128 times per R. Callison code)
  331. // 3. clear PCI ints
  332. // 4. clear RST to 0
  333. writel( 0xff000001L,
  334. (fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST));
  335. for( i=0; i<128; i++)
  336. ulBuff = readl( fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST);
  337. // clear the soft reset
  338. for( i=0; i<8; i++)
  339. writel( 0, (fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST));
  340. // clear out our copy of Tach regs,
  341. // because they must be invalid now,
  342. // since TachLite reset all his regs.
  343. CpqTsDestroyTachLiteQues(cpqfcHBAdata,0); // remove Host-based Que structs
  344. cpqfcTSClearLinkStatusCounters(fcChip); // clear our s/w accumulators
  345. // lower bits give GBIC info
  346. fcChip->Registers.TYstatus.value =
  347. readl( fcChip->Registers.TYstatus.address );
  348. break;
  349. /*
  350. case 2: // freeze SCSI
  351. case 3: // reset Outbound command que (ERQ)
  352. case 4: // unfreeze OSM (Outbound Seq. Man.) 'er'
  353. case 5: // report status
  354. break;
  355. */
  356. default:
  357. ret_status = -1; // invalid option passed to RESET function
  358. break;
  359. }
  360. LEAVE("ResetTach");
  361. return ret_status;
  362. }
  363. // 'addrBase' is IOBaseU for both TachLite and (older) Tachyon
  364. int CpqTsLaserControl( void* addrBase, int opcode )
  365. {
  366. ULONG dwBuff;
  367. dwBuff = readl((addrBase + TL_MEM_TACH_CONTROL) ); // read TL Control reg
  368. // (change only bit 4)
  369. if( opcode == 1)
  370. dwBuff |= ~0xffffffefL; // set - ON
  371. else
  372. dwBuff &= 0xffffffefL; // clear - OFF
  373. writel( dwBuff, (addrBase + TL_MEM_TACH_CONTROL)); // write TL Control reg
  374. return 0;
  375. }
  376. // Use controller's "Options" field to determine loopback mode (if any)
  377. // internal loopback (silicon - no GBIC)
  378. // external loopback (GBIC - no FC loop)
  379. // no loopback: L_PORT, external cable from GBIC required
  380. int CpqTsInitializeFrameManager( void *pChip, int opcode)
  381. {
  382. PTACHYON fcChip;
  383. int iStatus;
  384. ULONG wwnLo, wwnHi; // for readback verification
  385. ENTER("InitializeFrameManager");
  386. fcChip = (PTACHYON)pChip;
  387. if( !fcChip->Registers.ReMapMemBase ) // undefined controller?
  388. return -1;
  389. // TL/TS UG, pg. 184
  390. // 0x0065 = 100ms for RT_TOV
  391. // 0x01f5 = 500ms for ED_TOV
  392. // 0x07D1 = 2000ms
  393. fcChip->Registers.ed_tov.value = 0x006507D1;
  394. writel( fcChip->Registers.ed_tov.value,
  395. (fcChip->Registers.ed_tov.address));
  396. // Set LP_TOV to the FC-AL2 specified 2 secs.
  397. // TL/TS UG, pg. 185
  398. writel( 0x07d00010, fcChip->Registers.ReMapMemBase +TL_MEM_FM_TIMEOUT2);
  399. // Now try to read the WWN from the adapter's NVRAM
  400. iStatus = CpqTsReadWriteWWN( fcChip, 1); // '1' for READ
  401. if( iStatus ) // NVRAM read failed?
  402. {
  403. printk(" WARNING! HBA NVRAM WWN read failed - make alias\n");
  404. // make up a WWN. If NULL or duplicated on loop, FC loop may hang!
  405. fcChip->Registers.wwn_hi = (__u32)jiffies;
  406. fcChip->Registers.wwn_hi |= 0x50000000L;
  407. fcChip->Registers.wwn_lo = 0x44556677L;
  408. }
  409. writel( fcChip->Registers.wwn_hi,
  410. fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_HI);
  411. writel( fcChip->Registers.wwn_lo,
  412. fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_LO);
  413. // readback for verification:
  414. wwnHi = readl( fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_HI );
  415. wwnLo = readl( fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_LO);
  416. // test for correct chip register WRITE/READ
  417. DEBUG_PCI( printk(" WWN %08X%08X\n",
  418. fcChip->Registers.wwn_hi, fcChip->Registers.wwn_lo ) );
  419. if( wwnHi != fcChip->Registers.wwn_hi ||
  420. wwnLo != fcChip->Registers.wwn_lo )
  421. {
  422. printk( "cpqfcTS: WorldWideName register load failed\n");
  423. return -1; // FAILED!
  424. }
  425. // set Frame Manager Initialize command
  426. fcChip->Registers.FMcontrol.value = 0x06;
  427. // Note: for test/debug purposes, we may use "Hard" address,
  428. // but we completely support "soft" addressing, including
  429. // dynamically changing our address.
  430. if( fcChip->Options.intLoopback == 1 ) // internal loopback
  431. fcChip->Registers.FMconfig.value = 0x0f002080L;
  432. else if( fcChip->Options.extLoopback == 1 ) // internal loopback
  433. fcChip->Registers.FMconfig.value = 0x0f004080L;
  434. else // L_Port
  435. fcChip->Registers.FMconfig.value = 0x55000100L; // hard address (55h start)
  436. // fcChip->Registers.FMconfig.value = 0x01000080L; // soft address (can't pick)
  437. // fcChip->Registers.FMconfig.value = 0x55000100L; // hard address (55h start)
  438. // write config to FM
  439. if( !fcChip->Options.intLoopback && !fcChip->Options.extLoopback )
  440. // (also need LASER for real LOOP)
  441. fcChip->LaserControl( fcChip->Registers.ReMapMemBase, 1); // turn on LASER
  442. writel( fcChip->Registers.FMconfig.value,
  443. fcChip->Registers.FMconfig.address);
  444. // issue INITIALIZE command to FM - ACTION!
  445. writel( fcChip->Registers.FMcontrol.value,
  446. fcChip->Registers.FMcontrol.address);
  447. LEAVE("InitializeFrameManager");
  448. return 0;
  449. }
  450. // This "look ahead" function examines the IMQ for occurrence of
  451. // "type". Returns 1 if found, 0 if not.
  452. static int PeekIMQEntry( PTACHYON fcChip, ULONG type)
  453. {
  454. ULONG CI = fcChip->IMQ->consumerIndex;
  455. ULONG PI = fcChip->IMQ->producerIndex; // snapshot of IMQ indexes
  456. while( CI != PI )
  457. { // proceed with search
  458. if( (++CI) >= IMQ_LEN ) CI = 0; // rollover check
  459. switch( type )
  460. {
  461. case ELS_LILP_FRAME:
  462. {
  463. // first, we need to find an Inbound Completion message,
  464. // If we find it, check the incoming frame payload (1st word)
  465. // for LILP frame
  466. if( (fcChip->IMQ->QEntry[CI].type & 0x1FF) == 0x104 )
  467. {
  468. TachFCHDR_GCMND* fchs;
  469. #error This is too much stack
  470. ULONG ulFibreFrame[2048/4]; // max DWORDS in incoming FC Frame
  471. USHORT SFQpi = (USHORT)(fcChip->IMQ->QEntry[CI].word[0] & 0x0fffL);
  472. CpqTsGetSFQEntry( fcChip,
  473. SFQpi, // SFQ producer ndx
  474. ulFibreFrame, // contiguous dest. buffer
  475. FALSE); // DON'T update chip--this is a "lookahead"
  476. fchs = (TachFCHDR_GCMND*)&ulFibreFrame;
  477. if( fchs->pl[0] == ELS_LILP_FRAME)
  478. {
  479. return 1; // found the LILP frame!
  480. }
  481. else
  482. {
  483. // keep looking...
  484. }
  485. }
  486. }
  487. break;
  488. case OUTBOUND_COMPLETION:
  489. if( (fcChip->IMQ->QEntry[CI].type & 0x1FF) == 0x00 )
  490. {
  491. // any OCM errors?
  492. if( fcChip->IMQ->QEntry[CI].word[2] & 0x7a000000L )
  493. return 1; // found OCM error
  494. }
  495. break;
  496. default:
  497. break;
  498. }
  499. }
  500. return 0; // failed to find "type"
  501. }
  502. static void SetTachTOV( CPQFCHBA* cpqfcHBAdata)
  503. {
  504. PTACHYON fcChip = &cpqfcHBAdata->fcChip;
  505. // TL/TS UG, pg. 184
  506. // 0x0065 = 100ms for RT_TOV
  507. // 0x01f5 = 500ms for ED_TOV
  508. // 0x07d1 = 2000ms for ED_TOV
  509. // SANMark Level 1 requires an "initialization backoff"
  510. // (See "SANMark Test Suite Level 1":
  511. // initialization_timeout.fcal.SANMark-1.fc)
  512. // We have to use 2sec, 24sec, then 128sec when login/
  513. // port discovery processes fail to complete.
  514. // when port discovery completes (logins done), we set
  515. // ED_TOV to 500ms -- this is the normal operational case
  516. // On the first Link Down, we'll move to 2 secs (7D1 ms)
  517. if( (fcChip->Registers.ed_tov.value &0xFFFF) <= 0x1f5)
  518. fcChip->Registers.ed_tov.value = 0x006507D1;
  519. // If we get another LST after we moved TOV to 2 sec,
  520. // increase to 24 seconds (5DC1 ms) per SANMark!
  521. else if( (fcChip->Registers.ed_tov.value &0xFFFF) <= 0x7D1)
  522. fcChip->Registers.ed_tov.value = 0x00655DC1;
  523. // If we get still another LST, set the max TOV (Tachyon
  524. // has only 16 bits for ms timer, so the max is 65.5 sec)
  525. else if( (fcChip->Registers.ed_tov.value &0xFFFF) <= 0x5DC1)
  526. fcChip->Registers.ed_tov.value = 0x0065FFFF;
  527. writel( fcChip->Registers.ed_tov.value,
  528. (fcChip->Registers.ed_tov.address));
  529. // keep the same 2sec LP_TOV
  530. writel( 0x07D00010, fcChip->Registers.ReMapMemBase +TL_MEM_FM_TIMEOUT2);
  531. }
  532. // The IMQ is an array with IMQ_LEN length, each element (QEntry)
  533. // with eight 32-bit words. Tachyon PRODUCES a QEntry with each
  534. // message it wants to send to the host. The host CONSUMES IMQ entries
  535. // This function copies the current
  536. // (or oldest not-yet-processed) QEntry to
  537. // the caller, clears/ re-enables the interrupt, and updates the
  538. // (Host) Consumer Index.
  539. // Return value:
  540. // 0 message processed, none remain (producer and consumer
  541. // indexes match)
  542. // 1 message processed, more messages remain
  543. // -1 no message processed - none were available to process
  544. // Remarks:
  545. // TL/TS UG specifices that the following actions for
  546. // INTA_L handling:
  547. // 1. read PCI Interrupt Status register (0xff)
  548. // 2. all IMQ messages should be processed before writing the
  549. // IMQ consumer index.
  550. int CpqTsProcessIMQEntry(void *host)
  551. {
  552. struct Scsi_Host *HostAdapter = (struct Scsi_Host *)host;
  553. CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
  554. PTACHYON fcChip = &cpqfcHBAdata->fcChip;
  555. FC_EXCHANGES *Exchanges = fcChip->Exchanges;
  556. int iStatus;
  557. USHORT i, RPCset, DPCset;
  558. ULONG x_ID;
  559. ULONG ulBuff, dwStatus;
  560. TachFCHDR_GCMND* fchs;
  561. #error This is too much stack
  562. ULONG ulFibreFrame[2048/4]; // max number of DWORDS in incoming Fibre Frame
  563. UCHAR ucInboundMessageType; // Inbound CM, dword 3 "type" field
  564. ENTER("ProcessIMQEntry");
  565. // check TachLite's IMQ producer index -
  566. // is a new message waiting for us?
  567. // equal indexes means empty que
  568. if( fcChip->IMQ->producerIndex != fcChip->IMQ->consumerIndex )
  569. { // need to process message
  570. #ifdef IMQ_DEBUG
  571. printk("PI %X, CI %X type: %X\n",
  572. fcChip->IMQ->producerIndex,fcChip->IMQ->consumerIndex,
  573. fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].type);
  574. #endif
  575. // Examine Completion Messages in IMQ
  576. // what CM_Type?
  577. switch( (UCHAR)(fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].type
  578. & 0xffL) )
  579. {
  580. case OUTBOUND_COMPLETION:
  581. // Remarks:
  582. // x_IDs (OX_ID, RX_ID) are partitioned by SEST entries
  583. // (starting at 0), and SFS entries (starting at
  584. // SEST_LEN -- outside the SEST space).
  585. // Psuedo code:
  586. // x_ID (OX_ID or RX_ID) from message is Trans_ID or SEST index
  587. // range check - x_ID
  588. // if x_ID outside 'Transactions' length, error - exit
  589. // if any OCM error, copy error status to Exchange slot
  590. // if FCP ASSIST transaction (x_ID within SEST),
  591. // call fcComplete (to App)
  592. // ...
  593. ulBuff = fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1];
  594. x_ID = ulBuff & 0x7fffL; // lower 14 bits SEST_Index/Trans_ID
  595. // Range check CM OX/RX_ID value...
  596. if( x_ID < TACH_MAX_XID ) // don't go beyond array space
  597. {
  598. if( ulBuff & 0x20000000L ) // RPC -Response Phase Complete?
  599. RPCset = 1; // (SEST transactions only)
  600. else
  601. RPCset = 0;
  602. if( ulBuff & 0x40000000L ) // DPC -Data Phase Complete?
  603. DPCset = 1; // (SEST transactions only)
  604. else
  605. DPCset = 0;
  606. // set the status for this Outbound transaction's ID
  607. dwStatus = 0L;
  608. if( ulBuff & 0x10000000L ) // SPE? (SEST Programming Error)
  609. dwStatus |= SESTPROG_ERR;
  610. ulBuff = fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2];
  611. if( ulBuff & 0x7a000000L ) // any other errs?
  612. {
  613. if( ulBuff & 0x40000000L )
  614. dwStatus |= INV_ENTRY;
  615. if( ulBuff & 0x20000000L )
  616. dwStatus |= FRAME_TO; // FTO
  617. if( ulBuff & 0x10000000L )
  618. dwStatus |= HOSTPROG_ERR;
  619. if( ulBuff & 0x08000000L )
  620. dwStatus |= LINKFAIL_TX;
  621. if( ulBuff & 0x02000000L )
  622. dwStatus |= ABORTSEQ_NOTIFY; // ASN
  623. }
  624. if( dwStatus ) // any errors?
  625. {
  626. // set the Outbound Completion status
  627. Exchanges->fcExchange[ x_ID ].status |= dwStatus;
  628. // if this Outbound frame was for a SEST entry, automatically
  629. // reque it in the case of LINKFAIL (it will restart on PDISC)
  630. if( x_ID < TACH_SEST_LEN )
  631. {
  632. printk(" #OCM error %Xh x_ID %X# ",
  633. dwStatus, x_ID);
  634. Exchanges->fcExchange[x_ID].timeOut = 30000; // seconds default
  635. // We Q ABTS for each exchange.
  636. // NOTE: We can get FRAME_TO on bad alpa (device gone). Since
  637. // bad alpa is reported before FRAME_TO, examine the status
  638. // flags to see if the device is removed. If so, DON'T
  639. // post an ABTS, since it will be terminated by the bad alpa
  640. // message.
  641. if( dwStatus & FRAME_TO ) // check for device removed...
  642. {
  643. if( !(Exchanges->fcExchange[x_ID].status & DEVICE_REMOVED) )
  644. {
  645. // presumes device is still there: send ABTS.
  646. cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID);
  647. }
  648. }
  649. else // Abort all other errors
  650. {
  651. cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID);
  652. }
  653. // if the HPE bit is set, we have to CLose the LOOP
  654. // (see TL/TS UG, pg. 239)
  655. if( dwStatus &= HOSTPROG_ERR )
  656. // set CL bit (see TL/TS UG, pg. 172)
  657. writel( 4, fcChip->Registers.FMcontrol.address);
  658. }
  659. }
  660. // NOTE: we don't necessarily care about ALL completion messages...
  661. // SCSI resp. complete OR
  662. if( ((x_ID < TACH_SEST_LEN) && RPCset)||
  663. (x_ID >= TACH_SEST_LEN) ) // non-SCSI command
  664. {
  665. // exchange done; complete to upper levels with status
  666. // (if necessary) and free the exchange slot
  667. if( x_ID >= TACH_SEST_LEN ) // Link Service Outbound frame?
  668. // A Request or Reply has been sent
  669. { // signal waiting WorkerThread
  670. up( cpqfcHBAdata->TYOBcomplete); // frame is OUT of Tach
  671. // WorkerThread will complete Xchng
  672. }
  673. else // X_ID is for FCP assist (SEST)
  674. {
  675. // TBD (target mode)
  676. // fcCompleteExchange( fcChip, x_ID); // TRE completed
  677. }
  678. }
  679. }
  680. else // ERROR CONDITION! bogus x_ID in completion message
  681. {
  682. printk(" ProcessIMQ (OBCM) x_id out of range %Xh\n", x_ID);
  683. }
  684. // Load the Frame Manager's error counters. We check them here
  685. // because presumably the link is up and healthy enough for the
  686. // counters to be meaningful (i.e., don't check them while loop
  687. // is initializing).
  688. fcChip->Registers.FMLinkStatus1.value = // get TL's counter
  689. readl(fcChip->Registers.FMLinkStatus1.address);
  690. fcChip->Registers.FMLinkStatus2.value = // get TL's counter
  691. readl(fcChip->Registers.FMLinkStatus2.address);
  692. fcParseLinkStatusCounters( fcChip); // load into 6 s/w accumulators
  693. break;
  694. case ERROR_IDLE_COMPLETION: // TachLite Error Idle...
  695. // We usually get this when the link goes down during heavy traffic.
  696. // For now, presume that if SEST Exchanges are open, we will
  697. // get this as our cue to INVALIDATE all SEST entries
  698. // (and we OWN all the SEST entries).
  699. // See TL/TS UG, pg. 53
  700. for( x_ID = 0; x_ID < TACH_SEST_LEN; x_ID++)
  701. {
  702. // Does this VALid SEST entry need to be invalidated for Abort?
  703. fcChip->SEST->u[ x_ID].IWE.Hdr_Len &= 0x7FFFFFFF;
  704. }
  705. CpqTsUnFreezeTachlite( fcChip, 2); // unfreeze Tachyon, if Link OK
  706. break;
  707. case INBOUND_SFS_COMPLETION: //0x04
  708. // NOTE! we must process this SFQ message to avoid SFQ filling
  709. // up and stopping TachLite. Incoming commands are placed here,
  710. // as well as 'unknown' frames (e.g. LIP loop position data)
  711. // write this CM's producer index to global...
  712. // TL/TS UG, pg 234:
  713. // Type: 0 - reserved
  714. // 1 - Unassisted FCP
  715. // 2 - BAD FCP
  716. // 3 - Unkown Frame
  717. // 4-F reserved
  718. fcChip->SFQ->producerIndex = (USHORT)
  719. (fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[0] & 0x0fffL);
  720. ucInboundMessageType = 0; // default to useless frame
  721. // we can only process two Types: 1, Unassisted FCP, and 3, Unknown
  722. // Also, we aren't interested in processing frame fragments
  723. // so don't Que anything with 'LKF' bit set
  724. if( !(fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2]
  725. & 0x40000000) ) // 'LKF' link failure bit clear?
  726. {
  727. ucInboundMessageType = (UCHAR) // ICM DWord3, "Type"
  728. (fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2] & 0x0fL);
  729. }
  730. else
  731. {
  732. fcChip->fcStats.linkFailRX++;
  733. // printk("LKF (link failure) bit set on inbound message\n");
  734. }
  735. // clears SFQ entry from Tachyon buffer; copies to contiguous ulBuff
  736. CpqTsGetSFQEntry(
  737. fcChip, // i.e. this Device Object
  738. (USHORT)fcChip->SFQ->producerIndex, // SFQ producer ndx
  739. ulFibreFrame, TRUE); // contiguous destination buffer, update chip
  740. // analyze the incoming frame outside the INT handler...
  741. // (i.e., Worker)
  742. if( ucInboundMessageType == 1 )
  743. {
  744. fchs = (TachFCHDR_GCMND*)ulFibreFrame; // cast to examine IB frame
  745. // don't fill up our Q with garbage - only accept FCP-CMND
  746. // or XRDY frames
  747. if( (fchs->d_id & 0xFF000000) == 0x06000000 ) // CMND
  748. {
  749. // someone sent us a SCSI command
  750. // fcPutScsiQue( cpqfcHBAdata,
  751. // SFQ_UNASSISTED_FCP, ulFibreFrame);
  752. }
  753. else if( ((fchs->d_id & 0xFF000000) == 0x07000000) || // RSP (status)
  754. (fchs->d_id & 0xFF000000) == 0x05000000 ) // XRDY
  755. {
  756. ULONG x_ID;
  757. // Unfortunately, ABTS requires a Freeze on the chip so
  758. // we can modify the shared memory SEST. When frozen,
  759. // any received Exchange frames cannot be processed by
  760. // Tachyon, so they will be dumped in here. It is too
  761. // complex to attempt the reconstruct these frames in
  762. // the correct Exchange context, so we simply seek to
  763. // find status or transfer ready frames, and cause the
  764. // exchange to complete with errors before the timeout
  765. // expires. We use a Linux Scsi Cmnd result code that
  766. // causes immediate retry.
  767. // Do we have an open exchange that matches this s_id
  768. // and ox_id?
  769. for( x_ID = 0; x_ID < TACH_SEST_LEN; x_ID++)
  770. {
  771. if( (fchs->s_id & 0xFFFFFF) ==
  772. (Exchanges->fcExchange[x_ID].fchs.d_id & 0xFFFFFF)
  773. &&
  774. (fchs->ox_rx_id & 0xFFFF0000) ==
  775. (Exchanges->fcExchange[x_ID].fchs.ox_rx_id & 0xFFFF0000) )
  776. {
  777. // printk(" #R/X frame x_ID %08X# ", fchs->ox_rx_id );
  778. // simulate the anticipated error - since the
  779. // SEST was frozen, frames were lost...
  780. Exchanges->fcExchange[ x_ID ].status |= SFQ_FRAME;
  781. // presumes device is still there: send ABTS.
  782. cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID);
  783. break; // done
  784. }
  785. }
  786. }
  787. }
  788. else if( ucInboundMessageType == 3)
  789. {
  790. // FC Link Service frames (e.g. PLOGI, ACC) come in here.
  791. cpqfcTSPutLinkQue( cpqfcHBAdata, SFQ_UNKNOWN, ulFibreFrame);
  792. }
  793. else if( ucInboundMessageType == 2 ) // "bad FCP"?
  794. {
  795. #ifdef IMQ_DEBUG
  796. printk("Bad FCP incoming frame discarded\n");
  797. #endif
  798. }
  799. else // don't know this type
  800. {
  801. #ifdef IMQ_DEBUG
  802. printk("Incoming frame discarded, type: %Xh\n", ucInboundMessageType);
  803. #endif
  804. }
  805. // Check the Frame Manager's error counters. We check them here
  806. // because presumably the link is up and healthy enough for the
  807. // counters to be meaningful (i.e., don't check them while loop
  808. // is initializing).
  809. fcChip->Registers.FMLinkStatus1.value = // get TL's counter
  810. readl(fcChip->Registers.FMLinkStatus1.address);
  811. fcChip->Registers.FMLinkStatus2.value = // get TL's counter
  812. readl(fcChip->Registers.FMLinkStatus2.address);
  813. break;
  814. // We get this CM because we issued a freeze
  815. // command to stop outbound frames. We issue the
  816. // freeze command at Link Up time; when this message
  817. // is received, the ERQ base can be switched and PDISC
  818. // frames can be sent.
  819. case ERQ_FROZEN_COMPLETION: // note: expect ERQ followed immediately
  820. // by FCP when freezing TL
  821. fcChip->Registers.TYstatus.value = // read what's frozen
  822. readl(fcChip->Registers.TYstatus.address);
  823. // (do nothing; wait for FCP frozen message)
  824. break;
  825. case FCP_FROZEN_COMPLETION:
  826. fcChip->Registers.TYstatus.value = // read what's frozen
  827. readl(fcChip->Registers.TYstatus.address);
  828. // Signal the kernel thread to proceed with SEST modification
  829. up( cpqfcHBAdata->TachFrozen);
  830. break;
  831. case INBOUND_C1_TIMEOUT:
  832. case MFS_BUF_WARN:
  833. case IMQ_BUF_WARN:
  834. break;
  835. // In older Tachyons, we 'clear' the internal 'core' interrupt state
  836. // by reading the FMstatus register. In newer TachLite (Tachyon),
  837. // we must WRITE the register
  838. // to clear the condition (TL/TS UG, pg 179)
  839. case FRAME_MGR_INTERRUPT:
  840. {
  841. PFC_LOGGEDIN_PORT pLoggedInPort;
  842. fcChip->Registers.FMstatus.value =
  843. readl( fcChip->Registers.FMstatus.address );
  844. // PROBLEM: It is possible, especially with "dumb" hubs that
  845. // don't automatically LIP on by-pass of ports that are going
  846. // away, for the hub by-pass process to destroy critical
  847. // ordered sets of a frame. The result of this is a hung LPSM
  848. // (Loop Port State Machine), which on Tachyon results in a
  849. // (default 2 sec) Loop State Timeout (LST) FM message. We
  850. // want to avoid this relatively huge timeout by detecting
  851. // likely scenarios which will result in LST.
  852. // To do this, we could examine FMstatus for Loss of Synchronization
  853. // and/or Elastic Store (ES) errors. Of these, Elastic Store is better
  854. // because we get this indication more quickly than the LOS.
  855. // Not all ES errors are harmfull, so we don't want to LIP on every
  856. // ES. Instead, on every ES, detect whether our LPSM in in one
  857. // of the LST states: ARBITRATING, OPEN, OPENED, XMITTED CLOSE,
  858. // or RECEIVED CLOSE. (See TL/TS UG, pg. 181)
  859. // If any of these LPSM states are detected
  860. // in combination with the LIP while LDn is not set,
  861. // send an FM init (LIP F7,F7 for loops)!
  862. // It is critical to the physical link stability NOT to reset (LIP)
  863. // more than absolutely necessary; this is a basic premise of the
  864. // SANMark level 1 spec.
  865. {
  866. ULONG Lpsm = (fcChip->Registers.FMstatus.value & 0xF0) >>4;
  867. if( (fcChip->Registers.FMstatus.value & 0x400) // ElasticStore?
  868. &&
  869. !(fcChip->Registers.FMstatus.value & 0x100) // NOT LDn
  870. &&
  871. !(fcChip->Registers.FMstatus.value & 0x1000)) // NOT LF
  872. {
  873. if( (Lpsm != 0) || // not MONITORING? or
  874. !(Lpsm & 0x8) )// not already offline?
  875. {
  876. // now check the particular LST states...
  877. if( (Lpsm == ARBITRATING) || (Lpsm == OPEN) ||
  878. (Lpsm == OPENED) || (Lpsm == XMITTD_CLOSE) ||
  879. (Lpsm == RCVD_CLOSE) )
  880. {
  881. // re-init the loop before it hangs itself!
  882. printk(" #req FMinit on E-S: LPSM %Xh# ",Lpsm);
  883. fcChip->fcStats.FMinits++;
  884. writel( 6, fcChip->Registers.FMcontrol.address); // LIP
  885. }
  886. }
  887. }
  888. else if( fcChip->Registers.FMstatus.value & 0x40000 ) // LST?
  889. {
  890. printk(" #req FMinit on LST, LPSM %Xh# ",Lpsm);
  891. fcChip->fcStats.FMinits++;
  892. writel( 6, fcChip->Registers.FMcontrol.address); // LIP
  893. }
  894. }
  895. // clear only the 'interrupting' type bits for this REG read
  896. writel( (fcChip->Registers.FMstatus.value & 0xff3fff00L),
  897. fcChip->Registers.FMstatus.address);
  898. // copy frame manager status to unused ULONG slot
  899. fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[0] =
  900. fcChip->Registers.FMstatus.value; // (for debugging)
  901. // Load the Frame Manager's error counters. We check them here
  902. // because presumably the link is up and healthy enough for the
  903. // counters to be meaningful (i.e., don't check them while loop
  904. // is initializing).
  905. fcChip->Registers.FMLinkStatus1.value = // get TL's counter
  906. readl(fcChip->Registers.FMLinkStatus1.address);
  907. fcChip->Registers.FMLinkStatus2.value = // get TL's counter
  908. readl(fcChip->Registers.FMLinkStatus2.address);
  909. // Get FM BB_Credit Zero Reg - does not clear on READ
  910. fcChip->Registers.FMBB_CreditZero.value = // get TL's counter
  911. readl(fcChip->Registers.FMBB_CreditZero.address);
  912. fcParseLinkStatusCounters( fcChip); // load into 6 s/w accumulators
  913. // LINK DOWN
  914. if( fcChip->Registers.FMstatus.value & 0x100L ) // Link DOWN bit
  915. {
  916. #ifdef IMQ_DEBUG
  917. printk("LinkDn\n");
  918. #endif
  919. printk(" #LDn# ");
  920. fcChip->fcStats.linkDown++;
  921. SetTachTOV( cpqfcHBAdata); // must set according to SANMark
  922. // Check the ERQ - force it to be "empty" to prevent Tach
  923. // from sending out frames before we do logins.
  924. if( fcChip->ERQ->producerIndex != fcChip->ERQ->consumerIndex)
  925. {
  926. // printk("#ERQ PI != CI#");
  927. CpqTsFreezeTachlite( fcChip, 1); // freeze ERQ only
  928. fcChip->ERQ->producerIndex = fcChip->ERQ->consumerIndex = 0;
  929. writel( fcChip->ERQ->base,
  930. (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_BASE));
  931. // re-writing base forces ERQ PI to equal CI
  932. }
  933. // link down transition occurred -- port_ids can change
  934. // on next LinkUp, so we must invalidate current logins
  935. // (and any I/O in progress) until PDISC or PLOGI/PRLI
  936. // completes
  937. {
  938. pLoggedInPort = &fcChip->fcPorts;
  939. while( pLoggedInPort ) // for all ports which are expecting
  940. // PDISC after the next LIP, set the
  941. // logoutTimer
  942. {
  943. if( pLoggedInPort->pdisc) // expecting PDISC within 2 sec?
  944. {
  945. pLoggedInPort->LOGO_timer = 3; // we want 2 seconds
  946. // but Timer granularity
  947. // is 1 second
  948. }
  949. // suspend any I/O in progress until
  950. // PDISC received...
  951. pLoggedInPort->prli = FALSE; // block FCP-SCSI commands
  952. pLoggedInPort = pLoggedInPort->pNextPort;
  953. } // ... all Previously known ports checked
  954. }
  955. // since any hot plugging device may NOT support LILP frames
  956. // (such as early Tachyon chips), clear this flag indicating
  957. // we shouldn't use (our copy of) a LILP map.
  958. // If we receive an LILP frame, we'll set it again.
  959. fcChip->Options.LILPin = 0; // our LILPmap is invalid
  960. cpqfcHBAdata->PortDiscDone = 0; // must re-validate FC ports!
  961. // also, we want to invalidate (i.e. INITIATOR_ABORT) any
  962. // open Login exchanges, in case the LinkDown happened in the
  963. // middle of logins. It's possible that some ports already
  964. // ACCepted login commands which we have not processed before
  965. // another LinkDown occurred. Any accepted Login exhanges are
  966. // invalidated by LinkDown, even before they are acknowledged.
  967. // It's also possible for a port to have a Queued Reply or Request
  968. // for login which was interrupted by LinkDown; it may come later,
  969. // but it will be unacceptable to us.
  970. // we must scan the entire exchange space, find every Login type
  971. // originated by us, and abort it. This is NOT an abort due to
  972. // timeout, so we don't actually send abort to the other port -
  973. // we just complete it to free up the fcExchange slot.
  974. for( i=TACH_SEST_LEN; i< TACH_MAX_XID; i++)
  975. { // looking for Extended Link Serv.Exchanges
  976. if( Exchanges->fcExchange[i].type == ELS_PDISC ||
  977. Exchanges->fcExchange[i].type == ELS_PLOGI ||
  978. Exchanges->fcExchange[i].type == ELS_PRLI )
  979. {
  980. // ABORT the exchange!
  981. #ifdef IMQ_DEBUG
  982. printk("Originator ABORT x_id %Xh, type %Xh, port_id %Xh on LDn\n",
  983. i, Exchanges->fcExchange[i].type,
  984. Exchanges->fcExchange[i].fchs.d_id);
  985. #endif
  986. Exchanges->fcExchange[i].status |= INITIATOR_ABORT;
  987. cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, i); // abort on LDn
  988. }
  989. }
  990. }
  991. // ################ LINK UP ##################
  992. if( fcChip->Registers.FMstatus.value & 0x200L ) // Link Up bit
  993. { // AL_PA could have changed
  994. // We need the following code, duplicated from LinkDn condition,
  995. // because it's possible for the Tachyon to re-initialize (hard
  996. // reset) without ever getting a LinkDn indication.
  997. pLoggedInPort = &fcChip->fcPorts;
  998. while( pLoggedInPort ) // for all ports which are expecting
  999. // PDISC after the next LIP, set the
  1000. // logoutTimer
  1001. {
  1002. if( pLoggedInPort->pdisc) // expecting PDISC within 2 sec?
  1003. {
  1004. pLoggedInPort->LOGO_timer = 3; // we want 2 seconds
  1005. // but Timer granularity
  1006. // is 1 second
  1007. // suspend any I/O in progress until
  1008. // PDISC received...
  1009. }
  1010. pLoggedInPort = pLoggedInPort->pNextPort;
  1011. } // ... all Previously known ports checked
  1012. // CpqTs acquired AL_PA in register AL_PA (ACQ_ALPA)
  1013. fcChip->Registers.rcv_al_pa.value =
  1014. readl(fcChip->Registers.rcv_al_pa.address);
  1015. // Now, if our acquired address is DIFFERENT from our
  1016. // previous one, we are not allow to do PDISC - we
  1017. // must go back to PLOGI, which will terminate I/O in
  1018. // progress for ALL logged in FC devices...
  1019. // (This is highly unlikely).
  1020. if( (fcChip->Registers.my_al_pa & 0xFF) !=
  1021. ((fcChip->Registers.rcv_al_pa.value >> 16) &0xFF) )
  1022. {
  1023. // printk(" #our HBA port_id changed!# "); // FC port_id changed!!
  1024. pLoggedInPort = &fcChip->fcPorts;
  1025. while( pLoggedInPort ) // for all ports which are expecting
  1026. // PDISC after the next LIP, set the
  1027. // logoutTimer
  1028. {
  1029. pLoggedInPort->pdisc = FALSE;
  1030. pLoggedInPort->prli = FALSE;
  1031. pLoggedInPort = pLoggedInPort->pNextPort;
  1032. } // ... all Previously known ports checked
  1033. // when the port_id changes, we must terminate
  1034. // all open exchanges.
  1035. cpqfcTSTerminateExchange( cpqfcHBAdata, NULL, PORTID_CHANGED);
  1036. }
  1037. // Replace the entire 24-bit port_id. We only know the
  1038. // lower 8 bits (alpa) from Tachyon; if a FLOGI is done,
  1039. // we'll get the upper 16-bits from the FLOGI ACC frame.
  1040. // If someone plugs into Fabric switch, we'll do FLOGI and
  1041. // get full 24-bit port_id; someone could then remove and
  1042. // hot-plug us into a dumb hub. If we send a 24-bit PLOGI
  1043. // to a "private" loop device, it might blow up.
  1044. // Consequently, we force the upper 16-bits of port_id to
  1045. // be re-set on every LinkUp transition
  1046. fcChip->Registers.my_al_pa =
  1047. (fcChip->Registers.rcv_al_pa.value >> 16) & 0xFF;
  1048. // copy frame manager status to unused ULONG slot
  1049. fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1] =
  1050. fcChip->Registers.my_al_pa; // (for debugging)
  1051. // for TachLite, we need to write the acquired al_pa
  1052. // back into the FMconfig register, because after
  1053. // first initialization, the AQ (prev. acq.) bit gets
  1054. // set, causing TL FM to use the AL_PA field in FMconfig.
  1055. // (In Tachyon, FM writes the acquired AL_PA for us.)
  1056. ulBuff = readl( fcChip->Registers.FMconfig.address);
  1057. ulBuff &= 0x00ffffffL; // mask out current al_pa
  1058. ulBuff |= ( fcChip->Registers.my_al_pa << 24 ); // or in acq. al_pa
  1059. fcChip->Registers.FMconfig.value = ulBuff; // copy it back
  1060. writel( fcChip->Registers.FMconfig.value, // put in TachLite
  1061. fcChip->Registers.FMconfig.address);
  1062. #ifdef IMQ_DEBUG
  1063. printk("#LUp %Xh, FMstat 0x%08X#",
  1064. fcChip->Registers.my_al_pa, fcChip->Registers.FMstatus.value);
  1065. #endif
  1066. // also set the WRITE-ONLY My_ID Register (for Fabric
  1067. // initialization)
  1068. writel( fcChip->Registers.my_al_pa,
  1069. fcChip->Registers.ReMapMemBase +TL_MEM_TACH_My_ID);
  1070. fcChip->fcStats.linkUp++;
  1071. // reset TL statistics counters
  1072. // (we ignore these error counters
  1073. // while link is down)
  1074. ulBuff = // just reset TL's counter
  1075. readl( fcChip->Registers.FMLinkStatus1.address);
  1076. ulBuff = // just reset TL's counter
  1077. readl( fcChip->Registers.FMLinkStatus2.address);
  1078. // for initiator, need to start verifying ports (e.g. PDISC)
  1079. CpqTsUnFreezeTachlite( fcChip, 2); // unfreeze Tachlite, if Link OK
  1080. // Tachyon creates an interesting problem for us on LILP frames.
  1081. // Instead of writing the incoming LILP frame into the SFQ before
  1082. // indicating LINK UP (the actual order of events), Tachyon tells
  1083. // us LINK UP, and later us the LILP. So we delay, then examine the
  1084. // IMQ for an Inbound CM (x04); if found, we can set
  1085. // LINKACTIVE after processing the LILP. Otherwise, just proceed.
  1086. // Since Tachyon imposes this time delay (and doesn't tell us
  1087. // what it is), we have to impose a delay before "Peeking" the IMQ
  1088. // for Tach hardware (DMA) delivery.
  1089. // Processing LILP is required by SANMark
  1090. udelay( 1000); // microsec delay waiting for LILP (if it comes)
  1091. if( PeekIMQEntry( fcChip, ELS_LILP_FRAME) )
  1092. { // found SFQ LILP, which will post LINKACTIVE
  1093. // printk("skipping LINKACTIVE post\n");
  1094. }
  1095. else
  1096. cpqfcTSPutLinkQue( cpqfcHBAdata, LINKACTIVE, ulFibreFrame);
  1097. }
  1098. // ******* Set Fabric Login indication ********
  1099. if( fcChip->Registers.FMstatus.value & 0x2000 )
  1100. {
  1101. printk(" #Fabric# ");
  1102. fcChip->Options.fabric = 1;
  1103. }
  1104. else
  1105. fcChip->Options.fabric = 0;
  1106. // ******* LIP(F8,x) or BAD AL_PA? ********
  1107. if( fcChip->Registers.FMstatus.value & 0x30000L )
  1108. {
  1109. // copy the error AL_PAs
  1110. fcChip->Registers.rcv_al_pa.value =
  1111. readl(fcChip->Registers.rcv_al_pa.address);
  1112. // Bad AL_PA?
  1113. if( fcChip->Registers.FMstatus.value & 0x10000L )
  1114. {
  1115. PFC_LOGGEDIN_PORT pLoggedInPort;
  1116. // copy "BAD" al_pa field
  1117. fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1] =
  1118. (fcChip->Registers.rcv_al_pa.value & 0xff00L) >> 8;
  1119. pLoggedInPort = fcFindLoggedInPort( fcChip,
  1120. NULL, // DON'T search Scsi Nexus
  1121. fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1], // port id
  1122. NULL, // DON'T search linked list for FC WWN
  1123. NULL); // DON'T care about end of list
  1124. if( pLoggedInPort )
  1125. {
  1126. // Just in case we got this BAD_ALPA because a device
  1127. // quietly disappeared (can happen on non-managed hubs such
  1128. // as the Vixel Rapport 1000),
  1129. // do an Implicit Logout. We never expect this on a Logged
  1130. // in port (but do expect it on port discovery).
  1131. // (As a reasonable alternative, this could be changed to
  1132. // simply start the implicit logout timer, giving the device
  1133. // several seconds to "come back".)
  1134. //
  1135. printk(" #BAD alpa %Xh# ",
  1136. fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1]);
  1137. cpqfcTSImplicitLogout( cpqfcHBAdata, pLoggedInPort);
  1138. }
  1139. }
  1140. // LIP(f8,x)?
  1141. if( fcChip->Registers.FMstatus.value & 0x20000L )
  1142. {
  1143. // for debugging, copy al_pa field
  1144. fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2] =
  1145. (fcChip->Registers.rcv_al_pa.value & 0xffL);
  1146. // get the other port's al_pa
  1147. // (one that sent LIP(F8,?) )
  1148. }
  1149. }
  1150. // Elastic store err
  1151. if( fcChip->Registers.FMstatus.value & 0x400L )
  1152. {
  1153. // don't count e-s if loop is down!
  1154. if( !(USHORT)(fcChip->Registers.FMstatus.value & 0x80) )
  1155. fcChip->fcStats.e_stores++;
  1156. }
  1157. }
  1158. break;
  1159. case INBOUND_FCP_XCHG_COMPLETION: // 0x0C
  1160. // Remarks:
  1161. // On Tachlite TL/TS, we get this message when the data phase
  1162. // of a SEST inbound transfer is complete. For example, if a WRITE command
  1163. // was received with OX_ID 0, we might respond with XFER_RDY with
  1164. // RX_ID 8001. This would start the SEST controlled data phases. When
  1165. // all data frames are received, we get this inbound completion. This means
  1166. // we should send a status frame to complete the status phase of the
  1167. // FCP-SCSI exchange, using the same OX_ID,RX_ID that we used for data
  1168. // frames.
  1169. // See Outbound CM discussion of x_IDs
  1170. // Psuedo Code
  1171. // Get SEST index (x_ID)
  1172. // x_ID out of range, return (err condition)
  1173. // set status bits from 2nd dword
  1174. // free transactionID & SEST entry
  1175. // call fcComplete with transactionID & status
  1176. ulBuff = fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[0];
  1177. x_ID = ulBuff & 0x7fffL; // lower 14 bits SEST_Index/Trans_ID
  1178. // (mask out MSB "direction" bit)
  1179. // Range check CM OX/RX_ID value...
  1180. if( x_ID < TACH_SEST_LEN ) // don't go beyond SEST array space
  1181. {
  1182. //#define FCP_COMPLETION_DBG 1
  1183. #ifdef FCP_COMPLETION_DBG
  1184. printk(" FCP_CM x_ID %Xh, status %Xh, Cmnd %p\n",
  1185. x_ID, ulBuff, Exchanges->fcExchange[x_ID].Cmnd);
  1186. #endif
  1187. if( ulBuff & 0x08000000L ) // RPC -Response Phase Complete - or -
  1188. // time to send response frame?
  1189. RPCset = 1; // (SEST transaction)
  1190. else
  1191. RPCset = 0;
  1192. // set the status for this Inbound SCSI transaction's ID
  1193. dwStatus = 0L;
  1194. if( ulBuff & 0x70000000L ) // any errs?
  1195. {
  1196. if( ulBuff & 0x40000000L )
  1197. dwStatus |= LINKFAIL_RX;
  1198. if( ulBuff & 0x20000000L )
  1199. dwStatus |= COUNT_ERROR;
  1200. if( ulBuff & 0x10000000L )
  1201. dwStatus |= OVERFLOW;
  1202. }
  1203. // FCP transaction done - copy status
  1204. Exchanges->fcExchange[ x_ID ].status = dwStatus;
  1205. // Did the exchange get an FCP-RSP response frame?
  1206. // (Note the little endian/big endian FC payload difference)
  1207. if( RPCset ) // SEST transaction Response frame rec'd
  1208. {
  1209. // complete the command in our driver...
  1210. cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev,fcChip, x_ID);
  1211. } // end "RPCset"
  1212. else // ("target" logic)
  1213. {
  1214. // Tachlite says all data frames have been received - now it's time
  1215. // to analyze data transfer (successful?), then send a response
  1216. // frame for this exchange
  1217. ulFibreFrame[0] = x_ID; // copy for later reference
  1218. // if this was a TWE, we have to send satus response
  1219. if( Exchanges->fcExchange[ x_ID].type == SCSI_TWE )
  1220. {
  1221. // fcPutScsiQue( cpqfcHBAdata,
  1222. // NEED_FCP_RSP, ulFibreFrame); // (ulFibreFrame not used here)
  1223. }
  1224. }
  1225. }
  1226. else // ERROR CONDITION! bogus x_ID in completion message
  1227. {
  1228. printk("IN FCP_XCHG: bad x_ID: %Xh\n", x_ID);
  1229. }
  1230. break;
  1231. case INBOUND_SCSI_DATA_COMMAND:
  1232. case BAD_SCSI_FRAME:
  1233. case INB_SCSI_STATUS_COMPLETION:
  1234. case BUFFER_PROCESSED_COMPLETION:
  1235. break;
  1236. }
  1237. // Tachyon is producing;
  1238. // we are consuming
  1239. fcChip->IMQ->consumerIndex++; // increment OUR consumerIndex
  1240. if( fcChip->IMQ->consumerIndex >= IMQ_LEN)// check for rollover
  1241. fcChip->IMQ->consumerIndex = 0L; // reset it
  1242. if( fcChip->IMQ->producerIndex == fcChip->IMQ->consumerIndex )
  1243. { // all Messages are processed -
  1244. iStatus = 0; // no more messages to process
  1245. }
  1246. else
  1247. iStatus = 1; // more messages to process
  1248. // update TachLite's ConsumerIndex... (clears INTA_L)
  1249. // NOTE: according to TL/TS UG, the
  1250. // "host must return completion messages in sequential order".
  1251. // Does this mean one at a time, in the order received? We
  1252. // presume so.
  1253. writel( fcChip->IMQ->consumerIndex,
  1254. (fcChip->Registers.ReMapMemBase + IMQ_CONSUMER_INDEX));
  1255. #if IMQ_DEBUG
  1256. printk("Process IMQ: writing consumer ndx %d\n ",
  1257. fcChip->IMQ->consumerIndex);
  1258. printk("PI %X, CI %X\n",
  1259. fcChip->IMQ->producerIndex,fcChip->IMQ->consumerIndex );
  1260. #endif
  1261. }
  1262. else
  1263. {
  1264. // hmmm... why did we get interrupted/called with no message?
  1265. iStatus = -1; // nothing to process
  1266. #if IMQ_DEBUG
  1267. printk("Process IMQ: no message PI %Xh CI %Xh",
  1268. fcChip->IMQ->producerIndex,
  1269. fcChip->IMQ->consumerIndex);
  1270. #endif
  1271. }
  1272. LEAVE("ProcessIMQEntry");
  1273. return iStatus;
  1274. }
  1275. // This routine initializes Tachyon according to the following
  1276. // options (opcode1):
  1277. // 1 - RESTART Tachyon, simulate power on condition by shutting
  1278. // down laser, resetting the hardware, de-allocating all buffers;
  1279. // continue
  1280. // 2 - Config Tachyon / PCI registers;
  1281. // continue
  1282. // 3 - Allocating memory and setting Tachyon queues (write Tachyon regs);
  1283. // continue
  1284. // 4 - Config frame manager registers, initialize, turn on laser
  1285. //
  1286. // Returns:
  1287. // -1 on fatal error
  1288. // 0 on success
  1289. int CpqTsInitializeTachLite( void *pHBA, int opcode1, int opcode2)
  1290. {
  1291. CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA;
  1292. PTACHYON fcChip = &cpqfcHBAdata->fcChip;
  1293. ULONG ulBuff;
  1294. UCHAR bBuff;
  1295. int iStatus=-1; // assume failure
  1296. ENTER("InitializeTachLite");
  1297. // verify board's base address (sanity check)
  1298. if( !fcChip->Registers.ReMapMemBase) // NULL address for card?
  1299. return -1; // FATAL error!
  1300. switch( opcode1 )
  1301. {
  1302. case 1: // restore hardware to power-on (hard) restart
  1303. iStatus = fcChip->ResetTachyon(
  1304. cpqfcHBAdata, opcode2); // laser off, reset hardware
  1305. // de-allocate aligned buffers
  1306. /* TBD // reset FC link Q (producer and consumer = 0)
  1307. fcLinkQReset(cpqfcHBAdata);
  1308. */
  1309. if( iStatus )
  1310. break;
  1311. case 2: // Config PCI/Tachyon registers
  1312. // NOTE: For Tach TL/TS, bit 31 must be set to 1. For TS chips, a read
  1313. // of bit 31 indicates state of M66EN signal; if 1, chip may run at
  1314. // 33-66MHz (see TL/TS UG, pg 159)
  1315. ulBuff = 0x80000000; // TachLite Configuration Register
  1316. writel( ulBuff, fcChip->Registers.TYconfig.address);
  1317. // ulBuff = 0x0147L; // CpqTs PCI CFGCMD register
  1318. // WritePCIConfiguration( fcChip->Backplane.bus,
  1319. // fcChip->Backplane.slot, TLCFGCMD, ulBuff, 4);
  1320. // ulBuff = 0x0L; // test!
  1321. // ReadPCIConfiguration( fcChip->Backplane.bus,
  1322. // fcChip->Backplane.slot, TLCFGCMD, &ulBuff, 4);
  1323. // read back for reference...
  1324. fcChip->Registers.TYconfig.value =
  1325. readl( fcChip->Registers.TYconfig.address );
  1326. // what is the PCI bus width?
  1327. pci_read_config_byte( cpqfcHBAdata->PciDev,
  1328. 0x43, // PCIMCTR offset
  1329. &bBuff);
  1330. fcChip->Registers.PCIMCTR = bBuff;
  1331. // set string identifying the chip on the circuit board
  1332. fcChip->Registers.TYstatus.value =
  1333. readl( fcChip->Registers.TYstatus.address);
  1334. {
  1335. // Now that we are supporting multiple boards, we need to change
  1336. // this logic to check for PCI vendor/device IDs...
  1337. // for now, quick & dirty is simply checking Chip rev
  1338. ULONG RevId = (fcChip->Registers.TYstatus.value &0x3E0)>>5;
  1339. UCHAR Minor = (UCHAR)(RevId & 0x3);
  1340. UCHAR Major = (UCHAR)((RevId & 0x1C) >>2);
  1341. /* printk(" HBA Tachyon RevId %d.%d\n", Major, Minor); */
  1342. if( (Major == 1) && (Minor == 2) )
  1343. {
  1344. sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE66_TS12);
  1345. }
  1346. else if( (Major == 1) && (Minor == 3) )
  1347. {
  1348. sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE66_TS13);
  1349. }
  1350. else if( (Major == 2) && (Minor == 1) )
  1351. {
  1352. sprintf( cpqfcHBAdata->fcChip.Name, SAGILENT_XL2_21);
  1353. }
  1354. else
  1355. sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE_UNKNOWN);
  1356. }
  1357. case 3: // allocate mem, set Tachyon Que registers
  1358. iStatus = CpqTsCreateTachLiteQues( cpqfcHBAdata, opcode2);
  1359. if( iStatus )
  1360. break;
  1361. // now that the Queues exist, Tach can DMA to them, so
  1362. // we can begin processing INTs
  1363. // INTEN register - enable INT (TachLite interrupt)
  1364. writeb( 0x1F, fcChip->Registers.ReMapMemBase + IINTEN);
  1365. // Fall through
  1366. case 4: // Config Fame Manager, Init Loop Command, laser on
  1367. // L_PORT or loopback
  1368. // depending on Options
  1369. iStatus = CpqTsInitializeFrameManager( fcChip,0 );
  1370. if( iStatus )
  1371. {
  1372. // failed to initialize Frame Manager
  1373. break;
  1374. }
  1375. default:
  1376. break;
  1377. }
  1378. LEAVE("InitializeTachLite");
  1379. return iStatus;
  1380. }
  1381. // Depending on the type of platform memory allocation (e.g. dynamic),
  1382. // it's probably best to free memory in opposite order as it was allocated.
  1383. // Order of allocation: see other function
  1384. int CpqTsDestroyTachLiteQues( void *pHBA, int opcode)
  1385. {
  1386. CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA;
  1387. PTACHYON fcChip = &cpqfcHBAdata->fcChip;
  1388. USHORT i, iStatus=0;
  1389. void* vPtr; // mem Align manager sets this to the freed address on success
  1390. unsigned long ulPtr; // for 64-bit pointer cast (e.g. Alpa machine)
  1391. FC_EXCHANGES *Exchanges = fcChip->Exchanges;
  1392. PSGPAGES j, next;
  1393. ENTER("DestroyTachLiteQues");
  1394. if( fcChip->SEST )
  1395. {
  1396. // search out and free Pool for Extended S/G list pages
  1397. for( i=0; i < TACH_SEST_LEN; i++) // for each exchange
  1398. {
  1399. // It's possible that extended S/G pages were allocated, mapped, and
  1400. // not cleared due to error conditions or O/S driver termination.
  1401. // Make sure they're all gone.
  1402. if (Exchanges->fcExchange[i].Cmnd != NULL)
  1403. cpqfc_pci_unmap(cpqfcHBAdata->PciDev, Exchanges->fcExchange[i].Cmnd,
  1404. fcChip, i); // undo DMA mappings.
  1405. for (j=fcChip->SEST->sgPages[i] ; j != NULL ; j = next) {
  1406. next = j->next;
  1407. kfree(j);
  1408. }
  1409. fcChip->SEST->sgPages[i] = NULL;
  1410. }
  1411. ulPtr = (unsigned long)fcChip->SEST;
  1412. vPtr = fcMemManager( cpqfcHBAdata->PciDev,
  1413. &cpqfcHBAdata->dynamic_mem[0],
  1414. 0,0, (ULONG)ulPtr, NULL ); // 'free' mem
  1415. fcChip->SEST = 0L; // null invalid ptr
  1416. if( !vPtr )
  1417. {
  1418. printk("SEST mem not freed\n");
  1419. iStatus = -1;
  1420. }
  1421. }
  1422. if( fcChip->SFQ )
  1423. {
  1424. ulPtr = (unsigned long)fcChip->SFQ;
  1425. vPtr = fcMemManager( cpqfcHBAdata->PciDev,
  1426. &cpqfcHBAdata->dynamic_mem[0],
  1427. 0,0, (ULONG)ulPtr, NULL ); // 'free' mem
  1428. fcChip->SFQ = 0L; // null invalid ptr
  1429. if( !vPtr )
  1430. {
  1431. printk("SFQ mem not freed\n");
  1432. iStatus = -2;
  1433. }
  1434. }
  1435. if( fcChip->IMQ )
  1436. {
  1437. // clear Indexes to show empty Queue
  1438. fcChip->IMQ->producerIndex = 0;
  1439. fcChip->IMQ->consumerIndex = 0;
  1440. ulPtr = (unsigned long)fcChip->IMQ;
  1441. vPtr = fcMemManager( cpqfcHBAdata->PciDev, &cpqfcHBAdata->dynamic_mem[0],
  1442. 0,0, (ULONG)ulPtr, NULL ); // 'free' mem
  1443. fcChip->IMQ = 0L; // null invalid ptr
  1444. if( !vPtr )
  1445. {
  1446. printk("IMQ mem not freed\n");
  1447. iStatus = -3;
  1448. }
  1449. }
  1450. if( fcChip->ERQ ) // release memory blocks used by the queues
  1451. {
  1452. ulPtr = (unsigned long)fcChip->ERQ;
  1453. vPtr = fcMemManager( cpqfcHBAdata->PciDev, &cpqfcHBAdata->dynamic_mem[0],
  1454. 0,0, (ULONG)ulPtr, NULL ); // 'free' mem
  1455. fcChip->ERQ = 0L; // null invalid ptr
  1456. if( !vPtr )
  1457. {
  1458. printk("ERQ mem not freed\n");
  1459. iStatus = -4;
  1460. }
  1461. }
  1462. // free up the primary EXCHANGES struct and Link Q
  1463. cpqfc_free_dma_consistent(cpqfcHBAdata);
  1464. LEAVE("DestroyTachLiteQues");
  1465. return iStatus; // non-zero (failed) if any memory not freed
  1466. }
  1467. // The SFQ is an array with SFQ_LEN length, each element (QEntry)
  1468. // with eight 32-bit words. TachLite places incoming FC frames (i.e.
  1469. // a valid FC frame with our AL_PA ) in contiguous SFQ entries
  1470. // and sends a completion message telling the host where the frame is
  1471. // in the que.
  1472. // This function copies the current (or oldest not-yet-processed) QEntry to
  1473. // a caller's contiguous buffer and updates the Tachyon chip's consumer index
  1474. //
  1475. // NOTE:
  1476. // An FC frame may consume one or many SFQ entries. We know the total
  1477. // length from the completion message. The caller passes a buffer large
  1478. // enough for the complete message (max 2k).
  1479. static void CpqTsGetSFQEntry(
  1480. PTACHYON fcChip,
  1481. USHORT producerNdx,
  1482. ULONG *ulDestPtr, // contiguous destination buffer
  1483. BOOLEAN UpdateChip)
  1484. {
  1485. ULONG total_bytes=0;
  1486. ULONG consumerIndex = fcChip->SFQ->consumerIndex;
  1487. // check passed copy of SFQ producer index -
  1488. // is a new message waiting for us?
  1489. // equal indexes means SFS is copied
  1490. while( producerNdx != consumerIndex )
  1491. { // need to process message
  1492. total_bytes += 64; // maintain count to prevent writing past buffer
  1493. // don't allow copies over Fibre Channel defined length!
  1494. if( total_bytes <= 2048 )
  1495. {
  1496. memcpy( ulDestPtr,
  1497. &fcChip->SFQ->QEntry[consumerIndex],
  1498. 64 ); // each SFQ entry is 64 bytes
  1499. ulDestPtr += 16; // advance pointer to next 64 byte block
  1500. }
  1501. // Tachyon is producing,
  1502. // and we are consuming
  1503. if( ++consumerIndex >= SFQ_LEN)// check for rollover
  1504. consumerIndex = 0L; // reset it
  1505. }
  1506. // if specified, update the Tachlite chip ConsumerIndex...
  1507. if( UpdateChip )
  1508. {
  1509. fcChip->SFQ->consumerIndex = consumerIndex;
  1510. writel( fcChip->SFQ->consumerIndex,
  1511. fcChip->Registers.SFQconsumerIndex.address);
  1512. }
  1513. }
  1514. // TachLite routinely freezes it's core ques - Outbound FIFO, Inbound FIFO,
  1515. // and Exchange Request Queue (ERQ) on error recover -
  1516. // (e.g. whenever a LIP occurs). Here
  1517. // we routinely RESUME by clearing these bits, but only if the loop is up
  1518. // to avoid ERROR IDLE messages forever.
  1519. void CpqTsUnFreezeTachlite( void *pChip, int type )
  1520. {
  1521. PTACHYON fcChip = (PTACHYON)pChip;
  1522. fcChip->Registers.TYcontrol.value =
  1523. readl(fcChip->Registers.TYcontrol.address);
  1524. // (bit 4 of value is GBIC LASER)
  1525. // if we 'unfreeze' the core machines before the loop is healthy
  1526. // (i.e. FLT, OS, LS failure bits set in FMstatus)
  1527. // we can get 'error idle' messages forever. Verify that
  1528. // FMstatus (Link Status) is OK before unfreezing.
  1529. if( !(fcChip->Registers.FMstatus.value & 0x07000000L) && // bits clear?
  1530. !(fcChip->Registers.FMstatus.value & 0x80 )) // Active LPSM?
  1531. {
  1532. fcChip->Registers.TYcontrol.value &= ~0x300L; // clear FEQ, FFA
  1533. if( type == 1 ) // unfreeze ERQ only
  1534. {
  1535. // printk("Unfreezing ERQ\n");
  1536. fcChip->Registers.TYcontrol.value |= 0x10000L; // set REQ
  1537. }
  1538. else // unfreeze both ERQ and FCP-ASSIST (SEST)
  1539. {
  1540. // printk("Unfreezing ERQ & FCP-ASSIST\n");
  1541. // set ROF, RIF, REQ - resume Outbound FCP, Inbnd FCP, ERQ
  1542. fcChip->Registers.TYcontrol.value |= 0x70000L; // set ROF, RIF, REQ
  1543. }
  1544. writel( fcChip->Registers.TYcontrol.value,
  1545. fcChip->Registers.TYcontrol.address);
  1546. }
  1547. // readback for verify (TachLite still frozen?)
  1548. fcChip->Registers.TYstatus.value =
  1549. readl(fcChip->Registers.TYstatus.address);
  1550. }
  1551. // Whenever an FC Exchange Abort is required, we must manipulate the
  1552. // Host/Tachyon shared memory SEST table. Before doing this, we
  1553. // must freeze Tachyon, which flushes certain buffers and ensure we
  1554. // can manipulate the SEST without contention.
  1555. // This freeze function will result in FCP & ERQ FROZEN completion
  1556. // messages (per argument "type").
  1557. void CpqTsFreezeTachlite( void *pChip, int type )
  1558. {
  1559. PTACHYON fcChip = (PTACHYON)pChip;
  1560. fcChip->Registers.TYcontrol.value =
  1561. readl(fcChip->Registers.TYcontrol.address);
  1562. //set FFA, FEQ - freezes SCSI assist and ERQ
  1563. if( type == 1) // freeze ERQ only
  1564. fcChip->Registers.TYcontrol.value |= 0x100L; // (bit 4 is laser)
  1565. else // freeze both FCP assists (SEST) and ERQ
  1566. fcChip->Registers.TYcontrol.value |= 0x300L; // (bit 4 is laser)
  1567. writel( fcChip->Registers.TYcontrol.value,
  1568. fcChip->Registers.TYcontrol.address);
  1569. }
  1570. // TL has two Frame Manager Link Status Registers, with three 8-bit
  1571. // fields each. These eight bit counters are cleared after each read,
  1572. // so we define six 32-bit accumulators for these TL counters. This
  1573. // function breaks out each 8-bit field and adds the value to the existing
  1574. // sum. (s/w counters cleared independently)
  1575. void fcParseLinkStatusCounters(PTACHYON fcChip)
  1576. {
  1577. UCHAR bBuff;
  1578. ULONG ulBuff;
  1579. // The BB0 timer usually increments when TL is initialized, resulting
  1580. // in an initially bogus count. If our own counter is ZERO, it means we
  1581. // are reading this thing for the first time, so we ignore the first count.
  1582. // Also, reading the register does not clear it, so we have to keep an
  1583. // additional static counter to detect rollover (yuk).
  1584. if( fcChip->fcStats.lastBB0timer == 0L) // TL was reset? (ignore 1st values)
  1585. {
  1586. // get TL's register counter - the "last" count
  1587. fcChip->fcStats.lastBB0timer =
  1588. fcChip->Registers.FMBB_CreditZero.value & 0x00ffffffL;
  1589. }
  1590. else // subsequent pass - check for rollover
  1591. {
  1592. // "this" count
  1593. ulBuff = fcChip->Registers.FMBB_CreditZero.value & 0x00ffffffL;
  1594. if( fcChip->fcStats.lastBB0timer > ulBuff ) // rollover happened
  1595. {
  1596. // counter advanced to max...
  1597. fcChip->fcStats.BB0_Timer += (0x00FFFFFFL - fcChip->fcStats.lastBB0timer);
  1598. fcChip->fcStats.BB0_Timer += ulBuff; // plus some more
  1599. }
  1600. else // no rollover -- more counts or no change
  1601. {
  1602. fcChip->fcStats.BB0_Timer += (ulBuff - fcChip->fcStats.lastBB0timer);
  1603. }
  1604. fcChip->fcStats.lastBB0timer = ulBuff;
  1605. }
  1606. bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus1.value >> 24);
  1607. fcChip->fcStats.LossofSignal += bBuff;
  1608. bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus1.value >> 16);
  1609. fcChip->fcStats.BadRXChar += bBuff;
  1610. bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus1.value >> 8);
  1611. fcChip->fcStats.LossofSync += bBuff;
  1612. bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus2.value >> 24);
  1613. fcChip->fcStats.Rx_EOFa += bBuff;
  1614. bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus2.value >> 16);
  1615. fcChip->fcStats.Dis_Frm += bBuff;
  1616. bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus2.value >> 8);
  1617. fcChip->fcStats.Bad_CRC += bBuff;
  1618. }
  1619. void cpqfcTSClearLinkStatusCounters(PTACHYON fcChip)
  1620. {
  1621. ENTER("ClearLinkStatusCounters");
  1622. memset( &fcChip->fcStats, 0, sizeof( FCSTATS));
  1623. LEAVE("ClearLinkStatusCounters");
  1624. }
  1625. // The following function reads the I2C hardware to get the adapter's
  1626. // World Wide Name (WWN).
  1627. // If the WWN is "500805f1fadb43e8" (as printed on the card), the
  1628. // Tachyon WWN_hi (32-bit) register is 500805f1, and WWN_lo register
  1629. // is fadb43e8.
  1630. // In the NVRAM, the bytes appear as:
  1631. // [2d] ..
  1632. // [2e] ..
  1633. // [2f] 50
  1634. // [30] 08
  1635. // [31] 05
  1636. // [32] f1
  1637. // [33] fa
  1638. // [34] db
  1639. // [35] 43
  1640. // [36] e8
  1641. //
  1642. // In the Fibre Channel (Big Endian) format, the FC-AL LISM frame will
  1643. // be correctly loaded by Tachyon silicon. In the login payload, bytes
  1644. // must be correctly swapped for Big Endian format.
  1645. int CpqTsReadWriteWWN( PVOID pChip, int Read)
  1646. {
  1647. PTACHYON fcChip = (PTACHYON)pChip;
  1648. #define NVRAM_SIZE 512
  1649. unsigned short i, count = NVRAM_SIZE;
  1650. UCHAR nvRam[NVRAM_SIZE], WWNbuf[8];
  1651. ULONG ulBuff;
  1652. int iStatus=-1; // assume failure
  1653. int WWNoffset;
  1654. ENTER("ReadWriteWWN");
  1655. // Now try to read the WWN from the adapter's NVRAM
  1656. if( Read ) // READing NVRAM WWN?
  1657. {
  1658. ulBuff = cpqfcTS_ReadNVRAM( fcChip->Registers.TYstatus.address,
  1659. fcChip->Registers.TYcontrol.address,
  1660. count, &nvRam[0] );
  1661. if( ulBuff ) // NVRAM read successful?
  1662. {
  1663. iStatus = 0; // success!
  1664. // for engineering/ prototype boards, the data may be
  1665. // invalid (GIGO, usually all "FF"); this prevents the
  1666. // parse routine from working correctly, which means
  1667. // nothing will be written to our passed buffer.
  1668. WWNoffset = cpqfcTS_GetNVRAM_data( WWNbuf, nvRam );
  1669. if( !WWNoffset ) // uninitialized NVRAM -- copy bytes directly
  1670. {
  1671. printk( "CAUTION: Copying NVRAM data on fcChip\n");
  1672. for( i= 0; i < 8; i++)
  1673. WWNbuf[i] = nvRam[i +0x2f]; // dangerous! some formats won't work
  1674. }
  1675. fcChip->Registers.wwn_hi = 0L;
  1676. fcChip->Registers.wwn_lo = 0L;
  1677. for( i=0; i<4; i++) // WWN bytes are big endian in NVRAM
  1678. {
  1679. ulBuff = 0L;
  1680. ulBuff = (ULONG)(WWNbuf[i]) << (8 * (3-i));
  1681. fcChip->Registers.wwn_hi |= ulBuff;
  1682. }
  1683. for( i=0; i<4; i++) // WWN bytes are big endian in NVRAM
  1684. {
  1685. ulBuff = 0L;
  1686. ulBuff = (ULONG)(WWNbuf[i+4]) << (8 * (3-i));
  1687. fcChip->Registers.wwn_lo |= ulBuff;
  1688. }
  1689. } // done reading
  1690. else
  1691. {
  1692. printk( "cpqfcTS: NVRAM read failed\n");
  1693. }
  1694. }
  1695. else // WRITE
  1696. {
  1697. // NOTE: WRITE not supported & not used in released driver.
  1698. printk("ReadWriteNRAM: can't write NVRAM; aborting write\n");
  1699. }
  1700. LEAVE("ReadWriteWWN");
  1701. return iStatus;
  1702. }
  1703. // The following function reads or writes the entire "NVRAM" contents of
  1704. // the I2C hardware (i.e. the NM24C03). Note that HP's 5121A (TS 66Mhz)
  1705. // adapter does not use the NM24C03 chip, so this function only works on
  1706. // Compaq's adapters.
  1707. int CpqTsReadWriteNVRAM( PVOID pChip, PVOID buf, int Read)
  1708. {
  1709. PTACHYON fcChip = (PTACHYON)pChip;
  1710. #define NVRAM_SIZE 512
  1711. ULONG ulBuff;
  1712. UCHAR *ucPtr = buf; // cast caller's void ptr to UCHAR array
  1713. int iStatus=-1; // assume failure
  1714. if( Read ) // READing NVRAM?
  1715. {
  1716. ulBuff = cpqfcTS_ReadNVRAM( // TRUE on success
  1717. fcChip->Registers.TYstatus.address,
  1718. fcChip->Registers.TYcontrol.address,
  1719. 256, // bytes to write
  1720. ucPtr ); // source ptr
  1721. if( ulBuff )
  1722. iStatus = 0; // success
  1723. else
  1724. {
  1725. #ifdef DBG
  1726. printk( "CAUTION: NVRAM read failed\n");
  1727. #endif
  1728. }
  1729. } // done reading
  1730. else // WRITING NVRAM
  1731. {
  1732. printk("cpqfcTS: WRITE of FC Controller's NVRAM disabled\n");
  1733. }
  1734. return iStatus;
  1735. }