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