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;