~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/net/fc/iph5526.c

Version: ~ [ 2.2.5 ] ~ [ 2.4.1 ] ~ [ 2.4.9 ] ~ [ 2.6.17.10 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /**********************************************************************
  2  * iph5526.c: IP/SCSI driver for the Interphase 5526 PCI Fibre Channel
  3  *                        Card.
  4  * Copyright (C) 1999 Vineet M Abraham <vmabraham@hotmail.com>
  5  *
  6  * This program is free software; you can redistribute it and/or 
  7  * modify it under the terms of the GNU General Public License as 
  8  * published by the Free Software Foundation; either version 2, or 
  9  * (at your option) any later version.
 10  *
 11  * This program is distributed in the hope that it will be useful, but
 12  * WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * General Public License for more details.
 15  *********************************************************************/
 16 /**********************************************************************
 17 Log:
 18 Vineet M Abraham
 19 02.12.99 Support multiple cards.
 20 03.15.99 Added Fabric support.
 21 04.04.99 Added N_Port support.
 22 04.15.99 Added SCSI support.
 23 06.18.99 Added ABTS Protocol.
 24 06.24.99 Fixed data corruption when multiple XFER_RDYs are received.
 25 07.07.99 Can be loaded as part of the Kernel. Changed semaphores. Added
 26          more checks before invalidating SEST entries.
 27 07.08.99 Added Broadcast IP stuff and fixed an unicast timeout bug.
 28 ***********************************************************************/
 29 /* TODO:
 30         R_T_TOV set to 15msec in Loop topology. Need to be 100 msec.
 31     SMP testing.
 32         Fix ADISC Tx before completing FLOGI. 
 33 */      
 34 
 35 static const char *version =
 36     "iph5526.c:v1.0 07.08.99 Vineet Abraham (vmabraham@hotmail.com)\n";
 37 
 38 #include <linux/module.h>
 39 #include <linux/kernel.h>
 40 #include <linux/sched.h>
 41 #include <linux/errno.h>
 42 #include <linux/pci.h>
 43 #include <linux/init.h>
 44 #include <linux/mm.h>
 45 #include <linux/delay.h>
 46 #include <linux/skbuff.h>
 47 #include <linux/if_arp.h>
 48 #include <linux/timer.h>
 49 #include <linux/spinlock.h>
 50 #include <asm/system.h>
 51 #include <asm/io.h>
 52 
 53 #include <linux/netdevice.h>
 54 #include <linux/fcdevice.h> /* had the declarations for init_fcdev among others + includes if_fcdevice.h */
 55 
 56 #include <linux/blk.h>
 57 #include "../../scsi/sd.h"
 58 #include "../../scsi/scsi.h"
 59 #include "../../scsi/hosts.h"
 60 #include "../../fc4/fcp.h"
 61 
 62 /* driver specific header files */
 63 #include "tach.h"
 64 #include "tach_structs.h"
 65 #include "iph5526_ip.h"
 66 #include "iph5526_scsi.h"
 67 #include "iph5526_novram.c"
 68 
 69 #define RUN_AT(x) (jiffies + (x))
 70 
 71 #define DEBUG_5526_0 0
 72 #define DEBUG_5526_1 0
 73 #define DEBUG_5526_2 0
 74 
 75 #if DEBUG_5526_0
 76 #define DPRINTK(format, a...) {printk("%s: ", fi->name); \
 77                                                            printk(format, ##a); \
 78                                                            printk("\n");}
 79 #define ENTER(x)        {printk("%s: ", fi->name); \
 80                                          printk("iph5526.c : entering %s()\n", x);}
 81 #define LEAVE(x)        {printk("%s: ", fi->name); \
 82                                          printk("iph5526.c : leaving %s()\n",x);}
 83 
 84 #else
 85 #define DPRINTK(format, a...) {}
 86 #define ENTER(x)        {}
 87 #define LEAVE(x)        {}
 88 #endif
 89 
 90 #if DEBUG_5526_1
 91 #define DPRINTK1(format, a...) {printk("%s: ", fi->name); \
 92                                                            printk(format, ##a); \
 93                                                            printk("\n");}
 94 #else
 95 #define DPRINTK1(format, a...) {}
 96 #endif
 97 
 98 #if DEBUG_5526_2
 99 #define DPRINTK2(format, a...) {printk("%s: ", fi->name); \
100                                                            printk(format, ##a); \
101                                                            printk("\n");}
102 #else
103 #define DPRINTK2(format, a...) {}
104 #endif
105 
106 #define T_MSG(format, a...) {printk("%s: ", fi->name); \
107                                                          printk(format, ##a);\
108                                                          printk("\n");}
109 
110 #define ALIGNED_SFS_ADDR(addr) ((((unsigned long)(addr) + (SFS_BUFFER_SIZE - 1)) & ~(SFS_BUFFER_SIZE - 1)) - (unsigned long)(addr))
111 #define ALIGNED_ADDR(addr, len) ((((unsigned long)(addr) + (len - 1)) & ~(len - 1)) - (unsigned long)(addr))
112 
113 
114 static struct pci_device_id iph5526_pci_tbl[] __initdata = {
115         { PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_5526, PCI_ANY_ID, PCI_ANY_ID, },
116         { PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_55x6, PCI_ANY_ID, PCI_ANY_ID, },
117         { }                     /* Terminating entry */
118 };
119 MODULE_DEVICE_TABLE(pci, iph5526_pci_tbl);
120 
121 #define MAX_FC_CARDS 2
122 static struct fc_info *fc[MAX_FC_CARDS+1];
123 static unsigned int pci_irq_line;
124 static struct {
125         unsigned short vendor_id;
126         unsigned short device_id;
127         char *name;
128 }
129 clone_list[] __initdata  = {
130         {PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_5526, "Interphase Fibre Channel HBA"},
131         {PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_55x6, "Interphase Fibre Channel HBA"},
132         {0,}
133 };
134 
135 static void tachyon_interrupt(int irq, void *dev_id, struct pt_regs *regs);
136 static void tachyon_interrupt_handler(int irq, void* dev_id, struct pt_regs* regs);
137 
138 static int initialize_register_pointers(struct fc_info *fi);
139 void clean_up_memory(struct fc_info *fi);
140 
141 static int tachyon_init(struct fc_info *fi);
142 static int build_queues(struct fc_info *fi);
143 static void build_tachyon_header(struct fc_info *fi, u_int my_id, u_int r_ctl, u_int d_id, u_int type, u_char seq_id, u_char df_ctl, u_short ox_id, u_short rx_id, char *data);
144 static int get_free_header(struct fc_info *fi);
145 static void build_EDB(struct fc_info *fi, char *data, u_short flags, u_short len);
146 static int get_free_EDB(struct fc_info *fi);
147 static void build_ODB(struct fc_info *fi, u_char seq_id, u_int d_id, u_int len, u_int cntl, u_short mtu, u_short ox_id, u_short rx_id, int NW_header, int int_required, u_int frame_class);
148 static void write_to_tachyon_registers(struct fc_info *fi);
149 static void reset_latch(struct fc_info *fi);
150 static void reset_tachyon(struct fc_info *fi, u_int value);
151 static void take_tachyon_offline(struct fc_info *fi);
152 static void read_novram(struct fc_info *fi);
153 static void reset_ichip(struct fc_info *fi);
154 static void update_OCQ_indx(struct fc_info *fi);
155 static void update_IMQ_indx(struct fc_info *fi, int count);
156 static void update_SFSBQ_indx(struct fc_info *fi);
157 static void update_MFSBQ_indx(struct fc_info *fi, int count);
158 static void update_tachyon_header_indx(struct fc_info *fi);
159 static void update_EDB_indx(struct fc_info *fi);
160 static void handle_FM_interrupt(struct fc_info *fi);
161 static void handle_MFS_interrupt(struct fc_info *fi);
162 static void handle_OOO_interrupt(struct fc_info *fi);
163 static void handle_SFS_interrupt(struct fc_info *fi);
164 static void handle_OCI_interrupt(struct fc_info *fi);
165 static void handle_SFS_BUF_WARN_interrupt(struct fc_info *fi);
166 static void handle_MFS_BUF_WARN_interrupt(struct fc_info *fi);
167 static void handle_IMQ_BUF_WARN_interrupt(struct fc_info *fi);
168 static void handle_Unknown_Frame_interrupt(struct fc_info *fi);
169 static void handle_Busied_Frame_interrupt(struct fc_info *fi);
170 static void handle_Bad_SCSI_Frame_interrupt(struct fc_info *fi);
171 static void handle_Inbound_SCSI_Status_interrupt(struct fc_info *fi);
172 static void handle_Inbound_SCSI_Command_interrupt(struct fc_info *fi);
173 static void completion_message_handler(struct fc_info *fi, u_int imq_int_type);
174 static void fill_login_frame(struct fc_info *fi, u_int logi);
175 
176 static int tx_exchange(struct fc_info *fi, char *data, u_int len, u_int r_ctl, u_int type, u_int d_id, u_int mtu, int int_required, u_short ox_id, u_int frame_class);
177 static int tx_sequence(struct fc_info *fi, char *data, u_int len, u_int mtu, u_int d_id, u_short ox_id, u_short rx_id, u_char seq_id, int NW_flag, int int_required, u_int frame_class);
178 static int validate_login(struct fc_info *fi, u_int *base_ptr);
179 static void add_to_address_cache(struct fc_info *fi, u_int *base_ptr);
180 static void remove_from_address_cache(struct fc_info *fi, u_int *data, u_int cmnd_code);
181 static int node_logged_in_prev(struct fc_info *fi, u_int *buff_addr);
182 static int sid_logged_in(struct fc_info *fi, u_int s_id);
183 static struct fc_node_info *look_up_cache(struct fc_info *fi, char *data);
184 static int display_cache(struct fc_info *fi);
185 
186 static void tx_logi(struct fc_info *fi, u_int logi, u_int d_id);
187 static void tx_logi_acc(struct fc_info *fi, u_int logi, u_int d_id, u_short received_ox_id);
188 static void tx_prli(struct fc_info *fi, u_int command_code, u_int d_id, u_short received_ox_id);
189 static void tx_logo(struct fc_info *fi, u_int d_id, u_short received_ox_id);
190 static void tx_adisc(struct fc_info *fi, u_int cmnd_code, u_int d_id, u_short received_ox_id);
191 static void tx_ls_rjt(struct fc_info *fi, u_int d_id, u_short received_ox_id, u_short reason_code, u_short expln_code);
192 static u_int plogi_ok(struct fc_info *fi, u_int *buff_addr, int size);
193 static void tx_acc(struct fc_info *fi, u_int d_id, u_short received_ox_id);
194 static void tx_name_server_req(struct fc_info *fi, u_int req);
195 static void rscn_handler(struct fc_info *fi, u_int node_id);
196 static void tx_scr(struct fc_info *fi);
197 static void scr_timer(unsigned long data);
198 static void explore_fabric(struct fc_info *fi, u_int *buff_addr);
199 static void perform_adisc(struct fc_info *fi);
200 static void local_port_discovery(struct fc_info *fi);
201 static void add_to_ox_id_list(struct fc_info *fi, u_int transaction_id, u_int cmnd_code);
202 static u_int remove_from_ox_id_list(struct fc_info *fi, u_short received_ox_id);
203 static void add_display_cache_timer(struct fc_info *fi);
204 
205 /* Timers... */
206 static void nos_ols_timer(unsigned long data);
207 static void loop_timer(unsigned long data);
208 static void fabric_explore_timer(unsigned long data);
209 static void port_discovery_timer(unsigned long data);
210 static void display_cache_timer(unsigned long data);
211 
212 /* SCSI Stuff */
213 static int add_to_sest(struct fc_info *fi, Scsi_Cmnd *Cmnd, struct fc_node_info *ni);
214 static struct fc_node_info *resolve_target(struct fc_info *fi, u_char target);
215 static void update_FCP_CMND_indx(struct fc_info *fi);
216 static int get_free_SDB(struct fc_info *fi);
217 static void update_SDB_indx(struct fc_info *fi);
218 static void mark_scsi_sid(struct fc_info *fi, u_int *buff_addr, u_char action);
219 static void invalidate_SEST_entry(struct fc_info *fi, u_short received_ox_id);
220 static int abort_exchange(struct fc_info *fi, u_short ox_id);
221 static void flush_tachyon_cache(struct fc_info *fi, u_short ox_id);
222 static int get_scsi_oxid(struct fc_info *fi);
223 static void update_scsi_oxid(struct fc_info *fi);
224 
225 Scsi_Host_Template driver_template = IPH5526_SCSI_FC;
226 
227 static void iph5526_timeout(struct net_device *dev);
228 
229 static int iph5526_probe_pci(struct net_device *dev);
230 
231 int __init iph5526_probe(struct net_device *dev)
232 {
233         if (pci_present() && (iph5526_probe_pci(dev) == 0))
234                 return 0;
235     return -ENODEV;
236 }
237 
238 static int __init iph5526_probe_pci(struct net_device *dev)
239 {
240 #ifdef MODULE
241         struct fc_info *fi = (struct fc_info *)dev->priv;
242 #else
243         struct fc_info *fi;
244         static int count = 0;
245  
246         if(fc[count] != NULL) {
247                 if (dev == NULL) {
248                         dev = init_fcdev(NULL, 0);
249                         if (dev == NULL)
250                                 return -ENOMEM;
251                 }
252                 fi = fc[count];
253 #endif
254                 fi->dev = dev;
255                 dev->base_addr = fi->base_addr;
256                 dev->irq = fi->irq;
257                 if (dev->priv == NULL) 
258                         dev->priv = fi; 
259                 fcdev_init(dev);
260                 /* Assign ur MAC address.
261                  */
262                 dev->dev_addr[0] = (fi->g.my_port_name_high & 0x0000FF00) >> 8;
263                 dev->dev_addr[1] = fi->g.my_port_name_high;
264                 dev->dev_addr[2] = (fi->g.my_port_name_low & 0xFF000000) >> 24;
265                 dev->dev_addr[3] = (fi->g.my_port_name_low & 0x00FF0000) >> 16;
266                 dev->dev_addr[4] = (fi->g.my_port_name_low & 0x0000FF00) >> 8;
267                 dev->dev_addr[5] = fi->g.my_port_name_low;
268 #ifndef MODULE
269                 count++;
270         }
271         else
272                 return -ENODEV;
273 #endif
274         display_cache(fi);
275         return 0;
276 }
277 
278 static int __init fcdev_init(struct net_device *dev)
279 {
280         dev->open = iph5526_open;
281         dev->stop = iph5526_close;
282         dev->hard_start_xmit = iph5526_send_packet;
283         dev->get_stats = iph5526_get_stats;
284         dev->set_multicast_list = NULL;
285         dev->change_mtu = iph5526_change_mtu; 
286         dev->tx_timeout = iph5526_timeout;
287         dev->watchdog_timeo = 5*HZ;
288 #ifndef MODULE
289         fc_setup(dev);
290 #endif
291         return 0;
292 }
293 
294 /* initialize tachyon and take it OnLine */
295 static int tachyon_init(struct fc_info *fi)
296 {
297         ENTER("tachyon_init");
298         if (build_queues(fi) == 0) {
299                 T_MSG("build_queues() failed");
300                 return 0;
301         }
302 
303         /* Retrieve your port/node name.
304          */
305         read_novram(fi);
306 
307         reset_ichip(fi);
308 
309         reset_tachyon(fi, SOFTWARE_RESET);
310 
311         LEAVE("tachyon_init");
312         return 1;
313 }
314 
315 /* Build the 4 Qs - IMQ, OCQ, MFSBQ, SFSBQ */
316 /* Lots of dma_pages needed as Tachyon DMAs almost everything into 
317  * host memory.
318  */
319 static int build_queues(struct fc_info *fi)
320 {
321 int i,j;
322 u_char *addr;
323         ENTER("build_queues");
324         /* Initializing Queue Variables.
325          */
326         fi->q.ptr_host_ocq_cons_indx = NULL;
327         fi->q.ptr_host_hpcq_cons_indx = NULL;
328         fi->q.ptr_host_imq_prod_indx = NULL;
329 
330         fi->q.ptr_ocq_base = NULL;
331         fi->q.ocq_len = 0;
332         fi->q.ocq_end = 0;
333         fi->q.ocq_prod_indx = 0;
334 
335         fi->q.ptr_imq_base = NULL;
336         fi->q.imq_len = 0;
337         fi->q.imq_end = 0;
338         fi->q.imq_cons_indx = 0;
339         fi->q.imq_prod_indx = 0;
340 
341         fi->q.ptr_mfsbq_base = NULL;
342         fi->q.mfsbq_len = 0;
343         fi->q.mfsbq_end = 0;
344         fi->q.mfsbq_prod_indx = 0;
345         fi->q.mfsbq_cons_indx = 0;
346         fi->q.mfsbuff_len = 0;
347         fi->q.mfsbuff_end = 0;
348         fi->g.mfs_buffer_count = 0;
349 
350         fi->q.ptr_sfsbq_base = NULL;
351         fi->q.sfsbq_len = 0;
352         fi->q.sfsbq_end = 0;
353         fi->q.sfsbq_prod_indx = 0;
354         fi->q.sfsbq_cons_indx = 0;
355         fi->q.sfsbuff_len = 0;
356         fi->q.sfsbuff_end = 0;
357 
358         fi->q.sdb_indx = 0;
359         fi->q.fcp_cmnd_indx = 0;
360 
361         fi->q.ptr_edb_base = NULL;
362         fi->q.edb_buffer_indx = 0;
363         fi->q.ptr_tachyon_header_base = NULL;
364         fi->q.tachyon_header_indx = 0;
365         fi->node_info_list = NULL;
366         fi->ox_id_list = NULL;
367         fi->g.loop_up = FALSE;
368         fi->g.ptp_up = FALSE;
369         fi->g.link_up = FALSE;
370         fi->g.fabric_present = FALSE;
371         fi->g.n_port_try = FALSE;
372         fi->g.dont_init = FALSE;
373         fi->g.nport_timer_set = FALSE;
374         fi->g.lport_timer_set = FALSE;
375         fi->g.no_of_targets = 0;
376         fi->g.sem = 0;
377         fi->g.perform_adisc = FALSE;
378         fi->g.e_i = 0;
379 
380         /* build OCQ */
381         if ( (fi->q.ptr_ocq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) {
382                 T_MSG("failed to get OCQ page");
383                 return 0;
384         }
385         /* set up the OCQ structures */
386         for (i = 0; i < OCQ_LENGTH; i++)
387                 fi->q.ptr_odb[i] = fi->q.ptr_ocq_base + NO_OF_ENTRIES*i;
388 
389         /* build IMQ */
390         if ( (fi->q.ptr_imq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) {
391                 T_MSG("failed to get IMQ page");
392                 return 0;
393         }
394         for (i = 0; i < IMQ_LENGTH; i++)
395                 fi->q.ptr_imqe[i] = fi->q.ptr_imq_base + NO_OF_ENTRIES*i;
396 
397         /* build MFSBQ */
398         if ( (fi->q.ptr_mfsbq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) {
399                 T_MSG("failed to get MFSBQ page");
400                 return 0;
401         }
402         memset((char *)fi->q.ptr_mfsbq_base, 0, MFSBQ_LENGTH * 32);
403         /* Allocate one huge chunk of memory... helps while reassembling
404          * frames.
405          */
406         if ( (addr = (u_char *)__get_free_pages(GFP_KERNEL, 5) ) == 0) {
407                 T_MSG("failed to get MFSBQ page");
408                 return 0;
409         }
410         /* fill in addresses of empty buffers */
411         for (i = 0; i < MFSBQ_LENGTH; i++) {
412                 for (j = 0; j < NO_OF_ENTRIES; j++) {
413                                 *(fi->q.ptr_mfsbq_base + i*NO_OF_ENTRIES + j) = htonl(virt_to_bus(addr));
414                                 addr += MFS_BUFFER_SIZE;
415                 }
416         }
417 
418         /* The number of entries in each MFS buffer is 8. There are 8
419          * MFS buffers. That leaves us with 4096-256 bytes. We use them
420          * as temporary space for ELS frames. This is done to make sure that
421          * the addresses are aligned.
422          */
423         fi->g.els_buffer[0] = fi->q.ptr_mfsbq_base + MFSBQ_LENGTH*NO_OF_ENTRIES;
424         for (i = 1; i < MAX_PENDING_FRAMES; i++)
425                 fi->g.els_buffer[i] = fi->g.els_buffer[i-1] + 64;
426         
427         /* build SFSBQ */
428         if ( (fi->q.ptr_sfsbq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) {
429                 T_MSG("failed to get SFSBQ page");
430                 return 0;
431         }
432         memset((char *)fi->q.ptr_sfsbq_base, 0, SFSBQ_LENGTH * 32);
433         /* fill in addresses of empty buffers */
434         for (i = 0; i < SFSBQ_LENGTH; i++)
435                 for (j = 0; j < NO_OF_ENTRIES; j++){
436                         addr = kmalloc(SFS_BUFFER_SIZE*2, GFP_KERNEL);
437                         if (addr == NULL){ 
438                                 T_MSG("ptr_sfs_buffer : memory not allocated");
439                                 return 0;
440                         }
441                         else {
442                         int offset = ALIGNED_SFS_ADDR(addr);
443                                 memset((char *)addr, 0, SFS_BUFFER_SIZE);
444                                 fi->q.ptr_sfs_buffers[i*NO_OF_ENTRIES +j] = (u_int *)addr;
445                                 addr += offset;
446                                 *(fi->q.ptr_sfsbq_base + i*NO_OF_ENTRIES + j) = htonl(virt_to_bus(addr));
447                         }
448                 }
449 
450         /* The number of entries in each SFS buffer is 8. There are 8
451          * MFS buffers. That leaves us with 4096-256 bytes. We use them
452          * as temporary space for ARP frames. This is done inorder to 
453          * support HW_Types of 0x1 and 0x6. 
454          */
455         fi->g.arp_buffer = (char *)fi->q.ptr_sfsbq_base + SFSBQ_LENGTH*NO_OF_ENTRIES*4;
456         
457         /* build EDB */
458         if ((fi->q.ptr_edb_base = (u_int *)__get_free_pages(GFP_KERNEL, 5) ) == 0) {
459                 T_MSG("failed to get EDB page");
460                 return 0;
461         }
462         for (i = 0; i < EDB_LEN; i++)
463                 fi->q.ptr_edb[i] = fi->q.ptr_edb_base + 2*i;
464 
465         /* build SEST */
466 
467         /* OX_IDs range from 0x0 - 0x4FFF.
468          */
469         if ((fi->q.ptr_sest_base = (u_int *)__get_free_pages(GFP_KERNEL, 5)) == 0) {
470                 T_MSG("failed to get SEST page");
471                 return 0;
472         }
473         for (i = 0; i < SEST_LENGTH; i++)
474                 fi->q.ptr_sest[i] = fi->q.ptr_sest_base + NO_OF_ENTRIES*i;
475         
476         if ((fi->q.ptr_sdb_base = (u_int *)__get_free_pages(GFP_KERNEL, 5)) == 0) {
477                 T_MSG("failed to get SDB page");
478                 return 0;
479         }
480         for (i = 0 ; i < NO_OF_SDB_ENTRIES; i++)
481                 fi->q.ptr_sdb_slot[i] = fi->q.ptr_sdb_base + (SDB_SIZE/4)*i;
482 
483         if ((fi->q.ptr_fcp_cmnd_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) {
484                 T_MSG("failed to get FCP_CMND page");
485                 return 0;
486         }
487         for (i = 0; i < NO_OF_FCP_CMNDS; i++)
488                 fi->q.ptr_fcp_cmnd[i] = fi->q.ptr_fcp_cmnd_base + NO_OF_ENTRIES*i;
489 
490         /* Allocate space for Tachyon Header as well... 
491          */
492         if ((fi->q.ptr_tachyon_header_base = (u_int *)__get_free_pages(GFP_KERNEL, 0) ) == 0) {
493                 T_MSG("failed to get tachyon_header page");
494                 return 0;
495         }
496         for (i = 0; i < NO_OF_TACH_HEADERS; i++) 
497                 fi->q.ptr_tachyon_header[i] = fi->q.ptr_tachyon_header_base + 16*i;
498         
499         /* Allocate memory for indices.
500          * Indices should be aligned on 32 byte boundries. 
501          */
502         fi->q.host_ocq_cons_indx = kmalloc(2*32, GFP_KERNEL);
503         if (fi->q.host_ocq_cons_indx == NULL){ 
504                 T_MSG("fi->q.host_ocq_cons_indx : memory not allocated");
505                 return 0;
506         }
507         fi->q.ptr_host_ocq_cons_indx = fi->q.host_ocq_cons_indx; 
508         if ((u_long)(fi->q.host_ocq_cons_indx) % 32)
509                 fi->q.host_ocq_cons_indx++;
510         
511         fi->q.host_hpcq_cons_indx = kmalloc(2*32, GFP_KERNEL);
512         if (fi->q.host_hpcq_cons_indx == NULL){ 
513                 T_MSG("fi->q.host_hpcq_cons_indx : memory not allocated");
514                 return 0;
515         }
516         fi->q.ptr_host_hpcq_cons_indx= fi->q.host_hpcq_cons_indx;
517         if ((u_long)(fi->q.host_hpcq_cons_indx) % 32)
518                 fi->q.host_hpcq_cons_indx++;
519 
520         fi->q.host_imq_prod_indx = kmalloc(2*32, GFP_KERNEL);
521         if (fi->q.host_imq_prod_indx == NULL){ 
522                 T_MSG("fi->q.host_imq_prod_indx : memory not allocated");
523                 return 0;
524         }
525         fi->q.ptr_host_imq_prod_indx = fi->q.host_imq_prod_indx;
526         if ((u_long)(fi->q.host_imq_prod_indx) % 32)
527                 fi->q.host_imq_prod_indx++;
528 
529         LEAVE("build_queues");
530         return 1;
531 }
532 
533 
534 static void write_to_tachyon_registers(struct fc_info *fi)
535 {
536 u_int bus_addr, bus_indx_addr, i;
537 
538         ENTER("write_to_tachyon_registers");
539 
540         /* Clear Queues each time Tachyon is reset */
541         memset((char *)fi->q.ptr_ocq_base, 0, OCQ_LENGTH * 32);
542         memset((char *)fi->q.ptr_imq_base, 0, IMQ_LENGTH * 32);
543         memset((char *)fi->q.ptr_edb_base, 0, EDB_LEN * 8);
544         memset((char *)fi->q.ptr_sest_base, 0, SEST_LENGTH * 32);
545         memset((char *)fi->q.ptr_sdb_base, 0, NO_OF_SDB_ENTRIES * SDB_SIZE);
546         memset((char *)fi->q.ptr_tachyon_header_base, 0xFF, NO_OF_TACH_HEADERS * TACH_HEADER_SIZE);
547         for (i = 0; i < SEST_LENGTH; i++)
548                 fi->q.free_scsi_oxid[i] = OXID_AVAILABLE;
549         for (i = 0; i < NO_OF_SDB_ENTRIES; i++)
550                 fi->q.sdb_slot_status[i] = SDB_FREE;
551 
552         take_tachyon_offline(fi);
553         writel(readl(fi->t_r.ptr_tach_config_reg) | SCSI_ENABLE | WRITE_STREAM_SIZE | READ_STREAM_SIZE | PARITY_EVEN | OOO_REASSEMBLY_DISABLE, fi->t_r.ptr_tach_config_reg);
554 
555         /* Write OCQ registers */
556         fi->q.ocq_prod_indx = 0;
557         *(fi->q.host_ocq_cons_indx) = 0;
558         
559         /* The Tachyon needs to be passed the "real" address */
560         bus_addr = virt_to_bus(fi->q.ptr_ocq_base);
561         writel(bus_addr, fi->t_r.ptr_ocq_base_reg);
562         writel(OCQ_LENGTH - 1, fi->t_r. ptr_ocq_len_reg);
563         bus_indx_addr = virt_to_bus(fi->q.host_ocq_cons_indx);
564         writel(bus_indx_addr, fi->t_r.ptr_ocq_cons_indx_reg);
565 
566         /* Write IMQ registers */
567         fi->q.imq_cons_indx = 0;
568         *(fi->q.host_imq_prod_indx) = 0;
569         bus_addr = virt_to_bus(fi->q.ptr_imq_base);
570         writel(bus_addr, fi->t_r.ptr_imq_base_reg);
571         writel(IMQ_LENGTH - 1, fi->t_r.ptr_imq_len_reg);
572         bus_indx_addr = virt_to_bus(fi->q.host_imq_prod_indx);
573         writel(bus_indx_addr, fi->t_r.ptr_imq_prod_indx_reg);
574         
575         /* Write MFSBQ registers */
576         fi->q.mfsbq_prod_indx = MFSBQ_LENGTH - 1;
577         fi->q.mfsbuff_end = MFS_BUFFER_SIZE - 1;
578         fi->q.mfsbq_cons_indx = 0;
579         bus_addr = virt_to_bus(fi->q.ptr_mfsbq_base);
580         writel(bus_addr, fi->t_r.ptr_mfsbq_base_reg);
581         writel(MFSBQ_LENGTH - 1, fi->t_r.ptr_mfsbq_len_reg);
582         writel(fi->q.mfsbuff_end, fi->t_r.ptr_mfsbuff_len_reg);
583         /* Do this last as tachyon will prefetch the 
584          * first entry as soon as we write to it.
585          */
586         writel(fi->q.mfsbq_prod_indx, fi->t_r.ptr_mfsbq_prod_reg);
587 
588         /* Write SFSBQ registers */
589         fi->q.sfsbq_prod_indx = SFSBQ_LENGTH - 1;
590         fi->q.sfsbuff_end = SFS_BUFFER_SIZE - 1;
591         fi->q.sfsbq_cons_indx = 0;
592         bus_addr = virt_to_bus(fi->q.ptr_sfsbq_base);
593         writel(bus_addr, fi->t_r.ptr_sfsbq_base_reg);
594         writel(SFSBQ_LENGTH - 1, fi->t_r.ptr_sfsbq_len_reg);
595         writel(fi->q.sfsbuff_end, fi->t_r.ptr_sfsbuff_len_reg);
596         /* Do this last as tachyon will prefetch the first 
597          * entry as soon as we write to it. 
598          */
599         writel(fi->q.sfsbq_prod_indx, fi->t_r.ptr_sfsbq_prod_reg);
600 
601         /* Write SEST registers */
602         bus_addr = virt_to_bus(fi->q.ptr_sest_base);
603         writel(bus_addr, fi->t_r.ptr_sest_base_reg);
604         writel(SEST_LENGTH - 1, fi->t_r.ptr_sest_len_reg);
605         /* the last 2 bits _should_ be 1 */
606         writel(SEST_BUFFER_SIZE - 1, fi->t_r.ptr_scsibuff_len_reg);
607 
608         /* write AL_TIME & E_D_TOV into the registers */
609         writel(TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
610         /* Tell Tachyon to pick a Soft Assigned AL_PA */
611         writel(LOOP_INIT_SOFT_ADDRESS, fi->t_r.ptr_fm_config_reg);
612 
613         /* Read the WWN from EEPROM . But, for now we assign it here. */
614         writel(WORLD_WIDE_NAME_LOW, fi->t_r.ptr_fm_wwn_low_reg);
615         writel(WORLD_WIDE_NAME_HIGH, fi->t_r.ptr_fm_wwn_hi_reg);
616 
617         DPRINTK1("TACHYON initializing as L_Port...\n");
618         writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
619                         
620         LEAVE("write_to_tachyon_registers");
621 }
622 
623 
624 static void tachyon_interrupt(int irq, void* dev_id, struct pt_regs* regs)
625 {
626 struct Scsi_Host *host = dev_id;
627 struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
628 struct fc_info *fi = hostdata->fi; 
629 u_long flags;
630         spin_lock_irqsave(&fi->fc_lock, flags);
631         tachyon_interrupt_handler(irq, dev_id, regs);
632         spin_unlock_irqrestore(&fi->fc_lock, flags);
633 }
634 
635 static void tachyon_interrupt_handler(int irq, void* dev_id, struct pt_regs* regs)
636 {
637 struct Scsi_Host *host = dev_id;
638 struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
639 struct fc_info *fi = hostdata->fi; 
640 u_int *ptr_imq_entry;
641 u_int imq_int_type, current_IMQ_index = 0, prev_IMQ_index;
642 int index, no_of_entries = 0;
643 
644         DPRINTK("\n");
645         ENTER("tachyon_interrupt");
646         if (fi->q.host_imq_prod_indx != NULL) {
647                 current_IMQ_index =  ntohl(*(fi->q.host_imq_prod_indx));
648         }
649         else {
650                 /* _Should not_ happen */
651                 T_MSG("IMQ_indx NULL. DISABLING INTERRUPTS!!!\n");
652                 writel(0x0, fi->i_r.ptr_ichip_hw_control_reg);
653         }
654 
655         if (current_IMQ_index > fi->q.imq_cons_indx)
656                 no_of_entries = current_IMQ_index - fi->q.imq_cons_indx;
657         else
658         if (current_IMQ_index < fi->q.imq_cons_indx)
659                 no_of_entries = IMQ_LENGTH - (fi->q.imq_cons_indx - current_IMQ_index);
660 
661         if (no_of_entries == 0) {
662         u_int ichip_status;
663                 ichip_status = readl(fi->i_r.ptr_ichip_hw_status_reg);
664                 if (ichip_status & 0x20) {
665                         /* Should _never_ happen. Might require a hard reset */
666                         T_MSG("Too bad... PCI Bus Error. Resetting (i)chip"); 
667                         reset_ichip(fi);
668                         T_MSG("DISABLING INTERRUPTS!!!\n");
669                         writel(0x0, fi->i_r.ptr_ichip_hw_control_reg);
670                 }
671         }
672 
673         prev_IMQ_index = current_IMQ_index;
674         for (index = 0; index < no_of_entries; index++) {
675                 ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
676                 imq_int_type = ntohl(*ptr_imq_entry);
677 
678                 completion_message_handler(fi, imq_int_type);
679                 if ((fi->g.link_up == FALSE) && ((imq_int_type == MFS_BUF_WARN) || (imq_int_type == SFS_BUF_WARN) || (imq_int_type == IMQ_BUF_WARN))) 
680                         break;
681                 update_IMQ_indx(fi, 1);
682         
683                 /* Check for more entries */
684                 current_IMQ_index =  ntohl(*(fi->q.host_imq_prod_indx));
685                 if (current_IMQ_index != prev_IMQ_index) {
686                         no_of_entries++;
687                         prev_IMQ_index = current_IMQ_index;
688                 }
689         } /*end of for loop*/           
690         return;
691         LEAVE("tachyon_interrupt");
692 }
693 
694 
695 static void handle_SFS_BUF_WARN_interrupt(struct fc_info *fi)
696 {
697 int i;
698         ENTER("handle_SFS_BUF_WARN_interrupt");
699         if (fi->g.link_up == FALSE) {
700                 reset_tachyon(fi, SOFTWARE_RESET);
701                 return;
702         }
703         /* Free up all but one entry in the Q. 
704          */
705         for (i = 0; i < ((SFSBQ_LENGTH - 1) * NO_OF_ENTRIES); i++) {
706                 handle_SFS_interrupt(fi);
707                 update_IMQ_indx(fi, 1);
708         }
709         LEAVE("handle_SFS_BUF_WARN_interrupt");
710 }
711 
712 /* Untested_Code_Begin */ 
713 static void handle_MFS_BUF_WARN_interrupt(struct fc_info *fi)
714 {
715 int i;
716         ENTER("handle_MFS_BUF_WARN_interrupt");
717         if (fi->g.link_up == FALSE) {
718                 reset_tachyon(fi, SOFTWARE_RESET);
719                 return;
720         }
721         /* FIXME: freeing up 8 entries. 
722          */
723         for (i = 0; i < NO_OF_ENTRIES; i++) {
724                 handle_MFS_interrupt(fi);
725                 update_IMQ_indx(fi, 1);
726         }
727         LEAVE("handle_MFS_BUF_WARN_interrupt");
728 }
729 /*Untested_Code_End */
730 
731 static void handle_IMQ_BUF_WARN_interrupt(struct fc_info *fi)
732 {
733 u_int *ptr_imq_entry;
734 u_int imq_int_type, current_IMQ_index = 0, temp_imq_cons_indx;
735 int index, no_of_entries = 0;
736 
737         ENTER("handle_IMQ_BUF_WARN_interrupt");
738         if (fi->g.link_up == FALSE) {
739                 reset_tachyon(fi, SOFTWARE_RESET);
740                 return;
741         }
742         current_IMQ_index =  ntohl(*(fi->q.host_imq_prod_indx));
743 
744         if (current_IMQ_index > fi->q.imq_cons_indx)
745                 no_of_entries = current_IMQ_index - fi->q.imq_cons_indx;
746         else
747                 if (current_IMQ_index < fi->q.imq_cons_indx)
748                         no_of_entries = IMQ_LENGTH - (fi->q.imq_cons_indx - current_IMQ_index);
749         /* We dont want to look at the same IMQ entry again. 
750          */
751         temp_imq_cons_indx = fi->q.imq_cons_indx + 1;
752         if (no_of_entries != 0)
753                 no_of_entries -= 1;
754         for (index = 0; index < no_of_entries; index++) {
755                 ptr_imq_entry = fi->q.ptr_imqe[temp_imq_cons_indx];
756                 imq_int_type = ntohl(*ptr_imq_entry);
757                 if (imq_int_type != IMQ_BUF_WARN)
758                         completion_message_handler(fi, imq_int_type);
759                 temp_imq_cons_indx++;
760                 if (temp_imq_cons_indx == IMQ_LENGTH)
761                         temp_imq_cons_indx = 0;
762         } /*end of for loop*/   
763         if (no_of_entries != 0)
764                 update_IMQ_indx(fi, no_of_entries);
765         LEAVE("handle_IMQ_BUF_WARN_interrupt");
766 }
767 
768 static void completion_message_handler(struct fc_info *fi, u_int imq_int_type)
769 {
770         switch(imq_int_type) {
771                 case OUTBOUND_COMPLETION:
772                         DPRINTK("OUTBOUND_COMPLETION message received");
773                         break;
774                 case OUTBOUND_COMPLETION_I:
775                         DPRINTK("OUTBOUND_COMPLETION_I message received");
776                         handle_OCI_interrupt(fi);
777                         break;
778                 case OUT_HI_PRI_COMPLETION:
779                         DPRINTK("OUT_HI_PRI_COMPLETION message received");
780                         break;
781                 case OUT_HI_PRI_COMPLETION_I:
782                         DPRINTK("OUT_HI_PRI_COMPLETION_I message received");
783                         break;
784                 case INBOUND_MFS_COMPLETION:
785                         DPRINTK("INBOUND_MFS_COMPLETION message received");
786                         handle_MFS_interrupt(fi);
787                         break;
788                 case INBOUND_OOO_COMPLETION:
789                         DPRINTK("INBOUND_OOO_COMPLETION message received");
790                         handle_OOO_interrupt(fi);
791                         break;
792                 case INBOUND_SFS_COMPLETION:
793                         DPRINTK("INBOUND_SFS_COMPLETION message received");
794                         handle_SFS_interrupt(fi);
795                         break;
796                 case INBOUND_UNKNOWN_FRAME_I:
797                         DPRINTK("INBOUND_UNKNOWN_FRAME message received");
798                         handle_Unknown_Frame_interrupt(fi);
799                         break;
800                 case INBOUND_BUSIED_FRAME:
801                         DPRINTK("INBOUND_BUSIED_FRAME message received");
802                         handle_Busied_Frame_interrupt(fi);
803                         break;
804                 case FRAME_MGR_INTERRUPT:
805                         DPRINTK("FRAME_MGR_INTERRUPT message received");
806                         handle_FM_interrupt(fi);
807                         break;
808                 case READ_STATUS:
809                         DPRINTK("READ_STATUS message received");
810                         break;
811                 case SFS_BUF_WARN:
812                         DPRINTK("SFS_BUF_WARN message received");
813                         handle_SFS_BUF_WARN_interrupt(fi);
814                         break;
815                 case MFS_BUF_WARN:
816                         DPRINTK("MFS_BUF_WARN message received");
817                         handle_MFS_BUF_WARN_interrupt(fi);
818                         break;
819                 case IMQ_BUF_WARN:
820                         DPRINTK("IMQ_BUF_WARN message received");
821                         handle_IMQ_BUF_WARN_interrupt(fi);
822                         break;
823                 case INBOUND_C1_TIMEOUT:
824                         DPRINTK("INBOUND_C1_TIMEOUT message received");
825                         break;
826                 case BAD_SCSI_FRAME:
827                         DPRINTK("BAD_SCSI_FRAME message received");
828                         handle_Bad_SCSI_Frame_interrupt(fi);
829                         break;
830                 case INB_SCSI_STATUS_COMPLETION:
831                         DPRINTK("INB_SCSI_STATUS_COMPL message received");
832                         handle_Inbound_SCSI_Status_interrupt(fi);
833                         break;
834                 case INBOUND_SCSI_COMMAND:
835                         DPRINTK("INBOUND_SCSI_COMMAND message received");
836                         handle_Inbound_SCSI_Command_interrupt(fi);
837                         break;
838                 case INBOUND_SCSI_DATA_COMPLETION:
839                         DPRINTK("INBOUND_SCSI_DATA message received");
840                         /* Only for targets */
841                         break;
842                 default:                
843                         T_MSG("DEFAULT message received, type = %x", imq_int_type);
844                         return;
845         }
846         reset_latch(fi);
847 }
848 
849 static void handle_OCI_interrupt(struct fc_info *fi)
850 {
851 u_int *ptr_imq_entry;
852 u_long transaction_id = 0;
853 unsigned short status, seq_count, transmitted_ox_id;
854 struct Scsi_Host *host = fi->host;
855 struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
856 Scsi_Cmnd *Cmnd;
857 u_int tag;
858 
859         ENTER("handle_OCI_interrupt");
860         ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
861         transaction_id = ntohl(*(ptr_imq_entry + 1));
862         status = ntohl(*(ptr_imq_entry + 2)) >> 16;
863         seq_count = ntohl(*(ptr_imq_entry + 3));
864         DPRINTK("transaction_id= %x", (u_int)transaction_id);
865         tag = transaction_id & 0xFFFF0000;
866         transmitted_ox_id = transaction_id;
867 
868         /* The INT could be either due to TIME_OUT | BAD_ALPA. 
869          * But we check only for TimeOuts. Bad AL_PA will 
870          * caught by FM_interrupt handler. 
871          */
872 
873         if ((status == OCM_TIMEOUT_OR_BAD_ALPA) && (!fi->g.port_discovery) && (!fi->g.perform_adisc)){
874                 DPRINTK("Frame TimeOut on OX_ID = %x", (u_int)transaction_id);
875 
876                 /* Is it a SCSI frame that is timing out ? Not a very good check... 
877                  */
878                 if ((transmitted_ox_id <= MAX_SCSI_OXID) && ((tag == FC_SCSI_BAD_TARGET) || (tag < 0x00FF0000))) {
879                         /* If it is a Bad AL_PA, we report it as BAD_TARGET.
880                          * Else, we allow the command to time-out. A Link
881                          * re-initialization could be taking place.
882                          */
883                         if (tag == FC_SCSI_BAD_TARGET) {
884                                 Cmnd = hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID];
885                                 hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID] = NULL;
886                                 if (Cmnd != NULL) {
887                                         Cmnd->result = DID_BAD_TARGET << 16;
888                                         (*Cmnd->scsi_done) (Cmnd);
889                                 }
890                                 else
891                                         T_MSG("NULL Command out of handler!");
892                         } /* if Bad Target */
893                         else {
894                         u_char missing_target = tag >> 16;
895                         struct fc_node_info *q = fi->node_info_list;
896                                 /* A Node that we thought was logged in has gone
897                                  * away. We are the optimistic kind and we keep
898                                  * hoping that our dear little Target will come back
899                                  * to us. For now we log him out.
900                                  */
901                                 DPRINTK2("Missing Target = %d", missing_target);
902                                 while (q != NULL) {
903                                         if (q->target_id == missing_target) {
904                                                 T_MSG("Target %d Logged out", q->target_id);
905                                                 q->login = LOGIN_ATTEMPTED;
906                                                 if (fi->num_nodes > 0)
907                                                         fi->num_nodes--;
908                                                 tx_logi(fi, ELS_PLOGI, q->d_id);
909                                                 break;
910                                         }
911                                         else
912                                                 q = q->next;
913                                 }
914                         }
915                 } /* End of SCSI frame timing out. */
916                 else {
917                         if (seq_count > 1) {
918                                 /* An IP frame was transmitted to a Bad AL_PA. Free up
919                                  * the skb used.
920                                  */
921                                 dev_kfree_skb_irq((struct sk_buff *)(bus_to_virt(transaction_id)));
922                                 netif_wake_queue(fi->dev);
923                         }
924                 } /* End of IP frame timing out. */
925         } /* End of frame timing out. */
926         else {
927                 /* Frame was transmitted successfully. Check if it was an ELS
928                  * frame or an IP frame or a Bad_Target_Notification frame (in
929                  * case of a ptp_link). Ugly!
930                  */
931                 if ((status == 0) && (seq_count == 0)) {
932                 u_int tag = transaction_id & 0xFFFF0000;
933                 /* Continue with port discovery after an ELS is successfully 
934                  * transmitted. (status == 0). 
935                  */
936                         DPRINTK("tag = %x", tag);
937                         switch(tag) {
938                                 case ELS_FLOGI:
939                                         /* Letz use the Name Server instead */
940                                         fi->g.explore_fabric = TRUE;
941                                         fi->g.port_discovery = FALSE;
942                                         fi->g.alpa_list_index = MAX_NODES;
943                                         add_to_ox_id_list(fi, transaction_id, tag);
944                                         break;
945                                 case ELS_PLOGI:
946                                         if (fi->g.fabric_present && (fi->g.name_server == FALSE))
947                                                 add_to_ox_id_list(fi,transaction_id,ELS_NS_PLOGI);
948                                         else
949                                                 add_to_ox_id_list(fi, transaction_id, tag);
950                                         break;
951                                 case FC_SCSI_BAD_TARGET:
952                                         Cmnd = hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID];
953                                         hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID] = NULL;
954                                         if (Cmnd != NULL) {
955                                                 Cmnd->result = DID_BAD_TARGET << 16;
956                                                 (*Cmnd->scsi_done) (Cmnd);
957                                         }
958                                         else
959                                                 T_MSG("NULL Command out of handler!");
960                                         break;
961                                 default:
962                                         add_to_ox_id_list(fi, transaction_id, tag);
963                         }
964                 
965                         if (fi->g.alpa_list_index >= MAX_NODES) {
966                                 if (fi->g.port_discovery == TRUE) {
967                                         fi->g.port_discovery = FALSE;
968                                         add_display_cache_timer(fi);
969                                 }
970                                 fi->g.alpa_list_index = MAX_NODES;
971                         }
972                         if (fi->g.port_discovery == TRUE) 
973                                 local_port_discovery(fi);
974                 }
975                 else {
976                         /* An IP frame has been successfully transmitted.
977                          * Free the skb that was used for this IP frame.
978                          */
979                         if ((status == 0) && (seq_count > 1)) {
980                                 dev_kfree_skb_irq((struct sk_buff *)(bus_to_virt(transaction_id)));
981                                 netif_wake_queue(fi->dev);
982                         }
983                 }
984         }
985         LEAVE("handle_OCI_interrupt");
986 }
987 
988 /* Right now we discard OOO frames */
989 static void handle_OOO_interrupt(struct fc_info *fi)
990 {
991 u_int *ptr_imq_entry;
992 int queue_indx, offset, payload_size;
993 int no_of_buffers = 1; /* header is in a separate buffer */
994         ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
995         offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
996         queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
997         queue_indx = queue_indx >> 16;
998         payload_size = ntohl(*(ptr_imq_entry + 2)) - TACHYON_HEADER_LEN;
999         /* Calculate total number of buffers */
1000         no_of_buffers += payload_size / MFS_BUFFER_SIZE;
1001         if (payload_size % MFS_BUFFER_SIZE)
1002                 no_of_buffers++;
1003 
1004         /* provide Tachyon will another set of buffers */
1005         fi->g.mfs_buffer_count += no_of_buffers;
1006         if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) {
1007         int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES;
1008                 fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count;
1009                 update_MFSBQ_indx(fi, count);
1010         }
1011 }
1012 
1013 static void handle_MFS_interrupt(struct fc_info *fi)
1014 {
1015 u_int *ptr_imq_entry, *buff_addr;
1016 u_int type_of_frame, s_id;
1017 int queue_indx, offset, payload_size, starting_indx, starting_offset;
1018 u_short received_ox_id;
1019 int no_of_buffers = 1; /* header is in a separate buffer */
1020 struct sk_buff *skb;
1021 int wrap_around = FALSE, no_of_wrap_buffs = NO_OF_ENTRIES - 1;
1022         ENTER("handle_MFS_interrupt");
1023         ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
1024         offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
1025         queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
1026         queue_indx = queue_indx >> 16;
1027         DPRINTK("queue_indx = %d, offset  = %d\n", queue_indx, offset);
1028         payload_size = ntohl(*(ptr_imq_entry + 2)) - TACHYON_HEADER_LEN;
1029         DPRINTK("payload_size = %d", payload_size);
1030         /* Calculate total number of buffers */
1031         no_of_buffers += payload_size / MFS_BUFFER_SIZE;
1032         if (payload_size % MFS_BUFFER_SIZE)
1033                 no_of_buffers++;
1034         DPRINTK("no_of_buffers = %d", no_of_buffers);
1035 
1036         if ((no_of_buffers - 1) <= offset) {
1037                 starting_offset = offset - (no_of_buffers - 1);
1038                 starting_indx = queue_indx;
1039         }
1040         else {
1041         int temp = no_of_buffers - (offset + 1);
1042         int no_of_queues = temp / NO_OF_ENTRIES;
1043                 starting_offset = temp % NO_OF_ENTRIES;
1044                 if (starting_offset != 0) {
1045                         no_of_wrap_buffs = starting_offset - 1; //exclude header
1046                         starting_offset = NO_OF_ENTRIES - starting_offset;
1047                         no_of_queues++;
1048                 }
1049                 starting_indx = queue_indx - no_of_queues;
1050                 if (starting_indx < 0) {
1051                         no_of_wrap_buffs -= (starting_indx + 1) * NO_OF_ENTRIES; 
1052                         starting_indx = MFSBQ_LENGTH + starting_indx;
1053                         wrap_around = TRUE;
1054                 }
1055         }
1056         
1057         DPRINTK("starting_indx = %d, starting offset = %d no_of_wrap_buffs = %d\n", starting_indx, starting_offset, no_of_wrap_buffs);
1058         /* Get Tachyon Header from first buffer */
1059         buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_mfsbq_base + starting_indx*NO_OF_ENTRIES + starting_offset)));
1060         
1061 
1062         /* extract Type of Frame */
1063         type_of_frame = (u_int)ntohl(*(buff_addr + 4)) & 0xFF000000;
1064         s_id = (u_int)ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
1065         received_ox_id = ntohl(*(buff_addr + 6)) >> 16;
1066         buff_addr += MFS_BUFFER_SIZE/4;
1067         DPRINTK("type_of_frame = %x, s_id = %x, ox_id = %x", type_of_frame, s_id, received_ox_id);
1068 
1069         switch(type_of_frame) {
1070           case TYPE_LLC_SNAP:
1071                 skb = dev_alloc_skb(payload_size);
1072                 if (skb == NULL) {
1073                         printk(KERN_NOTICE "%s: In handle_MFS_interrupt() Memory squeeze, dropping packet.\n", fi->name);
1074                         fi->fc_stats.rx_dropped++;
1075                         fi->g.mfs_buffer_count += no_of_buffers;
1076                         if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) {
1077                         int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES;
1078                                 fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count;
1079                                 update_MFSBQ_indx(fi, count);
1080                                 return;
1081                         }
1082                 }
1083                 if (wrap_around) {
1084                 int wrap_size = no_of_wrap_buffs * MFS_BUFFER_SIZE;
1085                 int tail_size = payload_size - wrap_size;
1086                         DPRINTK("wrap_size = %d, tail_size = %d\n", wrap_size, tail_size);
1087                         if (no_of_wrap_buffs) 
1088                                 memcpy(skb_put(skb, wrap_size), buff_addr, wrap_size);
1089                         buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_mfsbq_base)));
1090                         memcpy(skb_put(skb, tail_size), buff_addr, tail_size);
1091                 }
1092                 else
1093                         memcpy(skb_put(skb, payload_size), buff_addr, payload_size);
1094                 rx_net_mfs_packet(fi, skb);
1095                 break;
1096         default:
1097                 T_MSG("Unknown Frame Type received. Type = %x", type_of_frame);
1098         }
1099 
1100         /* provide Tachyon will another set of buffers */
1101         fi->g.mfs_buffer_count += no_of_buffers;
1102         if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) {
1103         int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES;
1104                 fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count;
1105                 update_MFSBQ_indx(fi, count);
1106         }
1107         LEAVE("handle_MFS_interrupt");
1108 }
1109 
1110 static void handle_Unknown_Frame_interrupt(struct fc_info *fi)
1111 {
1112 u_int *ptr_imq_entry;
1113 int queue_indx, offset;
1114         ENTER("handle_Unknown_Frame_interrupt");
1115         ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
1116         offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
1117         queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
1118         queue_indx = queue_indx >> 16;
1119         /* We discard the "unknown" frame */
1120         /* provide Tachyon will another set of buffers */
1121         if (offset == (NO_OF_ENTRIES - 1))
1122                 update_SFSBQ_indx(fi);
1123         LEAVE("handle_Unknown_Frame_interrupt");
1124 }
1125 
1126 static void handle_Busied_Frame_interrupt(struct fc_info *fi)
1127 {
1128 u_int *ptr_imq_entry;
1129 int queue_indx, offset;
1130         ENTER("handle_Busied_Frame_interrupt");
1131         ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
1132         offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
1133         queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
1134         queue_indx = queue_indx >> 16;
1135         /* We discard the "busied" frame */
1136         /* provide Tachyon will another set of buffers */
1137         if (offset == (NO_OF_ENTRIES - 1))
1138                 update_SFSBQ_indx(fi);
1139         LEAVE("handle_Busied_Frame_interrupt");
1140 }
1141 
1142 static void handle_Bad_SCSI_Frame_interrupt(struct fc_info *fi)
1143 {
1144 u_int *ptr_imq_entry, *buff_addr, *tach_header, *ptr_edb;
1145 u_int s_id, rctl, frame_class, burst_len, transfered_len, len = 0;
1146 int queue_indx, offset, payload_size, i;
1147 u_short ox_id, rx_id, x_id, mtu = 512;
1148 u_char target_id = 0xFF;
1149 
1150         ENTER("handle_Bad_SCSI_Frame_interrupt");
1151         ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
1152         offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
1153         queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
1154         queue_indx = queue_indx >> 16;
1155         payload_size = ntohl(*(ptr_imq_entry + 2));
1156 
1157         buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset)));
1158 
1159         rctl = ntohl(*(buff_addr + 2)) & 0xFF000000;
1160         s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
1161         ox_id = ntohl(*(buff_addr + 6)) >> 16;
1162         rx_id = ntohl(*(buff_addr + 6));
1163         x_id = ox_id & MAX_SCSI_XID;
1164 
1165         /* Any frame that comes in with OX_ID that matches an OX_ID 
1166          * that has been allocated for SCSI, will be called a Bad
1167          * SCSI frame if the Exchange is not valid any more.
1168          *
1169          * We will also get a Bad SCSI frame interrupt if we receive
1170          * a XFER_RDY with offset != 0. Tachyon washes its hands off
1171          * this Exchange. We have to take care of ourselves. Grrr...
1172          */
1173         if (rctl == DATA_DESCRIPTOR) {
1174         struct fc_node_info *q = fi->node_info_list;
1175                 while (q != NULL) {
1176                         if (q->d_id == s_id) {
1177                                 target_id = q->target_id;
1178                                 mtu = q->mtu;
1179                                 break;
1180                         }
1181                         else
1182                                 q = q->next;
1183                 }
1184                 frame_class = target_id;
1185                 transfered_len = ntohl(*(buff_addr + 8));
1186                 burst_len = ntohl(*(buff_addr + 9));
1187 
1188                 build_ODB(fi, fi->g.seq_id, s_id, burst_len, 0, mtu, ox_id, rx_id, 0, 0, frame_class << 16);
1189                 /* Update the SEQ_ID and Relative Offset in the 
1190                  * Tachyon Header Structure.
1191                  */
1192                 tach_header = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 5)));
1193                 *(tach_header + 5) = htonl(fi->g.seq_id << 24);
1194                 *(tach_header + 7) = htonl(transfered_len);
1195                 fi->g.odb.hdr_addr = *(fi->q.ptr_sest[x_id] + 5);
1196 
1197                 /* Invalidate the EDBs used 
1198                  */
1199                 ptr_edb = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 7)));
1200 
1201                 for (i = 0; i < EDB_LEN; i++)
1202                         if (fi->q.ptr_edb[i] == ptr_edb)
1203                                 break;
1204                 ptr_edb--;      
1205                 
1206                 if (i < EDB_LEN) {
1207                 int j;
1208                         do {
1209                                 ptr_edb += 2;
1210                                 len += (htonl(*ptr_edb) & 0xFFFF);
1211                                 j = i;
1212                                 fi->q.free_edb_list[i++] = EDB_FREE;
1213                                 if (i == EDB_LEN) {
1214                                         i = 0;
1215                                         ptr_edb = fi->q.ptr_edb_base - 1;
1216                                 }
1217                         } while (len < transfered_len);
1218                         if (len > transfered_len) {
1219                                 ptr_edb--;
1220                                 fi->q.free_edb_list[j] = EDB_BUSY;
1221                         }
1222                         else
1223                                 ptr_edb++;
1224                 }
1225                 else {
1226                         T_MSG("EDB not found while freeing");
1227                         if (offset == (NO_OF_ENTRIES - 1))
1228                                 update_SFSBQ_indx(fi);
1229                         return;
1230                 }
1231 
1232                 /* Update the EDB pointer in the ODB.
1233                  */
1234                 fi->g.odb.edb_addr = htonl(virt_to_bus(ptr_edb));
1235                 memcpy(fi->q.ptr_odb[fi->q.ocq_prod_indx], &(fi->g.odb), sizeof(ODB));
1236                 /* Update the EDB pointer in the SEST entry. We might need
1237                  * this if get another XFER_RDY for the same Exchange.
1238                  */
1239                 *(fi->q.ptr_sest[x_id] + 7) = htonl(virt_to_bus(ptr_edb));
1240 
1241                 update_OCQ_indx(fi);
1242                 if (fi->g.seq_id == MAX_SEQ_ID)
1243                         fi->g.seq_id = 0;
1244                 else
1245                         fi->g.seq_id++;
1246         }
1247         else 
1248         /* Could be a BA_ACC or a BA_RJT.
1249          */
1250         if (rctl == RCTL_BASIC_ACC) {
1251         u_int bls_type = remove_from_ox_id_list(fi, ox_id);
1252                 DPRINTK1("BA_ACC received from S_ID 0x%x with OX_ID = %x in response to %x", s_id, ox_id, bls_type);
1253                 if (bls_type == RCTL_BASIC_ABTS) {
1254                 u_int STE_bit;
1255                         /* Invalidate resources for that Exchange.
1256                          */
1257                         STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
1258                         if (STE_bit & SEST_V) {
1259                                 *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
1260                                 invalidate_SEST_entry(fi, ox_id);
1261                         }
1262                 }
1263         }
1264         else
1265         if (rctl == RCTL_BASIC_RJT) {
1266         u_int bls_type = remove_from_ox_id_list(fi, ox_id);
1267                 DPRINTK1("BA_RJT received from S_ID 0x%x with OX_ID = %x in response to %x", s_id, ox_id, bls_type);
1268                 if (bls_type == RCTL_BASIC_ABTS) {
1269                 u_int STE_bit;
1270                         /* Invalidate resources for that Exchange.
1271                          */
1272                         STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
1273                         if (STE_bit & SEST_V) {
1274                                 *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
1275                                 invalidate_SEST_entry(fi, ox_id);
1276                         }
1277                 }
1278         }
1279         else
1280                 DPRINTK1("Frame with R_CTL = %x received from S_ID 0x%x with OX_ID %x", rctl, s_id, ox_id);
1281 
1282         /* Else, discard the "Bad" SCSI frame.
1283          */
1284 
1285         /* provide Tachyon will another set of buffers 
1286          */
1287         if (offset == (NO_OF_ENTRIES - 1))
1288                 update_SFSBQ_indx(fi);
1289         LEAVE("handle_Bad_SCSI_Frame_interrupt");
1290 }
1291 
1292 static void handle_Inbound_SCSI_Status_interrupt(struct fc_info *fi)
1293 {
1294 struct Scsi_Host *host = fi->host;
1295 struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
1296 u_int *ptr_imq_entry, *buff_addr, *ptr_rsp_info, *ptr_sense_info = NULL;
1297 int queue_indx, offset, payload_size;
1298 u_short received_ox_id, x_id;
1299 Scsi_Cmnd *Cmnd;
1300 u_int fcp_status, fcp_rsp_info_len = 0, fcp_sense_info_len = 0, s_id;
1301         ENTER("handle_SCSI_status_interrupt");
1302 
1303         ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
1304         offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
1305         queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
1306         queue_indx = queue_indx >> 16;
1307         buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset)));
1308         payload_size = ntohl(*(ptr_imq_entry + 2));
1309         received_ox_id = ntohl(*(buff_addr + 6)) >> 16;
1310 
1311         buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset)));
1312 
1313         fcp_status = ntohl(*(buff_addr + 10));
1314         ptr_rsp_info = buff_addr + 14;
1315         if (fcp_status & FCP_STATUS_RSP_LEN)
1316                 fcp_rsp_info_len = ntohl(*(buff_addr + 13));
1317                 
1318         if (fcp_status & FCP_STATUS_SENSE_LEN) {
1319                 ptr_sense_info = ptr_rsp_info + fcp_rsp_info_len / 4;
1320                 fcp_sense_info_len = ntohl(*(buff_addr + 12));
1321                 DPRINTK("sense_info = %x", (u_int)ntohl(*ptr_sense_info));
1322         }
1323         DPRINTK("fcp_status = %x, fcp_rsp_len = %x", fcp_status, fcp_rsp_info_len);
1324         x_id = received_ox_id & MAX_SCSI_XID;
1325         Cmnd = hostdata->cmnd_handler[x_id];
1326         hostdata->cmnd_handler[x_id] = NULL;
1327         if (Cmnd != NULL) {
1328                 memset(Cmnd->sense_buffer, 0, sizeof(Cmnd->sense_buffer));
1329                 /* Check if there is a Sense field */
1330                 if (fcp_status & FCP_STATUS_SENSE_LEN) {
1331                 int size = sizeof(Cmnd->sense_buffer);
1332                         if (fcp_sense_info_len < size)
1333                                 size = fcp_sense_info_len;
1334                         memcpy(Cmnd->sense_buffer, (char *)ptr_sense_info, size);
1335                 }
1336                 Cmnd->result = fcp_status & FCP_STATUS_MASK;
1337                 (*Cmnd->scsi_done) (Cmnd);
1338         }
1339         else
1340                 T_MSG("NULL Command out of handler!");
1341 
1342         invalidate_SEST_entry(fi, received_ox_id);
1343         s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
1344         fi->q.free_scsi_oxid[x_id] = OXID_AVAILABLE;
1345 
1346         /* provide Tachyon will another set of buffers */
1347         if (offset == (NO_OF_ENTRIES - 1))
1348                 update_SFSBQ_indx(fi);
1349         LEAVE("handle_SCSI_status_interrupt");
1350 }
1351 
1352 static void invalidate_SEST_entry(struct fc_info *fi, u_short received_ox_id)
1353 {
1354 u_short x_id = received_ox_id & MAX_SCSI_XID;
1355         /* Invalidate SEST entry if it is an OutBound SEST Entry 
1356          */
1357         if (!(received_ox_id & SCSI_READ_BIT)) {
1358         u_int *ptr_tach_header, *ptr_edb;
1359         u_short temp_ox_id = NOT_SCSI_XID;
1360         int i;
1361                 *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
1362 
1363                 /* Invalidate the Tachyon Header structure 
1364                  */
1365                 ptr_tach_header = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 5)));
1366                 for (i = 0; i < NO_OF_TACH_HEADERS; i++) 
1367                         if(fi->q.ptr_tachyon_header[i] == ptr_tach_header)
1368                                 break;
1369                 if (i < NO_OF_TACH_HEADERS) 
1370                         memset(ptr_tach_header, 0xFF, 32);
1371                 else
1372                         T_MSG("Tachyon Header not found while freeing in invalidate_SEST_entry()");
1373 
1374                 /* Invalidate the EDB used 
1375                  */
1376                 ptr_edb = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 7)));
1377                 for (i = 0; i < EDB_LEN; i++)
1378                         if (fi->q.ptr_edb[i] == ptr_edb)
1379                                 break;
1380                 ptr_edb--;      
1381                 if (i < EDB_LEN) {
1382                         do {
1383                                 ptr_edb += 2;
1384                                 fi->q.free_edb_list[i++] = EDB_FREE;
1385                                 if (i == EDB_LEN) {
1386                                         i = 0;
1387                                         ptr_edb = fi->q.ptr_edb_base - 1;
1388                                 }
1389                         } while ((htonl(*ptr_edb) & 0x80000000) != 0x80000000);
1390                 }
1391                 else
1392                         T_MSG("EDB not found while freeing in invalidate_SEST_entry()");
1393                 
1394                 /* Search for its other header structure and destroy it! 
1395                  */
1396                 if ((ptr_tach_header + 16) < (fi->q.ptr_tachyon_header_base + (MY_PAGE_SIZE/4)))
1397                         ptr_tach_header += 16;
1398                 else
1399                         ptr_tach_header = fi->q.ptr_tachyon_header_base;
1400                 while (temp_ox_id != x_id) {
1401                         temp_ox_id = ntohl(*(ptr_tach_header + 6)) >> 16;
1402                         if (temp_ox_id == x_id) {
1403                                 /* Paranoid checking...
1404                                  */
1405                                 for (i = 0; i < NO_OF_TACH_HEADERS; i++) 
1406                                         if(fi->q.ptr_tachyon_header[i] == ptr_tach_header)
1407                                                 break;
1408                                 if (i < NO_OF_TACH_HEADERS)
1409                                         memset(ptr_tach_header, 0xFF, 32);
1410                                 else
1411                                         T_MSG("Tachyon Header not found while freeing in invalidate_SEST_entry()");
1412                                 break;
1413                         }
1414                         else {
1415                                 if ((ptr_tach_header + 16) < (fi->q.ptr_tachyon_header_base + (MY_PAGE_SIZE/4)))
1416                                         ptr_tach_header += 16;
1417                                 else
1418                                         ptr_tach_header = fi->q.ptr_tachyon_header_base;
1419                         }
1420                 }
1421         }
1422         else {
1423         u_short sdb_table_indx;
1424                 /* An Inbound Command has completed or needs to be Aborted. 
1425                  * Clear up the SDB buffers.
1426                  */
1427                 sdb_table_indx = *(fi->q.ptr_sest[x_id] + 5);
1428                 fi->q.sdb_slot_status[sdb_table_indx] = SDB_FREE;
1429         }
1430 }
1431 
1432 static void handle_Inbound_SCSI_Command_interrupt(struct fc_info *fi)
1433 {
1434 u_int *ptr_imq_entry;
1435 int queue_indx, offset;
1436         ENTER("handle_Inbound_SCSI_Command_interrupt");
1437         ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
1438         offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
1439         queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
1440         queue_indx = queue_indx >> 16;
1441         /* We discard the SCSI frame as we shouldn't be receiving
1442          * a SCSI Command in the first place 
1443          */
1444         /* provide Tachyon will another set of buffers */
1445         if (offset == (NO_OF_ENTRIES - 1))
1446                 update_SFSBQ_indx(fi);
1447         LEAVE("handle_Inbound_SCSI_Command_interrupt");
1448 }
1449 
1450 static void handle_SFS_interrupt(struct fc_info *fi)
1451 {
1452 u_int *ptr_imq_entry, *buff_addr;
1453 u_int class_of_frame, type_of_frame, s_id, els_type = 0, rctl;
1454 int queue_indx, offset, payload_size, login_state;
1455 u_short received_ox_id, fs_cmnd_code;
1456         ENTER("handle_SFS_interrupt");
1457         ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
1458         offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
1459         queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
1460         queue_indx = queue_indx >> 16;
1461         DPRINTK("queue_indx = %d, offset  = %d\n", queue_indx, offset);
1462         payload_size = ntohl(*(ptr_imq_entry + 2));
1463         DPRINTK("payload_size = %d", payload_size);
1464 
1465         buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset)));
1466 
1467         /* extract Type of Frame */
1468         type_of_frame = ntohl(*(buff_addr + 4)) & 0xFF000000;
1469         s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
1470         received_ox_id = ntohl(*(buff_addr + 6)) >> 16;
1471         switch(type_of_frame) {
1472                 case TYPE_BLS:
1473                         rctl = ntohl(*(buff_addr + 2)) & 0xFF000000;
1474                         switch(rctl) {
1475                                 case RCTL_BASIC_ABTS:
1476                                         /* As an Initiator, we should never be receiving 
1477                                          * this.
1478                                          */
1479                                         DPRINTK1("ABTS received from S_ID 0x%x with OX_ID = %x", s_id, received_ox_id);
1480                                         break;
1481                         }
1482                         break;
1483                 case TYPE_ELS:
1484                         class_of_frame = ntohl(*(buff_addr + 8));
1485                         login_state = sid_logged_in(fi, s_id);
1486                         switch(class_of_frame & 0xFF000000) {
1487                                 case ELS_PLOGI:
1488                                         if (s_id != fi->g.my_id) {
1489                                                 u_int ret_code;
1490                                                 DPRINTK1("PLOGI received from D_ID 0x%x with 0X_ID = %x", s_id, received_ox_id);
1491                                                 if ((ret_code = plogi_ok(fi, buff_addr, payload_size)) == 0){
1492                                                         tx_logi_acc(fi, ELS_ACC, s_id, received_ox_id);
1493                                                         add_to_address_cache(fi, buff_addr);
1494                                                 }
1495                                                 else {
1496                                                         u_short cmnd_code = ret_code >> 16;
1497                                                         u_short expln_code =  ret_code;
1498                                                         tx_ls_rjt(fi, s_id, received_ox_id, cmnd_code, expln_code);
1499                                                 }
1500                                         }
1501                                         break;
1502                                 case ELS_ACC:
1503                                         els_type = remove_from_ox_id_list(fi, received_ox_id);
1504                                         DPRINTK1("ELS_ACC received from D_ID 0x%x in response to ELS %x", s_id, els_type);
1505                                         switch(els_type) {
1506                                                 case ELS_PLOGI:
1507                                                         add_to_address_cache(fi, buff_addr);
1508                                                         tx_prli(fi, ELS_PRLI, s_id, OX_ID_FIRST_SEQUENCE);
1509                                                         break;
1510                                                 case ELS_FLOGI:
1511                                                         add_to_address_cache(fi, buff_addr);
1512                                                         fi->g.my_id = ntohl(*(buff_addr + 2)) & 0x00FFFFFF;
1513                                                         fi->g.fabric_present = TRUE;
1514                                                         fi->g.my_ddaa = fi->g.my_id & 0xFFFF00;
1515                                                         /* Login to the Name Server 
1516                                                          */
1517                                                         tx_logi(fi, ELS_PLOGI, DIRECTORY_SERVER); 
1518                                                         break;
1519                                                 case ELS_NS_PLOGI:
1520                                                         fi->g.name_server = TRUE;
1521                                                         add_to_address_cache(fi, buff_addr);
1522                                                         tx_name_server_req(fi, FCS_RFC_4);
1523                                                         tx_scr(fi);
1524                                                         /* Some devices have a delay before 
1525                                                          * registering with the Name Server 
1526                                                          */
1527                                                         udelay(500); 
1528                                                         tx_name_server_req(fi, FCS_GP_ID4);
1529                                                         break;
1530                                                 case ELS_PRLI:
1531                                                         mark_scsi_sid(fi, buff_addr, ADD_ENTRY);
1532                                                         break;
1533                                                 case ELS_ADISC:
1534                                                         if (!(validate_login(fi, buff_addr)))
1535                                                                 tx_logo(fi, s_id, OX_ID_FIRST_SEQUENCE);
1536                                                         break;
1537                                         }
1538                                         break;
1539                                 case ELS_PDISC:
1540                                         DPRINTK1("ELS_PDISC received from D_ID 0x%x", s_id);
1541                                         tx_logo(fi, s_id, received_ox_id);
1542                                         break;
1543                                 case ELS_ADISC:
1544                                         DPRINTK1("ELS_ADISC received from D_ID 0x%x", s_id);
1545                                         if (node_logged_in_prev(fi, buff_addr))
1546                                                 tx_adisc(fi, ELS_ACC, s_id, received_ox_id);
1547                                         else
1548                                                 tx_logo(fi, s_id, received_ox_id);
1549                                         break;
1550                                 case ELS_PRLI:
1551                                         DPRINTK1("ELS_PRLI received from D_ID 0x%x", s_id);
1552                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) {
1553                                                 tx_prli(fi, ELS_ACC, s_id, received_ox_id);
1554                                                 mark_scsi_sid(fi, buff_addr, ADD_ENTRY);
1555                                         }
1556                                         else
1557                                                 tx_logo(fi, s_id, received_ox_id);
1558                                         break;
1559                                 case ELS_PRLO:
1560                                         DPRINTK1("ELS_PRLO received from D_ID 0x%x", s_id);
1561                                         if ((login_state == NODE_LOGGED_OUT) || (login_state == NODE_NOT_PRESENT))
1562                                                 tx_logo(fi, s_id, received_ox_id);
1563                                         else
1564                                         if (login_state == NODE_LOGGED_IN)
1565 
1566                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1567                                         else
1568                                         if (login_state == NODE_PROCESS_LOGGED_IN) {
1569                                                 tx_prli(fi, ELS_ACC, s_id, received_ox_id);
1570                                                 mark_scsi_sid(fi, buff_addr, DELETE_ENTRY);
1571                                         }
1572                                         break;
1573                                 case ELS_LS_RJT:
1574                                         els_type = remove_from_ox_id_list(fi, received_ox_id);
1575                                         DPRINTK1("ELS_LS_RJT received from D_ID 0x%x in response to %x", s_id, els_type);
1576                                         /* We should be chking the reason code.
1577                                          */
1578                                         switch (els_type) {
1579                                                 case ELS_ADISC:
1580                                                         tx_logi(fi, ELS_PLOGI, s_id);
1581                                                         break;
1582                                         }               
1583                                         break;
1584                                 case ELS_LOGO:
1585                                         els_type = remove_from_ox_id_list(fi, received_ox_id);
1586                                         DPRINTK1("ELS_LOGO received from D_ID 0x%x in response to %x", s_id, els_type);
1587                                         remove_from_address_cache(fi, buff_addr, ELS_LOGO);
1588                                         tx_acc(fi, s_id, received_ox_id);
1589                                         if (els_type == ELS_ADISC)
1590                                                 tx_logi(fi, ELS_PLOGI, s_id);
1591                                         break;
1592                                 case ELS_RSCN:
1593                                         DPRINTK1("ELS_RSCN received from D_ID 0x%x", s_id);
1594                                         tx_acc(fi, s_id, received_ox_id);
1595                                         remove_from_address_cache(fi, buff_addr, ELS_RSCN);
1596                                         break;
1597                                 case ELS_FARP_REQ:
1598                                         /* We do not support FARP.
1599                                            So, silently discard it */
1600                                         DPRINTK1("ELS_FARP_REQ received from D_ID 0x%x", s_id);
1601                                         break;
1602                                 case ELS_ABTX:
1603                                         DPRINTK1("ELS_ABTX received from D_ID 0x%x", s_id);
1604                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1605                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1606                                         else
1607                                                 tx_logo(fi, s_id, received_ox_id);
1608                                         break;
1609                                 case ELS_FLOGI:
1610                                         DPRINTK1("ELS_FLOGI received from D_ID 0x%x", s_id);
1611                                         if (fi->g.ptp_up == TRUE) {
1612                                                 /* The node could have come up as an N_Port
1613                                                  * in a Loop! So,try initializing as an NL_port
1614                                                  */
1615                                                 take_tachyon_offline(fi);
1616                                                 /* write AL_TIME & E_D_TOV into the registers */
1617                                                 writel(TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
1618                                                 writel(LOOP_INIT_SOFT_ADDRESS, fi->t_r.ptr_fm_config_reg);
1619                                                 DPRINTK1("FLOGI received, TACHYON initializing as L_Port...\n");
1620                                                 writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
1621                                         }
1622                                         else {
1623                                                 if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1624                                                         tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1625                                                 else
1626                                                         tx_logo(fi, s_id, received_ox_id);
1627                                         }
1628                                         break;
1629                                 case ELS_ADVC:
1630                                         DPRINTK1("ELS_ADVC received from D_ID 0x%x", s_id);
1631                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1632                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1633                                         else
1634                                                 tx_logo(fi, s_id, received_ox_id);
1635                                         break;
1636                                 case ELS_ECHO:
1637                                         DPRINTK1("ELS_ECHO received from D_ID 0x%x", s_id);
1638                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1639                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1640                                         else
1641                                                 tx_logo(fi, s_id, received_ox_id);
1642                                         break;
1643                                 case ELS_ESTC:
1644                                         DPRINTK1("ELS_ESTC received from D_ID 0x%x", s_id);
1645                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1646                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1647                                         else
1648                                                 tx_logo(fi, s_id, received_ox_id);
1649                                         break;
1650                                 case ELS_ESTS:
1651                                         DPRINTK1("ELS_ESTS received from D_ID 0x%x", s_id);
1652                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1653                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1654                                         else
1655                                                 tx_logo(fi, s_id, received_ox_id);
1656                                         break;
1657                                 case ELS_RCS:
1658                                         DPRINTK1("ELS_RCS received from D_ID 0x%x", s_id);
1659                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1660                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1661                                         else
1662                                                 tx_logo(fi, s_id, received_ox_id);
1663                                         break;
1664                                 case ELS_RES:
1665                                         DPRINTK1("ELS_RES received from D_ID 0x%x", s_id);
1666                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1667                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1668                                         else
1669                                                 tx_logo(fi, s_id, received_ox_id);
1670                                         break;
1671                                 case ELS_RLS:
1672                                         DPRINTK1("ELS_RLS received from D_ID 0x%x", s_id);
1673                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1674                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1675                                         else
1676                                                 tx_logo(fi, s_id, received_ox_id);
1677                                         break;
1678                                 case ELS_RRQ:
1679                                         DPRINTK1("ELS_RRQ received from D_ID 0x%x", s_id);
1680                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1681                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1682                                         else
1683                                                 tx_logo(fi, s_id, received_ox_id);
1684                                         break;
1685                                 case ELS_RSS:
1686                                         DPRINTK1("ELS_RSS received from D_ID 0x%x", s_id);
1687                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1688                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1689                                         else
1690                                                 tx_logo(fi, s_id, received_ox_id);
1691                                         break;
1692                                 case ELS_RTV:
1693                                         DPRINTK1("ELS_RTV received from D_ID 0x%x", s_id);
1694                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1695                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1696                                         else
1697                                                 tx_logo(fi, s_id, received_ox_id);
1698                                         break;
1699                                 case ELS_RSI:
1700                                         DPRINTK1("ELS_RSI received from D_ID 0x%x", s_id);
1701                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1702                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1703                                         else
1704                                                 tx_logo(fi, s_id, received_ox_id);
1705                                         break;
1706                                 case ELS_TEST:
1707                                         /* No reply sequence */
1708                                         DPRINTK1("ELS_TEST received from D_ID 0x%x", s_id);
1709                                         break;
1710                                 case ELS_RNC:
1711                                         DPRINTK1("ELS_RNC received from D_ID 0x%x", s_id);
1712                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1713                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1714                                         else
1715                                                 tx_logo(fi, s_id, received_ox_id);
1716                                         break;
1717                                 case ELS_RVCS:
1718                                         DPRINTK1("ELS_RVCS received from D_ID 0x%x", s_id);
1719                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1720                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1721                                         else
1722                                                 tx_logo(fi, s_id, received_ox_id);
1723                                         break;
1724                                 case ELS_TPLS:
1725                                         DPRINTK1("ELS_TPLS received from D_ID 0x%x", s_id);
1726                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1727                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1728                                         else
1729                                                 tx_logo(fi, s_id, received_ox_id);
1730                                         break;
1731                                 case ELS_GAID:
1732                                         DPRINTK1("ELS_GAID received from D_ID 0x%x", s_id);
1733                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1734                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1735                                         else
1736                                                 tx_logo(fi, s_id, received_ox_id);
1737                                         break;
1738                                 case ELS_FACT:
1739                                         DPRINTK1("ELS_FACT received from D_ID 0x%x", s_id);
1740                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1741                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1742                                         else
1743                                                 tx_logo(fi, s_id, received_ox_id);
1744                                         break;
1745                                 case ELS_FAN:
1746                                         /* Hmmm... You don't support FAN ??? */
1747                                         DPRINTK1("ELS_FAN received from D_ID 0x%x", s_id);
1748                                         tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1749                                         break;
1750                                 case ELS_FDACT:
1751                                         DPRINTK1("ELS_FDACT received from D_ID 0x%x", s_id);
1752                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1753                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1754                                         else
1755                                                 tx_logo(fi, s_id, received_ox_id);
1756                                         break;
1757                                 case ELS_NACT:
1758                                         DPRINTK1("ELS_NACT received from D_ID 0x%x", s_id);
1759                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1760                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1761                                         else
1762                                                 tx_logo(fi, s_id, received_ox_id);
1763                                         break;
1764                                 case ELS_NDACT:
1765                                         DPRINTK1("ELS_NDACT received from D_ID 0x%x", s_id);
1766                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1767                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1768                                         else
1769                                                 tx_logo(fi, s_id, received_ox_id);
1770                                         break;
1771                                 case ELS_QoSR:
1772                                         DPRINTK1("ELS_QoSR received from D_ID 0x%x", s_id);
1773                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1774                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1775                                         else
1776                                                 tx_logo(fi, s_id, received_ox_id);
1777                                         break;
1778                                 case ELS_FDISC:
1779                                         DPRINTK1("ELS_FDISC received from D_ID 0x%x", s_id);
1780                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1781                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1782                                         else
1783                                                 tx_logo(fi, s_id, received_ox_id);
1784                                         break;
1785                                 default:
1786                                         DPRINTK1("ELS Frame %x received from D_ID 0x%x", class_of_frame, s_id);
1787                                         if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1788                                                 tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1789                                         else
1790                                                 tx_logo(fi, s_id, received_ox_id);
1791                                         break;
1792                         }
1793                         break;
1794                 case TYPE_FC_SERVICES:
1795                         fs_cmnd_code = (ntohl(*(buff_addr + 10)) & 0xFFFF0000) >>16;
1796                         switch(fs_cmnd_code) {
1797                                 case FCS_ACC:
1798                                         els_type = remove_from_ox_id_list(fi, received_ox_id);
1799                                         DPRINTK1("FCS_ACC received from D_ID 0x%x in response to %x", s_id, els_type);
1800                                         if (els_type == FCS_GP_ID4) 
1801                                                 explore_fabric(fi, buff_addr);
1802                                         break;
1803                                 case FCS_REJECT:
1804                                         DPRINTK1("FCS_REJECT received from D_ID 0x%x in response to %x", s_id, els_type);
1805                                         break;
1806                         }
1807                         break;
1808                 case TYPE_LLC_SNAP:
1809                         rx_net_packet(fi, (u_char *)buff_addr, payload_size);
1810                         break;
1811                 default:
1812                         T_MSG("Frame Type %x received from %x", type_of_frame, s_id);
1813         }
1814 
1815         /* provide Tachyon will another set of buffers */
1816         if (offset == (NO_OF_ENTRIES - 1))
1817                 update_SFSBQ_indx(fi);
1818         LEAVE("handle_SFS_interrupt");
1819 }
1820 
1821 static void handle_FM_interrupt(struct fc_info *fi)
1822 {
1823 u_int fm_status;
1824 u_int tachyon_status;
1825 
1826         ENTER("handle_FM_interrupt");
1827         fm_status = readl(fi->t_r.ptr_fm_status_reg);
1828         tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
1829         DPRINTK("FM_status = %x, Tachyon_status = %x", fm_status, tachyon_status);
1830         if (fm_status & LINK_DOWN) {
1831                 T_MSG("Fibre Channel Link DOWN");
1832                 fm_status = readl(fi->t_r.ptr_fm_status_reg);
1833                 
1834                 del_timer(&fi->explore_timer);
1835                 del_timer(&fi->nport_timer);
1836                 del_timer(&fi->lport_timer);
1837                 del_timer(&fi->display_cache_timer);
1838                 fi->g.link_up = FALSE;
1839                 if (fi->g.ptp_up == TRUE)
1840                         fi->g.n_port_try = FALSE;
1841                 fi->g.ptp_up = FALSE;
1842                 fi->g.port_discovery = FALSE;
1843                 fi->g.explore_fabric = FALSE;
1844                 fi->g.perform_adisc = FALSE;
1845 
1846                 /* Logout will all nodes */
1847                 if (fi->node_info_list) {
1848                         struct fc_node_info *temp_list = fi->node_info_list;
1849                                 while(temp_list) {
1850                                         temp_list->login = LOGIN_ATTEMPTED;
1851                                         temp_list = temp_list->next;
1852                                 }
1853                                 fi->num_nodes = 0;
1854                 }
1855 
1856                 if ((fi->g.n_port_try == FALSE) && (fi->g.dont_init == FALSE)){
1857                         take_tachyon_offline(fi);
1858                         /* write AL_TIME & E_D_TOV into the registers */
1859                         writel(TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
1860                         
1861                         if ((fi->g.fabric_present == TRUE) && (fi->g.loop_up == TRUE)) {
1862                         u_int al_pa = fi->g.my_id & 0xFF;
1863                                 writel((al_pa << 24) | LOOP_INIT_FABRIC_ADDRESS | LOOP_INIT_PREVIOUS_ADDRESS, fi->t_r.ptr_fm_config_reg);
1864                         }
1865                         else 
1866                         if (fi->g.loop_up == TRUE) {
1867                         u_int al_pa = fi->g.my_id & 0xFF;
1868                                 writel((al_pa << 24) | LOOP_INIT_PREVIOUS_ADDRESS, fi->t_r.ptr_fm_config_reg);
1869                         }
1870                         else 
1871                                 writel(LOOP_INIT_SOFT_ADDRESS, fi->t_r.ptr_fm_config_reg);
1872                         fi->g.loop_up = FALSE;
1873                         DPRINTK1("In LDWN TACHYON initializing as L_Port...\n");
1874                         writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
1875                 }
1876         }
1877 
1878     if (fm_status & NON_PARTICIPATING) {
1879                 T_MSG("Did not acquire an AL_PA. I am not participating");
1880     }
1881         else
1882         if ((fm_status & LINK_UP) && ((fm_status & LINK_DOWN) == 0)) {
1883           T_MSG("Fibre Channel Link UP");
1884           if ((fm_status & NON_PARTICIPATING) != TRUE) {
1885                 fi->g.link_up = TRUE;
1886                 if (tachyon_status & OSM_FROZEN) {
1887                         reset_tachyon(fi, ERROR_RELEASE);
1888                         reset_tachyon(fi, OCQ_RESET);
1889                 }
1890                 init_timer(&fi->explore_timer);
1891                 init_timer(&fi->nport_timer);
1892                 init_timer(&fi->lport_timer);
1893                 init_timer(&fi->display_cache_timer);
1894                 if ((fm_status & OLD_PORT) == 0) {
1895                         fi->g.loop_up = TRUE;
1896                         fi->g.ptp_up = FALSE;
1897                         fi->g.my_id = readl(fi->t_r.ptr_fm_config_reg) >> 24;
1898                         DPRINTK1("My AL_PA = %x", fi->g.my_id);
1899                         fi->g.port_discovery = TRUE;
1900                         fi->g.explore_fabric = FALSE;
1901                 }
1902                 else
1903                 if (((fm_status & 0xF0) == OLD_PORT) && ((fm_status & 0x0F) == PORT_STATE_ACTIVE)) {
1904                         fi->g.loop_up = FALSE;
1905                         fi->g.my_id = 0x0;
1906                         /* In a point-to-point configuration, we expect to be
1907                          * connected to an F_Port. This driver does not yet support
1908                          * a configuration where it is connected to another N_Port
1909                          * directly.
1910                          */
1911                         fi->g.explore_fabric = TRUE;
1912                         fi->g.port_discovery = FALSE;
1913                         if (fi->g.n_port_try == FALSE) {
1914                                 take_tachyon_offline(fi);
1915                                 /* write R_T_TOV & E_D_TOV into the registers */
1916                                 writel(PTP_TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
1917                                 writel(BB_CREDIT | NPORT, fi->t_r.ptr_fm_config_reg);
1918                                 fi->g.n_port_try = TRUE;
1919                                 DPRINTK1("In LUP TACHYON initializing as N_Port...\n");
1920                                 writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
1921                         }
1922                         else {
1923                                 fi->g.ptp_up = TRUE;
1924                                 tx_logi(fi, ELS_FLOGI, F_PORT); 
1925                         }
1926                 }
1927                 fi->g.my_ddaa = 0x0;
1928                 fi->g.fabric_present = FALSE; 
1929                 /* We havn't sent out any Name Server Reqs */
1930                 fi->g.name_server = FALSE;
1931                 fi->g.alpa_list_index = 0;
1932                 fi->g.ox_id = NOT_SCSI_XID;
1933                 fi->g.my_mtu = FRAME_SIZE;
1934                 
1935                 /* Implicitly LOGO with all logged-in nodes. 
1936                  */
1937                 if (fi->node_info_list) {
1938                 struct fc_node_info *temp_list = fi->node_info_list;
1939                         while(temp_list) {
1940                                 temp_list->login = LOGIN_ATTEMPTED;
1941                                 temp_list = temp_list->next;
1942                         }
1943                         fi->num_nodes = 0;
1944                         fi->g.perform_adisc = TRUE;
1945                         //fi->g.perform_adisc = FALSE;
1946                         fi->g.port_discovery = FALSE;
1947                         tx_logi(fi, ELS_FLOGI, F_PORT); 
1948                 }
1949                 else { 
1950                         /* If Link coming up for the _first_ time or no nodes
1951                          * were logged in before...
1952                          */
1953                         fi->g.scsi_oxid = 0;
1954                         fi->g.seq_id = 0x00;
1955                         fi->g.perform_adisc = FALSE;
1956                 }
1957 
1958                 /* reset OX_ID table */
1959                 while (fi->ox_id_list) {
1960                 struct ox_id_els_map *temp = fi->ox_id_list;
1961                         fi->ox_id_list = fi->ox_id_list->next;
1962                         kfree(temp);
1963                 }
1964                 fi->ox_id_list = NULL;
1965           } /* End of if partipating */
1966         }
1967 
1968         if (fm_status & ELASTIC_STORE_ERROR) {
1969                 /* Too much junk on the Link 
1970                  */
1971                 /* Trying to clear it up by Txing PLOGI to urself */
1972                 if (fi->g.link_up == TRUE)
1973                         tx_logi(fi, ELS_PLOGI, fi->g.my_id); 
1974         }
1975 
1976         if (fm_status & LOOP_UP) {
1977                 if (tachyon_status & OSM_FROZEN) {
1978                         reset_tachyon(fi, ERROR_RELEASE);
1979                         reset_tachyon(fi, OCQ_RESET);
1980                 }
1981         }
1982         
1983         if (fm_status & NOS_OLS_RECEIVED){
1984                 if (fi->g.nport_timer_set == FALSE) {
1985                         DPRINTK("NOS/OLS Received");
1986                         DPRINTK("FM_status = %x", fm_status);
1987                         fi->nport_timer.function = nos_ols_timer;
1988                         fi->nport_timer.data = (unsigned long)fi;
1989                         fi->nport_timer.expires = RUN_AT((3*HZ)/100); /* 30 msec */
1990                         init_timer(&fi->nport_timer);
1991                         add_timer(&fi->nport_timer);
1992                         fi->g.nport_timer_set = TRUE;
1993                 }
1994         }
1995 
1996         if (((fm_status & 0xF0) == OLD_PORT) && (((fm_status & 0x0F) == PORT_STATE_LF1) || ((fm_status & 0x0F) == PORT_STATE_LF2))) {
1997                 DPRINTK1("Link Fail-I in OLD-PORT.");
1998                 take_tachyon_offline(fi);
1999                 reset_tachyon(fi, SOFTWARE_RESET);
2000         }
2001 
2002         if (fm_status & LOOP_STATE_TIMEOUT){
2003                 if ((fm_status & 0xF0) == ARBITRATING) 
2004                         DPRINTK1("ED_TOV timesout.In ARBITRATING state...");
2005                 if ((fm_status & 0xF0) == ARB_WON)
2006                         DPRINTK1("ED_TOV timesout.In ARBITRATION WON state...");
2007                 if ((fm_status & 0xF0) == OPEN)
2008                         DPRINTK1("ED_TOV timesout.In OPEN state...");
2009                 if ((fm_status & 0xF0) == OPENED)
2010                         DPRINTK1("ED_TOV timesout.In OPENED state...");
2011                 if ((fm_status & 0xF0) == TX_CLS)
2012                         DPRINTK1("ED_TOV timesout.In XMITTED CLOSE state...");
2013                 if ((fm_status & 0xF0) == RX_CLS)
2014                         DPRINTK1("ED_TOV timesout.In RECEIVED CLOSE state...");
2015                 if ((fm_status & 0xF0) == INITIALIZING)
2016                         DPRINTK1("ED_TOV timesout.In INITIALIZING state...");
2017                 DPRINTK1("Initializing Loop...");
2018                 writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
2019         }
2020         
2021         if ((fm_status & BAD_ALPA) && (fi->g.loop_up == TRUE)) {
2022         u_char bad_alpa = (readl(fi->t_r.ptr_fm_rx_al_pa_reg) & 0xFF00) >> 8;
2023                 if (tachyon_status & OSM_FROZEN) {
2024                         reset_tachyon(fi, ERROR_RELEASE);
2025                         reset_tachyon(fi, OCQ_RESET);
2026                 }
2027                 /* Fix for B34 */
2028                 tx_logi(fi, ELS_PLOGI, fi->g.my_id); 
2029 
2030                 if (!fi->g.port_discovery && !fi->g.perform_adisc) {
2031                         if (bad_alpa != 0xFE)
2032                                 DPRINTK("Bad AL_PA = %x", bad_alpa);
2033                 }
2034                 else {
2035                         if ((fi->g.perform_adisc == TRUE) && (bad_alpa == 0x00)) {
2036                                 DPRINTK1("Performing ADISC...");
2037                                 fi->g.fabric_present = FALSE;
2038                                 perform_adisc(fi);
2039                         }
2040                 }
2041         }
2042         
2043         if (fm_status & LIPF_RECEIVED){
2044                 DPRINTK("LIP(F8) Received");
2045         }
2046 
2047         if (fm_status & LINK_FAILURE) {
2048                 if (fm_status & LOSS_OF_SIGNAL)
2049                         DPRINTK1("Detected Loss of Signal.");
2050                 if (fm_status & OUT_OF_SYNC)
2051                         DPRINTK1("Detected Loss of Synchronization.");
2052         }
2053 
2054         if (fm_status & TRANSMIT_PARITY_ERROR) {
2055                 /* Bad! Should not happen. Solution-> Hard Reset.
2056                  */
2057                 T_MSG("Parity Error. Perform Hard Reset!");
2058         }
2059 
2060         if (fi->g.alpa_list_index >= MAX_NODES){
2061                 if (fi->g.port_discovery == TRUE) {
2062                         fi->g.port_discovery = FALSE;
2063                         add_display_cache_timer(fi);
2064                 }
2065                 fi->g.alpa_list_index = MAX_NODES;
2066         }
2067 
2068         if (fi->g.port_discovery == TRUE) 
2069                 local_port_discovery(fi);
2070 
2071         LEAVE("handle_FM_interrupt");
2072         return;
2073 }
2074 
2075 static void local_port_discovery(struct fc_info *fi)
2076 {
2077         if (fi->g.loop_up == TRUE) {
2078                 /* If this is not here, some of the Bad AL_PAs are missed. 
2079                  */
2080                 udelay(20); 
2081                 if ((fi->g.alpa_list_index == 0) && (fi->g.fabric_present == FALSE)){
2082                         tx_logi(fi, ELS_FLOGI, F_PORT); 
2083                 }
2084                 else {
2085                 int login_state = sid_logged_in(fi, fi->g.my_ddaa | alpa_list[fi->g.alpa_list_index]);
2086                         while ((fi->g.alpa_list_index == 0) || ((fi->g.alpa_list_index < MAX_NODES) && ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN) || (alpa_list[fi->g.alpa_list_index] == (fi->g.my_id & 0xFF)))))
2087                                 fi->g.alpa_list_index++;
2088                         if (fi->g.alpa_list_index < MAX_NODES)
2089                                 tx_logi(fi, ELS_PLOGI, alpa_list[fi->g.alpa_list_index]); 
2090                 }
2091                 fi->g.alpa_list_index++;
2092                 if (fi->g.alpa_list_index >= MAX_NODES){
2093                         if (fi->g.port_discovery == TRUE) {
2094                                 fi->g.port_discovery = FALSE;
2095                                 add_display_cache_timer(fi);
2096                         }
2097                         fi->g.alpa_list_index = MAX_NODES;
2098                 }
2099         }
2100 }
2101 
2102 static void nos_ols_timer(unsigned long data)
2103 {
2104 struct fc_info *fi = (struct fc_info*)data;
2105 u_int fm_status;
2106         fm_status = readl(fi->t_r.ptr_fm_status_reg);
2107         DPRINTK1("FM_status in timer= %x", fm_status);
2108         fi->g.nport_timer_set = FALSE;
2109         del_timer(&fi->nport_timer);
2110         if ((fi->g.ptp_up == TRUE) || (fi->g.loop_up == TRUE))
2111                 return;
2112         if (((fm_status & 0xF0) == OLD_PORT) && (((fm_status & 0x0F) == PORT_STATE_ACTIVE) || ((fm_status & 0x0F) == PORT_STATE_OFFLINE))) {
2113                 DPRINTK1("In OLD-PORT after E_D_TOV.");
2114                 take_tachyon_offline(fi);
2115                 /* write R_T_TOV & E_D_TOV into the registers */
2116                 writel(PTP_TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
2117                 writel(BB_CREDIT | NPORT, fi->t_r.ptr_fm_config_reg);
2118                 fi->g.n_port_try = TRUE;
2119                 DPRINTK1("In timer, TACHYON initializing as N_Port...\n");
2120                 writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
2121         }
2122         else
2123         if ((fi->g.lport_timer_set == FALSE) && ((fm_status & 0xF0) == LOOP_FAIL)) {
2124                 DPRINTK1("Loop Fail after E_D_TOV.");
2125                 fi->lport_timer.function = loop_timer;
2126                 fi->lport_timer.data = (unsigned long)fi;
2127                 fi->lport_timer.expires = RUN_AT((8*HZ)/100); 
2128                 init_timer(&fi->lport_timer);
2129                 add_timer(&fi->lport_timer);
2130                 fi->g.lport_timer_set = TRUE;
2131                 take_tachyon_offline(fi);
2132                 reset_tachyon(fi, SOFTWARE_RESET);
2133         }
2134         else
2135         if (((fm_status & 0xF0) == OLD_PORT) && (((fm_status & 0x0F) == PORT_STATE_LF1) || ((fm_status & 0x0F) == PORT_STATE_LF2))) {
2136                 DPRINTK1("Link Fail-II in OLD-PORT.");
2137                 take_tachyon_offline(fi);
2138                 reset_tachyon(fi, SOFTWARE_RESET);
2139         }
2140 }
2141 
2142 static void loop_timer(unsigned long data)
2143 {
2144 struct fc_info *fi = (struct fc_info*)data;
2145         fi->g.lport_timer_set = FALSE;
2146         del_timer(&fi->lport_timer);
2147         if ((fi->g.ptp_up == TRUE) || (fi->g.loop_up == TRUE))
2148                 return;
2149 }
2150 
2151 static void add_display_cache_timer(struct fc_info *fi)
2152 {
2153         fi->display_cache_timer.function = display_cache_timer;
2154         fi->display_cache_timer.data = (unsigned long)fi;
2155         fi->display_cache_timer.expires = RUN_AT(fi->num_nodes * HZ); 
2156         init_timer(&fi->display_cache_timer);
2157         add_timer(&fi->display_cache_timer);
2158 }
2159 
2160 static void display_cache_timer(unsigned long data)
2161 {
2162 struct fc_info *fi = (struct fc_info*)data;
2163         del_timer(&fi->display_cache_timer);
2164         display_cache(fi);
2165         return;
2166 }
2167 
2168 static void reset_tachyon(struct fc_info *fi, u_int value)
2169 {
2170 u_int tachyon_status, reset_done = OCQ_RESET_STATUS | SCSI_FREEZE_STATUS;
2171 int not_done = 1, i = 0;
2172         writel(value, fi->t_r.ptr_tach_control_reg);
2173         if (value == OCQ_RESET) 
2174                 fi->q.ocq_prod_indx = 0;
2175         tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
2176 
2177         /* Software resets are immediately done, whereas other aren't. It 
2178         about 30 clocks to do the reset */
2179         if (value != SOFTWARE_RESET) {
2180                 while(not_done) {
2181                         if (i++ > 100000) {
2182                                 T_MSG("Reset was unsuccessful! Tachyon Status = %x", tachyon_status);
2183                                 break;
2184                         }
2185                         tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
2186                         if ((tachyon_status & reset_done) == 0)
2187                                 not_done = 0;
2188                 }
2189         }
2190         else {
2191                 write_to_tachyon_registers(fi);
2192         }
2193 }
2194 
2195 static void take_tachyon_offline(struct fc_info *fi)
2196 {
2197 u_int fm_status = readl(fi->t_r.ptr_fm_status_reg);
2198 
2199         /* The first two conditions will never be true. The Manual and
2200          * the errata say this. But the current implementation is
2201          * decently stable.
2202          */      
2203         //if ((fm_status & 0xF0) == LOOP_FAIL) {
2204         if (fm_status == LOOP_FAIL) {
2205                 // workaround as in P. 89 
2206                 writel(HOST_CONTROL, fi->t_r.ptr_fm_control_reg);
2207                 if (fi->g.loop_up == TRUE)
2208                         writel(SOFTWARE_RESET, fi->t_r.ptr_tach_control_reg);
2209                 else {
2210                         writel(OFFLINE, fi->t_r.ptr_fm_control_reg);
2211                         writel(EXIT_HOST_CONTROL, fi->t_r.ptr_fm_control_reg);
2212                 }
2213         }
2214         else
2215         //if ((fm_status & LOOP_UP) == LOOP_UP) {
2216         if (fm_status == LOOP_UP) {
2217                 writel(SOFTWARE_RESET, fi->t_r.ptr_tach_control_reg);
2218         }
2219         else
2220                 writel(OFFLINE, fi->t_r.ptr_fm_control_reg);
2221 }
2222 
2223 
2224 static void read_novram(struct fc_info *fi)
2225 {
2226 int off = 0;
2227         fi->n_r.ptr_novram_hw_control_reg = fi->i_r.ptr_ichip_hw_control_reg; 
2228         fi->n_r.ptr_novram_hw_status_reg = fi->i_r.ptr_ichip_hw_status_reg; 
2229         iph5526_nr_do_init(fi);
2230         if (fi->clone_id == PCI_VENDOR_ID_INTERPHASE)
2231                 off = 32;
2232         
2233         fi->g.my_node_name_high = (fi->n_r.data[off] << 16) | fi->n_r.data[off+1];
2234         fi->g.my_node_name_low = (fi->n_r.data[off+2] << 16) | fi->n_r.data[off+3];
2235         fi->g.my_port_name_high = (fi->n_r.data[off+4] << 16) | fi->n_r.data[off+5];
2236         fi->g.my_port_name_low = (fi->n_r.data[off+6] << 16) | fi->n_r.data[off+7];
2237         DPRINTK("node_name = %x %x", fi->g.my_node_name_high, fi->g.my_node_name_low);
2238         DPRINTK("port_name = %x %x", fi->g.my_port_name_high, fi->g.my_port_name_low);
2239 }
2240 
2241 static void reset_ichip(struct fc_info *fi)
2242 {
2243         /* (i)chip reset */
2244         writel(ICHIP_HCR_RESET, fi->i_r.ptr_ichip_hw_control_reg);
2245         /*wait for chip to get reset */
2246         mdelay(10);
2247         /*de-assert reset */
2248         writel(ICHIP_HCR_DERESET, fi->i_r.ptr_ichip_hw_control_reg);
2249         
2250         /* enable INT lines on the (i)chip */
2251         writel(ICHIP_HCR_ENABLE_INTA , fi->i_r.ptr_ichip_hw_control_reg);
2252         /* enable byte swap */
2253         writel(ICHIP_HAMR_BYTE_SWAP_ADDR_TR, fi->i_r.ptr_ichip_hw_addr_mask_reg);
2254 }
2255 
2256 static void tx_logi(struct fc_info *fi, u_int logi, u_int d_id)
2257 {
2258 int int_required = 1;
2259 u_short ox_id = OX_ID_FIRST_SEQUENCE;
2260 u_int r_ctl = RCTL_ELS_UCTL;
2261 u_int type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
2262 u_int my_mtu = fi->g.my_mtu;
2263         ENTER("tx_logi");
2264         /* We dont want interrupted for our own logi. 
2265          * It screws up the port discovery process. 
2266          */
2267         if (d_id == fi->g.my_id)
2268                 int_required = 0;
2269         fill_login_frame(fi, logi);     
2270         fi->g.type_of_frame = FC_ELS;
2271         memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.login, sizeof(LOGIN));
2272         tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),sizeof(LOGIN), r_ctl, type, d_id, my_mtu, int_required, ox_id, logi);
2273         fi->g.e_i++;
2274         if (fi->g.e_i == MAX_PENDING_FRAMES)
2275                 fi->g.e_i = 0;
2276         LEAVE("tx_logi");
2277         return;
2278 }
2279 
2280 static void tx_logi_acc(struct fc_info *fi, u_int logi, u_int d_id, u_short received_ox_id)
2281 {
2282 int int_required = 0;
2283 u_int r_ctl = RCTL_ELS_SCTL;
2284 u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE;
2285 u_int my_mtu = fi->g.my_mtu;
2286         ENTER("tx_logi_acc");
2287         fill_login_frame(fi, logi);     
2288         fi->g.type_of_frame = FC_ELS;
2289         memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.login, sizeof(LOGIN));
2290         tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),sizeof(LOGIN), r_ctl, type, d_id, my_mtu, int_required, received_ox_id, logi);
2291         fi->g.e_i++;
2292         if (fi->g.e_i == MAX_PENDING_FRAMES)
2293                 fi->g.e_i = 0;
2294         LEAVE("tx_logi_acc");
2295         return;
2296 }
2297 
2298 static void tx_prli(struct fc_info *fi, u_int command_code, u_int d_id, u_short received_ox_id)
2299 {
2300 int int_required = 1;
2301 u_int r_ctl = RCTL_ELS_UCTL;
2302 u_int type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
2303 u_int my_mtu = fi->g.my_mtu;
2304         ENTER("tx_prli");
2305         if (command_code == ELS_PRLI)
2306                 fi->g.prli.cmnd_code = htons((ELS_PRLI | PAGE_LEN) >> 16);
2307         else {
2308                 fi->g.prli.cmnd_code = htons((ELS_ACC | PAGE_LEN) >> 16);
2309                 int_required = 0;
2310                 type  = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE;
2311                 r_ctl = RCTL_ELS_SCTL;
2312         }
2313         fi->g.prli.payload_length = htons(PRLI_LEN);
2314         fi->g.prli.type_code = htons(FCP_TYPE_CODE);
2315         fi->g.prli.est_image_pair = htons(IMAGE_PAIR);
2316         fi->g.prli.responder_pa = 0;
2317         fi->g.prli.originator_pa = 0;
2318         fi->g.prli.service_params = htonl(INITIATOR_FUNC | READ_XFER_RDY_DISABLED);
2319         fi->g.type_of_frame = FC_ELS;
2320         memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.prli, sizeof(PRLI));
2321         tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]), sizeof(PRLI), r_ctl, type, d_id, my_mtu, int_required, received_ox_id, command_code);
2322         fi->g.e_i++;
2323         if (fi->g.e_i == MAX_PENDING_FRAMES)
2324                 fi->g.e_i = 0;
2325         LEAVE("tx_prli");
2326         return;
2327 }
2328 
2329 static void tx_logo(struct fc_info *fi, u_int d_id, u_short received_ox_id)
2330 {
2331 int int_required = 1;
2332 u_int r_ctl = RCTL_ELS_UCTL;
2333 u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | SEQUENCE_RESPONDER | FIRST_SEQUENCE | END_SEQUENCE | SEQUENCE_INITIATIVE;
2334 int size = sizeof(LOGO);
2335 char fc_id[3];
2336 u_int my_mtu = fi->g.my_mtu;
2337         ENTER("tx_logo");
2338         fi->g.logo.logo_cmnd = htonl(ELS_LOGO);
2339         fi->g.logo.reserved = 0;
2340         memcpy(fc_id, &(fi->g.my_id), 3);
2341         fi->g.logo.n_port_id_0 = fc_id[0];
2342         fi->g.logo.n_port_id_1 = fc_id[1];
2343         fi->g.logo.n_port_id_2 = fc_id[2];
2344         fi->g.logo.port_name_up = htonl(N_PORT_NAME_HIGH);
2345         fi->g.logo.port_name_low = htonl(N_PORT_NAME_LOW);
2346         fi->g.type_of_frame = FC_ELS;
2347         memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.logo, sizeof(LOGO));
2348         tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, received_ox_id, ELS_LOGO);
2349         fi->g.e_i++;
2350         if (fi->g.e_i == MAX_PENDING_FRAMES)
2351                 fi->g.e_i = 0;
2352         LEAVE("tx_logo");
2353 }
2354 
2355 static void tx_adisc(struct fc_info *fi, u_int cmnd_code, u_int d_id, u_short received_ox_id)
2356 {
2357 int int_required = 0;
2358 u_int r_ctl = RCTL_ELS_SCTL;
2359 u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | SEQUENCE_RESPONDER | FIRST_SEQUENCE | END_SEQUENCE;
2360 int size = sizeof(ADISC);
2361 u_int my_mtu = fi->g.my_mtu;
2362         fi->g.adisc.ls_cmnd_code = htonl(cmnd_code);
2363         fi->g.adisc.hard_address = htonl(0);
2364         fi->g.adisc.port_name_high = htonl(N_PORT_NAME_HIGH);   
2365         fi->g.adisc.port_name_low = htonl(N_PORT_NAME_LOW);     
2366         fi->g.adisc.node_name_high = htonl(NODE_NAME_HIGH);     
2367         fi->g.adisc.node_name_low = htonl(NODE_NAME_LOW);       
2368         fi->g.adisc.n_port_id = htonl(fi->g.my_id);
2369         if (cmnd_code == ELS_ADISC) {
2370                 int_required = 1;
2371                 r_ctl = RCTL_ELS_UCTL;
2372                 type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
2373         }
2374         fi->g.type_of_frame = FC_ELS;
2375         memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.adisc, size);
2376         tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, received_ox_id, cmnd_code);
2377         fi->g.e_i++;
2378         if (fi->g.e_i == MAX_PENDING_FRAMES)
2379                 fi->g.e_i = 0;
2380 }
2381 
2382 static void tx_ls_rjt(struct fc_info *fi, u_int d_id, u_short received_ox_id, u_short reason_code, u_short expln_code)
2383 {
2384 int int_required = 0;
2385 u_int r_ctl = RCTL_ELS_SCTL;
2386 u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE;
2387 int size = sizeof(LS_RJT);
2388 u_int my_mtu = fi->g.my_mtu;
2389         ENTER("tx_ls_rjt");
2390         fi->g.ls_rjt.cmnd_code = htonl(ELS_LS_RJT);
2391         fi->g.ls_rjt.reason_code = htonl((reason_code << 16) | expln_code); 
2392         fi->g.type_of_frame = FC_ELS;
2393         memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.ls_rjt, size);
2394         tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, received_ox_id, ELS_LS_RJT);
2395         fi->g.e_i++;
2396         if (fi->g.e_i == MAX_PENDING_FRAMES)
2397                 fi->g.e_i = 0;
2398         LEAVE("tx_ls_rjt");
2399 }
2400 
2401 static void tx_abts(struct fc_info *fi, u_int d_id, u_short ox_id)
2402 {
2403 int int_required = 1;
2404 u_int r_ctl = RCTL_BASIC_ABTS;
2405 u_int type  = TYPE_BLS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
2406 int size = 0;
2407 u_int my_mtu = fi->g.my_mtu;
2408         ENTER("tx_abts");
2409         fi->g.type_of_frame = FC_BLS;
2410         tx_exchange(fi, NULL, size, r_ctl, type, d_id, my_mtu, int_required, ox_id, RCTL_BASIC_ABTS);
2411         LEAVE("tx_abts");
2412 }
2413 
2414 static u_int plogi_ok(struct fc_info *fi, u_int *buff_addr, int size)
2415 {
2416 int ret_code = 0;
2417 u_short mtu = ntohl(*(buff_addr + 10)) & 0x00000FFF;
2418 u_short class3 = ntohl(*(buff_addr + 25)) >> 16;
2419 u_short class3_conc_seq = ntohl(*(buff_addr + 27)) >> 16;
2420 u_short open_seq = ntohl(*(buff_addr + 28)) >> 16;
2421         DPRINTK1("mtu = %x class3 = %x conc_seq = %x open_seq = %x", mtu, class3, class3_conc_seq, open_seq);   
2422         size -= TACHYON_HEADER_LEN;
2423         if (!(class3 & 0x8000)) {
2424                 DPRINTK1("Received PLOGI with class3 = %x", class3);
2425                 ret_code = (LOGICAL_ERR << 16) | NO_EXPLN;
2426                 return ret_code;
2427         }
2428         if (mtu < 256) {
2429                 DPRINTK1("Received PLOGI with MTU set to %x", mtu);
2430                 ret_code = (LOGICAL_ERR << 16) | RECV_FIELD_SIZE;
2431                 return ret_code;
2432         }
2433         if (size != PLOGI_LEN) {        
2434                 DPRINTK1("Received PLOGI of size %x", size);
2435                 ret_code = (LOGICAL_ERR << 16) | INV_PAYLOAD_LEN;
2436                 return ret_code;
2437         }
2438         if (class3_conc_seq == 0) {     
2439                 DPRINTK1("Received PLOGI with conc_seq == 0");
2440                 ret_code = (LOGICAL_ERR << 16) | CONC_SEQ;
2441                 return ret_code;
2442         }
2443         if (open_seq == 0) {    
2444                 DPRINTK1("Received PLOGI with open_seq == 0");
2445                 ret_code = (LOGICAL_ERR << 16) | NO_EXPLN;
2446                 return ret_code;
2447         }
2448 
2449         /* Could potentially check for more fields, but might end up
2450            not talking to most of the devices. ;-) */
2451         /* Things that could get checked are:
2452            common_features = 0x8800
2453            total_concurrent_seq = at least 1
2454         */
2455         return ret_code;
2456 }
2457 
2458 static void tx_acc(struct fc_info *fi, u_int d_id, u_short received_ox_id)
2459 {
2460 int int_required = 0;
2461 u_int r_ctl = RCTL_ELS_SCTL;
2462 u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE;
2463 int size = sizeof(ACC);
2464 u_int my_mtu = fi->g.my_mtu;
2465         ENTER("tx_acc");
2466         fi->g.acc.cmnd_code = htonl(ELS_ACC);
2467         fi->g.type_of_frame = FC_ELS;
2468         memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.acc, size);
2469         tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, received_ox_id, ELS_ACC);
2470         fi->g.e_i++;
2471         if (fi->g.e_i == MAX_PENDING_FRAMES)
2472                 fi->g.e_i = 0;
2473         LEAVE("tx_acc");
2474 }
2475 
2476 
2477 static void tx_name_server_req(struct fc_info *fi, u_int req)
2478 {
2479 int int_required = 1, i, size = 0;
2480 u_short ox_id = OX_ID_FIRST_SEQUENCE;
2481 u_int type  = TYPE_FC_SERVICES | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
2482 u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_CONTROL;
2483 u_int my_mtu = fi->g.my_mtu, d_id = DIRECTORY_SERVER;
2484 CT_HDR ct_hdr;
2485         ENTER("tx_name_server_req");
2486         /* Fill up CT_Header */
2487         ct_hdr.rev_in_id = htonl(FC_CT_REV);
2488         ct_hdr.fs_type = DIRECTORY_SERVER_APP;
2489         ct_hdr.fs_subtype = NAME_SERVICE;
2490         ct_hdr.options = 0;
2491         ct_hdr.resv1 = 0;
2492         ct_hdr.cmnd_resp_code = htons(req >> 16);
2493         ct_hdr.max_res_size = 0;
2494         ct_hdr.resv2 = 0;
2495         ct_hdr.reason_code = 0;
2496         ct_hdr.expln_code = 0;
2497         ct_hdr.vendor_unique = 0;
2498         
2499         fi->g.type_of_frame = FC_ELS;
2500         switch(req) {
2501                 case FCS_RFC_4:
2502                         memcpy(&(fi->g.rfc_4.ct_hdr), &ct_hdr, sizeof(CT_HDR));
2503                         fi->g.rfc_4.s_id = htonl(fi->g.my_id);
2504                         for (i = 0; i < 32; i++)
2505                                 fi->g.rfc_4.bit_map[i] = 0;
2506                         /* We support IP & SCSI */
2507                         fi->g.rfc_4.bit_map[2] = 0x01;
2508                         fi->g.rfc_4.bit_map[3] = 0x20;
2509                         size = sizeof(RFC_4);
2510                         memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.rfc_4, size);
2511                         tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, ox_id, req);
2512                         break;
2513                 case FCS_GP_ID4:
2514                         memcpy(&(fi->g.gp_id4.ct_hdr), &ct_hdr, sizeof(CT_HDR));
2515                         fi->g.gp_id4.port_type = htonl(PORT_TYPE_NX_PORTS);
2516                         size = sizeof(GP_ID4);
2517                         memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.gp_id4, size);
2518                         tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, ox_id, req);
2519                         break;
2520         }
2521         fi->g.e_i++;
2522         if (fi->g.e_i == MAX_PENDING_FRAMES)
2523                 fi->g.e_i = 0;
2524         LEAVE("tx_name_server_req");
2525 }
2526 
2527 static void tx_scr(struct fc_info *fi)
2528 {
2529 int int_required = 1, size = sizeof(SCR);
2530 u_short ox_id = OX_ID_FIRST_SEQUENCE;
2531 u_int type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
2532 u_int r_ctl = RCTL_ELS_UCTL;
2533 u_int my_mtu = fi->g.my_mtu, d_id = FABRIC_CONTROLLER;
2534         ENTER("tx_scr");
2535         fi->g.scr.cmnd_code = htonl(ELS_SCR);
2536         fi->g.scr.reg_function = htonl(FULL_REGISTRATION);
2537         fi->g.type_of_frame = FC_ELS;
2538         memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.scr, size);
2539         tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, ox_id, ELS_SCR);
2540         fi->g.e_i++;
2541         if (fi->g.e_i == MAX_PENDING_FRAMES)
2542                 fi->g.e_i = 0;
2543         LEAVE("tx_scr");
2544 }
2545 
2546 static void perform_adisc(struct fc_info *fi)
2547 {
2548 int count = 0;
2549         /* Will be set to TRUE when timer expires in a PLDA environment. 
2550          */
2551         fi->g.port_discovery = FALSE;
2552 
2553         if (fi->node_info_list) {
2554                 struct fc_node_info *temp_list = fi->node_info_list;
2555                 while(temp_list) {
2556                         /* Tx ADISC to all non-fabric based 
2557                          * entities.
2558                          */
2559                         if ((temp_list->d_id & 0xFF0000) != 0xFF0000)
2560                                 tx_adisc(fi, ELS_ADISC, temp_list->d_id, OX_ID_FIRST_SEQUENCE);
2561                         temp_list = temp_list->next;
2562                         udelay(20);
2563                         count++;
2564                 }
2565         }
2566         /* Perform Port Discovery after timer expires.
2567          * We are giving time for the ADISCed nodes to respond
2568          * so that we dont have to perform PLOGI to those whose
2569          * login are _still_ valid.
2570          */
2571         fi->explore_timer.function = port_discovery_timer;
2572         fi->explore_timer.data = (unsigned long)fi;
2573         fi->explore_timer.expires = RUN_AT((count*3*HZ)/100); 
2574         init_timer(&fi->explore_timer);
2575         add_timer(&fi->explore_timer);
2576 }
2577 
2578 static void explore_fabric(struct fc_info *fi, u_int *buff_addr)
2579 {
2580 u_int *addr = buff_addr + 12; /* index into payload */
2581 u_char control_code;
2582 u_int d_id;
2583 int count = 0;
2584         ENTER("explore_fabric");
2585         DPRINTK1("entering explore_fabric");
2586 
2587         /*fi->g.perform_adisc = TRUE;
2588         fi->g.explore_fabric = TRUE;
2589         perform_adisc(fi);*/
2590         
2591         do {
2592                 d_id = ntohl(*addr) & 0x00FFFFFF;
2593                 if (d_id != fi->g.my_id) {
2594                         if (sid_logged_in(fi, d_id) == NODE_NOT_PRESENT)
2595                                 tx_logi(fi, ELS_PLOGI, d_id); 
2596                         else
2597                         if (sid_logged_in(fi, d_id) == NODE_LOGGED_OUT)
2598                                 tx_adisc(fi, ELS_ADISC, d_id, OX_ID_FIRST_SEQUENCE); 
2599                         count++;
2600                 }
2601                 control_code = (ntohl(*addr) & 0xFF000000) >> 24;
2602                 addr++;
2603                 DPRINTK1("cc = %x, d_id = %x", control_code, d_id);
2604         } while (control_code != 0x80);
2605         
2606         fi->explore_timer.function = fabric_explore_timer;
2607         fi->explore_timer.data = (unsigned long)fi;
2608         /* We give 30 msec for each device to respond and then send out
2609          * our SCSI enquiries. 
2610          */
2611         fi->explore_timer.expires = RUN_AT((count*3*HZ)/100); 
2612         init_timer(&fi->explore_timer);
2613         add_timer(&fi->explore_timer);
2614 
2615         DPRINTK1("leaving explore_fabric");
2616         LEAVE("explore_fabric");
2617 }
2618 
2619 static void fabric_explore_timer(unsigned long data)
2620 {
2621 struct fc_info *fi = (struct fc_info*)data;
2622         del_timer(&fi->explore_timer);
2623 
2624         if ((fi->g.loop_up == TRUE) && (fi->g.ptp_up == FALSE)) {
2625                 /* Initiate Local Port Discovery on the Local Loop.
2626                  */
2627                 fi->g.port_discovery = TRUE;
2628                 fi->g.alpa_list_index = 1;
2629                 local_port_discovery(fi);
2630         }
2631         fi->g.explore_fabric = FALSE;
2632         return;
2633 }
2634 
2635 static void port_discovery_timer(unsigned long data)
2636 {
2637 struct fc_info *fi = (struct fc_info*)data;
2638         del_timer(&fi->explore_timer);
2639         
2640         if ((fi->g.loop_up == TRUE) && (fi->g.explore_fabric != TRUE)) {
2641                 fi->g.port_discovery = TRUE;
2642                 fi->g.alpa_list_index = 1;
2643                 local_port_discovery(fi);
2644         }
2645         fi->g.perform_adisc = FALSE;
2646         return;
2647 }
2648 
2649 static void add_to_ox_id_list(struct fc_info *fi, u_int transaction_id, u_int cmnd_code)
2650 {
2651 struct ox_id_els_map *p, *q = fi->ox_id_list, *r = NULL;
2652 int size = sizeof(struct ox_id_els_map);
2653         while (q != NULL) {
2654                 r = q;
2655                 q = q->next;
2656         }
2657         p = (struct ox_id_els_map *)kmalloc(size, GFP_ATOMIC);
2658         if (p == NULL) {
2659                 T_MSG("kmalloc failed in add_to_ox_id_list()");
2660                 return;
2661         }
2662         p->ox_id = transaction_id;
2663         p->els = cmnd_code;
2664         p->next = NULL;
2665         if (fi->ox_id_list == NULL)
2666                 fi->ox_id_list = p;
2667         else
2668                 r->next = p;
2669         return;
2670 }
2671 
2672 static u_int remove_from_ox_id_list(struct fc_info *fi, u_short received_ox_id)
2673 {
2674 struct ox_id_els_map *p = fi->ox_id_list, *q = fi->ox_id_list;
2675 u_int els_type;
2676         while (q != NULL) {
2677                 if (q->ox_id == received_ox_id) {
2678 
2679                         if (q == fi->ox_id_list) 
2680                                 fi->ox_id_list = fi->ox_id_list->next;
2681                         else
2682                                 if (q->next == NULL) 
2683                                         p->next = NULL;
2684                         else 
2685                                         p->next = q->next;
2686 
2687                         els_type = q->els;
2688                         kfree(q);
2689                         return els_type;
2690                 }
2691                 p = q;
2692                 q = q->next;
2693         }
2694         if (q == NULL)
2695                 DPRINTK2("Could not find ox_id %x in ox_id_els_map", received_ox_id);
2696         return 0;
2697 }
2698 
2699 static void build_tachyon_header(struct fc_info *fi, u_int my_id, u_int r_ctl, u_int d_id, u_int type, u_char seq_id, u_char df_ctl, u_short ox_id, u_short rx_id, char *data)
2700 {
2701 u_char alpa = d_id & 0x0000FF;
2702 u_int dest_ddaa = d_id &0xFFFF00;
2703 
2704         ENTER("build_tachyon_header");
2705         DPRINTK("d_id = %x, my_ddaa = %x", d_id, fi->g.my_ddaa);
2706         /* Does it have to go to/thru a Fabric? */
2707         if ((dest_ddaa != 0) && ((d_id == F_PORT) || (fi->g.fabric_present && (dest_ddaa != fi->g.my_ddaa))))
2708                 alpa = 0x00;
2709         fi->g.tach_header.resv = 0x00000000;
2710         fi->g.tach_header.sof_and_eof = SOFI3 | EOFN;
2711         fi->g.tach_header.dest_alpa = alpa;
2712         /* Set LCr properly to have enuff credit */
2713         if (alpa == REPLICATE)
2714                 fi->g.tach_header.lcr_and_time_stamp = htons(0xC00);/* LCr=3 */
2715         else
2716                 fi->g.tach_header.lcr_and_time_stamp = 0;
2717         fi->g.tach_header.r_ctl_and_d_id = htonl(r_ctl | d_id);
2718         fi->g.tach_header.vc_id_and_s_id = htonl(my_id);
2719         fi->g.tach_header.type_and_f_cntl = htonl(type);
2720         fi->g.tach_header.seq_id = seq_id;
2721         fi->g.tach_header.df_cntl = df_ctl;
2722         fi->g.tach_header.seq_cnt = 0;
2723         fi->g.tach_header.ox_id = htons(ox_id);
2724         fi->g.tach_header.rx_id = htons(rx_id);
2725         fi->g.tach_header.ro = 0;
2726         if (data) {
2727                 /* We use the Seq_Count to keep track of IP frames in the
2728                  * OCI_interrupt handler. Initial Seq_Count of IP frames is 1.
2729                  */
2730                 if (fi->g.type_of_frame == FC_BROADCAST)
2731                         fi->g.tach_header.seq_cnt = htons(0x1);
2732                 else
2733                         fi->g.tach_header.seq_cnt = htons(0x2);
2734                 fi->g.tach_header.nw_header.d_naa = htons(0x1000);
2735                 fi->g.tach_header.nw_header.s_naa = htons(0x1000);
2736                 memcpy(&(fi->g.tach_header.nw_header.dest_high), data, 2);
2737                 memcpy(&(fi->g.tach_header.nw_header.dest_low), data + 2, 4);
2738                 memcpy(&(fi->g.tach_header.nw_header.source_high), data + 6, 2);
2739                 memcpy(&(fi->g.tach_header.nw_header.source_low), data + 8, 4);
2740         }
2741         LEAVE("build_tachyon_header");
2742 }
2743 
2744 static void build_EDB(struct fc_info *fi, char *data, u_short flags, u_short len)
2745 {
2746         fi->g.edb.buf_addr = ntohl((u_int)virt_to_bus(data));
2747         fi->g.edb.ehf = ntohs(flags);
2748         if (len % 4)
2749                 len += (4 - (len % 4));
2750         fi->g.edb.buf_len = ntohs(len);
2751 }
2752 
2753 static void build_ODB(struct fc_info *fi, u_char seq_id, u_int d_id, u_int len, u_int cntl, u_short mtu, u_short ox_id, u_short rx_id, int NW_header, int int_required, u_int frame_class)
2754 {
2755         fi->g.odb.seq_d_id = htonl(seq_id << 24 | d_id);
2756         fi->g.odb.tot_len = len;
2757         if (NW_header)
2758                 fi->g.odb.tot_len += NW_HEADER_LEN;
2759         if (fi->g.odb.tot_len % 4)
2760                 fi->g.odb.tot_len += (4 - (fi->g.odb.tot_len % 4));
2761         fi->g.odb.tot_len = htonl(fi->g.odb.tot_len);
2762         switch(int_required) {
2763                 case NO_COMP_AND_INT:
2764                         fi->g.odb.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | ODB_NO_INT | ODB_NO_COMP | cntl);
2765                         break;
2766                 case INT_AND_COMP_REQ:
2767                         fi->g.odb.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | cntl);
2768                         break;
2769                 case NO_INT_COMP_REQ:
2770                         fi->g.odb.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | ODB_NO_INT | cntl);
2771                         break;
2772         }
2773         fi->g.odb.rx_id = htons(rx_id);
2774         fi->g.odb.cs_enable = 0;
2775         fi->g.odb.cs_seed = htons(1);
2776 
2777         fi->g.odb.hdr_addr = htonl(virt_to_bus(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx]));
2778         fi->g.odb.frame_len = htons(mtu);
2779 
2780         if (NW_header) {
2781                 /* The pointer to the sk_buff is in here. Freed up when the
2782                  * OCI_interrupt is received.
2783                  */
2784                 fi->g.odb.trans_id = htonl(frame_class);
2785                 fi->g.odb.hdr_len = TACHYON_HEADER_LEN + NW_HEADER_LEN;
2786         }
2787         else {
2788                 /* helps in tracking transmitted OX_IDs */
2789                 fi->g.odb.trans_id = htonl((frame_class & 0xFFFF0000) | ox_id);
2790                 fi->g.odb.hdr_len = TACHYON_HEADER_LEN;
2791         }
2792         fi->g.odb.hdr_len = htons(fi->g.odb.hdr_len);
2793                 
2794         fi->g.odb.edb_addr = htonl(virt_to_bus(fi->q.ptr_edb[fi->q.edb_buffer_indx]));
2795 }
2796 
2797 static void fill_login_frame(struct fc_info *fi, u_int logi)
2798 {
2799 int i;
2800         fi->g.login.ls_cmnd_code= htonl(logi);
2801         fi->g.login.fc_ph_version = htons(PH_VERSION);
2802         if (fi->g.loop_up)
2803                 fi->g.login.buff_to_buff_credit = htons(LOOP_BB_CREDIT);
2804         else
2805         if (fi->g.ptp_up)
2806                 fi->g.login.buff_to_buff_credit = htons(PT2PT_BB_CREDIT);
2807         if ((logi != ELS_FLOGI) || (logi == ELS_ACC))
2808                 fi->g.login.common_features = htons(PLOGI_C_F);
2809         else
2810         if (logi == ELS_FLOGI)
2811                 fi->g.login.common_features = htons(FLOGI_C_F);
2812         fi->g.login.recv_data_field_size = htons(FRAME_SIZE);
2813         fi->g.login.n_port_total_conc_seq = htons(CONCURRENT_SEQUENCES);
2814         fi->g.login.rel_off_by_info_cat = htons(RO_INFO_CATEGORY);
2815         fi->g.login.ED_TOV = htonl(E_D_TOV);
2816         fi->g.login.n_port_name_high = htonl(N_PORT_NAME_HIGH);
2817         fi->g.login.n_port_name_low = htonl(N_PORT_NAME_LOW);
2818         fi->g.login.node_name_high = htonl(NODE_NAME_HIGH);
2819         fi->g.login.node_name_low = htonl(NODE_NAME_LOW);
2820         
2821         /* Fill Class 1 parameters */
2822         fi->g.login.c_of_s[0].service_options = htons(0);
2823         fi->g.login.c_of_s[0].initiator_ctl = htons(0);
2824         fi->g.login.c_of_s[0].recipient_ctl = htons(0);
2825         fi->g.login.c_of_s[0].recv_data_field_size = htons(0);
2826         fi->g.login.c_of_s[0].concurrent_sequences = htons(0);
2827         fi->g.login.c_of_s[0].n_port_end_to_end_credit = htons(0);
2828         fi->g.login.c_of_s[0].open_seq_per_exchange = htons(0);
2829         fi->g.login.c_of_s[0].resv = htons(0);
2830 
2831         /* Fill Class 2 parameters */
2832         fi->g.login.c_of_s[1].service_options = htons(0);
2833         fi->g.login.c_of_s[1].initiator_ctl = htons(0);
2834         fi->g.login.c_of_s[1].recipient_ctl = htons(0);
2835         fi->g.login.c_of_s[1].recv_data_field_size = htons(0);
2836         fi->g.login.c_of_s[1].concurrent_sequences = htons(0);
2837         fi->g.login.c_of_s[1].n_port_end_to_end_credit = htons(0);
2838         fi->g.login.c_of_s[1].open_seq_per_exchange = htons(0);
2839         fi->g.login.c_of_s[1].resv = htons(0);
2840 
2841         /* Fill Class 3 parameters */
2842         if (logi == ELS_FLOGI)
2843                 fi->g.login.c_of_s[2].service_options  = htons(SERVICE_VALID | SEQUENCE_DELIVERY);
2844         else
2845                 fi->g.login.c_of_s[2].service_options  = htons(SERVICE_VALID);
2846         fi->g.login.c_of_s[2].initiator_ctl = htons(0);
2847         fi->g.login.c_of_s[2].recipient_ctl = htons(0);
2848         fi->g.login.c_of_s[2].recv_data_field_size = htons(FRAME_SIZE);
2849         fi->g.login.c_of_s[2].concurrent_sequences = htons(CLASS3_CONCURRENT_SEQUENCE);
2850         fi->g.login.c_of_s[2].n_port_end_to_end_credit = htons(0);
2851         fi->g.login.c_of_s[2].open_seq_per_exchange = htons(CLASS3_OPEN_SEQUENCE);
2852         fi->g.login.c_of_s[2].resv = htons(0);
2853         
2854         for(i = 0; i < 4; i++) {
2855                 fi->g.login.resv[i] = 0;
2856                 fi->g.login.vendor_version_level[i] = 0;
2857         }
2858 }
2859 
2860 
2861 /* clear the Interrupt Latch on the (i)chip, so that you can receive 
2862  * Interrupts from Tachyon in future 
2863  */
2864 static void reset_latch(struct fc_info *fi)
2865 {
2866         writel(readl(fi->i_r.ptr_ichip_hw_status_reg) | ICHIP_HSR_INT_LATCH, fi->i_r.ptr_ichip_hw_status_reg);
2867 }
2868 
2869 static void update_OCQ_indx(struct fc_info *fi)
2870 {
2871         fi->q.ocq_prod_indx++;
2872         if (fi->q.ocq_prod_indx == OCQ_LENGTH)
2873                 fi->q.ocq_prod_indx = 0;
2874         writel(fi->q.ocq_prod_indx, fi->t_r.ptr_ocq_prod_indx_reg);
2875 }
2876 
2877 static void update_IMQ_indx(struct fc_info *fi, int count)
2878 {
2879         fi->q.imq_cons_indx += count;
2880         if (fi->q.imq_cons_indx >= IMQ_LENGTH)
2881                 fi->q.imq_cons_indx -= IMQ_LENGTH;
2882         writel(fi->q.imq_cons_indx, fi->t_r.ptr_imq_cons_indx_reg);
2883 }
2884 
2885 static void update_SFSBQ_indx(struct fc_info *fi)
2886 {
2887         fi->q.sfsbq_prod_indx++;
2888         if (fi->q.sfsbq_prod_indx == SFSBQ_LENGTH)
2889                 fi->q.sfsbq_prod_indx = 0;
2890         writel(fi->q.sfsbq_prod_indx, fi->t_r.ptr_sfsbq_prod_reg);
2891 }
2892 
2893 static void update_MFSBQ_indx(struct fc_info *fi, int count)
2894 {
2895         fi->q.mfsbq_prod_indx += count;
2896         if (fi->q.mfsbq_prod_indx >= MFSBQ_LENGTH)
2897                 fi->q.mfsbq_prod_indx -= MFSBQ_LENGTH;
2898         writel(fi->q.mfsbq_prod_indx, fi->t_r.ptr_mfsbq_prod_reg);
2899 }
2900 
2901 
2902 static void update_tachyon_header_indx(struct fc_info *fi)
2903 {
2904         fi->q.tachyon_header_indx++;
2905         if (fi->q.tachyon_header_indx == NO_OF_TACH_HEADERS)
2906                 fi->q.tachyon_header_indx = 0;
2907 }
2908 
2909 static void update_EDB_indx(struct fc_info *fi)
2910 {
2911         fi->q.edb_buffer_indx++;
2912         if (fi->q.edb_buffer_indx == EDB_LEN)
2913                 fi->q.edb_buffer_indx = 0;
2914 }
2915 
2916 static int iph5526_open(struct net_device *dev)
2917 {
2918         netif_start_queue(dev);
2919         MOD_INC_USE_COUNT;
2920         return 0;
2921 }
2922 
2923 static int iph5526_close(struct net_device *dev)
2924 {
2925         netif_stop_queue(dev);
2926         MOD_DEC_USE_COUNT;
2927         return 0;
2928 }
2929 
2930 static void iph5526_timeout(struct net_device *dev)
2931 {
2932         struct fc_info *fi = (struct fc_info*)dev->priv;
2933         printk(KERN_WARNING "%s: timed out on send.\n", dev->name);
2934         fi->fc_stats.rx_dropped++;
2935         dev->trans_start = jiffies;
2936         netif_wake_queue(dev);
2937 }
2938 
2939 static int iph5526_send_packet(struct sk_buff *skb, struct net_device *dev)
2940 {
2941         struct fc_info *fi = (struct fc_info*)dev->priv;
2942         int status = 0;
2943         short type = 0;
2944         u_long flags;
2945         struct fcllc *fcllc;
2946         
2947         ENTER("iph5526_send_packet");
2948         
2949         netif_stop_queue(dev);
2950         /* Strip off the pseudo header.
2951          */
2952         skb->data = skb->data + 2*FC_ALEN; 
2953         skb->len = skb->len - 2*FC_ALEN;
2954         fcllc = (struct fcllc *)skb->data;
2955         type = ntohs(fcllc->ethertype);
2956 
2957         spin_lock_irqsave(&fi->fc_lock, flags);
2958         switch(type) {
2959                 case ETH_P_IP:
2960                         status = tx_ip_packet(skb, skb->len, fi);
2961                         break;
2962                 case ETH_P_ARP:
2963                         status = tx_arp_packet(skb->data, skb->len, fi);
2964                         break;
2965                 default:
2966                         T_MSG("WARNING!!! Received Unknown Packet Type... Discarding...");
2967                         fi->fc_stats.rx_dropped++;
2968                         break;
2969         }
2970         spin_unlock_irqrestore(&fi->fc_lock, flags);
2971 
2972         if (status) {
2973                 fi->fc_stats.tx_bytes += skb->len;
2974                 fi->fc_stats.tx_packets++;
2975         }
2976         else
2977                 fi->fc_stats.rx_dropped++;
2978         dev->trans_start = jiffies;
2979         /* We free up the IP buffers in the OCI_interrupt handler.
2980          * status == 0 implies that the frame was not transmitted. So the
2981          * skb is freed here.
2982          */
2983         if ((type == ETH_P_ARP) || (status == 0))
2984                 dev_kfree_skb(skb);
2985         else
2986                 netif_wake_queue(dev);
2987         LEAVE("iph5526_send_packet");
2988         return 0;
2989 }
2990 
2991 static int iph5526_change_mtu(struct net_device *dev, int mtu)
2992 {
2993         return 0;
2994 }
2995 
2996 static int tx_ip_packet(struct sk_buff *skb, unsigned long len, struct fc_info *fi)
2997 {
2998 u_int d_id;
2999 int int_required = 1;
3000 u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_DATA;
3001 u_int type = TYPE_LLC_SNAP;
3002 u_short ox_id = OX_ID_FIRST_SEQUENCE;
3003 u_int mtu;
3004 struct fc_node_info *q;
3005 
3006         ENTER("tx_ip_packet");
3007         q = look_up_cache(fi, skb->data - 2*FC_ALEN);
3008         if (q != NULL) {
3009                 d_id = q->d_id;
3010                 DPRINTK("Look-Up Cache Succeeded for d_id = %x", d_id);
3011                 mtu = q->mtu;
3012                 if (q->login == LOGIN_COMPLETED){
3013                         fi->g.type_of_frame = FC_IP;
3014                         return tx_exchange(fi, skb->data, len, r_ctl, type, d_id, mtu, int_required, ox_id, virt_to_bus(skb));
3015                 }
3016                 
3017                 if (q->d_id == BROADCAST) {
3018                 struct fc_node_info *p = fi->node_info_list;
3019                 int return_value = FALSE;
3020                         fi->g.type_of_frame = FC_BROADCAST;
3021                         /* Do unicast to local nodes.
3022                          */
3023                         int_required = 0;
3024                         while(p != NULL) {
3025                                 d_id = p->d_id;
3026                                 if ((d_id & 0xFFFF00) == fi->g.my_ddaa)
3027                                         return_value |= tx_exchange(fi, skb->data, len, r_ctl, type, d_id, fi->g.my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
3028                                 p = p->next;
3029                         }
3030                         kfree(q);
3031                         return return_value;
3032                 }
3033                 
3034                 if (q->login != LOGIN_COMPLETED) {      
3035                         DPRINTK1("Node not logged in... Txing PLOGI to %x", d_id);
3036                         /* FIXME: we are dumping the frame here */
3037                         tx_logi(fi, ELS_PLOGI, d_id); 
3038                 }
3039         }
3040         DPRINTK2("Look-Up Cache Failed");
3041         LEAVE("tx_ip_packet");
3042         return 0;
3043 }
3044 
3045 static int tx_arp_packet(char *data, unsigned long len, struct fc_info *fi)
3046 {
3047 u_int opcode = data[ARP_OPCODE_0]; 
3048 u_int d_id;
3049 int int_required = 0, return_value = FALSE;
3050 u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_DATA;
3051 u_int type = TYPE_LLC_SNAP;
3052 u_short ox_id = OX_ID_FIRST_SEQUENCE;
3053 u_int my_mtu = fi->g.my_mtu;
3054         ENTER("tx_arp_packet");
3055 
3056         opcode = opcode << 8 | data[ARP_OPCODE_1];
3057         fi->g.type_of_frame = FC_IP;
3058 
3059         if (opcode == ARPOP_REQUEST) {
3060         struct fc_node_info *q = fi->node_info_list;
3061                 d_id = BROADCAST;
3062                 return_value |= tx_exchange(fi, data, len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
3063                 /* Some devices support HW_TYPE 0x01 */
3064                 memcpy(fi->g.arp_buffer, data - 2*FC_ALEN, len + 2*FC_ALEN);
3065                 fi->g.arp_buffer[9 + 2*FC_ALEN] = 0x01;
3066                 return_value |= tx_exchange(fi, (char *)(fi->g.arp_buffer + 2*FC_ALEN), len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
3067 
3068                 /* Do unicast to local nodes.
3069                  */
3070                 while(q != NULL) {
3071                         fi->g.type_of_frame = FC_BROADCAST;
3072                         d_id = q->d_id;
3073                         if ((d_id & 0xFFFF00) == fi->g.my_ddaa) {
3074                                 return_value |= tx_exchange(fi, data, len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
3075                                 // Some devices support HW_TYPE 0x01
3076                                 memcpy(fi->g.arp_buffer, data - 2*FC_ALEN, len + 2*FC_ALEN);
3077                                 fi->g.arp_buffer[9 + 2*FC_ALEN] = 0x01;
3078                                 return_value |= tx_exchange(fi, (char *)(fi->g.arp_buffer + 2*FC_ALEN), len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
3079                         }
3080                         q = q->next;
3081                 }
3082                 return return_value;
3083         }
3084         else
3085         if (opcode == ARPOP_REPLY) {
3086         struct fc_node_info *q; u_int mtu;
3087                 DPRINTK("We are sending out an ARP reply");
3088                 q = look_up_cache(fi, data - 2*FC_ALEN);
3089                 if (q != NULL) {
3090                         d_id = q->d_id;
3091                         DPRINTK("Look-Up Cache Succeeded for d_id = %x", d_id);
3092                         mtu = q->mtu;
3093                         if (q->login == LOGIN_COMPLETED){
3094                                 tx_exchange(fi, data, len, r_ctl, type, d_id, mtu, int_required, ox_id, TYPE_LLC_SNAP);
3095                                 /* Some devices support HW_TYPE 0x01 */
3096                                 memcpy(fi->g.arp_buffer, data - 2*FC_ALEN, len + 2*FC_ALEN);
3097                                 fi->g.arp_buffer[9 + 2*FC_ALEN] = 0x01;
3098                                 return tx_exchange(fi, (char *)(fi->g.arp_buffer + 2*FC_ALEN), len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
3099                         }
3100                         else {
3101                                 DPRINTK1("Node not logged in... Txing PLOGI to %x", d_id);
3102                                 tx_logi(fi, ELS_PLOGI, d_id); /* FIXME: we are dumping the frame here */
3103                         }
3104                 }
3105                 DPRINTK2("Look-Up Cache Failed");
3106         }
3107         else {
3108                 T_MSG("Warning!!! Invalid Opcode in ARP Packet!");
3109         }
3110         LEAVE("tx_arp_packet");
3111         return 0;
3112 }
3113 
3114 
3115 static void rx_net_packet(struct fc_info *fi, u_char *buff_addr, int payload_size)
3116 {
3117 struct net_device *dev = fi->dev;
3118 struct sk_buff *skb;
3119 u_int skb_size = 0;
3120 struct fch_hdr fch;
3121         ENTER("rx_net_packet");
3122         skb_size = payload_size - TACHYON_HEADER_LEN;
3123         DPRINTK("skb_size = %d", skb_size);
3124         fi->fc_stats.rx_bytes += skb_size - 2;
3125         skb = dev_alloc_skb(skb_size);
3126         if (skb == NULL) {
3127                 printk(KERN_NOTICE "%s: In rx_net_packet() Memory squeeze, dropping packet.\n", dev->name);
3128                 fi->fc_stats.rx_dropped++;
3129                 return;
3130         }
3131         /* Skip over the Tachyon Frame Header.
3132          */
3133         buff_addr += TACHYON_HEADER_LEN; 
3134 
3135         memcpy(fch.daddr, buff_addr + 2, FC_ALEN);
3136         memcpy(fch.saddr, buff_addr + 10, FC_ALEN);
3137         buff_addr += 2;
3138         memcpy(buff_addr, fch.daddr, FC_ALEN);
3139         memcpy(buff_addr + 6, fch.saddr, FC_ALEN);
3140         skb_reserve(skb, 2);
3141         memcpy(skb_put(skb, skb_size - 2), buff_addr, skb_size - 2);
3142         skb->dev = dev;
3143         skb->protocol = fc_type_trans(skb, dev);
3144         DPRINTK("protocol = %x", skb->protocol);
3145         
3146         /* Hmmm... to accept HW Type 0x01 as well... 
3147          */
3148         if (skb->protocol == ntohs(ETH_P_ARP))
3149                 skb->data[1] = 0x06;
3150         netif_rx(skb);
3151         fi->fc_stats.rx_packets++;
3152         LEAVE("rx_net_packet");
3153 }
3154 
3155 
3156 static void rx_net_mfs_packet(struct fc_info *fi, struct sk_buff *skb)
3157 {
3158 struct net_device *dev = fi->dev;
3159 struct fch_hdr fch;
3160         ENTER("rx_net_mfs_packet");
3161         /* Construct your Hard Header */
3162         memcpy(fch.daddr, skb->data + 2, FC_ALEN);
3163         memcpy(fch.saddr, skb->data + 10, FC_ALEN);
3164         skb_pull(skb, 2);
3165         memcpy(skb->data, fch.daddr, FC_ALEN);
3166         memcpy(skb->data + 6, fch.saddr, FC_ALEN);
3167         skb->dev = dev;
3168         skb->protocol = fc_type_trans(skb, dev);
3169         DPRINTK("protocol = %x", skb->protocol);
3170         netif_rx(skb);
3171         LEAVE("rx_net_mfs_packet");
3172 }
3173 
3174 unsigned short fc_type_trans(struct sk_buff *skb, struct net_device *dev) 
3175 {
3176 struct fch_hdr *fch=(struct fch_hdr *)skb->data;
3177 struct fcllc *fcllc;
3178         skb->mac.raw = skb->data;
3179         fcllc = (struct fcllc *)(skb->data + sizeof(struct fch_hdr) + 2);
3180         skb_pull(skb,sizeof(struct fch_hdr) + 2);
3181 
3182         if(*fch->daddr & 1) {
3183                 if(!memcmp(fch->daddr,dev->broadcast,FC_ALEN))  
3184                         skb->pkt_type = PACKET_BROADCAST;
3185                 else
3186                         skb->pkt_type = PACKET_MULTICAST;
3187         }
3188         else if(dev->flags & IFF_PROMISC) {
3189                 if(memcmp(fch->daddr, dev->dev_addr, FC_ALEN))
3190                         skb->pkt_type=PACKET_OTHERHOST;
3191         }
3192         
3193         /* Strip the SNAP header from ARP packets since we don't 
3194          * pass them through to the 802.2/SNAP layers.
3195          */
3196 
3197         if (fcllc->dsap == EXTENDED_SAP &&
3198                 (fcllc->ethertype == ntohs(ETH_P_IP) ||
3199                  fcllc->ethertype == ntohs(ETH_P_ARP))) {
3200                 skb_pull(skb, sizeof(struct fcllc));
3201                 return fcllc->ethertype;
3202         }
3203         return ntohs(ETH_P_802_2);
3204 }
3205 
3206 static int tx_exchange(struct fc_info *fi, char *data, u_int len, u_int r_ctl, u_int type, u_int d_id, u_int mtu, int int_required, u_short tx_ox_id, u_int frame_class)
3207 {
3208 u_char df_ctl; 
3209 int NW_flag = 0, h_size, return_value;
3210 u_short rx_id = RX_ID_FIRST_SEQUENCE;
3211 u_int tachyon_status;
3212 u_int my_id = fi->g.my_id;
3213         ENTER("tx_exchange");
3214 
3215         tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
3216         DPRINTK("Tachyon Status = %x len = %d MTU = %d", tachyon_status, len, mtu);
3217         if (tachyon_status & OSM_FROZEN) {
3218                 reset_tachyon(fi, ERROR_RELEASE);
3219                 reset_tachyon(fi, OCQ_RESET);
3220                 DPRINTK("Tachyon Status = %x len = %d MTU = %d", tachyon_status, len, mtu);
3221         }
3222         if (tx_ox_id == OX_ID_FIRST_SEQUENCE) {
3223                 switch(fi->g.type_of_frame) {
3224                         case FC_SCSI_READ:
3225                                 tx_ox_id = fi->g.scsi_oxid | SCSI_READ_BIT;
3226                                 break;
3227                         case FC_SCSI_WRITE:
3228                                 tx_ox_id = fi->g.scsi_oxid;
3229                                 break;
3230                         default:
3231                                 tx_ox_id = fi->g.ox_id;
3232                                 break;
3233                 }
3234         }
3235         else {
3236                 switch(fi->g.type_of_frame) {
3237                         case FC_SCSI_READ:
3238                                 rx_id = fi->g.scsi_oxid | SCSI_READ_BIT;
3239                                 break;
3240                         case FC_SCSI_WRITE:
3241                                 rx_id = fi->g.scsi_oxid;
3242                                 break;
3243                         case FC_BLS:
3244                                 rx_id = RX_ID_FIRST_SEQUENCE;
3245                                 break;
3246                         default:
3247                                 rx_id = fi->g.ox_id;
3248                                 break;
3249                 }
3250         }
3251 
3252         if (type == TYPE_LLC_SNAP) {
3253                 df_ctl = 0x20;
3254                 NW_flag = 1;
3255                 /* Multi Frame Sequence ? If yes, set RO bit */
3256                 if (len > mtu)
3257                         type |= RELATIVE_OFF_PRESENT;
3258                 build_tachyon_header(fi, my_id, r_ctl, d_id, type, fi->g.seq_id, df_ctl, tx_ox_id, rx_id, data - 2*FC_ALEN);
3259         }
3260         else {
3261                 df_ctl = 0;
3262                 /* Multi Frame Sequence ? If yes, set RO bit */
3263                 if (len > mtu)
3264                         type |= RELATIVE_OFF_PRESENT;
3265                 build_tachyon_header(fi, my_id, r_ctl, d_id, type, fi->g.seq_id, df_ctl, tx_ox_id, rx_id, NULL);
3266         }
3267 
3268         /* Get free Tachyon Headers and EDBs */
3269         if (get_free_header(fi) || get_free_EDB(fi))
3270                 return 0;
3271 
3272         if ((type & 0xFF000000) == TYPE_LLC_SNAP) {
3273                 h_size =  TACHYON_HEADER_LEN + NW_HEADER_LEN;
3274                 memcpy(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx], &(fi->g.tach_header), h_size);
3275         }
3276         else 
3277                 memcpy(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx], &(fi->g.tach_header), TACHYON_HEADER_LEN);
3278 
3279         return_value = tx_sequence(fi, data, len, mtu, d_id, tx_ox_id, rx_id, fi->g.seq_id, NW_flag, int_required, frame_class);
3280         
3281         switch(fi->g.type_of_frame) {
3282                 case FC_SCSI_READ:
3283                 case FC_SCSI_WRITE:
3284                         update_scsi_oxid(fi);
3285                         break;
3286                 case FC_BLS:
3287                         break;
3288                 default:
3289                         fi->g.ox_id++;
3290                         if (fi->g.ox_id == 0xFFFF)
3291                                 fi->g.ox_id = NOT_SCSI_XID;
3292                         break;
3293         }
3294 
3295         if (fi->g.seq_id == MAX_SEQ_ID)
3296                 fi->g.seq_id = 0;
3297         else
3298                 fi->g.seq_id++;
3299         LEAVE("tx_exchange");
3300         return return_value;
3301 }
3302 
3303 static int tx_sequence(struct fc_info *fi, char *data, u_int len, u_int mtu, u_int d_id, u_short ox_id, u_short rx_id, u_char seq_id, int NW_flag, int int_required, u_int frame_class)
3304 {
3305 u_int cntl = 0;
3306 int return_value;
3307         ENTER("tx_sequence");
3308         build_EDB(fi, data, EDB_END, len);
3309         memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB));
3310         build_ODB(fi, seq_id, d_id, len, cntl, mtu, ox_id, rx_id, NW_flag, int_required, frame_class);
3311         memcpy(fi->q.ptr_odb[fi->q.ocq_prod_indx], &(fi->g.odb), sizeof(ODB));
3312         if (fi->g.link_up != TRUE) {
3313                 DPRINTK2("Fibre Channel Link not up. Dropping Exchange!");
3314                 return_value = FALSE;
3315         }
3316         else {
3317                 /* To be on the safe side, a check should be included
3318                  * at this point to check if we are overrunning 
3319                  * Tachyon.
3320                  */
3321                 update_OCQ_indx(fi);
3322                 return_value = TRUE;
3323         }
3324         update_EDB_indx(fi);
3325         update_tachyon_header_indx(fi);
3326         LEAVE("tx_sequence");
3327         return return_value;
3328 }
3329 
3330 static int get_free_header(struct fc_info *fi)
3331 {
3332 u_short temp_ox_id;
3333 u_int *tach_header, initial_indx = fi->q.tachyon_header_indx;
3334         /* Check if the header is in use.
3335          * We could have an outstanding command.
3336          * We should find a free slot as we can queue a
3337          * maximum of 32 SCSI commands only. 
3338          */
3339         tach_header = fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx];
3340         temp_ox_id = ntohl(*(tach_header + 6)) >> 16;
3341         /* We care about the SCSI writes only. Those are the wicked ones
3342          * that need an additional set of buffers.
3343          */
3344         while(temp_ox_id <= MAX_SCSI_XID) {
3345                 update_tachyon_header_indx(fi);
3346                 if (fi->q.tachyon_header_indx == initial_indx) {
3347                         /* Should never happen.
3348                          */
3349                         T_MSG("No free Tachyon headers available");
3350                         reset_tachyon(fi, SOFTWARE_RESET);
3351                         return 1;
3352                 }
3353                 tach_header = fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx];
3354                 temp_ox_id = ntohl(*(tach_header + 6)) >> 16;
3355         }
3356         return 0;
3357 }
3358 
3359 static int get_free_EDB(struct fc_info *fi)
3360 {
3361 unsigned int initial_indx = fi->q.edb_buffer_indx;
3362         /* Check if the EDB is in use.
3363          * We could have an outstanding SCSI Write command.
3364          * We should find a free slot as we can queue a
3365          * maximum of 32 SCSI commands only. 
3366          */
3367         while (fi->q.free_edb_list[fi->q.edb_buffer_indx] != EDB_FREE) {
3368                 update_EDB_indx(fi);
3369                 if (fi->q.edb_buffer_indx == initial_indx) {
3370                         T_MSG("No free EDB buffers avaliable")
3371                         reset_tachyon(fi, SOFTWARE_RESET);
3372                         return 1;
3373                 }
3374         }
3375         return 0;
3376 }               
3377 
3378 static int validate_login(struct fc_info *fi, u_int *base_ptr)
3379 {
3380 struct fc_node_info *q = fi->node_info_list;
3381 char n_port_name[PORT_NAME_LEN];
3382 char node_name[NODE_NAME_LEN];
3383 u_int s_id;
3384         ENTER("validate_login");
3385         /*index to Port Name in the payload. We need the 8 byte Port Name */
3386         memcpy(n_port_name, base_ptr + 10, PORT_NAME_LEN);
3387         memcpy(node_name, base_ptr + 12, NODE_NAME_LEN);
3388         s_id = ntohl(*(base_ptr + 3)) & 0x00FFFFFF;
3389         
3390         /* check if Fibre Channel IDs have changed */
3391         while(q != NULL) {      
3392                 if (memcmp(n_port_name, q->hw_addr, PORT_NAME_LEN) == 0) {
3393                         if ((s_id != q->d_id) || (memcmp(node_name, q->node_name, NODE_NAME_LEN) != 0)) {
3394                                 DPRINTK1("Fibre Channel ID of Node has changed. Txing LOGO.");
3395                                 return 0;
3396                         }
3397                         q->login = LOGIN_COMPLETED;
3398 #if DEBUG_5526_2
3399                         display_cache(fi);
3400 #endif
3401                         return 1;
3402                 }
3403                 q = q->next;
3404         }
3405         DPRINTK1("Port Name does not match. Txing LOGO.");
3406         return 0;
3407         LEAVE("validate_login");
3408 }
3409 
3410 static void add_to_address_cache(struct fc_info *fi, u_int *base_ptr)
3411 {
3412 int size = sizeof(struct fc_node_info);
3413 struct fc_node_info *p, *q = fi->node_info_list, *r = NULL;
3414 char n_port_name[PORT_NAME_LEN];
3415 u_int s_id;
3416         ENTER("add_to_address_cache");
3417         /*index to Port Name in the payload. We need the 8 byte Port Name */
3418         memcpy(n_port_name, base_ptr + 13, PORT_NAME_LEN);
3419         s_id = ntohl(*(base_ptr + 3)) & 0x00FFFFFF;
3420         
3421         /* check if info already exists */
3422         while(q != NULL) {      
3423                 if (memcmp(n_port_name, q->hw_addr, PORT_NAME_LEN) == 0) {
3424                         if (s_id != q->d_id) {
3425                                 memcpy(&(q->c_of_s[0]), base_ptr + 17, 3 * sizeof(CLASS_OF_SERVICE));
3426                                 q->mtu = ntohl(*(base_ptr + 10)) & 0x00000FFF;
3427                                 q->d_id = s_id;
3428                                 memcpy(q->node_name, base_ptr + 15, NODE_NAME_LEN);
3429                         }
3430                         q->login = LOGIN_COMPLETED;
3431                         q->scsi = FALSE;
3432                         fi->num_nodes++;
3433 #if DEBUG_5526_2
3434                         display_cache(fi);
3435 #endif
3436                         return;
3437                 }
3438                 r = q;
3439                 q = q->next;
3440         }
3441         p = (struct fc_node_info *)kmalloc(size, GFP_ATOMIC);
3442         if (p == NULL) {
3443                 T_MSG("kmalloc failed in add_to_address_cache()");
3444                 return;
3445         }
3446         memcpy(&(p->c_of_s[0]), base_ptr + 17, 3 * sizeof(CLASS_OF_SERVICE));
3447         p->mtu = ntohl(*(base_ptr + 10)) & 0x00000FFF;
3448         p->d_id = s_id;
3449         memcpy(p->hw_addr, base_ptr + 13, PORT_NAME_LEN);
3450         memcpy(p->node_name, base_ptr + 15, NODE_NAME_LEN);
3451         p->login = LOGIN_COMPLETED;
3452         p->scsi = FALSE;
3453         p->target_id = 0xFF;
3454         p->next = NULL;
3455         if (fi->node_info_list == NULL)
3456                 fi->node_info_list = p;
3457         else
3458                 r->next = p;
3459         fi->num_nodes++;
3460 #if DEBUG_5526_2
3461         display_cache(fi);
3462 #endif
3463         LEAVE("add_to_address_cache");
3464         return;
3465 }
3466 
3467 static void remove_from_address_cache(struct fc_info *fi, u_int *base_ptr, u_int cmnd_code)
3468 {
3469 struct fc_node_info *q = fi->node_info_list;
3470 u_int s_id;
3471         ENTER("remove_from_address_cache");
3472         s_id = ntohl(*(base_ptr + 3)) & 0x00FFFFFF;
3473         switch(cmnd_code) {
3474                 case ELS_LOGO:
3475                         /* check if info exists */
3476                         while (q != NULL) {
3477                                 if (s_id == q->d_id) {
3478                                         if (q->login == LOGIN_COMPLETED)
3479                                                 q->login = LOGIN_ATTEMPTED;
3480                                         if (fi->num_nodes > 0)
3481                                                 fi->num_nodes--;
3482 #if DEBUG_5526_2
3483                                         display_cache(fi);
3484 #endif
3485                                         return;
3486                                 }
3487                                 q = q->next;
3488                         }
3489                         DPRINTK1("ELS_LOGO received from node 0x%x which is not logged-in", s_id);
3490                         break;
3491                 case ELS_RSCN:
3492                 {
3493                 int payload_len = ntohl(*(base_ptr + 8)) & 0xFF;
3494                 int no_of_pages, i;
3495                 u_char address_format;
3496                 u_short received_ox_id = ntohl(*(base_ptr + 6)) >> 16;
3497                 u_int node_id, mask, *page_ptr = base_ptr + 9;
3498                         if ((payload_len < 4) || (payload_len > 256)) {
3499                                 DPRINTK1("RSCN with invalid payload length received");
3500                                 tx_ls_rjt(fi, s_id, received_ox_id, LOGICAL_ERR, RECV_FIELD_SIZE);
3501                                 return;
3502                         }
3503                         /* Page_size includes the Command Code */
3504                         no_of_pages = (payload_len / 4) - 1;
3505                         for (i = 0; i < no_of_pages; i++) {
3506                                 address_format = ntohl(*page_ptr) >> 24; 
3507                                 node_id = ntohl(*page_ptr) & 0x00FFFFFF;