OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [net/] [fc/] [iph5526.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/**********************************************************************
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
MODULE_LICENSE("GPL");
122
 
123
#define MAX_FC_CARDS 2
124
static struct fc_info *fc[MAX_FC_CARDS+1];
125
static unsigned int pci_irq_line;
126
static struct {
127
        unsigned short vendor_id;
128
        unsigned short device_id;
129
        char *name;
130
}
131
clone_list[] __initdata  = {
132
        {PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_5526, "Interphase Fibre Channel HBA"},
133
        {PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_55x6, "Interphase Fibre Channel HBA"},
134
        {0,}
135
};
136
 
137
static void tachyon_interrupt(int irq, void *dev_id, struct pt_regs *regs);
138
static void tachyon_interrupt_handler(int irq, void* dev_id, struct pt_regs* regs);
139
 
140
static int initialize_register_pointers(struct fc_info *fi);
141
void clean_up_memory(struct fc_info *fi);
142
 
143
static int tachyon_init(struct fc_info *fi);
144
static int build_queues(struct fc_info *fi);
145
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);
146
static int get_free_header(struct fc_info *fi);
147
static void build_EDB(struct fc_info *fi, char *data, u_short flags, u_short len);
148
static int get_free_EDB(struct fc_info *fi);
149
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);
150
static void write_to_tachyon_registers(struct fc_info *fi);
151
static void reset_latch(struct fc_info *fi);
152
static void reset_tachyon(struct fc_info *fi, u_int value);
153
static void take_tachyon_offline(struct fc_info *fi);
154
static void read_novram(struct fc_info *fi);
155
static void reset_ichip(struct fc_info *fi);
156
static void update_OCQ_indx(struct fc_info *fi);
157
static void update_IMQ_indx(struct fc_info *fi, int count);
158
static void update_SFSBQ_indx(struct fc_info *fi);
159
static void update_MFSBQ_indx(struct fc_info *fi, int count);
160
static void update_tachyon_header_indx(struct fc_info *fi);
161
static void update_EDB_indx(struct fc_info *fi);
162
static void handle_FM_interrupt(struct fc_info *fi);
163
static void handle_MFS_interrupt(struct fc_info *fi);
164
static void handle_OOO_interrupt(struct fc_info *fi);
165
static void handle_SFS_interrupt(struct fc_info *fi);
166
static void handle_OCI_interrupt(struct fc_info *fi);
167
static void handle_SFS_BUF_WARN_interrupt(struct fc_info *fi);
168
static void handle_MFS_BUF_WARN_interrupt(struct fc_info *fi);
169
static void handle_IMQ_BUF_WARN_interrupt(struct fc_info *fi);
170
static void handle_Unknown_Frame_interrupt(struct fc_info *fi);
171
static void handle_Busied_Frame_interrupt(struct fc_info *fi);
172
static void handle_Bad_SCSI_Frame_interrupt(struct fc_info *fi);
173
static void handle_Inbound_SCSI_Status_interrupt(struct fc_info *fi);
174
static void handle_Inbound_SCSI_Command_interrupt(struct fc_info *fi);
175
static void completion_message_handler(struct fc_info *fi, u_int imq_int_type);
176
static void fill_login_frame(struct fc_info *fi, u_int logi);
177
 
178
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);
179
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);
180
static int validate_login(struct fc_info *fi, u_int *base_ptr);
181
static void add_to_address_cache(struct fc_info *fi, u_int *base_ptr);
182
static void remove_from_address_cache(struct fc_info *fi, u_int *data, u_int cmnd_code);
183
static int node_logged_in_prev(struct fc_info *fi, u_int *buff_addr);
184
static int sid_logged_in(struct fc_info *fi, u_int s_id);
185
static struct fc_node_info *look_up_cache(struct fc_info *fi, char *data);
186
static int display_cache(struct fc_info *fi);
187
 
188
static void tx_logi(struct fc_info *fi, u_int logi, u_int d_id);
189
static void tx_logi_acc(struct fc_info *fi, u_int logi, u_int d_id, u_short received_ox_id);
190
static void tx_prli(struct fc_info *fi, u_int command_code, u_int d_id, u_short received_ox_id);
191
static void tx_logo(struct fc_info *fi, u_int d_id, u_short received_ox_id);
192
static void tx_adisc(struct fc_info *fi, u_int cmnd_code, u_int d_id, u_short received_ox_id);
193
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);
194
static u_int plogi_ok(struct fc_info *fi, u_int *buff_addr, int size);
195
static void tx_acc(struct fc_info *fi, u_int d_id, u_short received_ox_id);
196
static void tx_name_server_req(struct fc_info *fi, u_int req);
197
static void rscn_handler(struct fc_info *fi, u_int node_id);
198
static void tx_scr(struct fc_info *fi);
199
static void scr_timer(unsigned long data);
200
static void explore_fabric(struct fc_info *fi, u_int *buff_addr);
201
static void perform_adisc(struct fc_info *fi);
202
static void local_port_discovery(struct fc_info *fi);
203
static void add_to_ox_id_list(struct fc_info *fi, u_int transaction_id, u_int cmnd_code);
204
static u_int remove_from_ox_id_list(struct fc_info *fi, u_short received_ox_id);
205
static void add_display_cache_timer(struct fc_info *fi);
206
 
207
/* Timers... */
208
static void nos_ols_timer(unsigned long data);
209
static void loop_timer(unsigned long data);
210
static void fabric_explore_timer(unsigned long data);
211
static void port_discovery_timer(unsigned long data);
212
static void display_cache_timer(unsigned long data);
213
 
214
/* SCSI Stuff */
215
static int add_to_sest(struct fc_info *fi, Scsi_Cmnd *Cmnd, struct fc_node_info *ni);
216
static struct fc_node_info *resolve_target(struct fc_info *fi, u_char target);
217
static void update_FCP_CMND_indx(struct fc_info *fi);
218
static int get_free_SDB(struct fc_info *fi);
219
static void update_SDB_indx(struct fc_info *fi);
220
static void mark_scsi_sid(struct fc_info *fi, u_int *buff_addr, u_char action);
221
static void invalidate_SEST_entry(struct fc_info *fi, u_short received_ox_id);
222
static int abort_exchange(struct fc_info *fi, u_short ox_id);
223
static void flush_tachyon_cache(struct fc_info *fi, u_short ox_id);
224
static int get_scsi_oxid(struct fc_info *fi);
225
static void update_scsi_oxid(struct fc_info *fi);
226
 
227
static Scsi_Host_Template driver_template = IPH5526_SCSI_FC;
228
 
229
static void iph5526_timeout(struct net_device *dev);
230
 
231
static int iph5526_probe_pci(struct net_device *dev);
232
 
233
int __init iph5526_probe(struct net_device *dev)
234
{
235
        if (pci_present() && (iph5526_probe_pci(dev) == 0))
236
                return 0;
237
    return -ENODEV;
238
}
239
 
240
static int __init iph5526_probe_pci(struct net_device *dev)
241
{
242
#ifdef MODULE
243
        struct fc_info *fi = (struct fc_info *)dev->priv;
244
#else
245
        struct fc_info *fi;
246
        static int count;
247
 
248
        if(fc[count] != NULL) {
249
                if (dev == NULL) {
250
                        dev = init_fcdev(NULL, 0);
251
                        if (dev == NULL)
252
                                return -ENOMEM;
253
                }
254
                fi = fc[count];
255
#endif
256
                fi->dev = dev;
257
                dev->base_addr = fi->base_addr;
258
                dev->irq = fi->irq;
259
                if (dev->priv == NULL)
260
                        dev->priv = fi;
261
                fcdev_init(dev);
262
                /* Assign ur MAC address.
263
                 */
264
                dev->dev_addr[0] = (fi->g.my_port_name_high & 0x0000FF00) >> 8;
265
                dev->dev_addr[1] = fi->g.my_port_name_high;
266
                dev->dev_addr[2] = (fi->g.my_port_name_low & 0xFF000000) >> 24;
267
                dev->dev_addr[3] = (fi->g.my_port_name_low & 0x00FF0000) >> 16;
268
                dev->dev_addr[4] = (fi->g.my_port_name_low & 0x0000FF00) >> 8;
269
                dev->dev_addr[5] = fi->g.my_port_name_low;
270
#ifndef MODULE
271
                count++;
272
        }
273
        else
274
                return -ENODEV;
275
#endif
276
        display_cache(fi);
277
        return 0;
278
}
279
 
280
static int __init fcdev_init(struct net_device *dev)
281
{
282
        dev->open = iph5526_open;
283
        dev->stop = iph5526_close;
284
        dev->hard_start_xmit = iph5526_send_packet;
285
        dev->get_stats = iph5526_get_stats;
286
        dev->set_multicast_list = NULL;
287
        dev->change_mtu = iph5526_change_mtu;
288
        dev->tx_timeout = iph5526_timeout;
289
        dev->watchdog_timeo = 5*HZ;
290
#ifndef MODULE
291
        fc_setup(dev);
292
#endif
293
        return 0;
294
}
295
 
296
/* initialize tachyon and take it OnLine */
297
static int tachyon_init(struct fc_info *fi)
298
{
299
        ENTER("tachyon_init");
300
        if (build_queues(fi) == 0) {
301
                T_MSG("build_queues() failed");
302
                return 0;
303
        }
304
 
305
        /* Retrieve your port/node name.
306
         */
307
        read_novram(fi);
308
 
309
        reset_ichip(fi);
310
 
311
        reset_tachyon(fi, SOFTWARE_RESET);
312
 
313
        LEAVE("tachyon_init");
314
        return 1;
315
}
316
 
317
/* Build the 4 Qs - IMQ, OCQ, MFSBQ, SFSBQ */
318
/* Lots of dma_pages needed as Tachyon DMAs almost everything into
319
 * host memory.
320
 */
321
static int build_queues(struct fc_info *fi)
322
{
323
int i,j;
324
u_char *addr;
325
        ENTER("build_queues");
326
        /* Initializing Queue Variables.
327
         */
328
        fi->q.ptr_host_ocq_cons_indx = NULL;
329
        fi->q.ptr_host_hpcq_cons_indx = NULL;
330
        fi->q.ptr_host_imq_prod_indx = NULL;
331
 
332
        fi->q.ptr_ocq_base = NULL;
333
        fi->q.ocq_len = 0;
334
        fi->q.ocq_end = 0;
335
        fi->q.ocq_prod_indx = 0;
336
 
337
        fi->q.ptr_imq_base = NULL;
338
        fi->q.imq_len = 0;
339
        fi->q.imq_end = 0;
340
        fi->q.imq_cons_indx = 0;
341
        fi->q.imq_prod_indx = 0;
342
 
343
        fi->q.ptr_mfsbq_base = NULL;
344
        fi->q.mfsbq_len = 0;
345
        fi->q.mfsbq_end = 0;
346
        fi->q.mfsbq_prod_indx = 0;
347
        fi->q.mfsbq_cons_indx = 0;
348
        fi->q.mfsbuff_len = 0;
349
        fi->q.mfsbuff_end = 0;
350
        fi->g.mfs_buffer_count = 0;
351
 
352
        fi->q.ptr_sfsbq_base = NULL;
353
        fi->q.sfsbq_len = 0;
354
        fi->q.sfsbq_end = 0;
355
        fi->q.sfsbq_prod_indx = 0;
356
        fi->q.sfsbq_cons_indx = 0;
357
        fi->q.sfsbuff_len = 0;
358
        fi->q.sfsbuff_end = 0;
359
 
360
        fi->q.sdb_indx = 0;
361
        fi->q.fcp_cmnd_indx = 0;
362
 
363
        fi->q.ptr_edb_base = NULL;
364
        fi->q.edb_buffer_indx = 0;
365
        fi->q.ptr_tachyon_header_base = NULL;
366
        fi->q.tachyon_header_indx = 0;
367
        fi->node_info_list = NULL;
368
        fi->ox_id_list = NULL;
369
        fi->g.loop_up = FALSE;
370
        fi->g.ptp_up = FALSE;
371
        fi->g.link_up = FALSE;
372
        fi->g.fabric_present = FALSE;
373
        fi->g.n_port_try = FALSE;
374
        fi->g.dont_init = FALSE;
375
        fi->g.nport_timer_set = FALSE;
376
        fi->g.lport_timer_set = FALSE;
377
        fi->g.no_of_targets = 0;
378
        fi->g.sem = 0;
379
        fi->g.perform_adisc = FALSE;
380
        fi->g.e_i = 0;
381
 
382
        /* build OCQ */
383
        if ( (fi->q.ptr_ocq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) {
384
                T_MSG("failed to get OCQ page");
385
                return 0;
386
        }
387
        /* set up the OCQ structures */
388
        for (i = 0; i < OCQ_LENGTH; i++)
389
                fi->q.ptr_odb[i] = fi->q.ptr_ocq_base + NO_OF_ENTRIES*i;
390
 
391
        /* build IMQ */
392
        if ( (fi->q.ptr_imq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) {
393
                T_MSG("failed to get IMQ page");
394
                return 0;
395
        }
396
        for (i = 0; i < IMQ_LENGTH; i++)
397
                fi->q.ptr_imqe[i] = fi->q.ptr_imq_base + NO_OF_ENTRIES*i;
398
 
399
        /* build MFSBQ */
400
        if ( (fi->q.ptr_mfsbq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) {
401
                T_MSG("failed to get MFSBQ page");
402
                return 0;
403
        }
404
        memset((char *)fi->q.ptr_mfsbq_base, 0, MFSBQ_LENGTH * 32);
405
        /* Allocate one huge chunk of memory... helps while reassembling
406
         * frames.
407
         */
408
        if ( (addr = (u_char *)__get_free_pages(GFP_KERNEL, 5) ) == 0) {
409
                T_MSG("failed to get MFSBQ page");
410
                return 0;
411
        }
412
        /* fill in addresses of empty buffers */
413
        for (i = 0; i < MFSBQ_LENGTH; i++) {
414
                for (j = 0; j < NO_OF_ENTRIES; j++) {
415
                                *(fi->q.ptr_mfsbq_base + i*NO_OF_ENTRIES + j) = htonl(virt_to_bus(addr));
416
                                addr += MFS_BUFFER_SIZE;
417
                }
418
        }
419
 
420
        /* The number of entries in each MFS buffer is 8. There are 8
421
         * MFS buffers. That leaves us with 4096-256 bytes. We use them
422
         * as temporary space for ELS frames. This is done to make sure that
423
         * the addresses are aligned.
424
         */
425
        fi->g.els_buffer[0] = fi->q.ptr_mfsbq_base + MFSBQ_LENGTH*NO_OF_ENTRIES;
426
        for (i = 1; i < MAX_PENDING_FRAMES; i++)
427
                fi->g.els_buffer[i] = fi->g.els_buffer[i-1] + 64;
428
 
429
        /* build SFSBQ */
430
        if ( (fi->q.ptr_sfsbq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) {
431
                T_MSG("failed to get SFSBQ page");
432
                return 0;
433
        }
434
        memset((char *)fi->q.ptr_sfsbq_base, 0, SFSBQ_LENGTH * 32);
435
        /* fill in addresses of empty buffers */
436
        for (i = 0; i < SFSBQ_LENGTH; i++)
437
                for (j = 0; j < NO_OF_ENTRIES; j++){
438
                        addr = kmalloc(SFS_BUFFER_SIZE*2, GFP_KERNEL);
439
                        if (addr == NULL){
440
                                T_MSG("ptr_sfs_buffer : memory not allocated");
441
                                return 0;
442
                        }
443
                        else {
444
                        int offset = ALIGNED_SFS_ADDR(addr);
445
                                memset((char *)addr, 0, SFS_BUFFER_SIZE);
446
                                fi->q.ptr_sfs_buffers[i*NO_OF_ENTRIES +j] = (u_int *)addr;
447
                                addr += offset;
448
                                *(fi->q.ptr_sfsbq_base + i*NO_OF_ENTRIES + j) = htonl(virt_to_bus(addr));
449
                        }
450
                }
451
 
452
        /* The number of entries in each SFS buffer is 8. There are 8
453
         * MFS buffers. That leaves us with 4096-256 bytes. We use them
454
         * as temporary space for ARP frames. This is done inorder to
455
         * support HW_Types of 0x1 and 0x6.
456
         */
457
        fi->g.arp_buffer = (char *)fi->q.ptr_sfsbq_base + SFSBQ_LENGTH*NO_OF_ENTRIES*4;
458
 
459
        /* build EDB */
460
        if ((fi->q.ptr_edb_base = (u_int *)__get_free_pages(GFP_KERNEL, 5) ) == 0) {
461
                T_MSG("failed to get EDB page");
462
                return 0;
463
        }
464
        for (i = 0; i < EDB_LEN; i++)
465
                fi->q.ptr_edb[i] = fi->q.ptr_edb_base + 2*i;
466
 
467
        /* build SEST */
468
 
469
        /* OX_IDs range from 0x0 - 0x4FFF.
470
         */
471
        if ((fi->q.ptr_sest_base = (u_int *)__get_free_pages(GFP_KERNEL, 5)) == 0) {
472
                T_MSG("failed to get SEST page");
473
                return 0;
474
        }
475
        for (i = 0; i < SEST_LENGTH; i++)
476
                fi->q.ptr_sest[i] = fi->q.ptr_sest_base + NO_OF_ENTRIES*i;
477
 
478
        if ((fi->q.ptr_sdb_base = (u_int *)__get_free_pages(GFP_KERNEL, 5)) == 0) {
479
                T_MSG("failed to get SDB page");
480
                return 0;
481
        }
482
        for (i = 0 ; i < NO_OF_SDB_ENTRIES; i++)
483
                fi->q.ptr_sdb_slot[i] = fi->q.ptr_sdb_base + (SDB_SIZE/4)*i;
484
 
485
        if ((fi->q.ptr_fcp_cmnd_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) {
486
                T_MSG("failed to get FCP_CMND page");
487
                return 0;
488
        }
489
        for (i = 0; i < NO_OF_FCP_CMNDS; i++)
490
                fi->q.ptr_fcp_cmnd[i] = fi->q.ptr_fcp_cmnd_base + NO_OF_ENTRIES*i;
491
 
492
        /* Allocate space for Tachyon Header as well...
493
         */
494
        if ((fi->q.ptr_tachyon_header_base = (u_int *)__get_free_pages(GFP_KERNEL, 0) ) == 0) {
495
                T_MSG("failed to get tachyon_header page");
496
                return 0;
497
        }
498
        for (i = 0; i < NO_OF_TACH_HEADERS; i++)
499
                fi->q.ptr_tachyon_header[i] = fi->q.ptr_tachyon_header_base + 16*i;
500
 
501
        /* Allocate memory for indices.
502
         * Indices should be aligned on 32 byte boundries.
503
         */
504
        fi->q.host_ocq_cons_indx = kmalloc(2*32, GFP_KERNEL);
505
        if (fi->q.host_ocq_cons_indx == NULL){
506
                T_MSG("fi->q.host_ocq_cons_indx : memory not allocated");
507
                return 0;
508
        }
509
        fi->q.ptr_host_ocq_cons_indx = fi->q.host_ocq_cons_indx;
510
        if ((u_long)(fi->q.host_ocq_cons_indx) % 32)
511
                fi->q.host_ocq_cons_indx++;
512
 
513
        fi->q.host_hpcq_cons_indx = kmalloc(2*32, GFP_KERNEL);
514
        if (fi->q.host_hpcq_cons_indx == NULL){
515
                T_MSG("fi->q.host_hpcq_cons_indx : memory not allocated");
516
                return 0;
517
        }
518
        fi->q.ptr_host_hpcq_cons_indx= fi->q.host_hpcq_cons_indx;
519
        if ((u_long)(fi->q.host_hpcq_cons_indx) % 32)
520
                fi->q.host_hpcq_cons_indx++;
521
 
522
        fi->q.host_imq_prod_indx = kmalloc(2*32, GFP_KERNEL);
523
        if (fi->q.host_imq_prod_indx == NULL){
524
                T_MSG("fi->q.host_imq_prod_indx : memory not allocated");
525
                return 0;
526
        }
527
        fi->q.ptr_host_imq_prod_indx = fi->q.host_imq_prod_indx;
528
        if ((u_long)(fi->q.host_imq_prod_indx) % 32)
529
                fi->q.host_imq_prod_indx++;
530
 
531
        LEAVE("build_queues");
532
        return 1;
533
}
534
 
535
 
536
static void write_to_tachyon_registers(struct fc_info *fi)
537
{
538
u_int bus_addr, bus_indx_addr, i;
539
 
540
        ENTER("write_to_tachyon_registers");
541
 
542
        /* Clear Queues each time Tachyon is reset */
543
        memset((char *)fi->q.ptr_ocq_base, 0, OCQ_LENGTH * 32);
544
        memset((char *)fi->q.ptr_imq_base, 0, IMQ_LENGTH * 32);
545
        memset((char *)fi->q.ptr_edb_base, 0, EDB_LEN * 8);
546
        memset((char *)fi->q.ptr_sest_base, 0, SEST_LENGTH * 32);
547
        memset((char *)fi->q.ptr_sdb_base, 0, NO_OF_SDB_ENTRIES * SDB_SIZE);
548
        memset((char *)fi->q.ptr_tachyon_header_base, 0xFF, NO_OF_TACH_HEADERS * TACH_HEADER_SIZE);
549
        for (i = 0; i < SEST_LENGTH; i++)
550
                fi->q.free_scsi_oxid[i] = OXID_AVAILABLE;
551
        for (i = 0; i < NO_OF_SDB_ENTRIES; i++)
552
                fi->q.sdb_slot_status[i] = SDB_FREE;
553
 
554
        take_tachyon_offline(fi);
555
        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);
556
 
557
        /* Write OCQ registers */
558
        fi->q.ocq_prod_indx = 0;
559
        *(fi->q.host_ocq_cons_indx) = 0;
560
 
561
        /* The Tachyon needs to be passed the "real" address */
562
        bus_addr = virt_to_bus(fi->q.ptr_ocq_base);
563
        writel(bus_addr, fi->t_r.ptr_ocq_base_reg);
564
        writel(OCQ_LENGTH - 1, fi->t_r. ptr_ocq_len_reg);
565
        bus_indx_addr = virt_to_bus(fi->q.host_ocq_cons_indx);
566
        writel(bus_indx_addr, fi->t_r.ptr_ocq_cons_indx_reg);
567
 
568
        /* Write IMQ registers */
569
        fi->q.imq_cons_indx = 0;
570
        *(fi->q.host_imq_prod_indx) = 0;
571
        bus_addr = virt_to_bus(fi->q.ptr_imq_base);
572
        writel(bus_addr, fi->t_r.ptr_imq_base_reg);
573
        writel(IMQ_LENGTH - 1, fi->t_r.ptr_imq_len_reg);
574
        bus_indx_addr = virt_to_bus(fi->q.host_imq_prod_indx);
575
        writel(bus_indx_addr, fi->t_r.ptr_imq_prod_indx_reg);
576
 
577
        /* Write MFSBQ registers */
578
        fi->q.mfsbq_prod_indx = MFSBQ_LENGTH - 1;
579
        fi->q.mfsbuff_end = MFS_BUFFER_SIZE - 1;
580
        fi->q.mfsbq_cons_indx = 0;
581
        bus_addr = virt_to_bus(fi->q.ptr_mfsbq_base);
582
        writel(bus_addr, fi->t_r.ptr_mfsbq_base_reg);
583
        writel(MFSBQ_LENGTH - 1, fi->t_r.ptr_mfsbq_len_reg);
584
        writel(fi->q.mfsbuff_end, fi->t_r.ptr_mfsbuff_len_reg);
585
        /* Do this last as tachyon will prefetch the
586
         * first entry as soon as we write to it.
587
         */
588
        writel(fi->q.mfsbq_prod_indx, fi->t_r.ptr_mfsbq_prod_reg);
589
 
590
        /* Write SFSBQ registers */
591
        fi->q.sfsbq_prod_indx = SFSBQ_LENGTH - 1;
592
        fi->q.sfsbuff_end = SFS_BUFFER_SIZE - 1;
593
        fi->q.sfsbq_cons_indx = 0;
594
        bus_addr = virt_to_bus(fi->q.ptr_sfsbq_base);
595
        writel(bus_addr, fi->t_r.ptr_sfsbq_base_reg);
596
        writel(SFSBQ_LENGTH - 1, fi->t_r.ptr_sfsbq_len_reg);
597
        writel(fi->q.sfsbuff_end, fi->t_r.ptr_sfsbuff_len_reg);
598
        /* Do this last as tachyon will prefetch the first
599
         * entry as soon as we write to it.
600
         */
601
        writel(fi->q.sfsbq_prod_indx, fi->t_r.ptr_sfsbq_prod_reg);
602
 
603
        /* Write SEST registers */
604
        bus_addr = virt_to_bus(fi->q.ptr_sest_base);
605
        writel(bus_addr, fi->t_r.ptr_sest_base_reg);
606
        writel(SEST_LENGTH - 1, fi->t_r.ptr_sest_len_reg);
607
        /* the last 2 bits _should_ be 1 */
608
        writel(SEST_BUFFER_SIZE - 1, fi->t_r.ptr_scsibuff_len_reg);
609
 
610
        /* write AL_TIME & E_D_TOV into the registers */
611
        writel(TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
612
        /* Tell Tachyon to pick a Soft Assigned AL_PA */
613
        writel(LOOP_INIT_SOFT_ADDRESS, fi->t_r.ptr_fm_config_reg);
614
 
615
        /* Read the WWN from EEPROM . But, for now we assign it here. */
616
        writel(WORLD_WIDE_NAME_LOW, fi->t_r.ptr_fm_wwn_low_reg);
617
        writel(WORLD_WIDE_NAME_HIGH, fi->t_r.ptr_fm_wwn_hi_reg);
618
 
619
        DPRINTK1("TACHYON initializing as L_Port...\n");
620
        writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
621
 
622
        LEAVE("write_to_tachyon_registers");
623
}
624
 
625
 
626
static void tachyon_interrupt(int irq, void* dev_id, struct pt_regs* regs)
627
{
628
struct Scsi_Host *host = dev_id;
629
struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
630
struct fc_info *fi = hostdata->fi;
631
u_long flags;
632
        spin_lock_irqsave(&fi->fc_lock, flags);
633
        tachyon_interrupt_handler(irq, dev_id, regs);
634
        spin_unlock_irqrestore(&fi->fc_lock, flags);
635
}
636
 
637
static void tachyon_interrupt_handler(int irq, void* dev_id, struct pt_regs* regs)
638
{
639
struct Scsi_Host *host = dev_id;
640
struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
641
struct fc_info *fi = hostdata->fi;
642
u_int *ptr_imq_entry;
643
u_int imq_int_type, current_IMQ_index = 0, prev_IMQ_index;
644
int index, no_of_entries = 0;
645
 
646
        DPRINTK("\n");
647
        ENTER("tachyon_interrupt");
648
        if (fi->q.host_imq_prod_indx != NULL) {
649
                current_IMQ_index =  ntohl(*(fi->q.host_imq_prod_indx));
650
        }
651
        else {
652
                /* _Should not_ happen */
653
                T_MSG("IMQ_indx NULL. DISABLING INTERRUPTS!!!\n");
654
                writel(0x0, fi->i_r.ptr_ichip_hw_control_reg);
655
        }
656
 
657
        if (current_IMQ_index > fi->q.imq_cons_indx)
658
                no_of_entries = current_IMQ_index - fi->q.imq_cons_indx;
659
        else
660
        if (current_IMQ_index < fi->q.imq_cons_indx)
661
                no_of_entries = IMQ_LENGTH - (fi->q.imq_cons_indx - current_IMQ_index);
662
 
663
        if (no_of_entries == 0) {
664
        u_int ichip_status;
665
                ichip_status = readl(fi->i_r.ptr_ichip_hw_status_reg);
666
                if (ichip_status & 0x20) {
667
                        /* Should _never_ happen. Might require a hard reset */
668
                        T_MSG("Too bad... PCI Bus Error. Resetting (i)chip");
669
                        reset_ichip(fi);
670
                        T_MSG("DISABLING INTERRUPTS!!!\n");
671
                        writel(0x0, fi->i_r.ptr_ichip_hw_control_reg);
672
                }
673
        }
674
 
675
        prev_IMQ_index = current_IMQ_index;
676
        for (index = 0; index < no_of_entries; index++) {
677
                ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
678
                imq_int_type = ntohl(*ptr_imq_entry);
679
 
680
                completion_message_handler(fi, imq_int_type);
681
                if ((fi->g.link_up == FALSE) && ((imq_int_type == MFS_BUF_WARN) || (imq_int_type == SFS_BUF_WARN) || (imq_int_type == IMQ_BUF_WARN)))
682
                        break;
683
                update_IMQ_indx(fi, 1);
684
 
685
                /* Check for more entries */
686
                current_IMQ_index =  ntohl(*(fi->q.host_imq_prod_indx));
687
                if (current_IMQ_index != prev_IMQ_index) {
688
                        no_of_entries++;
689
                        prev_IMQ_index = current_IMQ_index;
690
                }
691
        } /*end of for loop*/
692
        return;
693
        LEAVE("tachyon_interrupt");
694
}
695
 
696
 
697
static void handle_SFS_BUF_WARN_interrupt(struct fc_info *fi)
698
{
699
int i;
700
        ENTER("handle_SFS_BUF_WARN_interrupt");
701
        if (fi->g.link_up == FALSE) {
702
                reset_tachyon(fi, SOFTWARE_RESET);
703
                return;
704
        }
705
        /* Free up all but one entry in the Q.
706
         */
707
        for (i = 0; i < ((SFSBQ_LENGTH - 1) * NO_OF_ENTRIES); i++) {
708
                handle_SFS_interrupt(fi);
709
                update_IMQ_indx(fi, 1);
710
        }
711
        LEAVE("handle_SFS_BUF_WARN_interrupt");
712
}
713
 
714
/* Untested_Code_Begin */
715
static void handle_MFS_BUF_WARN_interrupt(struct fc_info *fi)
716
{
717
int i;
718
        ENTER("handle_MFS_BUF_WARN_interrupt");
719
        if (fi->g.link_up == FALSE) {
720
                reset_tachyon(fi, SOFTWARE_RESET);
721
                return;
722
        }
723
        /* FIXME: freeing up 8 entries.
724
         */
725
        for (i = 0; i < NO_OF_ENTRIES; i++) {
726
                handle_MFS_interrupt(fi);
727
                update_IMQ_indx(fi, 1);
728
        }
729
        LEAVE("handle_MFS_BUF_WARN_interrupt");
730
}
731
/*Untested_Code_End */
732
 
733
static void handle_IMQ_BUF_WARN_interrupt(struct fc_info *fi)
734
{
735
u_int *ptr_imq_entry;
736
u_int imq_int_type, current_IMQ_index = 0, temp_imq_cons_indx;
737
int index, no_of_entries = 0;
738
 
739
        ENTER("handle_IMQ_BUF_WARN_interrupt");
740
        if (fi->g.link_up == FALSE) {
741
                reset_tachyon(fi, SOFTWARE_RESET);
742
                return;
743
        }
744
        current_IMQ_index =  ntohl(*(fi->q.host_imq_prod_indx));
745
 
746
        if (current_IMQ_index > fi->q.imq_cons_indx)
747
                no_of_entries = current_IMQ_index - fi->q.imq_cons_indx;
748
        else
749
                if (current_IMQ_index < fi->q.imq_cons_indx)
750
                        no_of_entries = IMQ_LENGTH - (fi->q.imq_cons_indx - current_IMQ_index);
751
        /* We dont want to look at the same IMQ entry again.
752
         */
753
        temp_imq_cons_indx = fi->q.imq_cons_indx + 1;
754
        if (no_of_entries != 0)
755
                no_of_entries -= 1;
756
        for (index = 0; index < no_of_entries; index++) {
757
                ptr_imq_entry = fi->q.ptr_imqe[temp_imq_cons_indx];
758
                imq_int_type = ntohl(*ptr_imq_entry);
759
                if (imq_int_type != IMQ_BUF_WARN)
760
                        completion_message_handler(fi, imq_int_type);
761
                temp_imq_cons_indx++;
762
                if (temp_imq_cons_indx == IMQ_LENGTH)
763
                        temp_imq_cons_indx = 0;
764
        } /*end of for loop*/
765
        if (no_of_entries != 0)
766
                update_IMQ_indx(fi, no_of_entries);
767
        LEAVE("handle_IMQ_BUF_WARN_interrupt");
768
}
769
 
770
static void completion_message_handler(struct fc_info *fi, u_int imq_int_type)
771
{
772
        switch(imq_int_type) {
773
                case OUTBOUND_COMPLETION:
774
                        DPRINTK("OUTBOUND_COMPLETION message received");
775
                        break;
776
                case OUTBOUND_COMPLETION_I:
777
                        DPRINTK("OUTBOUND_COMPLETION_I message received");
778
                        handle_OCI_interrupt(fi);
779
                        break;
780
                case OUT_HI_PRI_COMPLETION:
781
                        DPRINTK("OUT_HI_PRI_COMPLETION message received");
782
                        break;
783
                case OUT_HI_PRI_COMPLETION_I:
784
                        DPRINTK("OUT_HI_PRI_COMPLETION_I message received");
785
                        break;
786
                case INBOUND_MFS_COMPLETION:
787
                        DPRINTK("INBOUND_MFS_COMPLETION message received");
788
                        handle_MFS_interrupt(fi);
789
                        break;
790
                case INBOUND_OOO_COMPLETION:
791
                        DPRINTK("INBOUND_OOO_COMPLETION message received");
792
                        handle_OOO_interrupt(fi);
793
                        break;
794
                case INBOUND_SFS_COMPLETION:
795
                        DPRINTK("INBOUND_SFS_COMPLETION message received");
796
                        handle_SFS_interrupt(fi);
797
                        break;
798
                case INBOUND_UNKNOWN_FRAME_I:
799
                        DPRINTK("INBOUND_UNKNOWN_FRAME message received");
800
                        handle_Unknown_Frame_interrupt(fi);
801
                        break;
802
                case INBOUND_BUSIED_FRAME:
803
                        DPRINTK("INBOUND_BUSIED_FRAME message received");
804
                        handle_Busied_Frame_interrupt(fi);
805
                        break;
806
                case FRAME_MGR_INTERRUPT:
807
                        DPRINTK("FRAME_MGR_INTERRUPT message received");
808
                        handle_FM_interrupt(fi);
809
                        break;
810
                case READ_STATUS:
811
                        DPRINTK("READ_STATUS message received");
812
                        break;
813
                case SFS_BUF_WARN:
814
                        DPRINTK("SFS_BUF_WARN message received");
815
                        handle_SFS_BUF_WARN_interrupt(fi);
816
                        break;
817
                case MFS_BUF_WARN:
818
                        DPRINTK("MFS_BUF_WARN message received");
819
                        handle_MFS_BUF_WARN_interrupt(fi);
820
                        break;
821
                case IMQ_BUF_WARN:
822
                        DPRINTK("IMQ_BUF_WARN message received");
823
                        handle_IMQ_BUF_WARN_interrupt(fi);
824
                        break;
825
                case INBOUND_C1_TIMEOUT:
826
                        DPRINTK("INBOUND_C1_TIMEOUT message received");
827
                        break;
828
                case BAD_SCSI_FRAME:
829
                        DPRINTK("BAD_SCSI_FRAME message received");
830
                        handle_Bad_SCSI_Frame_interrupt(fi);
831
                        break;
832
                case INB_SCSI_STATUS_COMPLETION:
833
                        DPRINTK("INB_SCSI_STATUS_COMPL message received");
834
                        handle_Inbound_SCSI_Status_interrupt(fi);
835
                        break;
836
                case INBOUND_SCSI_COMMAND:
837
                        DPRINTK("INBOUND_SCSI_COMMAND message received");
838
                        handle_Inbound_SCSI_Command_interrupt(fi);
839
                        break;
840
                case INBOUND_SCSI_DATA_COMPLETION:
841
                        DPRINTK("INBOUND_SCSI_DATA message received");
842
                        /* Only for targets */
843
                        break;
844
                default:
845
                        T_MSG("DEFAULT message received, type = %x", imq_int_type);
846
                        return;
847
        }
848
        reset_latch(fi);
849
}
850
 
851
static void handle_OCI_interrupt(struct fc_info *fi)
852
{
853
u_int *ptr_imq_entry;
854
u_long transaction_id = 0;
855
unsigned short status, seq_count, transmitted_ox_id;
856
struct Scsi_Host *host = fi->host;
857
struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
858
Scsi_Cmnd *Cmnd;
859
u_int tag;
860
 
861
        ENTER("handle_OCI_interrupt");
862
        ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
863
        transaction_id = ntohl(*(ptr_imq_entry + 1));
864
        status = ntohl(*(ptr_imq_entry + 2)) >> 16;
865
        seq_count = ntohl(*(ptr_imq_entry + 3));
866
        DPRINTK("transaction_id= %x", (u_int)transaction_id);
867
        tag = transaction_id & 0xFFFF0000;
868
        transmitted_ox_id = transaction_id;
869
 
870
        /* The INT could be either due to TIME_OUT | BAD_ALPA.
871
         * But we check only for TimeOuts. Bad AL_PA will
872
         * caught by FM_interrupt handler.
873
         */
874
 
875
        if ((status == OCM_TIMEOUT_OR_BAD_ALPA) && (!fi->g.port_discovery) && (!fi->g.perform_adisc)){
876
                DPRINTK("Frame TimeOut on OX_ID = %x", (u_int)transaction_id);
877
 
878
                /* Is it a SCSI frame that is timing out ? Not a very good check...
879
                 */
880
                if ((transmitted_ox_id <= MAX_SCSI_OXID) && ((tag == FC_SCSI_BAD_TARGET) || (tag < 0x00FF0000))) {
881
                        /* If it is a Bad AL_PA, we report it as BAD_TARGET.
882
                         * Else, we allow the command to time-out. A Link
883
                         * re-initialization could be taking place.
884
                         */
885
                        if (tag == FC_SCSI_BAD_TARGET) {
886
                                Cmnd = hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID];
887
                                hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID] = NULL;
888
                                if (Cmnd != NULL) {
889
                                        Cmnd->result = DID_BAD_TARGET << 16;
890
                                        (*Cmnd->scsi_done) (Cmnd);
891
                                }
892
                                else
893
                                        T_MSG("NULL Command out of handler!");
894
                        } /* if Bad Target */
895
                        else {
896
                        u_char missing_target = tag >> 16;
897
                        struct fc_node_info *q = fi->node_info_list;
898
                                /* A Node that we thought was logged in has gone
899
                                 * away. We are the optimistic kind and we keep
900
                                 * hoping that our dear little Target will come back
901
                                 * to us. For now we log him out.
902
                                 */
903
                                DPRINTK2("Missing Target = %d", missing_target);
904
                                while (q != NULL) {
905
                                        if (q->target_id == missing_target) {
906
                                                T_MSG("Target %d Logged out", q->target_id);
907
                                                q->login = LOGIN_ATTEMPTED;
908
                                                if (fi->num_nodes > 0)
909
                                                        fi->num_nodes--;
910
                                                tx_logi(fi, ELS_PLOGI, q->d_id);
911
                                                break;
912
                                        }
913
                                        else
914
                                                q = q->next;
915
                                }
916
                        }
917
                } /* End of SCSI frame timing out. */
918
                else {
919
                        if (seq_count > 1) {
920
                                /* An IP frame was transmitted to a Bad AL_PA. Free up
921
                                 * the skb used.
922
                                 */
923
                                dev_kfree_skb_irq((struct sk_buff *)(bus_to_virt(transaction_id)));
924
                                netif_wake_queue(fi->dev);
925
                        }
926
                } /* End of IP frame timing out. */
927
        } /* End of frame timing out. */
928
        else {
929
                /* Frame was transmitted successfully. Check if it was an ELS
930
                 * frame or an IP frame or a Bad_Target_Notification frame (in
931
                 * case of a ptp_link). Ugly!
932
                 */
933
                if ((status == 0) && (seq_count == 0)) {
934
                u_int tag = transaction_id & 0xFFFF0000;
935
                /* Continue with port discovery after an ELS is successfully
936
                 * transmitted. (status == 0).
937
                 */
938
                        DPRINTK("tag = %x", tag);
939
                        switch(tag) {
940
                                case ELS_FLOGI:
941
                                        /* Letz use the Name Server instead */
942
                                        fi->g.explore_fabric = TRUE;
943
                                        fi->g.port_discovery = FALSE;
944
                                        fi->g.alpa_list_index = MAX_NODES;
945
                                        add_to_ox_id_list(fi, transaction_id, tag);
946
                                        break;
947
                                case ELS_PLOGI:
948
                                        if (fi->g.fabric_present && (fi->g.name_server == FALSE))
949
                                                add_to_ox_id_list(fi,transaction_id,ELS_NS_PLOGI);
950
                                        else
951
                                                add_to_ox_id_list(fi, transaction_id, tag);
952
                                        break;
953
                                case FC_SCSI_BAD_TARGET:
954
                                        Cmnd = hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID];
955
                                        hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID] = NULL;
956
                                        if (Cmnd != NULL) {
957
                                                Cmnd->result = DID_BAD_TARGET << 16;
958
                                                (*Cmnd->scsi_done) (Cmnd);
959
                                        }
960
                                        else
961
                                                T_MSG("NULL Command out of handler!");
962
                                        break;
963
                                default:
964
                                        add_to_ox_id_list(fi, transaction_id, tag);
965
                        }
966
 
967
                        if (fi->g.alpa_list_index >= MAX_NODES) {
968
                                if (fi->g.port_discovery == TRUE) {
969
                                        fi->g.port_discovery = FALSE;
970
                                        add_display_cache_timer(fi);
971
                                }
972
                                fi->g.alpa_list_index = MAX_NODES;
973
                        }
974
                        if (fi->g.port_discovery == TRUE)
975
                                local_port_discovery(fi);
976
                }
977
                else {
978
                        /* An IP frame has been successfully transmitted.
979
                         * Free the skb that was used for this IP frame.
980
                         */
981
                        if ((status == 0) && (seq_count > 1)) {
982
                                dev_kfree_skb_irq((struct sk_buff *)(bus_to_virt(transaction_id)));
983
                                netif_wake_queue(fi->dev);
984
                        }
985
                }
986
        }
987
        LEAVE("handle_OCI_interrupt");
988
}
989
 
990
/* Right now we discard OOO frames */
991
static void handle_OOO_interrupt(struct fc_info *fi)
992
{
993
u_int *ptr_imq_entry;
994
int queue_indx, offset, payload_size;
995
int no_of_buffers = 1; /* header is in a separate buffer */
996
        ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
997
        offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
998
        queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
999
        queue_indx = queue_indx >> 16;
1000
        payload_size = ntohl(*(ptr_imq_entry + 2)) - TACHYON_HEADER_LEN;
1001
        /* Calculate total number of buffers */
1002
        no_of_buffers += payload_size / MFS_BUFFER_SIZE;
1003
        if (payload_size % MFS_BUFFER_SIZE)
1004
                no_of_buffers++;
1005
 
1006
        /* provide Tachyon will another set of buffers */
1007
        fi->g.mfs_buffer_count += no_of_buffers;
1008
        if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) {
1009
        int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES;
1010
                fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count;
1011
                update_MFSBQ_indx(fi, count);
1012
        }
1013
}
1014
 
1015
static void handle_MFS_interrupt(struct fc_info *fi)
1016
{
1017
u_int *ptr_imq_entry, *buff_addr;
1018
u_int type_of_frame, s_id;
1019
int queue_indx, offset, payload_size, starting_indx, starting_offset;
1020
u_short received_ox_id;
1021
int no_of_buffers = 1; /* header is in a separate buffer */
1022
struct sk_buff *skb;
1023
int wrap_around = FALSE, no_of_wrap_buffs = NO_OF_ENTRIES - 1;
1024
        ENTER("handle_MFS_interrupt");
1025
        ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
1026
        offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
1027
        queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
1028
        queue_indx = queue_indx >> 16;
1029
        DPRINTK("queue_indx = %d, offset  = %d\n", queue_indx, offset);
1030
        payload_size = ntohl(*(ptr_imq_entry + 2)) - TACHYON_HEADER_LEN;
1031
        DPRINTK("payload_size = %d", payload_size);
1032
        /* Calculate total number of buffers */
1033
        no_of_buffers += payload_size / MFS_BUFFER_SIZE;
1034
        if (payload_size % MFS_BUFFER_SIZE)
1035
                no_of_buffers++;
1036
        DPRINTK("no_of_buffers = %d", no_of_buffers);
1037
 
1038
        if ((no_of_buffers - 1) <= offset) {
1039
                starting_offset = offset - (no_of_buffers - 1);
1040
                starting_indx = queue_indx;
1041
        }
1042
        else {
1043
        int temp = no_of_buffers - (offset + 1);
1044
        int no_of_queues = temp / NO_OF_ENTRIES;
1045
                starting_offset = temp % NO_OF_ENTRIES;
1046
                if (starting_offset != 0) {
1047
                        no_of_wrap_buffs = starting_offset - 1; //exclude header
1048
                        starting_offset = NO_OF_ENTRIES - starting_offset;
1049
                        no_of_queues++;
1050
                }
1051
                starting_indx = queue_indx - no_of_queues;
1052
                if (starting_indx < 0) {
1053
                        no_of_wrap_buffs -= (starting_indx + 1) * NO_OF_ENTRIES;
1054
                        starting_indx = MFSBQ_LENGTH + starting_indx;
1055
                        wrap_around = TRUE;
1056
                }
1057
        }
1058
 
1059
        DPRINTK("starting_indx = %d, starting offset = %d no_of_wrap_buffs = %d\n", starting_indx, starting_offset, no_of_wrap_buffs);
1060
        /* Get Tachyon Header from first buffer */
1061
        buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_mfsbq_base + starting_indx*NO_OF_ENTRIES + starting_offset)));
1062
 
1063
 
1064
        /* extract Type of Frame */
1065
        type_of_frame = (u_int)ntohl(*(buff_addr + 4)) & 0xFF000000;
1066
        s_id = (u_int)ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
1067
        received_ox_id = ntohl(*(buff_addr + 6)) >> 16;
1068
        buff_addr += MFS_BUFFER_SIZE/4;
1069
        DPRINTK("type_of_frame = %x, s_id = %x, ox_id = %x", type_of_frame, s_id, received_ox_id);
1070
 
1071
        switch(type_of_frame) {
1072
          case TYPE_LLC_SNAP:
1073
                skb = dev_alloc_skb(payload_size);
1074
                if (skb == NULL) {
1075
                        printk(KERN_NOTICE "%s: In handle_MFS_interrupt() Memory squeeze, dropping packet.\n", fi->name);
1076
                        fi->fc_stats.rx_dropped++;
1077
                        fi->g.mfs_buffer_count += no_of_buffers;
1078
                        if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) {
1079
                                int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES;
1080
                                fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count;
1081
                                update_MFSBQ_indx(fi, count);
1082
                        }
1083
                        return;
1084
                }
1085
                if (wrap_around) {
1086
                int wrap_size = no_of_wrap_buffs * MFS_BUFFER_SIZE;
1087
                int tail_size = payload_size - wrap_size;
1088
                        DPRINTK("wrap_size = %d, tail_size = %d\n", wrap_size, tail_size);
1089
                        if (no_of_wrap_buffs)
1090
                                memcpy(skb_put(skb, wrap_size), buff_addr, wrap_size);
1091
                        buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_mfsbq_base)));
1092
                        memcpy(skb_put(skb, tail_size), buff_addr, tail_size);
1093
                }
1094
                else
1095
                        memcpy(skb_put(skb, payload_size), buff_addr, payload_size);
1096
                rx_net_mfs_packet(fi, skb);
1097
                break;
1098
        default:
1099
                T_MSG("Unknown Frame Type received. Type = %x", type_of_frame);
1100
        }
1101
 
1102
        /* provide Tachyon will another set of buffers */
1103
        fi->g.mfs_buffer_count += no_of_buffers;
1104
        if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) {
1105
        int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES;
1106
                fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count;
1107
                update_MFSBQ_indx(fi, count);
1108
        }
1109
        LEAVE("handle_MFS_interrupt");
1110
}
1111
 
1112
static void handle_Unknown_Frame_interrupt(struct fc_info *fi)
1113
{
1114
u_int *ptr_imq_entry;
1115
int queue_indx, offset;
1116
        ENTER("handle_Unknown_Frame_interrupt");
1117
        ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
1118
        offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
1119
        queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
1120
        queue_indx = queue_indx >> 16;
1121
        /* We discard the "unknown" frame */
1122
        /* provide Tachyon will another set of buffers */
1123
        if (offset == (NO_OF_ENTRIES - 1))
1124
                update_SFSBQ_indx(fi);
1125
        LEAVE("handle_Unknown_Frame_interrupt");
1126
}
1127
 
1128
static void handle_Busied_Frame_interrupt(struct fc_info *fi)
1129
{
1130
u_int *ptr_imq_entry;
1131
int queue_indx, offset;
1132
        ENTER("handle_Busied_Frame_interrupt");
1133
        ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
1134
        offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
1135
        queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
1136
        queue_indx = queue_indx >> 16;
1137
        /* We discard the "busied" frame */
1138
        /* provide Tachyon will another set of buffers */
1139
        if (offset == (NO_OF_ENTRIES - 1))
1140
                update_SFSBQ_indx(fi);
1141
        LEAVE("handle_Busied_Frame_interrupt");
1142
}
1143
 
1144
static void handle_Bad_SCSI_Frame_interrupt(struct fc_info *fi)
1145
{
1146
u_int *ptr_imq_entry, *buff_addr, *tach_header, *ptr_edb;
1147
u_int s_id, rctl, frame_class, burst_len, transfered_len, len = 0;
1148
int queue_indx, offset, payload_size, i;
1149
u_short ox_id, rx_id, x_id, mtu = 512;
1150
u_char target_id = 0xFF;
1151
 
1152
        ENTER("handle_Bad_SCSI_Frame_interrupt");
1153
        ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
1154
        offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
1155
        queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
1156
        queue_indx = queue_indx >> 16;
1157
        payload_size = ntohl(*(ptr_imq_entry + 2));
1158
 
1159
        buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset)));
1160
 
1161
        rctl = ntohl(*(buff_addr + 2)) & 0xFF000000;
1162
        s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
1163
        ox_id = ntohl(*(buff_addr + 6)) >> 16;
1164
        rx_id = ntohl(*(buff_addr + 6));
1165
        x_id = ox_id & MAX_SCSI_XID;
1166
 
1167
        /* Any frame that comes in with OX_ID that matches an OX_ID
1168
         * that has been allocated for SCSI, will be called a Bad
1169
         * SCSI frame if the Exchange is not valid any more.
1170
         *
1171
         * We will also get a Bad SCSI frame interrupt if we receive
1172
         * a XFER_RDY with offset != 0. Tachyon washes its hands off
1173
         * this Exchange. We have to take care of ourselves. Grrr...
1174
         */
1175
        if (rctl == DATA_DESCRIPTOR) {
1176
        struct fc_node_info *q = fi->node_info_list;
1177
                while (q != NULL) {
1178
                        if (q->d_id == s_id) {
1179
                                target_id = q->target_id;
1180
                                mtu = q->mtu;
1181
                                break;
1182
                        }
1183
                        else
1184
                                q = q->next;
1185
                }
1186
                frame_class = target_id;
1187
                transfered_len = ntohl(*(buff_addr + 8));
1188
                burst_len = ntohl(*(buff_addr + 9));
1189
 
1190
                build_ODB(fi, fi->g.seq_id, s_id, burst_len, 0, mtu, ox_id, rx_id, 0, 0, frame_class << 16);
1191
                /* Update the SEQ_ID and Relative Offset in the
1192
                 * Tachyon Header Structure.
1193
                 */
1194
                tach_header = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 5)));
1195
                *(tach_header + 5) = htonl(fi->g.seq_id << 24);
1196
                *(tach_header + 7) = htonl(transfered_len);
1197
                fi->g.odb.hdr_addr = *(fi->q.ptr_sest[x_id] + 5);
1198
 
1199
                /* Invalidate the EDBs used
1200
                 */
1201
                ptr_edb = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 7)));
1202
 
1203
                for (i = 0; i < EDB_LEN; i++)
1204
                        if (fi->q.ptr_edb[i] == ptr_edb)
1205
                                break;
1206
                ptr_edb--;
1207
 
1208
                if (i < EDB_LEN) {
1209
                int j;
1210
                        do {
1211
                                ptr_edb += 2;
1212
                                len += (htonl(*ptr_edb) & 0xFFFF);
1213
                                j = i;
1214
                                fi->q.free_edb_list[i++] = EDB_FREE;
1215
                                if (i == EDB_LEN) {
1216
                                        i = 0;
1217
                                        ptr_edb = fi->q.ptr_edb_base - 1;
1218
                                }
1219
                        } while (len < transfered_len);
1220
                        if (len > transfered_len) {
1221
                                ptr_edb--;
1222
                                fi->q.free_edb_list[j] = EDB_BUSY;
1223
                        }
1224
                        else
1225
                                ptr_edb++;
1226
                }
1227
                else {
1228
                        T_MSG("EDB not found while freeing");
1229
                        if (offset == (NO_OF_ENTRIES - 1))
1230
                                update_SFSBQ_indx(fi);
1231
                        return;
1232
                }
1233
 
1234
                /* Update the EDB pointer in the ODB.
1235
                 */
1236
                fi->g.odb.edb_addr = htonl(virt_to_bus(ptr_edb));
1237
                memcpy(fi->q.ptr_odb[fi->q.ocq_prod_indx], &(fi->g.odb), sizeof(ODB));
1238
                /* Update the EDB pointer in the SEST entry. We might need
1239
                 * this if get another XFER_RDY for the same Exchange.
1240
                 */
1241
                *(fi->q.ptr_sest[x_id] + 7) = htonl(virt_to_bus(ptr_edb));
1242
 
1243
                update_OCQ_indx(fi);
1244
                if (fi->g.seq_id == MAX_SEQ_ID)
1245
                        fi->g.seq_id = 0;
1246
                else
1247
                        fi->g.seq_id++;
1248
        }
1249
        else
1250
        /* Could be a BA_ACC or a BA_RJT.
1251
         */
1252
        if (rctl == RCTL_BASIC_ACC) {
1253
        u_int bls_type = remove_from_ox_id_list(fi, ox_id);
1254
                DPRINTK1("BA_ACC received from S_ID 0x%x with OX_ID = %x in response to %x", s_id, ox_id, bls_type);
1255
                if (bls_type == RCTL_BASIC_ABTS) {
1256
                u_int STE_bit;
1257
                        /* Invalidate resources for that Exchange.
1258
                         */
1259
                        STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
1260
                        if (STE_bit & SEST_V) {
1261
                                *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
1262
                                invalidate_SEST_entry(fi, ox_id);
1263
                        }
1264
                }
1265
        }
1266
        else
1267
        if (rctl == RCTL_BASIC_RJT) {
1268
        u_int bls_type = remove_from_ox_id_list(fi, ox_id);
1269
                DPRINTK1("BA_RJT received from S_ID 0x%x with OX_ID = %x in response to %x", s_id, ox_id, bls_type);
1270
                if (bls_type == RCTL_BASIC_ABTS) {
1271
                u_int STE_bit;
1272
                        /* Invalidate resources for that Exchange.
1273
                         */
1274
                        STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
1275
                        if (STE_bit & SEST_V) {
1276
                                *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
1277
                                invalidate_SEST_entry(fi, ox_id);
1278
                        }
1279
                }
1280
        }
1281
        else
1282
                DPRINTK1("Frame with R_CTL = %x received from S_ID 0x%x with OX_ID %x", rctl, s_id, ox_id);
1283
 
1284
        /* Else, discard the "Bad" SCSI frame.
1285
         */
1286
 
1287
        /* provide Tachyon will another set of buffers
1288
         */
1289
        if (offset == (NO_OF_ENTRIES - 1))
1290
                update_SFSBQ_indx(fi);
1291
        LEAVE("handle_Bad_SCSI_Frame_interrupt");
1292
}
1293
 
1294
static void handle_Inbound_SCSI_Status_interrupt(struct fc_info *fi)
1295
{
1296
struct Scsi_Host *host = fi->host;
1297
struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
1298
u_int *ptr_imq_entry, *buff_addr, *ptr_rsp_info, *ptr_sense_info = NULL;
1299
int queue_indx, offset, payload_size;
1300
u_short received_ox_id, x_id;
1301
Scsi_Cmnd *Cmnd;
1302
u_int fcp_status, fcp_rsp_info_len = 0, fcp_sense_info_len = 0, s_id;
1303
        ENTER("handle_SCSI_status_interrupt");
1304
 
1305
        ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
1306
        offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
1307
        queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
1308
        queue_indx = queue_indx >> 16;
1309
        buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset)));
1310
        payload_size = ntohl(*(ptr_imq_entry + 2));
1311
        received_ox_id = ntohl(*(buff_addr + 6)) >> 16;
1312
 
1313
        buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset)));
1314
 
1315
        fcp_status = ntohl(*(buff_addr + 10));
1316
        ptr_rsp_info = buff_addr + 14;
1317
        if (fcp_status & FCP_STATUS_RSP_LEN)
1318
                fcp_rsp_info_len = ntohl(*(buff_addr + 13));
1319
 
1320
        if (fcp_status & FCP_STATUS_SENSE_LEN) {
1321
                ptr_sense_info = ptr_rsp_info + fcp_rsp_info_len / 4;
1322
                fcp_sense_info_len = ntohl(*(buff_addr + 12));
1323
                DPRINTK("sense_info = %x", (u_int)ntohl(*ptr_sense_info));
1324
        }
1325
        DPRINTK("fcp_status = %x, fcp_rsp_len = %x", fcp_status, fcp_rsp_info_len);
1326
        x_id = received_ox_id & MAX_SCSI_XID;
1327
        Cmnd = hostdata->cmnd_handler[x_id];
1328
        hostdata->cmnd_handler[x_id] = NULL;
1329
        if (Cmnd != NULL) {
1330
                memset(Cmnd->sense_buffer, 0, sizeof(Cmnd->sense_buffer));
1331
                /* Check if there is a Sense field */
1332
                if (fcp_status & FCP_STATUS_SENSE_LEN) {
1333
                int size = sizeof(Cmnd->sense_buffer);
1334
                        if (fcp_sense_info_len < size)
1335
                                size = fcp_sense_info_len;
1336
                        memcpy(Cmnd->sense_buffer, (char *)ptr_sense_info, size);
1337
                }
1338
                Cmnd->result = fcp_status & FCP_STATUS_MASK;
1339
                (*Cmnd->scsi_done) (Cmnd);
1340
        }
1341
        else
1342
                T_MSG("NULL Command out of handler!");
1343
 
1344
        invalidate_SEST_entry(fi, received_ox_id);
1345
        s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
1346
        fi->q.free_scsi_oxid[x_id] = OXID_AVAILABLE;
1347
 
1348
        /* provide Tachyon will another set of buffers */
1349
        if (offset == (NO_OF_ENTRIES - 1))
1350
                update_SFSBQ_indx(fi);
1351
        LEAVE("handle_SCSI_status_interrupt");
1352
}
1353
 
1354
static void invalidate_SEST_entry(struct fc_info *fi, u_short received_ox_id)
1355
{
1356
u_short x_id = received_ox_id & MAX_SCSI_XID;
1357
        /* Invalidate SEST entry if it is an OutBound SEST Entry
1358
         */
1359
        if (!(received_ox_id & SCSI_READ_BIT)) {
1360
        u_int *ptr_tach_header, *ptr_edb;
1361
        u_short temp_ox_id = NOT_SCSI_XID;
1362
        int i;
1363
                *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
1364
 
1365
                /* Invalidate the Tachyon Header structure
1366
                 */
1367
                ptr_tach_header = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 5)));
1368
                for (i = 0; i < NO_OF_TACH_HEADERS; i++)
1369
                        if(fi->q.ptr_tachyon_header[i] == ptr_tach_header)
1370
                                break;
1371
                if (i < NO_OF_TACH_HEADERS)
1372
                        memset(ptr_tach_header, 0xFF, 32);
1373
                else
1374
                        T_MSG("Tachyon Header not found while freeing in invalidate_SEST_entry()");
1375
 
1376
                /* Invalidate the EDB used
1377
                 */
1378
                ptr_edb = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 7)));
1379
                for (i = 0; i < EDB_LEN; i++)
1380
                        if (fi->q.ptr_edb[i] == ptr_edb)
1381
                                break;
1382
                ptr_edb--;
1383
                if (i < EDB_LEN) {
1384
                        do {
1385
                                ptr_edb += 2;
1386
                                fi->q.free_edb_list[i++] = EDB_FREE;
1387
                                if (i == EDB_LEN) {
1388
                                        i = 0;
1389
                                        ptr_edb = fi->q.ptr_edb_base - 1;
1390
                                }
1391
                        } while ((htonl(*ptr_edb) & 0x80000000) != 0x80000000);
1392
                }
1393
                else
1394
                        T_MSG("EDB not found while freeing in invalidate_SEST_entry()");
1395
 
1396
                /* Search for its other header structure and destroy it!
1397
                 */
1398
                if ((ptr_tach_header + 16) < (fi->q.ptr_tachyon_header_base + (MY_PAGE_SIZE/4)))
1399
                        ptr_tach_header += 16;
1400
                else
1401
                        ptr_tach_header = fi->q.ptr_tachyon_header_base;
1402
                while (temp_ox_id != x_id) {
1403
                        temp_ox_id = ntohl(*(ptr_tach_header + 6)) >> 16;
1404
                        if (temp_ox_id == x_id) {
1405
                                /* Paranoid checking...
1406
                                 */
1407
                                for (i = 0; i < NO_OF_TACH_HEADERS; i++)
1408
                                        if(fi->q.ptr_tachyon_header[i] == ptr_tach_header)
1409
                                                break;
1410
                                if (i < NO_OF_TACH_HEADERS)
1411
                                        memset(ptr_tach_header, 0xFF, 32);
1412
                                else
1413
                                        T_MSG("Tachyon Header not found while freeing in invalidate_SEST_entry()");
1414
                                break;
1415
                        }
1416
                        else {
1417
                                if ((ptr_tach_header + 16) < (fi->q.ptr_tachyon_header_base + (MY_PAGE_SIZE/4)))
1418
                                        ptr_tach_header += 16;
1419
                                else
1420
                                        ptr_tach_header = fi->q.ptr_tachyon_header_base;
1421
                        }
1422
                }
1423
        }
1424
        else {
1425
        u_short sdb_table_indx;
1426
                /* An Inbound Command has completed or needs to be Aborted.
1427
                 * Clear up the SDB buffers.
1428
                 */
1429
                sdb_table_indx = *(fi->q.ptr_sest[x_id] + 5);
1430
                fi->q.sdb_slot_status[sdb_table_indx] = SDB_FREE;
1431
        }
1432
}
1433
 
1434
static void handle_Inbound_SCSI_Command_interrupt(struct fc_info *fi)
1435
{
1436
u_int *ptr_imq_entry;
1437
int queue_indx, offset;
1438
        ENTER("handle_Inbound_SCSI_Command_interrupt");
1439
        ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
1440
        offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
1441
        queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
1442
        queue_indx = queue_indx >> 16;
1443
        /* We discard the SCSI frame as we shouldn't be receiving
1444
         * a SCSI Command in the first place
1445
         */
1446
        /* provide Tachyon will another set of buffers */
1447
        if (offset == (NO_OF_ENTRIES - 1))
1448
                update_SFSBQ_indx(fi);
1449
        LEAVE("handle_Inbound_SCSI_Command_interrupt");
1450
}
1451
 
1452
static void handle_SFS_interrupt(struct fc_info *fi)
1453
{
1454
u_int *ptr_imq_entry, *buff_addr;
1455
u_int class_of_frame, type_of_frame, s_id, els_type = 0, rctl;
1456
int queue_indx, offset, payload_size, login_state;
1457
u_short received_ox_id, fs_cmnd_code;
1458
        ENTER("handle_SFS_interrupt");
1459
        ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
1460
        offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
1461
        queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
1462
        queue_indx = queue_indx >> 16;
1463
        DPRINTK("queue_indx = %d, offset  = %d\n", queue_indx, offset);
1464
        payload_size = ntohl(*(ptr_imq_entry + 2));
1465
        DPRINTK("payload_size = %d", payload_size);
1466
 
1467
        buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset)));
1468
 
1469
        /* extract Type of Frame */
1470
        type_of_frame = ntohl(*(buff_addr + 4)) & 0xFF000000;
1471
        s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
1472
        received_ox_id = ntohl(*(buff_addr + 6)) >> 16;
1473
        switch(type_of_frame) {
1474
                case TYPE_BLS:
1475
                        rctl = ntohl(*(buff_addr + 2)) & 0xFF000000;
1476
                        switch(rctl) {
1477
                                case RCTL_BASIC_ABTS:
1478
                                        /* As an Initiator, we should never be receiving
1479
                                         * this.
1480
                                         */
1481
                                        DPRINTK1("ABTS received from S_ID 0x%x with OX_ID = %x", s_id, received_ox_id);
1482
                                        break;
1483
                        }
1484
                        break;
1485
                case TYPE_ELS:
1486
                        class_of_frame = ntohl(*(buff_addr + 8));
1487
                        login_state = sid_logged_in(fi, s_id);
1488
                        switch(class_of_frame & 0xFF000000) {
1489
                                case ELS_PLOGI:
1490
                                        if (s_id != fi->g.my_id) {
1491
                                                u_int ret_code;
1492
                                                DPRINTK1("PLOGI received from D_ID 0x%x with 0X_ID = %x", s_id, received_ox_id);
1493
                                                if ((ret_code = plogi_ok(fi, buff_addr, payload_size)) == 0){
1494
                                                        tx_logi_acc(fi, ELS_ACC, s_id, received_ox_id);
1495
                                                        add_to_address_cache(fi, buff_addr);
1496
                                                }
1497
                                                else {
1498
                                                        u_short cmnd_code = ret_code >> 16;
1499
                                                        u_short expln_code =  ret_code;
1500
                                                        tx_ls_rjt(fi, s_id, received_ox_id, cmnd_code, expln_code);
1501
                                                }
1502
                                        }
1503
                                        break;
1504
                                case ELS_ACC:
1505
                                        els_type = remove_from_ox_id_list(fi, received_ox_id);
1506
                                        DPRINTK1("ELS_ACC received from D_ID 0x%x in response to ELS %x", s_id, els_type);
1507
                                        switch(els_type) {
1508
                                                case ELS_PLOGI:
1509
                                                        add_to_address_cache(fi, buff_addr);
1510
                                                        tx_prli(fi, ELS_PRLI, s_id, OX_ID_FIRST_SEQUENCE);
1511
                                                        break;
1512
                                                case ELS_FLOGI:
1513
                                                        add_to_address_cache(fi, buff_addr);
1514
                                                        fi->g.my_id = ntohl(*(buff_addr + 2)) & 0x00FFFFFF;
1515
                                                        fi->g.fabric_present = TRUE;
1516
                                                        fi->g.my_ddaa = fi->g.my_id & 0xFFFF00;
1517
                                                        /* Login to the Name Server
1518
                                                         */
1519
                                                        tx_logi(fi, ELS_PLOGI, DIRECTORY_SERVER);
1520
                                                        break;
1521
                                                case ELS_NS_PLOGI:
1522
                                                        fi->g.name_server = TRUE;
1523
                                                        add_to_address_cache(fi, buff_addr);
1524
                                                        tx_name_server_req(fi, FCS_RFC_4);
1525
                                                        tx_scr(fi);
1526
                                                        /* Some devices have a delay before
1527
                                                         * registering with the Name Server
1528
                                                         */
1529
                                                        udelay(500);
1530
                                                        tx_name_server_req(fi, FCS_GP_ID4);
1531
                                                        break;
1532
                                                case ELS_PRLI:
1533
                                                        mark_scsi_sid(fi, buff_addr, ADD_ENTRY);
1534
                                                        break;
1535
                                                case ELS_ADISC:
1536
                                                        if (!(validate_login(fi, buff_addr)))
1537
                                                                tx_logo(fi, s_id, OX_ID_FIRST_SEQUENCE);
1538
                                                        break;
1539
                                        }
1540
                                        break;
1541
                                case ELS_PDISC:
1542
                                        DPRINTK1("ELS_PDISC received from D_ID 0x%x", s_id);
1543
                                        tx_logo(fi, s_id, received_ox_id);
1544
                                        break;
1545
                                case ELS_ADISC:
1546
                                        DPRINTK1("ELS_ADISC received from D_ID 0x%x", s_id);
1547
                                        if (node_logged_in_prev(fi, buff_addr))
1548
                                                tx_adisc(fi, ELS_ACC, s_id, received_ox_id);
1549
                                        else
1550
                                                tx_logo(fi, s_id, received_ox_id);
1551
                                        break;
1552
                                case ELS_PRLI:
1553
                                        DPRINTK1("ELS_PRLI received from D_ID 0x%x", s_id);
1554
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) {
1555
                                                tx_prli(fi, ELS_ACC, s_id, received_ox_id);
1556
                                                mark_scsi_sid(fi, buff_addr, ADD_ENTRY);
1557
                                        }
1558
                                        else
1559
                                                tx_logo(fi, s_id, received_ox_id);
1560
                                        break;
1561
                                case ELS_PRLO:
1562
                                        DPRINTK1("ELS_PRLO received from D_ID 0x%x", s_id);
1563
                                        if ((login_state == NODE_LOGGED_OUT) || (login_state == NODE_NOT_PRESENT))
1564
                                                tx_logo(fi, s_id, received_ox_id);
1565
                                        else
1566
                                        if (login_state == NODE_LOGGED_IN)
1567
 
1568
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1569
                                        else
1570
                                        if (login_state == NODE_PROCESS_LOGGED_IN) {
1571
                                                tx_prli(fi, ELS_ACC, s_id, received_ox_id);
1572
                                                mark_scsi_sid(fi, buff_addr, DELETE_ENTRY);
1573
                                        }
1574
                                        break;
1575
                                case ELS_LS_RJT:
1576
                                        els_type = remove_from_ox_id_list(fi, received_ox_id);
1577
                                        DPRINTK1("ELS_LS_RJT received from D_ID 0x%x in response to %x", s_id, els_type);
1578
                                        /* We should be chking the reason code.
1579
                                         */
1580
                                        switch (els_type) {
1581
                                                case ELS_ADISC:
1582
                                                        tx_logi(fi, ELS_PLOGI, s_id);
1583
                                                        break;
1584
                                        }
1585
                                        break;
1586
                                case ELS_LOGO:
1587
                                        els_type = remove_from_ox_id_list(fi, received_ox_id);
1588
                                        DPRINTK1("ELS_LOGO received from D_ID 0x%x in response to %x", s_id, els_type);
1589
                                        remove_from_address_cache(fi, buff_addr, ELS_LOGO);
1590
                                        tx_acc(fi, s_id, received_ox_id);
1591
                                        if (els_type == ELS_ADISC)
1592
                                                tx_logi(fi, ELS_PLOGI, s_id);
1593
                                        break;
1594
                                case ELS_RSCN:
1595
                                        DPRINTK1("ELS_RSCN received from D_ID 0x%x", s_id);
1596
                                        tx_acc(fi, s_id, received_ox_id);
1597
                                        remove_from_address_cache(fi, buff_addr, ELS_RSCN);
1598
                                        break;
1599
                                case ELS_FARP_REQ:
1600
                                        /* We do not support FARP.
1601
                                           So, silently discard it */
1602
                                        DPRINTK1("ELS_FARP_REQ received from D_ID 0x%x", s_id);
1603
                                        break;
1604
                                case ELS_ABTX:
1605
                                        DPRINTK1("ELS_ABTX received from D_ID 0x%x", s_id);
1606
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1607
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1608
                                        else
1609
                                                tx_logo(fi, s_id, received_ox_id);
1610
                                        break;
1611
                                case ELS_FLOGI:
1612
                                        DPRINTK1("ELS_FLOGI received from D_ID 0x%x", s_id);
1613
                                        if (fi->g.ptp_up == TRUE) {
1614
                                                /* The node could have come up as an N_Port
1615
                                                 * in a Loop! So,try initializing as an NL_port
1616
                                                 */
1617
                                                take_tachyon_offline(fi);
1618
                                                /* write AL_TIME & E_D_TOV into the registers */
1619
                                                writel(TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
1620
                                                writel(LOOP_INIT_SOFT_ADDRESS, fi->t_r.ptr_fm_config_reg);
1621
                                                DPRINTK1("FLOGI received, TACHYON initializing as L_Port...\n");
1622
                                                writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
1623
                                        }
1624
                                        else {
1625
                                                if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1626
                                                        tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1627
                                                else
1628
                                                        tx_logo(fi, s_id, received_ox_id);
1629
                                        }
1630
                                        break;
1631
                                case ELS_ADVC:
1632
                                        DPRINTK1("ELS_ADVC received from D_ID 0x%x", s_id);
1633
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1634
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1635
                                        else
1636
                                                tx_logo(fi, s_id, received_ox_id);
1637
                                        break;
1638
                                case ELS_ECHO:
1639
                                        DPRINTK1("ELS_ECHO received from D_ID 0x%x", s_id);
1640
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1641
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1642
                                        else
1643
                                                tx_logo(fi, s_id, received_ox_id);
1644
                                        break;
1645
                                case ELS_ESTC:
1646
                                        DPRINTK1("ELS_ESTC received from D_ID 0x%x", s_id);
1647
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1648
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1649
                                        else
1650
                                                tx_logo(fi, s_id, received_ox_id);
1651
                                        break;
1652
                                case ELS_ESTS:
1653
                                        DPRINTK1("ELS_ESTS received from D_ID 0x%x", s_id);
1654
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1655
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1656
                                        else
1657
                                                tx_logo(fi, s_id, received_ox_id);
1658
                                        break;
1659
                                case ELS_RCS:
1660
                                        DPRINTK1("ELS_RCS received from D_ID 0x%x", s_id);
1661
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1662
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1663
                                        else
1664
                                                tx_logo(fi, s_id, received_ox_id);
1665
                                        break;
1666
                                case ELS_RES:
1667
                                        DPRINTK1("ELS_RES received from D_ID 0x%x", s_id);
1668
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1669
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1670
                                        else
1671
                                                tx_logo(fi, s_id, received_ox_id);
1672
                                        break;
1673
                                case ELS_RLS:
1674
                                        DPRINTK1("ELS_RLS received from D_ID 0x%x", s_id);
1675
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1676
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1677
                                        else
1678
                                                tx_logo(fi, s_id, received_ox_id);
1679
                                        break;
1680
                                case ELS_RRQ:
1681
                                        DPRINTK1("ELS_RRQ received from D_ID 0x%x", s_id);
1682
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1683
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1684
                                        else
1685
                                                tx_logo(fi, s_id, received_ox_id);
1686
                                        break;
1687
                                case ELS_RSS:
1688
                                        DPRINTK1("ELS_RSS received from D_ID 0x%x", s_id);
1689
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1690
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1691
                                        else
1692
                                                tx_logo(fi, s_id, received_ox_id);
1693
                                        break;
1694
                                case ELS_RTV:
1695
                                        DPRINTK1("ELS_RTV received from D_ID 0x%x", s_id);
1696
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1697
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1698
                                        else
1699
                                                tx_logo(fi, s_id, received_ox_id);
1700
                                        break;
1701
                                case ELS_RSI:
1702
                                        DPRINTK1("ELS_RSI received from D_ID 0x%x", s_id);
1703
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1704
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1705
                                        else
1706
                                                tx_logo(fi, s_id, received_ox_id);
1707
                                        break;
1708
                                case ELS_TEST:
1709
                                        /* No reply sequence */
1710
                                        DPRINTK1("ELS_TEST received from D_ID 0x%x", s_id);
1711
                                        break;
1712
                                case ELS_RNC:
1713
                                        DPRINTK1("ELS_RNC received from D_ID 0x%x", s_id);
1714
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1715
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1716
                                        else
1717
                                                tx_logo(fi, s_id, received_ox_id);
1718
                                        break;
1719
                                case ELS_RVCS:
1720
                                        DPRINTK1("ELS_RVCS received from D_ID 0x%x", s_id);
1721
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1722
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1723
                                        else
1724
                                                tx_logo(fi, s_id, received_ox_id);
1725
                                        break;
1726
                                case ELS_TPLS:
1727
                                        DPRINTK1("ELS_TPLS received from D_ID 0x%x", s_id);
1728
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1729
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1730
                                        else
1731
                                                tx_logo(fi, s_id, received_ox_id);
1732
                                        break;
1733
                                case ELS_GAID:
1734
                                        DPRINTK1("ELS_GAID received from D_ID 0x%x", s_id);
1735
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1736
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1737
                                        else
1738
                                                tx_logo(fi, s_id, received_ox_id);
1739
                                        break;
1740
                                case ELS_FACT:
1741
                                        DPRINTK1("ELS_FACT received from D_ID 0x%x", s_id);
1742
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1743
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1744
                                        else
1745
                                                tx_logo(fi, s_id, received_ox_id);
1746
                                        break;
1747
                                case ELS_FAN:
1748
                                        /* Hmmm... You don't support FAN ??? */
1749
                                        DPRINTK1("ELS_FAN received from D_ID 0x%x", s_id);
1750
                                        tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1751
                                        break;
1752
                                case ELS_FDACT:
1753
                                        DPRINTK1("ELS_FDACT received from D_ID 0x%x", s_id);
1754
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1755
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1756
                                        else
1757
                                                tx_logo(fi, s_id, received_ox_id);
1758
                                        break;
1759
                                case ELS_NACT:
1760
                                        DPRINTK1("ELS_NACT received from D_ID 0x%x", s_id);
1761
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1762
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1763
                                        else
1764
                                                tx_logo(fi, s_id, received_ox_id);
1765
                                        break;
1766
                                case ELS_NDACT:
1767
                                        DPRINTK1("ELS_NDACT received from D_ID 0x%x", s_id);
1768
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1769
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1770
                                        else
1771
                                                tx_logo(fi, s_id, received_ox_id);
1772
                                        break;
1773
                                case ELS_QoSR:
1774
                                        DPRINTK1("ELS_QoSR received from D_ID 0x%x", s_id);
1775
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1776
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1777
                                        else
1778
                                                tx_logo(fi, s_id, received_ox_id);
1779
                                        break;
1780
                                case ELS_FDISC:
1781
                                        DPRINTK1("ELS_FDISC received from D_ID 0x%x", s_id);
1782
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1783
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1784
                                        else
1785
                                                tx_logo(fi, s_id, received_ox_id);
1786
                                        break;
1787
                                default:
1788
                                        DPRINTK1("ELS Frame %x received from D_ID 0x%x", class_of_frame, s_id);
1789
                                        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
1790
                                                tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
1791
                                        else
1792
                                                tx_logo(fi, s_id, received_ox_id);
1793
                                        break;
1794
                        }
1795
                        break;
1796
                case TYPE_FC_SERVICES:
1797
                        fs_cmnd_code = (ntohl(*(buff_addr + 10)) & 0xFFFF0000) >>16;
1798
                        switch(fs_cmnd_code) {
1799
                                case FCS_ACC:
1800
                                        els_type = remove_from_ox_id_list(fi, received_ox_id);
1801
                                        DPRINTK1("FCS_ACC received from D_ID 0x%x in response to %x", s_id, els_type);
1802
                                        if (els_type == FCS_GP_ID4)
1803
                                                explore_fabric(fi, buff_addr);
1804
                                        break;
1805
                                case FCS_REJECT:
1806
                                        DPRINTK1("FCS_REJECT received from D_ID 0x%x in response to %x", s_id, els_type);
1807
                                        break;
1808
                        }
1809
                        break;
1810
                case TYPE_LLC_SNAP:
1811
                        rx_net_packet(fi, (u_char *)buff_addr, payload_size);
1812
                        break;
1813
                default:
1814
                        T_MSG("Frame Type %x received from %x", type_of_frame, s_id);
1815
        }
1816
 
1817
        /* provide Tachyon will another set of buffers */
1818
        if (offset == (NO_OF_ENTRIES - 1))
1819
                update_SFSBQ_indx(fi);
1820
        LEAVE("handle_SFS_interrupt");
1821
}
1822
 
1823
static void handle_FM_interrupt(struct fc_info *fi)
1824
{
1825
u_int fm_status;
1826
u_int tachyon_status;
1827
 
1828
        ENTER("handle_FM_interrupt");
1829
        fm_status = readl(fi->t_r.ptr_fm_status_reg);
1830
        tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
1831
        DPRINTK("FM_status = %x, Tachyon_status = %x", fm_status, tachyon_status);
1832
        if (fm_status & LINK_DOWN) {
1833
                T_MSG("Fibre Channel Link DOWN");
1834
                fm_status = readl(fi->t_r.ptr_fm_status_reg);
1835
 
1836
                del_timer(&fi->explore_timer);
1837
                del_timer(&fi->nport_timer);
1838
                del_timer(&fi->lport_timer);
1839
                del_timer(&fi->display_cache_timer);
1840
                fi->g.link_up = FALSE;
1841
                if (fi->g.ptp_up == TRUE)
1842
                        fi->g.n_port_try = FALSE;
1843
                fi->g.ptp_up = FALSE;
1844
                fi->g.port_discovery = FALSE;
1845
                fi->g.explore_fabric = FALSE;
1846
                fi->g.perform_adisc = FALSE;
1847
 
1848
                /* Logout will all nodes */
1849
                if (fi->node_info_list) {
1850
                        struct fc_node_info *temp_list = fi->node_info_list;
1851
                                while(temp_list) {
1852
                                        temp_list->login = LOGIN_ATTEMPTED;
1853
                                        temp_list = temp_list->next;
1854
                                }
1855
                                fi->num_nodes = 0;
1856
                }
1857
 
1858
                if ((fi->g.n_port_try == FALSE) && (fi->g.dont_init == FALSE)){
1859
                        take_tachyon_offline(fi);
1860
                        /* write AL_TIME & E_D_TOV into the registers */
1861
                        writel(TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
1862
 
1863
                        if ((fi->g.fabric_present == TRUE) && (fi->g.loop_up == TRUE)) {
1864
                        u_int al_pa = fi->g.my_id & 0xFF;
1865
                                writel((al_pa << 24) | LOOP_INIT_FABRIC_ADDRESS | LOOP_INIT_PREVIOUS_ADDRESS, fi->t_r.ptr_fm_config_reg);
1866
                        }
1867
                        else
1868
                        if (fi->g.loop_up == TRUE) {
1869
                        u_int al_pa = fi->g.my_id & 0xFF;
1870
                                writel((al_pa << 24) | LOOP_INIT_PREVIOUS_ADDRESS, fi->t_r.ptr_fm_config_reg);
1871
                        }
1872
                        else
1873
                                writel(LOOP_INIT_SOFT_ADDRESS, fi->t_r.ptr_fm_config_reg);
1874
                        fi->g.loop_up = FALSE;
1875
                        DPRINTK1("In LDWN TACHYON initializing as L_Port...\n");
1876
                        writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
1877
                }
1878
        }
1879
 
1880
    if (fm_status & NON_PARTICIPATING) {
1881
                T_MSG("Did not acquire an AL_PA. I am not participating");
1882
    }
1883
        else
1884
        if ((fm_status & LINK_UP) && ((fm_status & LINK_DOWN) == 0)) {
1885
          T_MSG("Fibre Channel Link UP");
1886
          if ((fm_status & NON_PARTICIPATING) != TRUE) {
1887
                fi->g.link_up = TRUE;
1888
                if (tachyon_status & OSM_FROZEN) {
1889
                        reset_tachyon(fi, ERROR_RELEASE);
1890
                        reset_tachyon(fi, OCQ_RESET);
1891
                }
1892
                init_timer(&fi->explore_timer);
1893
                init_timer(&fi->nport_timer);
1894
                init_timer(&fi->lport_timer);
1895
                init_timer(&fi->display_cache_timer);
1896
                if ((fm_status & OLD_PORT) == 0) {
1897
                        fi->g.loop_up = TRUE;
1898
                        fi->g.ptp_up = FALSE;
1899
                        fi->g.my_id = readl(fi->t_r.ptr_fm_config_reg) >> 24;
1900
                        DPRINTK1("My AL_PA = %x", fi->g.my_id);
1901
                        fi->g.port_discovery = TRUE;
1902
                        fi->g.explore_fabric = FALSE;
1903
                }
1904
                else
1905
                if (((fm_status & 0xF0) == OLD_PORT) && ((fm_status & 0x0F) == PORT_STATE_ACTIVE)) {
1906
                        fi->g.loop_up = FALSE;
1907
                        fi->g.my_id = 0x0;
1908
                        /* In a point-to-point configuration, we expect to be
1909
                         * connected to an F_Port. This driver does not yet support
1910
                         * a configuration where it is connected to another N_Port
1911
                         * directly.
1912
                         */
1913
                        fi->g.explore_fabric = TRUE;
1914
                        fi->g.port_discovery = FALSE;
1915
                        if (fi->g.n_port_try == FALSE) {
1916
                                take_tachyon_offline(fi);
1917
                                /* write R_T_TOV & E_D_TOV into the registers */
1918
                                writel(PTP_TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
1919
                                writel(BB_CREDIT | NPORT, fi->t_r.ptr_fm_config_reg);
1920
                                fi->g.n_port_try = TRUE;
1921
                                DPRINTK1("In LUP TACHYON initializing as N_Port...\n");
1922
                                writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
1923
                        }
1924
                        else {
1925
                                fi->g.ptp_up = TRUE;
1926
                                tx_logi(fi, ELS_FLOGI, F_PORT);
1927
                        }
1928
                }
1929
                fi->g.my_ddaa = 0x0;
1930
                fi->g.fabric_present = FALSE;
1931
                /* We havn't sent out any Name Server Reqs */
1932
                fi->g.name_server = FALSE;
1933
                fi->g.alpa_list_index = 0;
1934
                fi->g.ox_id = NOT_SCSI_XID;
1935
                fi->g.my_mtu = TACH_FRAME_SIZE;
1936
 
1937
                /* Implicitly LOGO with all logged-in nodes.
1938
                 */
1939
                if (fi->node_info_list) {
1940
                struct fc_node_info *temp_list = fi->node_info_list;
1941
                        while(temp_list) {
1942
                                temp_list->login = LOGIN_ATTEMPTED;
1943
                                temp_list = temp_list->next;
1944
                        }
1945
                        fi->num_nodes = 0;
1946
                        fi->g.perform_adisc = TRUE;
1947
                        //fi->g.perform_adisc = FALSE;
1948
                        fi->g.port_discovery = FALSE;
1949
                        tx_logi(fi, ELS_FLOGI, F_PORT);
1950
                }
1951
                else {
1952
                        /* If Link coming up for the _first_ time or no nodes
1953
                         * were logged in before...
1954
                         */
1955
                        fi->g.scsi_oxid = 0;
1956
                        fi->g.seq_id = 0x00;
1957
                        fi->g.perform_adisc = FALSE;
1958
                }
1959
 
1960
                /* reset OX_ID table */
1961
                while (fi->ox_id_list) {
1962
                struct ox_id_els_map *temp = fi->ox_id_list;
1963
                        fi->ox_id_list = fi->ox_id_list->next;
1964
                        kfree(temp);
1965
                }
1966
                fi->ox_id_list = NULL;
1967
          } /* End of if partipating */
1968
        }
1969
 
1970
        if (fm_status & ELASTIC_STORE_ERROR) {
1971
                /* Too much junk on the Link
1972
                 */
1973
                /* Trying to clear it up by Txing PLOGI to urself */
1974
                if (fi->g.link_up == TRUE)
1975
                        tx_logi(fi, ELS_PLOGI, fi->g.my_id);
1976
        }
1977
 
1978
        if (fm_status & LOOP_UP) {
1979
                if (tachyon_status & OSM_FROZEN) {
1980
                        reset_tachyon(fi, ERROR_RELEASE);
1981
                        reset_tachyon(fi, OCQ_RESET);
1982
                }
1983
        }
1984
 
1985
        if (fm_status & NOS_OLS_RECEIVED){
1986
                if (fi->g.nport_timer_set == FALSE) {
1987
                        DPRINTK("NOS/OLS Received");
1988
                        DPRINTK("FM_status = %x", fm_status);
1989
                        fi->nport_timer.function = nos_ols_timer;
1990
                        fi->nport_timer.data = (unsigned long)fi;
1991
                        fi->nport_timer.expires = RUN_AT((3*HZ)/100); /* 30 msec */
1992
                        init_timer(&fi->nport_timer);
1993
                        add_timer(&fi->nport_timer);
1994
                        fi->g.nport_timer_set = TRUE;
1995
                }
1996
        }
1997
 
1998
        if (((fm_status & 0xF0) == OLD_PORT) && (((fm_status & 0x0F) == PORT_STATE_LF1) || ((fm_status & 0x0F) == PORT_STATE_LF2))) {
1999
                DPRINTK1("Link Fail-I in OLD-PORT.");
2000
                take_tachyon_offline(fi);
2001
                reset_tachyon(fi, SOFTWARE_RESET);
2002
        }
2003
 
2004
        if (fm_status & LOOP_STATE_TIMEOUT){
2005
                if ((fm_status & 0xF0) == ARBITRATING)
2006
                        DPRINTK1("ED_TOV timesout.In ARBITRATING state...");
2007
                if ((fm_status & 0xF0) == ARB_WON)
2008
                        DPRINTK1("ED_TOV timesout.In ARBITRATION WON state...");
2009
                if ((fm_status & 0xF0) == OPEN)
2010
                        DPRINTK1("ED_TOV timesout.In OPEN state...");
2011
                if ((fm_status & 0xF0) == OPENED)
2012
                        DPRINTK1("ED_TOV timesout.In OPENED state...");
2013
                if ((fm_status & 0xF0) == TX_CLS)
2014
                        DPRINTK1("ED_TOV timesout.In XMITTED CLOSE state...");
2015
                if ((fm_status & 0xF0) == RX_CLS)
2016
                        DPRINTK1("ED_TOV timesout.In RECEIVED CLOSE state...");
2017
                if ((fm_status & 0xF0) == INITIALIZING)
2018
                        DPRINTK1("ED_TOV timesout.In INITIALIZING state...");
2019
                DPRINTK1("Initializing Loop...");
2020
                writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
2021
        }
2022
 
2023
        if ((fm_status & BAD_ALPA) && (fi->g.loop_up == TRUE)) {
2024
        u_char bad_alpa = (readl(fi->t_r.ptr_fm_rx_al_pa_reg) & 0xFF00) >> 8;
2025
                if (tachyon_status & OSM_FROZEN) {
2026
                        reset_tachyon(fi, ERROR_RELEASE);
2027
                        reset_tachyon(fi, OCQ_RESET);
2028
                }
2029
                /* Fix for B34 */
2030
                tx_logi(fi, ELS_PLOGI, fi->g.my_id);
2031
 
2032
                if (!fi->g.port_discovery && !fi->g.perform_adisc) {
2033
                        if (bad_alpa != 0xFE)
2034
                                DPRINTK("Bad AL_PA = %x", bad_alpa);
2035
                }
2036
                else {
2037
                        if ((fi->g.perform_adisc == TRUE) && (bad_alpa == 0x00)) {
2038
                                DPRINTK1("Performing ADISC...");
2039
                                fi->g.fabric_present = FALSE;
2040
                                perform_adisc(fi);
2041
                        }
2042
                }
2043
        }
2044
 
2045
        if (fm_status & LIPF_RECEIVED){
2046
                DPRINTK("LIP(F8) Received");
2047
        }
2048
 
2049
        if (fm_status & LINK_FAILURE) {
2050
                if (fm_status & LOSS_OF_SIGNAL)
2051
                        DPRINTK1("Detected Loss of Signal.");
2052
                if (fm_status & OUT_OF_SYNC)
2053
                        DPRINTK1("Detected Loss of Synchronization.");
2054
        }
2055
 
2056
        if (fm_status & TRANSMIT_PARITY_ERROR) {
2057
                /* Bad! Should not happen. Solution-> Hard Reset.
2058
                 */
2059
                T_MSG("Parity Error. Perform Hard Reset!");
2060
        }
2061
 
2062
        if (fi->g.alpa_list_index >= MAX_NODES){
2063
                if (fi->g.port_discovery == TRUE) {
2064
                        fi->g.port_discovery = FALSE;
2065
                        add_display_cache_timer(fi);
2066
                }
2067
                fi->g.alpa_list_index = MAX_NODES;
2068
        }
2069
 
2070
        if (fi->g.port_discovery == TRUE)
2071
                local_port_discovery(fi);
2072
 
2073
        LEAVE("handle_FM_interrupt");
2074
        return;
2075
}
2076
 
2077
static void local_port_discovery(struct fc_info *fi)
2078
{
2079
        if (fi->g.loop_up == TRUE) {
2080
                /* If this is not here, some of the Bad AL_PAs are missed.
2081
                 */
2082
                udelay(20);
2083
                if ((fi->g.alpa_list_index == 0) && (fi->g.fabric_present == FALSE)){
2084
                        tx_logi(fi, ELS_FLOGI, F_PORT);
2085
                }
2086
                else {
2087
                int login_state = sid_logged_in(fi, fi->g.my_ddaa | alpa_list[fi->g.alpa_list_index]);
2088
                        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)))))
2089
                                fi->g.alpa_list_index++;
2090
                        if (fi->g.alpa_list_index < MAX_NODES)
2091
                                tx_logi(fi, ELS_PLOGI, alpa_list[fi->g.alpa_list_index]);
2092
                }
2093
                fi->g.alpa_list_index++;
2094
                if (fi->g.alpa_list_index >= MAX_NODES){
2095
                        if (fi->g.port_discovery == TRUE) {
2096
                                fi->g.port_discovery = FALSE;
2097
                                add_display_cache_timer(fi);
2098
                        }
2099
                        fi->g.alpa_list_index = MAX_NODES;
2100
                }
2101
        }
2102
}
2103
 
2104
static void nos_ols_timer(unsigned long data)
2105
{
2106
struct fc_info *fi = (struct fc_info*)data;
2107
u_int fm_status;
2108
        fm_status = readl(fi->t_r.ptr_fm_status_reg);
2109
        DPRINTK1("FM_status in timer= %x", fm_status);
2110
        fi->g.nport_timer_set = FALSE;
2111
        del_timer(&fi->nport_timer);
2112
        if ((fi->g.ptp_up == TRUE) || (fi->g.loop_up == TRUE))
2113
                return;
2114
        if (((fm_status & 0xF0) == OLD_PORT) && (((fm_status & 0x0F) == PORT_STATE_ACTIVE) || ((fm_status & 0x0F) == PORT_STATE_OFFLINE))) {
2115
                DPRINTK1("In OLD-PORT after E_D_TOV.");
2116
                take_tachyon_offline(fi);
2117
                /* write R_T_TOV & E_D_TOV into the registers */
2118
                writel(PTP_TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
2119
                writel(BB_CREDIT | NPORT, fi->t_r.ptr_fm_config_reg);
2120
                fi->g.n_port_try = TRUE;
2121
                DPRINTK1("In timer, TACHYON initializing as N_Port...\n");
2122
                writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
2123
        }
2124
        else
2125
        if ((fi->g.lport_timer_set == FALSE) && ((fm_status & 0xF0) == LOOP_FAIL)) {
2126
                DPRINTK1("Loop Fail after E_D_TOV.");
2127
                fi->lport_timer.function = loop_timer;
2128
                fi->lport_timer.data = (unsigned long)fi;
2129
                fi->lport_timer.expires = RUN_AT((8*HZ)/100);
2130
                init_timer(&fi->lport_timer);
2131
                add_timer(&fi->lport_timer);
2132
                fi->g.lport_timer_set = TRUE;
2133
                take_tachyon_offline(fi);
2134
                reset_tachyon(fi, SOFTWARE_RESET);
2135
        }
2136
        else
2137
        if (((fm_status & 0xF0) == OLD_PORT) && (((fm_status & 0x0F) == PORT_STATE_LF1) || ((fm_status & 0x0F) == PORT_STATE_LF2))) {
2138
                DPRINTK1("Link Fail-II in OLD-PORT.");
2139
                take_tachyon_offline(fi);
2140
                reset_tachyon(fi, SOFTWARE_RESET);
2141
        }
2142
}
2143
 
2144
static void loop_timer(unsigned long data)
2145
{
2146
struct fc_info *fi = (struct fc_info*)data;
2147
        fi->g.lport_timer_set = FALSE;
2148
        del_timer(&fi->lport_timer);
2149
        if ((fi->g.ptp_up == TRUE) || (fi->g.loop_up == TRUE))
2150
                return;
2151
}
2152
 
2153
static void add_display_cache_timer(struct fc_info *fi)
2154
{
2155
        fi->display_cache_timer.function = display_cache_timer;
2156
        fi->display_cache_timer.data = (unsigned long)fi;
2157
        fi->display_cache_timer.expires = RUN_AT(fi->num_nodes * HZ);
2158
        init_timer(&fi->display_cache_timer);
2159
        add_timer(&fi->display_cache_timer);
2160
}
2161
 
2162
static void display_cache_timer(unsigned long data)
2163
{
2164
struct fc_info *fi = (struct fc_info*)data;
2165
        del_timer(&fi->display_cache_timer);
2166
        display_cache(fi);
2167
        return;
2168
}
2169
 
2170
static void reset_tachyon(struct fc_info *fi, u_int value)
2171
{
2172
u_int tachyon_status, reset_done = OCQ_RESET_STATUS | SCSI_FREEZE_STATUS;
2173
int not_done = 1, i = 0;
2174
        writel(value, fi->t_r.ptr_tach_control_reg);
2175
        if (value == OCQ_RESET)
2176
                fi->q.ocq_prod_indx = 0;
2177
        tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
2178
 
2179
        /* Software resets are immediately done, whereas other aren't. It
2180
        about 30 clocks to do the reset */
2181
        if (value != SOFTWARE_RESET) {
2182
                while(not_done) {
2183
                        if (i++ > 100000) {
2184
                                T_MSG("Reset was unsuccessful! Tachyon Status = %x", tachyon_status);
2185
                                break;
2186
                        }
2187
                        tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
2188
                        if ((tachyon_status & reset_done) == 0)
2189
                                not_done = 0;
2190
                }
2191
        }
2192
        else {
2193
                write_to_tachyon_registers(fi);
2194
        }
2195
}
2196
 
2197
static void take_tachyon_offline(struct fc_info *fi)
2198
{
2199
u_int fm_status = readl(fi->t_r.ptr_fm_status_reg);
2200
 
2201
        /* The first two conditions will never be true. The Manual and
2202
         * the errata say this. But the current implementation is
2203
         * decently stable.
2204
         */
2205
        //if ((fm_status & 0xF0) == LOOP_FAIL) {
2206
        if (fm_status == LOOP_FAIL) {
2207
                // workaround as in P. 89 
2208
                writel(HOST_CONTROL, fi->t_r.ptr_fm_control_reg);
2209
                if (fi->g.loop_up == TRUE)
2210
                        writel(SOFTWARE_RESET, fi->t_r.ptr_tach_control_reg);
2211
                else {
2212
                        writel(OFFLINE, fi->t_r.ptr_fm_control_reg);
2213
                        writel(EXIT_HOST_CONTROL, fi->t_r.ptr_fm_control_reg);
2214
                }
2215
        }
2216
        else
2217
        //if ((fm_status & LOOP_UP) == LOOP_UP) {
2218
        if (fm_status == LOOP_UP) {
2219
                writel(SOFTWARE_RESET, fi->t_r.ptr_tach_control_reg);
2220
        }
2221
        else
2222
                writel(OFFLINE, fi->t_r.ptr_fm_control_reg);
2223
}
2224
 
2225
 
2226
static void read_novram(struct fc_info *fi)
2227
{
2228
int off = 0;
2229
        fi->n_r.ptr_novram_hw_control_reg = fi->i_r.ptr_ichip_hw_control_reg;
2230
        fi->n_r.ptr_novram_hw_status_reg = fi->i_r.ptr_ichip_hw_status_reg;
2231
        iph5526_nr_do_init(fi);
2232
        if (fi->clone_id == PCI_VENDOR_ID_INTERPHASE)
2233
                off = 32;
2234
 
2235
        fi->g.my_node_name_high = (fi->n_r.data[off] << 16) | fi->n_r.data[off+1];
2236
        fi->g.my_node_name_low = (fi->n_r.data[off+2] << 16) | fi->n_r.data[off+3];
2237
        fi->g.my_port_name_high = (fi->n_r.data[off+4] << 16) | fi->n_r.data[off+5];
2238
        fi->g.my_port_name_low = (fi->n_r.data[off+6] << 16) | fi->n_r.data[off+7];
2239
        DPRINTK("node_name = %x %x", fi->g.my_node_name_high, fi->g.my_node_name_low);
2240
        DPRINTK("port_name = %x %x", fi->g.my_port_name_high, fi->g.my_port_name_low);
2241
}
2242
 
2243
static void reset_ichip(struct fc_info *fi)
2244
{
2245
        /* (i)chip reset */
2246
        writel(ICHIP_HCR_RESET, fi->i_r.ptr_ichip_hw_control_reg);
2247
        /*wait for chip to get reset */
2248
        mdelay(10);
2249
        /*de-assert reset */
2250
        writel(ICHIP_HCR_DERESET, fi->i_r.ptr_ichip_hw_control_reg);
2251
 
2252
        /* enable INT lines on the (i)chip */
2253
        writel(ICHIP_HCR_ENABLE_INTA , fi->i_r.ptr_ichip_hw_control_reg);
2254
        /* enable byte swap */
2255
        writel(ICHIP_HAMR_BYTE_SWAP_ADDR_TR, fi->i_r.ptr_ichip_hw_addr_mask_reg);
2256
}
2257
 
2258
static void tx_logi(struct fc_info *fi, u_int logi, u_int d_id)
2259
{
2260
int int_required = 1;
2261
u_short ox_id = OX_ID_FIRST_SEQUENCE;
2262
u_int r_ctl = RCTL_ELS_UCTL;
2263
u_int type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
2264
u_int my_mtu = fi->g.my_mtu;
2265
        ENTER("tx_logi");
2266
        /* We dont want interrupted for our own logi.
2267
         * It screws up the port discovery process.
2268
         */
2269
        if (d_id == fi->g.my_id)
2270
                int_required = 0;
2271
        fill_login_frame(fi, logi);
2272
        fi->g.type_of_frame = FC_ELS;
2273
        memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.login, sizeof(LOGIN));
2274
        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);
2275
        fi->g.e_i++;
2276
        if (fi->g.e_i == MAX_PENDING_FRAMES)
2277
                fi->g.e_i = 0;
2278
        LEAVE("tx_logi");
2279
        return;
2280
}
2281
 
2282
static void tx_logi_acc(struct fc_info *fi, u_int logi, u_int d_id, u_short received_ox_id)
2283
{
2284
int int_required = 0;
2285
u_int r_ctl = RCTL_ELS_SCTL;
2286
u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE;
2287
u_int my_mtu = fi->g.my_mtu;
2288
        ENTER("tx_logi_acc");
2289
        fill_login_frame(fi, logi);
2290
        fi->g.type_of_frame = FC_ELS;
2291
        memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.login, sizeof(LOGIN));
2292
        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);
2293
        fi->g.e_i++;
2294
        if (fi->g.e_i == MAX_PENDING_FRAMES)
2295
                fi->g.e_i = 0;
2296
        LEAVE("tx_logi_acc");
2297
        return;
2298
}
2299
 
2300
static void tx_prli(struct fc_info *fi, u_int command_code, u_int d_id, u_short received_ox_id)
2301
{
2302
int int_required = 1;
2303
u_int r_ctl = RCTL_ELS_UCTL;
2304
u_int type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
2305
u_int my_mtu = fi->g.my_mtu;
2306
        ENTER("tx_prli");
2307
        if (command_code == ELS_PRLI)
2308
                fi->g.prli.cmnd_code = htons((ELS_PRLI | PAGE_LEN) >> 16);
2309
        else {
2310
                fi->g.prli.cmnd_code = htons((ELS_ACC | PAGE_LEN) >> 16);
2311
                int_required = 0;
2312
                type  = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE;
2313
                r_ctl = RCTL_ELS_SCTL;
2314
        }
2315
        fi->g.prli.payload_length = htons(PRLI_LEN);
2316
        fi->g.prli.type_code = htons(FCP_TYPE_CODE);
2317
        fi->g.prli.est_image_pair = htons(IMAGE_PAIR);
2318
        fi->g.prli.responder_pa = 0;
2319
        fi->g.prli.originator_pa = 0;
2320
        fi->g.prli.service_params = htonl(INITIATOR_FUNC | READ_XFER_RDY_DISABLED);
2321
        fi->g.type_of_frame = FC_ELS;
2322
        memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.prli, sizeof(PRLI));
2323
        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);
2324
        fi->g.e_i++;
2325
        if (fi->g.e_i == MAX_PENDING_FRAMES)
2326
                fi->g.e_i = 0;
2327
        LEAVE("tx_prli");
2328
        return;
2329
}
2330
 
2331
static void tx_logo(struct fc_info *fi, u_int d_id, u_short received_ox_id)
2332
{
2333
int int_required = 1;
2334
u_int r_ctl = RCTL_ELS_UCTL;
2335
u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | SEQUENCE_RESPONDER | FIRST_SEQUENCE | END_SEQUENCE | SEQUENCE_INITIATIVE;
2336
int size = sizeof(LOGO);
2337
char fc_id[3];
2338
u_int my_mtu = fi->g.my_mtu;
2339
        ENTER("tx_logo");
2340
        fi->g.logo.logo_cmnd = htonl(ELS_LOGO);
2341
        fi->g.logo.reserved = 0;
2342
        memcpy(fc_id, &(fi->g.my_id), 3);
2343
        fi->g.logo.n_port_id_0 = fc_id[0];
2344
        fi->g.logo.n_port_id_1 = fc_id[1];
2345
        fi->g.logo.n_port_id_2 = fc_id[2];
2346
        fi->g.logo.port_name_up = htonl(N_PORT_NAME_HIGH);
2347
        fi->g.logo.port_name_low = htonl(N_PORT_NAME_LOW);
2348
        fi->g.type_of_frame = FC_ELS;
2349
        memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.logo, sizeof(LOGO));
2350
        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);
2351
        fi->g.e_i++;
2352
        if (fi->g.e_i == MAX_PENDING_FRAMES)
2353
                fi->g.e_i = 0;
2354
        LEAVE("tx_logo");
2355
}
2356
 
2357
static void tx_adisc(struct fc_info *fi, u_int cmnd_code, u_int d_id, u_short received_ox_id)
2358
{
2359
int int_required = 0;
2360
u_int r_ctl = RCTL_ELS_SCTL;
2361
u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | SEQUENCE_RESPONDER | FIRST_SEQUENCE | END_SEQUENCE;
2362
int size = sizeof(ADISC);
2363
u_int my_mtu = fi->g.my_mtu;
2364
        fi->g.adisc.ls_cmnd_code = htonl(cmnd_code);
2365
        fi->g.adisc.hard_address = htonl(0);
2366
        fi->g.adisc.port_name_high = htonl(N_PORT_NAME_HIGH);
2367
        fi->g.adisc.port_name_low = htonl(N_PORT_NAME_LOW);
2368
        fi->g.adisc.node_name_high = htonl(NODE_NAME_HIGH);
2369
        fi->g.adisc.node_name_low = htonl(NODE_NAME_LOW);
2370
        fi->g.adisc.n_port_id = htonl(fi->g.my_id);
2371
        if (cmnd_code == ELS_ADISC) {
2372
                int_required = 1;
2373
                r_ctl = RCTL_ELS_UCTL;
2374
                type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
2375
        }
2376
        fi->g.type_of_frame = FC_ELS;
2377
        memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.adisc, size);
2378
        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);
2379
        fi->g.e_i++;
2380
        if (fi->g.e_i == MAX_PENDING_FRAMES)
2381
                fi->g.e_i = 0;
2382
}
2383
 
2384
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)
2385
{
2386
int int_required = 0;
2387
u_int r_ctl = RCTL_ELS_SCTL;
2388
u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE;
2389
int size = sizeof(LS_RJT);
2390
u_int my_mtu = fi->g.my_mtu;
2391
        ENTER("tx_ls_rjt");
2392
        fi->g.ls_rjt.cmnd_code = htonl(ELS_LS_RJT);
2393
        fi->g.ls_rjt.reason_code = htonl((reason_code << 16) | expln_code);
2394
        fi->g.type_of_frame = FC_ELS;
2395
        memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.ls_rjt, size);
2396
        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);
2397
        fi->g.e_i++;
2398
        if (fi->g.e_i == MAX_PENDING_FRAMES)
2399
                fi->g.e_i = 0;
2400
        LEAVE("tx_ls_rjt");
2401
}
2402
 
2403
static void tx_abts(struct fc_info *fi, u_int d_id, u_short ox_id)
2404
{
2405
int int_required = 1;
2406
u_int r_ctl = RCTL_BASIC_ABTS;
2407
u_int type  = TYPE_BLS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
2408
int size = 0;
2409
u_int my_mtu = fi->g.my_mtu;
2410
        ENTER("tx_abts");
2411
        fi->g.type_of_frame = FC_BLS;
2412
        tx_exchange(fi, NULL, size, r_ctl, type, d_id, my_mtu, int_required, ox_id, RCTL_BASIC_ABTS);
2413
        LEAVE("tx_abts");
2414
}
2415
 
2416
static u_int plogi_ok(struct fc_info *fi, u_int *buff_addr, int size)
2417
{
2418
int ret_code = 0;
2419
u_short mtu = ntohl(*(buff_addr + 10)) & 0x00000FFF;
2420
u_short class3 = ntohl(*(buff_addr + 25)) >> 16;
2421
u_short class3_conc_seq = ntohl(*(buff_addr + 27)) >> 16;
2422
u_short open_seq = ntohl(*(buff_addr + 28)) >> 16;
2423
        DPRINTK1("mtu = %x class3 = %x conc_seq = %x open_seq = %x", mtu, class3, class3_conc_seq, open_seq);
2424
        size -= TACHYON_HEADER_LEN;
2425
        if (!(class3 & 0x8000)) {
2426
                DPRINTK1("Received PLOGI with class3 = %x", class3);
2427
                ret_code = (LOGICAL_ERR << 16) | NO_EXPLN;
2428
                return ret_code;
2429
        }
2430
        if (mtu < 256) {
2431
                DPRINTK1("Received PLOGI with MTU set to %x", mtu);
2432
                ret_code = (LOGICAL_ERR << 16) | RECV_FIELD_SIZE;
2433
                return ret_code;
2434
        }
2435
        if (size != PLOGI_LEN) {
2436
                DPRINTK1("Received PLOGI of size %x", size);
2437
                ret_code = (LOGICAL_ERR << 16) | INV_PAYLOAD_LEN;
2438
                return ret_code;
2439
        }
2440
        if (class3_conc_seq == 0) {
2441
                DPRINTK1("Received PLOGI with conc_seq == 0");
2442
                ret_code = (LOGICAL_ERR << 16) | CONC_SEQ;
2443
                return ret_code;
2444
        }
2445
        if (open_seq == 0) {
2446
                DPRINTK1("Received PLOGI with open_seq == 0");
2447
                ret_code = (LOGICAL_ERR << 16) | NO_EXPLN;
2448
                return ret_code;
2449
        }
2450
 
2451
        /* Could potentially check for more fields, but might end up
2452
           not talking to most of the devices. ;-) */
2453
        /* Things that could get checked are:
2454
           common_features = 0x8800
2455
           total_concurrent_seq = at least 1
2456
        */
2457
        return ret_code;
2458
}
2459
 
2460
static void tx_acc(struct fc_info *fi, u_int d_id, u_short received_ox_id)
2461
{
2462
int int_required = 0;
2463
u_int r_ctl = RCTL_ELS_SCTL;
2464
u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE;
2465
int size = sizeof(ACC);
2466
u_int my_mtu = fi->g.my_mtu;
2467
        ENTER("tx_acc");
2468
        fi->g.acc.cmnd_code = htonl(ELS_ACC);
2469
        fi->g.type_of_frame = FC_ELS;
2470
        memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.acc, size);
2471
        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);
2472
        fi->g.e_i++;
2473
        if (fi->g.e_i == MAX_PENDING_FRAMES)
2474
                fi->g.e_i = 0;
2475
        LEAVE("tx_acc");
2476
}
2477
 
2478
 
2479
static void tx_name_server_req(struct fc_info *fi, u_int req)
2480
{
2481
int int_required = 1, i, size = 0;
2482
u_short ox_id = OX_ID_FIRST_SEQUENCE;
2483
u_int type  = TYPE_FC_SERVICES | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
2484
u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_CONTROL;
2485
u_int my_mtu = fi->g.my_mtu, d_id = DIRECTORY_SERVER;
2486
CT_HDR ct_hdr;
2487
        ENTER("tx_name_server_req");
2488
        /* Fill up CT_Header */
2489
        ct_hdr.rev_in_id = htonl(FC_CT_REV);
2490
        ct_hdr.fs_type = DIRECTORY_SERVER_APP;
2491
        ct_hdr.fs_subtype = NAME_SERVICE;
2492
        ct_hdr.options = 0;
2493
        ct_hdr.resv1 = 0;
2494
        ct_hdr.cmnd_resp_code = htons(req >> 16);
2495
        ct_hdr.max_res_size = 0;
2496
        ct_hdr.resv2 = 0;
2497
        ct_hdr.reason_code = 0;
2498
        ct_hdr.expln_code = 0;
2499
        ct_hdr.vendor_unique = 0;
2500
 
2501
        fi->g.type_of_frame = FC_ELS;
2502
        switch(req) {
2503
                case FCS_RFC_4:
2504
                        memcpy(&(fi->g.rfc_4.ct_hdr), &ct_hdr, sizeof(CT_HDR));
2505
                        fi->g.rfc_4.s_id = htonl(fi->g.my_id);
2506
                        for (i = 0; i < 32; i++)
2507
                                fi->g.rfc_4.bit_map[i] = 0;
2508
                        /* We support IP & SCSI */
2509
                        fi->g.rfc_4.bit_map[2] = 0x01;
2510
                        fi->g.rfc_4.bit_map[3] = 0x20;
2511
                        size = sizeof(RFC_4);
2512
                        memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.rfc_4, size);
2513
                        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);
2514
                        break;
2515
                case FCS_GP_ID4:
2516
                        memcpy(&(fi->g.gp_id4.ct_hdr), &ct_hdr, sizeof(CT_HDR));
2517
                        fi->g.gp_id4.port_type = htonl(PORT_TYPE_NX_PORTS);
2518
                        size = sizeof(GP_ID4);
2519
                        memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.gp_id4, size);
2520
                        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);
2521
                        break;
2522
        }
2523
        fi->g.e_i++;
2524
        if (fi->g.e_i == MAX_PENDING_FRAMES)
2525
                fi->g.e_i = 0;
2526
        LEAVE("tx_name_server_req");
2527
}
2528
 
2529
static void tx_scr(struct fc_info *fi)
2530
{
2531
int int_required = 1, size = sizeof(SCR);
2532
u_short ox_id = OX_ID_FIRST_SEQUENCE;
2533
u_int type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
2534
u_int r_ctl = RCTL_ELS_UCTL;
2535
u_int my_mtu = fi->g.my_mtu, d_id = FABRIC_CONTROLLER;
2536
        ENTER("tx_scr");
2537
        fi->g.scr.cmnd_code = htonl(ELS_SCR);
2538
        fi->g.scr.reg_function = htonl(FULL_REGISTRATION);
2539
        fi->g.type_of_frame = FC_ELS;
2540
        memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.scr, size);
2541
        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);
2542
        fi->g.e_i++;
2543
        if (fi->g.e_i == MAX_PENDING_FRAMES)
2544
                fi->g.e_i = 0;
2545
        LEAVE("tx_scr");
2546
}
2547
 
2548
static void perform_adisc(struct fc_info *fi)
2549
{
2550
int count = 0;
2551
        /* Will be set to TRUE when timer expires in a PLDA environment.
2552
         */
2553
        fi->g.port_discovery = FALSE;
2554
 
2555
        if (fi->node_info_list) {
2556
                struct fc_node_info *temp_list = fi->node_info_list;
2557
                while(temp_list) {
2558
                        /* Tx ADISC to all non-fabric based
2559
                         * entities.
2560
                         */
2561
                        if ((temp_list->d_id & 0xFF0000) != 0xFF0000)
2562
                                tx_adisc(fi, ELS_ADISC, temp_list->d_id, OX_ID_FIRST_SEQUENCE);
2563
                        temp_list = temp_list->next;
2564
                        udelay(20);
2565
                        count++;
2566
                }
2567
        }
2568
        /* Perform Port Discovery after timer expires.
2569
         * We are giving time for the ADISCed nodes to respond
2570
         * so that we dont have to perform PLOGI to those whose
2571
         * login are _still_ valid.
2572
         */
2573
        fi->explore_timer.function = port_discovery_timer;
2574
        fi->explore_timer.data = (unsigned long)fi;
2575
        fi->explore_timer.expires = RUN_AT((count*3*HZ)/100);
2576
        init_timer(&fi->explore_timer);
2577
        add_timer(&fi->explore_timer);
2578
}
2579
 
2580
static void explore_fabric(struct fc_info *fi, u_int *buff_addr)
2581
{
2582
u_int *addr = buff_addr + 12; /* index into payload */
2583
u_char control_code;
2584
u_int d_id;
2585
int count = 0;
2586
        ENTER("explore_fabric");
2587
        DPRINTK1("entering explore_fabric");
2588
 
2589
        /*fi->g.perform_adisc = TRUE;
2590
        fi->g.explore_fabric = TRUE;
2591
        perform_adisc(fi);*/
2592
 
2593
        do {
2594
                d_id = ntohl(*addr) & 0x00FFFFFF;
2595
                if (d_id != fi->g.my_id) {
2596
                        if (sid_logged_in(fi, d_id) == NODE_NOT_PRESENT)
2597
                                tx_logi(fi, ELS_PLOGI, d_id);
2598
                        else
2599
                        if (sid_logged_in(fi, d_id) == NODE_LOGGED_OUT)
2600
                                tx_adisc(fi, ELS_ADISC, d_id, OX_ID_FIRST_SEQUENCE);
2601
                        count++;
2602
                }
2603
                control_code = (ntohl(*addr) & 0xFF000000) >> 24;
2604
                addr++;
2605
                DPRINTK1("cc = %x, d_id = %x", control_code, d_id);
2606
        } while (control_code != 0x80);
2607
 
2608
        fi->explore_timer.function = fabric_explore_timer;
2609
        fi->explore_timer.data = (unsigned long)fi;
2610
        /* We give 30 msec for each device to respond and then send out
2611
         * our SCSI enquiries.
2612
         */
2613
        fi->explore_timer.expires = RUN_AT((count*3*HZ)/100);
2614
        init_timer(&fi->explore_timer);
2615
        add_timer(&fi->explore_timer);
2616
 
2617
        DPRINTK1("leaving explore_fabric");
2618
        LEAVE("explore_fabric");
2619
}
2620
 
2621
static void fabric_explore_timer(unsigned long data)
2622
{
2623
struct fc_info *fi = (struct fc_info*)data;
2624
        del_timer(&fi->explore_timer);
2625
 
2626
        if ((fi->g.loop_up == TRUE) && (fi->g.ptp_up == FALSE)) {
2627
                /* Initiate Local Port Discovery on the Local Loop.
2628
                 */
2629
                fi->g.port_discovery = TRUE;
2630
                fi->g.alpa_list_index = 1;
2631
                local_port_discovery(fi);
2632
        }
2633
        fi->g.explore_fabric = FALSE;
2634
        return;
2635
}
2636
 
2637
static void port_discovery_timer(unsigned long data)
2638
{
2639
struct fc_info *fi = (struct fc_info*)data;
2640
        del_timer(&fi->explore_timer);
2641
 
2642
        if ((fi->g.loop_up == TRUE) && (fi->g.explore_fabric != TRUE)) {
2643
                fi->g.port_discovery = TRUE;
2644
                fi->g.alpa_list_index = 1;
2645
                local_port_discovery(fi);
2646
        }
2647
        fi->g.perform_adisc = FALSE;
2648
        return;
2649
}
2650
 
2651
static void add_to_ox_id_list(struct fc_info *fi, u_int transaction_id, u_int cmnd_code)
2652
{
2653
struct ox_id_els_map *p, *q = fi->ox_id_list, *r = NULL;
2654
int size = sizeof(struct ox_id_els_map);
2655
        while (q != NULL) {
2656
                r = q;
2657
                q = q->next;
2658
        }
2659
        p = (struct ox_id_els_map *)kmalloc(size, GFP_ATOMIC);
2660
        if (p == NULL) {
2661
                T_MSG("kmalloc failed in add_to_ox_id_list()");
2662
                return;
2663
        }
2664
        p->ox_id = transaction_id;
2665
        p->els = cmnd_code;
2666
        p->next = NULL;
2667
        if (fi->ox_id_list == NULL)
2668
                fi->ox_id_list = p;
2669
        else
2670
                r->next = p;
2671
        return;
2672
}
2673
 
2674
static u_int remove_from_ox_id_list(struct fc_info *fi, u_short received_ox_id)
2675
{
2676
struct ox_id_els_map *p = fi->ox_id_list, *q = fi->ox_id_list;
2677
u_int els_type;
2678
        while (q != NULL) {
2679
                if (q->ox_id == received_ox_id) {
2680
 
2681
                        if (q == fi->ox_id_list)
2682
                                fi->ox_id_list = fi->ox_id_list->next;
2683
                        else
2684
                                if (q->next == NULL)
2685
                                        p->next = NULL;
2686
                        else
2687
                                        p->next = q->next;
2688
 
2689
                        els_type = q->els;
2690
                        kfree(q);
2691
                        return els_type;
2692
                }
2693
                p = q;
2694
                q = q->next;
2695
        }
2696
        if (q == NULL)
2697
                DPRINTK2("Could not find ox_id %x in ox_id_els_map", received_ox_id);
2698
        return 0;
2699
}
2700
 
2701
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)
2702
{
2703
u_char alpa = d_id & 0x0000FF;
2704
u_int dest_ddaa = d_id &0xFFFF00;
2705
 
2706
        ENTER("build_tachyon_header");
2707
        DPRINTK("d_id = %x, my_ddaa = %x", d_id, fi->g.my_ddaa);
2708
        /* Does it have to go to/thru a Fabric? */
2709
        if ((dest_ddaa != 0) && ((d_id == F_PORT) || (fi->g.fabric_present && (dest_ddaa != fi->g.my_ddaa))))
2710
                alpa = 0x00;
2711
        fi->g.tach_header.resv = 0x00000000;
2712
        fi->g.tach_header.sof_and_eof = SOFI3 | EOFN;
2713
        fi->g.tach_header.dest_alpa = alpa;
2714
        /* Set LCr properly to have enuff credit */
2715
        if (alpa == REPLICATE)
2716
                fi->g.tach_header.lcr_and_time_stamp = htons(0xC00);/* LCr=3 */
2717
        else
2718
                fi->g.tach_header.lcr_and_time_stamp = 0;
2719
        fi->g.tach_header.r_ctl_and_d_id = htonl(r_ctl | d_id);
2720
        fi->g.tach_header.vc_id_and_s_id = htonl(my_id);
2721
        fi->g.tach_header.type_and_f_cntl = htonl(type);
2722
        fi->g.tach_header.seq_id = seq_id;
2723
        fi->g.tach_header.df_cntl = df_ctl;
2724
        fi->g.tach_header.seq_cnt = 0;
2725
        fi->g.tach_header.ox_id = htons(ox_id);
2726
        fi->g.tach_header.rx_id = htons(rx_id);
2727
        fi->g.tach_header.ro = 0;
2728
        if (data) {
2729
                /* We use the Seq_Count to keep track of IP frames in the
2730
                 * OCI_interrupt handler. Initial Seq_Count of IP frames is 1.
2731
                 */
2732
                if (fi->g.type_of_frame == FC_BROADCAST)
2733
                        fi->g.tach_header.seq_cnt = htons(0x1);
2734
                else
2735
                        fi->g.tach_header.seq_cnt = htons(0x2);
2736
                fi->g.tach_header.nw_header.d_naa = htons(0x1000);
2737
                fi->g.tach_header.nw_header.s_naa = htons(0x1000);
2738
                memcpy(&(fi->g.tach_header.nw_header.dest_high), data, 2);
2739
                memcpy(&(fi->g.tach_header.nw_header.dest_low), data + 2, 4);
2740
                memcpy(&(fi->g.tach_header.nw_header.source_high), data + 6, 2);
2741
                memcpy(&(fi->g.tach_header.nw_header.source_low), data + 8, 4);
2742
        }
2743
        LEAVE("build_tachyon_header");
2744
}
2745
 
2746
static void build_EDB(struct fc_info *fi, char *data, u_short flags, u_short len)
2747
{
2748
        fi->g.edb.buf_addr = ntohl((u_int)virt_to_bus(data));
2749
        fi->g.edb.ehf = ntohs(flags);
2750
        if (len % 4)
2751
                len += (4 - (len % 4));
2752
        fi->g.edb.buf_len = ntohs(len);
2753
}
2754
 
2755
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)
2756
{
2757
        fi->g.odb.seq_d_id = htonl(seq_id << 24 | d_id);
2758
        fi->g.odb.tot_len = len;
2759
        if (NW_header)
2760
                fi->g.odb.tot_len += NW_HEADER_LEN;
2761
        if (fi->g.odb.tot_len % 4)
2762
                fi->g.odb.tot_len += (4 - (fi->g.odb.tot_len % 4));
2763
        fi->g.odb.tot_len = htonl(fi->g.odb.tot_len);
2764
        switch(int_required) {
2765
                case NO_COMP_AND_INT:
2766
                        fi->g.odb.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | ODB_NO_INT | ODB_NO_COMP | cntl);
2767
                        break;
2768
                case INT_AND_COMP_REQ:
2769
                        fi->g.odb.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | cntl);
2770
                        break;
2771
                case NO_INT_COMP_REQ:
2772
                        fi->g.odb.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | ODB_NO_INT | cntl);
2773
                        break;
2774
        }
2775
        fi->g.odb.rx_id = htons(rx_id);
2776
        fi->g.odb.cs_enable = 0;
2777
        fi->g.odb.cs_seed = htons(1);
2778
 
2779
        fi->g.odb.hdr_addr = htonl(virt_to_bus(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx]));
2780
        fi->g.odb.frame_len = htons(mtu);
2781
 
2782
        if (NW_header) {
2783
                /* The pointer to the sk_buff is in here. Freed up when the
2784
                 * OCI_interrupt is received.
2785
                 */
2786
                fi->g.odb.trans_id = htonl(frame_class);
2787
                fi->g.odb.hdr_len = TACHYON_HEADER_LEN + NW_HEADER_LEN;
2788
        }
2789
        else {
2790
                /* helps in tracking transmitted OX_IDs */
2791
                fi->g.odb.trans_id = htonl((frame_class & 0xFFFF0000) | ox_id);
2792
                fi->g.odb.hdr_len = TACHYON_HEADER_LEN;
2793
        }
2794
        fi->g.odb.hdr_len = htons(fi->g.odb.hdr_len);
2795
 
2796
        fi->g.odb.edb_addr = htonl(virt_to_bus(fi->q.ptr_edb[fi->q.edb_buffer_indx]));
2797
}
2798
 
2799
static void fill_login_frame(struct fc_info *fi, u_int logi)
2800
{
2801
int i;
2802
        fi->g.login.ls_cmnd_code= htonl(logi);
2803
        fi->g.login.fc_ph_version = htons(PH_VERSION);
2804
        if (fi->g.loop_up)
2805
                fi->g.login.buff_to_buff_credit = htons(LOOP_BB_CREDIT);
2806
        else
2807
        if (fi->g.ptp_up)
2808
                fi->g.login.buff_to_buff_credit = htons(PT2PT_BB_CREDIT);
2809
        if ((logi != ELS_FLOGI) || (logi == ELS_ACC))
2810
                fi->g.login.common_features = htons(PLOGI_C_F);
2811
        else
2812
        if (logi == ELS_FLOGI)
2813
                fi->g.login.common_features = htons(FLOGI_C_F);
2814
        fi->g.login.recv_data_field_size = htons(TACH_FRAME_SIZE);
2815
        fi->g.login.n_port_total_conc_seq = htons(CONCURRENT_SEQUENCES);
2816
        fi->g.login.rel_off_by_info_cat = htons(RO_INFO_CATEGORY);
2817
        fi->g.login.ED_TOV = htonl(E_D_TOV);
2818
        fi->g.login.n_port_name_high = htonl(N_PORT_NAME_HIGH);
2819
        fi->g.login.n_port_name_low = htonl(N_PORT_NAME_LOW);
2820
        fi->g.login.node_name_high = htonl(NODE_NAME_HIGH);
2821
        fi->g.login.node_name_low = htonl(NODE_NAME_LOW);
2822
 
2823
        /* Fill Class 1 parameters */
2824
        fi->g.login.c_of_s[0].service_options = htons(0);
2825
        fi->g.login.c_of_s[0].initiator_ctl = htons(0);
2826
        fi->g.login.c_of_s[0].recipient_ctl = htons(0);
2827
        fi->g.login.c_of_s[0].recv_data_field_size = htons(0);
2828
        fi->g.login.c_of_s[0].concurrent_sequences = htons(0);
2829
        fi->g.login.c_of_s[0].n_port_end_to_end_credit = htons(0);
2830
        fi->g.login.c_of_s[0].open_seq_per_exchange = htons(0);
2831
        fi->g.login.c_of_s[0].resv = htons(0);
2832
 
2833
        /* Fill Class 2 parameters */
2834
        fi->g.login.c_of_s[1].service_options = htons(0);
2835
        fi->g.login.c_of_s[1].initiator_ctl = htons(0);
2836
        fi->g.login.c_of_s[1].recipient_ctl = htons(0);
2837
        fi->g.login.c_of_s[1].recv_data_field_size = htons(0);
2838
        fi->g.login.c_of_s[1].concurrent_sequences = htons(0);
2839
        fi->g.login.c_of_s[1].n_port_end_to_end_credit = htons(0);
2840
        fi->g.login.c_of_s[1].open_seq_per_exchange = htons(0);
2841
        fi->g.login.c_of_s[1].resv = htons(0);
2842
 
2843
        /* Fill Class 3 parameters */
2844
        if (logi == ELS_FLOGI)
2845
                fi->g.login.c_of_s[2].service_options  = htons(SERVICE_VALID | SEQUENCE_DELIVERY);
2846
        else
2847
                fi->g.login.c_of_s[2].service_options  = htons(SERVICE_VALID);
2848
        fi->g.login.c_of_s[2].initiator_ctl = htons(0);
2849
        fi->g.login.c_of_s[2].recipient_ctl = htons(0);
2850
        fi->g.login.c_of_s[2].recv_data_field_size = htons(TACH_FRAME_SIZE);
2851
        fi->g.login.c_of_s[2].concurrent_sequences = htons(CLASS3_CONCURRENT_SEQUENCE);
2852
        fi->g.login.c_of_s[2].n_port_end_to_end_credit = htons(0);
2853
        fi->g.login.c_of_s[2].open_seq_per_exchange = htons(CLASS3_OPEN_SEQUENCE);
2854
        fi->g.login.c_of_s[2].resv = htons(0);
2855
 
2856
        for(i = 0; i < 4; i++) {
2857
                fi->g.login.resv[i] = 0;
2858
                fi->g.login.vendor_version_level[i] = 0;
2859
        }
2860
}
2861
 
2862
 
2863
/* clear the Interrupt Latch on the (i)chip, so that you can receive
2864
 * Interrupts from Tachyon in future
2865
 */
2866
static void reset_latch(struct fc_info *fi)
2867
{
2868
        writel(readl(fi->i_r.ptr_ichip_hw_status_reg) | ICHIP_HSR_INT_LATCH, fi->i_r.ptr_ichip_hw_status_reg);
2869
}
2870
 
2871
static void update_OCQ_indx(struct fc_info *fi)
2872
{
2873
        fi->q.ocq_prod_indx++;
2874
        if (fi->q.ocq_prod_indx == OCQ_LENGTH)
2875
                fi->q.ocq_prod_indx = 0;
2876
        writel(fi->q.ocq_prod_indx, fi->t_r.ptr_ocq_prod_indx_reg);
2877
}
2878
 
2879
static void update_IMQ_indx(struct fc_info *fi, int count)
2880
{
2881
        fi->q.imq_cons_indx += count;
2882
        if (fi->q.imq_cons_indx >= IMQ_LENGTH)
2883
                fi->q.imq_cons_indx -= IMQ_LENGTH;
2884
        writel(fi->q.imq_cons_indx, fi->t_r.ptr_imq_cons_indx_reg);
2885
}
2886
 
2887
static void update_SFSBQ_indx(struct fc_info *fi)
2888
{
2889
        fi->q.sfsbq_prod_indx++;
2890
        if (fi->q.sfsbq_prod_indx == SFSBQ_LENGTH)
2891
                fi->q.sfsbq_prod_indx = 0;
2892
        writel(fi->q.sfsbq_prod_indx, fi->t_r.ptr_sfsbq_prod_reg);
2893
}
2894
 
2895
static void update_MFSBQ_indx(struct fc_info *fi, int count)
2896
{
2897
        fi->q.mfsbq_prod_indx += count;
2898
        if (fi->q.mfsbq_prod_indx >= MFSBQ_LENGTH)
2899
                fi->q.mfsbq_prod_indx -= MFSBQ_LENGTH;
2900
        writel(fi->q.mfsbq_prod_indx, fi->t_r.ptr_mfsbq_prod_reg);
2901
}
2902
 
2903
 
2904
static void update_tachyon_header_indx(struct fc_info *fi)
2905
{
2906
        fi->q.tachyon_header_indx++;
2907
        if (fi->q.tachyon_header_indx == NO_OF_TACH_HEADERS)
2908
                fi->q.tachyon_header_indx = 0;
2909
}
2910
 
2911
static void update_EDB_indx(struct fc_info *fi)
2912
{
2913
        fi->q.edb_buffer_indx++;
2914
        if (fi->q.edb_buffer_indx == EDB_LEN)
2915
                fi->q.edb_buffer_indx = 0;
2916
}
2917
 
2918
static int iph5526_open(struct net_device *dev)
2919
{
2920
        netif_start_queue(dev);
2921
        MOD_INC_USE_COUNT;
2922
        return 0;
2923
}
2924
 
2925
static int iph5526_close(struct net_device *dev)
2926
{
2927
        netif_stop_queue(dev);
2928
        MOD_DEC_USE_COUNT;
2929
        return 0;
2930
}
2931
 
2932
static void iph5526_timeout(struct net_device *dev)
2933
{
2934
        struct fc_info *fi = (struct fc_info*)dev->priv;
2935
        printk(KERN_WARNING "%s: timed out on send.\n", dev->name);
2936
        fi->fc_stats.rx_dropped++;
2937
        dev->trans_start = jiffies;
2938
        netif_wake_queue(dev);
2939
}
2940
 
2941
static int iph5526_send_packet(struct sk_buff *skb, struct net_device *dev)
2942
{
2943
        struct fc_info *fi = (struct fc_info*)dev->priv;
2944
        int status = 0;
2945
        short type = 0;
2946
        u_long flags;
2947
        struct fcllc *fcllc;
2948
 
2949
        ENTER("iph5526_send_packet");
2950
 
2951
        netif_stop_queue(dev);
2952
        /* Strip off the pseudo header.
2953
         */
2954
        skb->data = skb->data + 2*FC_ALEN;
2955
        skb->len = skb->len - 2*FC_ALEN;
2956
        fcllc = (struct fcllc *)skb->data;
2957
        type = ntohs(fcllc->ethertype);
2958
 
2959
        spin_lock_irqsave(&fi->fc_lock, flags);
2960
        switch(type) {
2961
                case ETH_P_IP:
2962
                        status = tx_ip_packet(skb, skb->len, fi);
2963
                        break;
2964
                case ETH_P_ARP:
2965
                        status = tx_arp_packet(skb->data, skb->len, fi);
2966
                        break;
2967
                default:
2968
                        T_MSG("WARNING!!! Received Unknown Packet Type... Discarding...");
2969
                        fi->fc_stats.rx_dropped++;
2970
                        break;
2971
        }
2972
        spin_unlock_irqrestore(&fi->fc_lock, flags);
2973
 
2974
        if (status) {
2975
                fi->fc_stats.tx_bytes += skb->len;
2976
                fi->fc_stats.tx_packets++;
2977
        }
2978
        else
2979
                fi->fc_stats.rx_dropped++;
2980
        dev->trans_start = jiffies;
2981
        /* We free up the IP buffers in the OCI_interrupt handler.
2982
         * status == 0 implies that the frame was not transmitted. So the
2983
         * skb is freed here.
2984
         */
2985
        if ((type == ETH_P_ARP) || (status == 0))
2986
                dev_kfree_skb(skb);
2987
        netif_wake_queue(dev);
2988
        LEAVE("iph5526_send_packet");
2989
        return 0;
2990
}
2991
 
2992
static int iph5526_change_mtu(struct net_device *dev, int mtu)
2993
{
2994
        return 0;
2995
}
2996
 
2997
static int tx_ip_packet(struct sk_buff *skb, unsigned long len, struct fc_info *fi)
2998
{
2999
u_int d_id;
3000
int int_required = 1;
3001
u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_DATA;
3002
u_int type = TYPE_LLC_SNAP;
3003
u_short ox_id = OX_ID_FIRST_SEQUENCE;
3004
u_int mtu;
3005
struct fc_node_info *q;
3006
 
3007
        ENTER("tx_ip_packet");
3008
        q = look_up_cache(fi, skb->data - 2*FC_ALEN);
3009
        if (q != NULL) {
3010
                d_id = q->d_id;
3011
                DPRINTK("Look-Up Cache Succeeded for d_id = %x", d_id);
3012
                mtu = q->mtu;
3013
                if (q->login == LOGIN_COMPLETED){
3014
                        fi->g.type_of_frame = FC_IP;
3015
                        return tx_exchange(fi, skb->data, len, r_ctl, type, d_id, mtu, int_required, ox_id, virt_to_bus(skb));
3016
                }
3017
 
3018
                if (q->d_id == BROADCAST) {
3019
                struct fc_node_info *p = fi->node_info_list;
3020
                int return_value = FALSE;
3021
                        fi->g.type_of_frame = FC_BROADCAST;
3022
                        /* Do unicast to local nodes.
3023
                         */
3024
                        int_required = 0;
3025
                        while(p != NULL) {
3026
                                d_id = p->d_id;
3027
                                if ((d_id & 0xFFFF00) == fi->g.my_ddaa)
3028
                                        return_value |= tx_exchange(fi, skb->data, len, r_ctl, type, d_id, fi->g.my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
3029
                                p = p->next;
3030
                        }
3031
                        kfree(q);
3032
                        return return_value;
3033
                }
3034
 
3035
                if (q->login != LOGIN_COMPLETED) {
3036
                        DPRINTK1("Node not logged in... Txing PLOGI to %x", d_id);
3037
                        /* FIXME: we are dumping the frame here */
3038
                        tx_logi(fi, ELS_PLOGI, d_id);
3039
                }
3040
        }
3041
        DPRINTK2("Look-Up Cache Failed");
3042
        LEAVE("tx_ip_packet");
3043
        return 0;
3044
}
3045
 
3046
static int tx_arp_packet(char *data, unsigned long len, struct fc_info *fi)
3047
{
3048
u_int opcode = data[ARP_OPCODE_0];
3049
u_int d_id;
3050
int int_required = 0, return_value = FALSE;
3051
u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_DATA;
3052
u_int type = TYPE_LLC_SNAP;
3053
u_short ox_id = OX_ID_FIRST_SEQUENCE;
3054
u_int my_mtu = fi->g.my_mtu;
3055
        ENTER("tx_arp_packet");
3056
 
3057
        opcode = opcode << 8 | data[ARP_OPCODE_1];
3058
        fi->g.type_of_frame = FC_IP;
3059
 
3060
        if (opcode == ARPOP_REQUEST) {
3061
        struct fc_node_info *q = fi->node_info_list;
3062
                d_id = BROADCAST;
3063
                return_value |= tx_exchange(fi, data, len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
3064
                /* Some devices support HW_TYPE 0x01 */
3065
                memcpy(fi->g.arp_buffer, data - 2*FC_ALEN, len + 2*FC_ALEN);
3066
                fi->g.arp_buffer[9 + 2*FC_ALEN] = 0x01;
3067
                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);
3068
 
3069
                /* Do unicast to local nodes.
3070
                 */
3071
                while(q != NULL) {
3072
                        fi->g.type_of_frame = FC_BROADCAST;
3073
                        d_id = q->d_id;
3074
                        if ((d_id & 0xFFFF00) == fi->g.my_ddaa) {
3075
                                return_value |= tx_exchange(fi, data, len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
3076
                                // Some devices support HW_TYPE 0x01
3077
                                memcpy(fi->g.arp_buffer, data - 2*FC_ALEN, len + 2*FC_ALEN);
3078
                                fi->g.arp_buffer[9 + 2*FC_ALEN] = 0x01;
3079
                                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);
3080
                        }
3081
                        q = q->next;
3082
                }
3083
                return return_value;
3084
        }
3085
        else
3086
        if (opcode == ARPOP_REPLY) {
3087
        struct fc_node_info *q; u_int mtu;
3088
                DPRINTK("We are sending out an ARP reply");
3089
                q = look_up_cache(fi, data - 2*FC_ALEN);
3090
                if (q != NULL) {
3091
                        d_id = q->d_id;
3092
                        DPRINTK("Look-Up Cache Succeeded for d_id = %x", d_id);
3093
                        mtu = q->mtu;
3094
                        if (q->login == LOGIN_COMPLETED){
3095
                                tx_exchange(fi, data, len, r_ctl, type, d_id, mtu, int_required, ox_id, TYPE_LLC_SNAP);
3096
                                /* Some devices support HW_TYPE 0x01 */
3097
                                memcpy(fi->g.arp_buffer, data - 2*FC_ALEN, len + 2*FC_ALEN);
3098
                                fi->g.arp_buffer[9 + 2*FC_ALEN] = 0x01;
3099
                                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);
3100
                        }
3101
                        else {
3102
                                DPRINTK1("Node not logged in... Txing PLOGI to %x", d_id);
3103
                                tx_logi(fi, ELS_PLOGI, d_id); /* FIXME: we are dumping the frame here */
3104
                        }
3105
                }
3106
                DPRINTK2("Look-Up Cache Failed");
3107
        }
3108
        else {
3109
                T_MSG("Warning!!! Invalid Opcode in ARP Packet!");
3110
        }
3111
        LEAVE("tx_arp_packet");
3112
        return 0;
3113
}
3114
 
3115
 
3116
static void rx_net_packet(struct fc_info *fi, u_char *buff_addr, int payload_size)
3117
{
3118
struct net_device *dev = fi->dev;
3119
struct sk_buff *skb;
3120
u_int skb_size = 0;
3121
struct fch_hdr fch;
3122
        ENTER("rx_net_packet");
3123
        skb_size = payload_size - TACHYON_HEADER_LEN;
3124
        DPRINTK("skb_size = %d", skb_size);
3125
        fi->fc_stats.rx_bytes += skb_size - 2;
3126
        skb = dev_alloc_skb(skb_size);
3127
        if (skb == NULL) {
3128
                printk(KERN_NOTICE "%s: In rx_net_packet() Memory squeeze, dropping packet.\n", dev->name);
3129
                fi->fc_stats.rx_dropped++;
3130
                return;
3131
        }
3132
        /* Skip over the Tachyon Frame Header.
3133
         */
3134
        buff_addr += TACHYON_HEADER_LEN;
3135
 
3136
        memcpy(fch.daddr, buff_addr + 2, FC_ALEN);
3137
        memcpy(fch.saddr, buff_addr + 10, FC_ALEN);
3138
        buff_addr += 2;
3139
        memcpy(buff_addr, fch.daddr, FC_ALEN);
3140
        memcpy(buff_addr + 6, fch.saddr, FC_ALEN);
3141
        skb_reserve(skb, 2);
3142
        memcpy(skb_put(skb, skb_size - 2), buff_addr, skb_size - 2);
3143
        skb->dev = dev;
3144
        skb->protocol = fc_type_trans(skb, dev);
3145
        DPRINTK("protocol = %x", skb->protocol);
3146
 
3147
        /* Hmmm... to accept HW Type 0x01 as well...
3148
         */
3149
        if (skb->protocol == ntohs(ETH_P_ARP))
3150
                skb->data[1] = 0x06;
3151
        netif_rx(skb);
3152
        dev->last_rx = jiffies;
3153
        fi->fc_stats.rx_packets++;
3154
        LEAVE("rx_net_packet");
3155
}
3156
 
3157
 
3158
static void rx_net_mfs_packet(struct fc_info *fi, struct sk_buff *skb)
3159
{
3160
struct net_device *dev = fi->dev;
3161
struct fch_hdr fch;
3162
        ENTER("rx_net_mfs_packet");
3163
        /* Construct your Hard Header */
3164
        memcpy(fch.daddr, skb->data + 2, FC_ALEN);
3165
        memcpy(fch.saddr, skb->data + 10, FC_ALEN);
3166
        skb_pull(skb, 2);
3167
        memcpy(skb->data, fch.daddr, FC_ALEN);
3168
        memcpy(skb->data + 6, fch.saddr, FC_ALEN);
3169
        skb->dev = dev;
3170
        skb->protocol = fc_type_trans(skb, dev);
3171
        DPRINTK("protocol = %x", skb->protocol);
3172
        netif_rx(skb);
3173
        dev->last_rx = jiffies;
3174
        LEAVE("rx_net_mfs_packet");
3175
}
3176
 
3177
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)
3178
{
3179
u_char df_ctl;
3180
int NW_flag = 0, h_size, return_value;
3181
u_short rx_id = RX_ID_FIRST_SEQUENCE;
3182
u_int tachyon_status;
3183
u_int my_id = fi->g.my_id;
3184
        ENTER("tx_exchange");
3185
 
3186
        tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
3187
        DPRINTK("Tachyon Status = %x len = %d MTU = %d", tachyon_status, len, mtu);
3188
        if (tachyon_status & OSM_FROZEN) {
3189
                reset_tachyon(fi, ERROR_RELEASE);
3190
                reset_tachyon(fi, OCQ_RESET);
3191
                DPRINTK("Tachyon Status = %x len = %d MTU = %d", tachyon_status, len, mtu);
3192
        }
3193
        if (tx_ox_id == OX_ID_FIRST_SEQUENCE) {
3194
                switch(fi->g.type_of_frame) {
3195
                        case FC_SCSI_READ:
3196
                                tx_ox_id = fi->g.scsi_oxid | SCSI_READ_BIT;
3197
                                break;
3198
                        case FC_SCSI_WRITE:
3199
                                tx_ox_id = fi->g.scsi_oxid;
3200
                                break;
3201
                        default:
3202
                                tx_ox_id = fi->g.ox_id;
3203
                                break;
3204
                }
3205
        }
3206
        else {
3207
                switch(fi->g.type_of_frame) {
3208
                        case FC_SCSI_READ:
3209
                                rx_id = fi->g.scsi_oxid | SCSI_READ_BIT;
3210
                                break;
3211
                        case FC_SCSI_WRITE:
3212
                                rx_id = fi->g.scsi_oxid;
3213
                                break;
3214
                        case FC_BLS:
3215
                                rx_id = RX_ID_FIRST_SEQUENCE;
3216
                                break;
3217
                        default:
3218
                                rx_id = fi->g.ox_id;
3219
                                break;
3220
                }
3221
        }
3222
 
3223
        if (type == TYPE_LLC_SNAP) {
3224
                df_ctl = 0x20;
3225
                NW_flag = 1;
3226
                /* Multi Frame Sequence ? If yes, set RO bit */
3227
                if (len > mtu)
3228
                        type |= RELATIVE_OFF_PRESENT;
3229
                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);
3230
        }
3231
        else {
3232
                df_ctl = 0;
3233
                /* Multi Frame Sequence ? If yes, set RO bit */
3234
                if (len > mtu)
3235
                        type |= RELATIVE_OFF_PRESENT;
3236
                build_tachyon_header(fi, my_id, r_ctl, d_id, type, fi->g.seq_id, df_ctl, tx_ox_id, rx_id, NULL);
3237
        }
3238
 
3239
        /* Get free Tachyon Headers and EDBs */
3240
        if (get_free_header(fi) || get_free_EDB(fi))
3241
                return 0;
3242
 
3243
        if ((type & 0xFF000000) == TYPE_LLC_SNAP) {
3244
                h_size =  TACHYON_HEADER_LEN + NW_HEADER_LEN;
3245
                memcpy(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx], &(fi->g.tach_header), h_size);
3246
        }
3247
        else
3248
                memcpy(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx], &(fi->g.tach_header), TACHYON_HEADER_LEN);
3249
 
3250
        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);
3251
 
3252
        switch(fi->g.type_of_frame) {
3253
                case FC_SCSI_READ:
3254
                case FC_SCSI_WRITE:
3255
                        update_scsi_oxid(fi);
3256
                        break;
3257
                case FC_BLS:
3258
                        break;
3259
                default:
3260
                        fi->g.ox_id++;
3261
                        if (fi->g.ox_id == 0xFFFF)
3262
                                fi->g.ox_id = NOT_SCSI_XID;
3263
                        break;
3264
        }
3265
 
3266
        if (fi->g.seq_id == MAX_SEQ_ID)
3267
                fi->g.seq_id = 0;
3268
        else
3269
                fi->g.seq_id++;
3270
        LEAVE("tx_exchange");
3271
        return return_value;
3272
}
3273
 
3274
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)
3275
{
3276
u_int cntl = 0;
3277
int return_value;
3278
        ENTER("tx_sequence");
3279
        build_EDB(fi, data, EDB_END, len);
3280
        memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB));
3281
        build_ODB(fi, seq_id, d_id, len, cntl, mtu, ox_id, rx_id, NW_flag, int_required, frame_class);
3282
        memcpy(fi->q.ptr_odb[fi->q.ocq_prod_indx], &(fi->g.odb), sizeof(ODB));
3283
        if (fi->g.link_up != TRUE) {
3284
                DPRINTK2("Fibre Channel Link not up. Dropping Exchange!");
3285
                return_value = FALSE;
3286
        }
3287
        else {
3288
                /* To be on the safe side, a check should be included
3289
                 * at this point to check if we are overrunning
3290
                 * Tachyon.
3291
                 */
3292
                update_OCQ_indx(fi);
3293
                return_value = TRUE;
3294
        }
3295
        update_EDB_indx(fi);
3296
        update_tachyon_header_indx(fi);
3297
        LEAVE("tx_sequence");
3298
        return return_value;
3299
}
3300
 
3301
static int get_free_header(struct fc_info *fi)
3302
{
3303
u_short temp_ox_id;
3304
u_int *tach_header, initial_indx = fi->q.tachyon_header_indx;
3305
        /* Check if the header is in use.
3306
         * We could have an outstanding command.
3307
         * We should find a free slot as we can queue a
3308
         * maximum of 32 SCSI commands only.
3309
         */
3310
        tach_header = fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx];
3311
        temp_ox_id = ntohl(*(tach_header + 6)) >> 16;
3312
        /* We care about the SCSI writes only. Those are the wicked ones
3313
         * that need an additional set of buffers.
3314
         */
3315
        while(temp_ox_id <= MAX_SCSI_XID) {
3316
                update_tachyon_header_indx(fi);
3317
                if (fi->q.tachyon_header_indx == initial_indx) {
3318
                        /* Should never happen.
3319
                         */
3320
                        T_MSG("No free Tachyon headers available");
3321
                        reset_tachyon(fi, SOFTWARE_RESET);
3322
                        return 1;
3323
                }
3324
                tach_header = fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx];
3325
                temp_ox_id = ntohl(*(tach_header + 6)) >> 16;
3326
        }
3327
        return 0;
3328
}
3329
 
3330
static int get_free_EDB(struct fc_info *fi)
3331
{
3332
unsigned int initial_indx = fi->q.edb_buffer_indx;
3333
        /* Check if the EDB is in use.
3334
         * We could have an outstanding SCSI Write command.
3335
         * We should find a free slot as we can queue a
3336
         * maximum of 32 SCSI commands only.
3337
         */
3338
        while (fi->q.free_edb_list[fi->q.edb_buffer_indx] != EDB_FREE) {
3339
                update_EDB_indx(fi);
3340
                if (fi->q.edb_buffer_indx == initial_indx) {
3341
                        T_MSG("No free EDB buffers avaliable")
3342
                        reset_tachyon(fi, SOFTWARE_RESET);
3343
                        return 1;
3344
                }
3345
        }
3346
        return 0;
3347
}
3348
 
3349
static int validate_login(struct fc_info *fi, u_int *base_ptr)
3350
{
3351
struct fc_node_info *q = fi->node_info_list;
3352
char n_port_name[PORT_NAME_LEN];
3353
char node_name[NODE_NAME_LEN];
3354
u_int s_id;
3355
        ENTER("validate_login");
3356
        /*index to Port Name in the payload. We need the 8 byte Port Name */
3357
        memcpy(n_port_name, base_ptr + 10, PORT_NAME_LEN);
3358
        memcpy(node_name, base_ptr + 12, NODE_NAME_LEN);
3359
        s_id = ntohl(*(base_ptr + 3)) & 0x00FFFFFF;
3360
 
3361
        /* check if Fibre Channel IDs have changed */
3362
        while(q != NULL) {
3363
                if (memcmp(n_port_name, q->hw_addr, PORT_NAME_LEN) == 0) {
3364
                        if ((s_id != q->d_id) || (memcmp(node_name, q->node_name, NODE_NAME_LEN) != 0)) {
3365
                                DPRINTK1("Fibre Channel ID of Node has changed. Txing LOGO.");
3366
                                return 0;
3367
                        }
3368
                        q->login = LOGIN_COMPLETED;
3369
#if DEBUG_5526_2
3370
                        display_cache(fi);
3371
#endif
3372
                        return 1;
3373
                }
3374
                q = q->next;
3375
        }
3376
        DPRINTK1("Port Name does not match. Txing LOGO.");
3377
        return 0;
3378
        LEAVE("validate_login");
3379
}
3380
 
3381
static void add_to_address_cache(struct fc_info *fi, u_int *base_ptr)
3382
{
3383
int size = sizeof(struct fc_node_info);
3384
struct fc_node_info *p, *q = fi->node_info_list, *r = NULL;
3385
char n_port_name[PORT_NAME_LEN];
3386
u_int s_id;
3387
        ENTER("add_to_address_cache");
3388
        /*index to Port Name in the payload. We need the 8 byte Port Name */
3389
        memcpy(n_port_name, base_ptr + 13, PORT_NAME_LEN);
3390
        s_id = ntohl(*(base_ptr + 3)) & 0x00FFFFFF;
3391
 
3392
        /* check if info already exists */
3393
        while(q != NULL) {
3394
                if (memcmp(n_port_name, q->hw_addr, PORT_NAME_LEN) == 0) {
3395
                        if (s_id != q->d_id) {
3396
                                memcpy(&(q->c_of_s[0]), base_ptr + 17, 3 * sizeof(CLASS_OF_SERVICE));
3397
                                q->mtu = ntohl(*(base_ptr + 10)) & 0x00000FFF;
3398
                                q->d_id = s_id;
3399
                                memcpy(q->node_name, base_ptr + 15, NODE_NAME_LEN);
3400
                        }
3401
                        q->login = LOGIN_COMPLETED;
3402
                        q->scsi = FALSE;
3403
                        fi->num_nodes++;
3404
#if DEBUG_5526_2
3405
                        display_cache(fi);
3406
#endif
3407
                        return;
3408
                }
3409
                r = q;
3410
                q = q->next;
3411
        }
3412
        p = (struct fc_node_info *)kmalloc(size, GFP_ATOMIC);
3413
        if (p == NULL) {
3414
                T_MSG("kmalloc failed in add_to_address_cache()");
3415
                return;
3416
        }
3417
        memcpy(&(p->c_of_s[0]), base_ptr + 17, 3 * sizeof(CLASS_OF_SERVICE));
3418
        p->mtu = ntohl(*(base_ptr + 10)) & 0x00000FFF;
3419
        p->d_id = s_id;
3420
        memcpy(p->hw_addr, base_ptr + 13, PORT_NAME_LEN);
3421
        memcpy(p->node_name, base_ptr + 15, NODE_NAME_LEN);
3422
        p->login = LOGIN_COMPLETED;
3423
        p->scsi = FALSE;
3424
        p->target_id = 0xFF;
3425
        p->next = NULL;
3426
        if (fi->node_info_list == NULL)
3427
                fi->node_info_list = p;
3428
        else
3429
                r->next = p;
3430
        fi->num_nodes++;
3431
#if DEBUG_5526_2
3432
        display_cache(fi);
3433
#endif
3434
        LEAVE("add_to_address_cache");
3435
        return;
3436
}
3437
 
3438
static void remove_from_address_cache(struct fc_info *fi, u_int *base_ptr, u_int cmnd_code)
3439
{
3440
struct fc_node_info *q = fi->node_info_list;
3441
u_int s_id;
3442
        ENTER("remove_from_address_cache");
3443
        s_id = ntohl(*(base_ptr + 3)) & 0x00FFFFFF;
3444
        switch(cmnd_code) {
3445
                case ELS_LOGO:
3446
                        /* check if info exists */
3447
                        while (q != NULL) {
3448
                                if (s_id == q->d_id) {
3449
                                        if (q->login == LOGIN_COMPLETED)
3450
                                                q->login = LOGIN_ATTEMPTED;
3451
                                        if (fi->num_nodes > 0)
3452
                                                fi->num_nodes--;
3453
#if DEBUG_5526_2
3454
                                        display_cache(fi);
3455
#endif
3456
                                        return;
3457
                                }
3458
                                q = q->next;
3459
                        }
3460
                        DPRINTK1("ELS_LOGO received from node 0x%x which is not logged-in", s_id);
3461
                        break;
3462
                case ELS_RSCN:
3463
                {
3464
                int payload_len = ntohl(*(base_ptr + 8)) & 0xFF;
3465
                int no_of_pages, i;
3466
                u_char address_format;
3467
                u_short received_ox_id = ntohl(*(base_ptr + 6)) >> 16;
3468
                u_int node_id, mask, *page_ptr = base_ptr + 9;
3469
                        if ((payload_len < 4) || (payload_len > 256)) {
3470
                                DPRINTK1("RSCN with invalid payload length received");
3471
                                tx_ls_rjt(fi, s_id, received_ox_id, LOGICAL_ERR, RECV_FIELD_SIZE);
3472
                                return;
3473
                        }
3474
                        /* Page_size includes the Command Code */
3475
                        no_of_pages = (payload_len / 4) - 1;
3476
                        for (i = 0; i < no_of_pages; i++) {
3477
                                address_format = ntohl(*page_ptr) >> 24;
3478
                                node_id = ntohl(*page_ptr) & 0x00FFFFFF;
3479
                                switch(address_format) {
3480
                                        case PORT_ADDRESS_FORMAT:
3481
                                                rscn_handler(fi, node_id);
3482
                                                break;
3483
                                        case AREA_ADDRESS_FORMAT:
3484
                                        case DOMAIN_ADDRESS_FORMAT:
3485
                                                if (address_format == AREA_ADDRESS_FORMAT)
3486
                                                        mask = 0xFFFF00;
3487
                                                else
3488
                                                        mask = 0xFF0000;
3489
                                                while(q != NULL) {
3490
                                                        if ((q->d_id & mask) == (node_id & mask))
3491
                                                                rscn_handler(fi, q->d_id);
3492
                                                        q = q->next;
3493
                                                }
3494
                                                /* There might be some new nodes to be
3495
                                                 * discovered. But, some of the earlier
3496
                                                 * requests as a result of the RSCN might be
3497
                                                 * in progress. We dont want to duplicate that
3498
                                                 * effort. So letz call SCR after a lag.
3499
                                                 */
3500
                                                fi->explore_timer.function = scr_timer;
3501
                                                fi->explore_timer.data = (unsigned long)fi;
3502
                                                fi->explore_timer.expires = RUN_AT((no_of_pages*3*HZ)/100);
3503
                                                init_timer(&fi->explore_timer);
3504
                                                add_timer(&fi->explore_timer);
3505
                                                break;
3506
                                        default:
3507
                                                T_MSG("RSCN with invalid address format received");
3508
                                                tx_ls_rjt(fi, s_id, received_ox_id, LOGICAL_ERR, NO_EXPLN);
3509
                                }
3510
                                page_ptr += 1;
3511
                        } /* end of for loop */
3512
                } /* end of case RSCN: */
3513
                break;
3514
        }
3515
#if DEBUG_5526_2
3516
        display_cache(fi);
3517
#endif
3518
        LEAVE("remove_from_address_cache");
3519
}
3520
 
3521
static void rscn_handler(struct fc_info *fi, u_int node_id)
3522
{
3523
struct fc_node_info *q = fi->node_info_list;
3524
int login_state = sid_logged_in(fi, node_id);
3525
        if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) {
3526
                while(q != NULL) {
3527
                        if (q->d_id == node_id) {
3528
                                q->login = LOGIN_ATTEMPTED;
3529
                                if (fi->num_nodes > 0)
3530
                                        fi->num_nodes--;
3531
                                break;
3532
                        }
3533
                        else
3534
                                q = q->next;
3535
                }
3536
        }
3537
        else
3538
        if (login_state == NODE_LOGGED_OUT)
3539
                tx_adisc(fi, ELS_ADISC, node_id, OX_ID_FIRST_SEQUENCE);
3540
        else
3541
        if (login_state == NODE_LOGGED_OUT)
3542
                tx_logi(fi, ELS_PLOGI, node_id);
3543
}
3544
 
3545
static void scr_timer(unsigned long data)
3546
{
3547
struct fc_info *fi = (struct fc_info *)data;
3548
        del_timer(&fi->explore_timer);
3549
        tx_name_server_req(fi, FCS_GP_ID4);
3550
}
3551
 
3552
static int sid_logged_in(struct fc_info *fi, u_int s_id)
3553
{
3554
struct fc_node_info *temp = fi->node_info_list;
3555
        while(temp != NULL)
3556
                if ((temp->d_id == s_id) && (temp->login == LOGIN_COMPLETED)) {
3557
                        if (temp->scsi != FALSE)
3558
                                return NODE_PROCESS_LOGGED_IN;
3559
                        else
3560
                                return NODE_LOGGED_IN;
3561
                }
3562
                else
3563
                if ((temp->d_id == s_id) && (temp->login != LOGIN_COMPLETED))
3564
                        return NODE_LOGGED_OUT;
3565
                else
3566
                        temp = temp->next;
3567
        return NODE_NOT_PRESENT;
3568
}
3569
 
3570
static void mark_scsi_sid(struct fc_info *fi, u_int *buff_addr, u_char action)
3571
{
3572
struct fc_node_info *temp = fi->node_info_list;
3573
u_int s_id;
3574
u_int service_params;
3575
        s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
3576
        service_params = ntohl(*(buff_addr + 12)) & 0x000000F0;
3577
        while(temp != NULL)
3578
                if ((temp->d_id == s_id) && (temp->login == LOGIN_COMPLETED)) {
3579
                        if (action == DELETE_ENTRY) {
3580
                                temp->scsi = FALSE;
3581
#if DEBUG_5526_2
3582
                                display_cache(fi);
3583
#endif
3584
                                return;
3585
                        }
3586
                        /* Check if it is a SCSI Target */
3587
                        if (!(service_params & TARGET_FUNC)) {
3588
                                temp->scsi = INITIATOR;
3589
#if DEBUG_5526_2
3590
                                display_cache(fi);
3591
#endif
3592
                                return;
3593
                        }
3594
                        temp->scsi = TARGET;
3595
                        /* This helps to maintain the target_id no matter what your
3596
                         *  Fibre Channel ID is.
3597
                         */
3598
                        if (temp->target_id == 0xFF) {
3599
                                if (fi->g.no_of_targets <= MAX_SCSI_TARGETS)
3600
                                        temp->target_id = fi->g.no_of_targets++;
3601
                                else
3602
                                        T_MSG("MAX TARGETS reached!");
3603
                        }
3604
                        else
3605
                                DPRINTK1("Target_id %d already present", temp->target_id);
3606
#if DEBUG_5526_2
3607
                        display_cache(fi);
3608
#endif
3609
                        return;
3610
                }
3611
                else
3612
                        temp = temp->next;
3613
        return;
3614
}
3615
 
3616
static int node_logged_in_prev(struct fc_info *fi, u_int *buff_addr)
3617
{
3618
struct fc_node_info *temp;
3619
u_char *data = (u_char *)buff_addr;
3620
u_int s_id;
3621
char node_name[NODE_NAME_LEN];
3622
        s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
3623
        memcpy(node_name, buff_addr + 12, NODE_NAME_LEN);
3624
        /* point to port_name in the ADISC payload */
3625
        data += 10 * 4;
3626
        /* point to last 6 bytes of port_name */
3627
        data += 2;
3628
        temp = look_up_cache(fi, data);
3629
        if (temp != NULL) {
3630
                if ((temp->d_id == s_id) && (memcmp(node_name, temp->node_name, NODE_NAME_LEN) == 0)) {
3631
                        temp->login = LOGIN_COMPLETED;
3632
#if DEBUG_5526_2
3633
                        display_cache(fi);
3634
#endif
3635
                        return TRUE;
3636
                }
3637
        }
3638
        return FALSE;
3639
}
3640
 
3641
static struct fc_node_info *look_up_cache(struct fc_info *fi, char *data)
3642
{
3643
struct fc_node_info *temp_list = fi->node_info_list, *q;
3644
u_char n_port_name[FC_ALEN], temp_addr[FC_ALEN];
3645
        ENTER("look_up_cache");
3646
        memcpy(n_port_name, data, FC_ALEN);
3647
        while(temp_list) {
3648
                if (memcmp(n_port_name, &(temp_list->hw_addr[2]), FC_ALEN) == 0)
3649
                        return temp_list;
3650
                else
3651
                        temp_list = temp_list->next;
3652
        }
3653
 
3654
        /* Broadcast IP ?
3655
         */
3656
        temp_addr[0] = temp_addr[1] = temp_addr[2] = 0xFF;
3657
        temp_addr[3] = temp_addr[4] = temp_addr[5] = 0xFF;
3658
        if (memcmp(n_port_name, temp_addr, FC_ALEN) == 0) {
3659
                q = (struct fc_node_info *)kmalloc(sizeof(struct fc_node_info), GFP_ATOMIC);
3660
                if (q == NULL) {
3661
                        T_MSG("kmalloc failed in look_up_cache()");
3662
                        return NULL;
3663
                }
3664
                q->d_id = BROADCAST;
3665
                return q;
3666
        }
3667
        LEAVE("look_up_cache");
3668
        return NULL;
3669
}
3670
 
3671
static int display_cache(struct fc_info *fi)
3672
{
3673
struct fc_node_info *q = fi->node_info_list;
3674
#if DEBUG_5526_2
3675
struct ox_id_els_map *temp_ox_id_list = fi->ox_id_list;
3676
#endif
3677
int count = 0, j;
3678
        printk("\nFibre Channel Node Information for %s\n", fi->name);
3679
        printk("My FC_ID = %x, My WWN = %x %x, ", fi->g.my_id, fi->g.my_node_name_high, fi->g.my_node_name_low);
3680
        if (fi->g.ptp_up == TRUE)
3681
                printk("Port_Type = N_Port\n");
3682
        if (fi->g.loop_up == TRUE)
3683
                printk("Port_Type = L_Port\n");
3684
        while(q != NULL) {
3685
                printk("WWN = ");
3686
                for (j = 0; j < PORT_NAME_LEN; j++)
3687
                        printk("%x ", q->hw_addr[j]);
3688
                printk("FC_ID = %x, ", q->d_id);
3689
                printk("Login = ");
3690
                if (q->login == LOGIN_COMPLETED)
3691
                        printk("ON ");
3692
                else
3693
                        printk("OFF ");
3694
                if (q->scsi == TARGET)
3695
                        printk("Target_ID = %d ", q->target_id);
3696
                printk("\n");
3697
                q = q->next;
3698
                count++;
3699
        }
3700
 
3701
#if DEBUG_5526_2
3702
        printk("OX_ID -> ELS Map\n");
3703
        while(temp_ox_id_list) {
3704
                        printk("ox_id = %x, ELS = %x\n", temp_ox_id_list->ox_id, temp_ox_id_list->els);
3705
                        temp_ox_id_list = temp_ox_id_list->next;
3706
        }
3707
#endif
3708
 
3709
        return 0;
3710
}
3711
 
3712
static struct net_device_stats * iph5526_get_stats(struct net_device *dev)
3713
{
3714
struct fc_info *fi = (struct fc_info*)dev->priv;
3715
        return (struct net_device_stats *) &fi->fc_stats;
3716
}
3717
 
3718
 
3719
/* SCSI stuff starts here */
3720
 
3721
int iph5526_detect(Scsi_Host_Template *tmpt)
3722
{
3723
struct Scsi_Host *host = NULL;
3724
struct iph5526_hostdata *hostdata;
3725
struct fc_info *fi = NULL;
3726
int no_of_hosts = 0, timeout, i, j, count = 0;
3727
u_int pci_maddr = 0;
3728
struct pci_dev *pdev = NULL;
3729
 
3730
        tmpt->proc_name = "iph5526";
3731
        if (pci_present() == 0) {
3732
                printk("iph5526: PCI not present\n");
3733
                return 0;
3734
        }
3735
 
3736
        for (i = 0; i <= MAX_FC_CARDS; i++)
3737
                fc[i] = NULL;
3738
 
3739
        for (i = 0; clone_list[i].vendor_id != 0; i++)
3740
        while ((pdev = pci_find_device(clone_list[i].vendor_id, clone_list[i].device_id, pdev))) {
3741
                unsigned short pci_command;
3742
                if (pci_enable_device(pdev))
3743
                        continue;
3744
                if (count < MAX_FC_CARDS) {
3745
                        fc[count] = kmalloc(sizeof(struct fc_info), GFP_ATOMIC);
3746
                        if (fc[count] == NULL) {
3747
                                printk("iph5526.c: Unable to register card # %d\n", count + 1);
3748
                                return no_of_hosts;
3749
                        }
3750
                        memset(fc[count], 0, sizeof(struct fc_info));
3751
                }
3752
                else {
3753
                        printk("iph5526.c: Maximum Number of cards reached.\n");
3754
                        return no_of_hosts;
3755
                }
3756
 
3757
                fi = fc[count];
3758
                sprintf(fi->name, "fc%d", count);
3759
 
3760
                host = scsi_register(tmpt, sizeof(struct iph5526_hostdata));
3761
                if(host==NULL)
3762
                        return no_of_hosts;
3763
 
3764
                hostdata = (struct iph5526_hostdata *)host->hostdata;
3765
                memset(hostdata, 0 , sizeof(struct iph5526_hostdata));
3766
                for (j = 0; j < MAX_SCSI_TARGETS; j++)
3767
                        hostdata->tag_ages[j] = jiffies;
3768
                hostdata->fi = fi;
3769
                fi->host = host;
3770
                //host->max_id = MAX_SCSI_TARGETS;
3771
                host->max_id = 5;
3772
                host->hostt->use_new_eh_code = 1;
3773
                host->this_id = tmpt->this_id;
3774
 
3775
                pci_maddr = pci_resource_start(pdev, 0);
3776
                if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
3777
                        printk("iph5526.c : Cannot find proper PCI device base address.\n");
3778
                        scsi_unregister(host);
3779
                        kfree(fc[count]);
3780
                        fc[count] = NULL;
3781
                        continue;
3782
                }
3783
 
3784
                DPRINTK("pci_maddr = %x", pci_maddr);
3785
                pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
3786
 
3787
                pci_irq_line = pdev->irq;
3788
                printk("iph5526.c: PCI BIOS reports %s at i/o %#x, irq %d.\n", clone_list[i].name, pci_maddr, pci_irq_line);
3789
                fi->g.mem_base = ioremap(pci_maddr & PAGE_MASK, 1024);
3790
 
3791
                /* We use Memory Mapped IO. The initial space contains the
3792
                 * PCI Configuration registers followed by the (i) chip
3793
                 * registers followed by the Tachyon registers.
3794
                 */
3795
                /* Thatz where (i)chip maps Tachyon Address Space.
3796
                 */
3797
                fi->g.tachyon_base = (u_long)fi->g.mem_base + TACHYON_OFFSET + ( pci_maddr & ~PAGE_MASK );
3798
                DPRINTK("fi->g.tachyon_base = %x", (u_int)fi->g.tachyon_base);
3799
                if (fi->g.mem_base == NULL) {
3800
                        printk("iph5526.c : ioremap failed!!!\n");
3801
                        scsi_unregister(host);
3802
                        kfree(fc[count]);
3803
                        fc[count] = NULL;
3804
                        continue;
3805
                }
3806
                DPRINTK("IRQ1 = %d\n", pci_irq_line);
3807
                printk(version);
3808
                fi->base_addr = (long) pdev;
3809
 
3810
                if (pci_irq_line) {
3811
                int irqval = 0;
3812
                        /* Found it, get IRQ.
3813
                         */
3814
                        irqval = request_irq(pci_irq_line, &tachyon_interrupt, pci_irq_line ? SA_SHIRQ : 0, fi->name, host);
3815
                        if (irqval) {
3816
                                printk("iph5526.c : Unable to get IRQ %d (irqval = %d).\n", pci_irq_line, irqval);
3817
                                scsi_unregister(host);
3818
                                kfree(fc[count]);
3819
                                fc[count] = NULL;
3820
                                continue;
3821
                        }
3822
                        host->irq = fi->irq = pci_irq_line;
3823
                        pci_irq_line = 0;
3824
                        fi->clone_id = clone_list[i].vendor_id;
3825
                }
3826
 
3827
                if (!initialize_register_pointers(fi) || !tachyon_init(fi)) {
3828
                        printk("iph5526.c: TACHYON initialization failed for card # %d!!!\n", count + 1);
3829
                        free_irq(host->irq, host);
3830
                        scsi_unregister(host);
3831
                        if (fi)
3832
                                clean_up_memory(fi);
3833
                        kfree(fc[count]);
3834
                        fc[count] = NULL;
3835
                        break;
3836
                }
3837
                DPRINTK1("Fibre Channel card initialized");
3838
                /* Wait for the Link to come up and the login process
3839
                 * to complete.
3840
                 */
3841
                for(timeout = jiffies + 10*HZ; time_before(jiffies, timeout) && ((fi->g.link_up == FALSE) || (fi->g.port_discovery == TRUE) || (fi->g.explore_fabric == TRUE) || (fi->g.perform_adisc == TRUE));)
3842
                {
3843
                        cpu_relax();
3844
                        barrier();
3845
                }
3846
 
3847
                count++;
3848
                no_of_hosts++;
3849
        }
3850
        DPRINTK1("no_of_hosts = %d",no_of_hosts);
3851
 
3852
        /* This is to make sure that the ACC to the PRLI comes in
3853
         * for the last ALPA.
3854
         */
3855
        mdelay(1000); /* Ugly! Let the Gods forgive me */
3856
 
3857
        DPRINTK1("leaving iph5526_detect\n");
3858
        return no_of_hosts;
3859
}
3860
 
3861
 
3862
int iph5526_biosparam(Disk * disk, kdev_t n, int ip[])
3863
{
3864
int size = disk->capacity;
3865
        ip[0] = 64;
3866
        ip[1] = 32;
3867
        ip[2] = size >> 11;
3868
        if (ip[2] > 1024) {
3869
                ip[0] = 255;
3870
                ip[1] = 63;
3871
                ip[2] = size / (ip[0] * ip[1]);
3872
        }
3873
        return 0;
3874
}
3875
 
3876
int iph5526_queuecommand(Scsi_Cmnd *Cmnd, void (*done) (Scsi_Cmnd *))
3877
{
3878
int int_required = 0;
3879
u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_COMMAND;
3880
u_int type = TYPE_FCP | SEQUENCE_INITIATIVE;
3881
u_int frame_class = Cmnd->target;
3882
u_short ox_id = OX_ID_FIRST_SEQUENCE;
3883
struct Scsi_Host *host = Cmnd->host;
3884
struct iph5526_hostdata *hostdata = (struct iph5526_hostdata*)host->hostdata;
3885
struct fc_info *fi = hostdata->fi;
3886
struct fc_node_info *q;
3887
u_long flags;
3888
        ENTER("iph5526_queuecommand");
3889
 
3890
        spin_lock_irqsave(&fi->fc_lock, flags);
3891
        Cmnd->scsi_done = done;
3892
 
3893
        if (Cmnd->device->tagged_supported) {
3894
                switch(Cmnd->tag) {
3895
                        case SIMPLE_QUEUE_TAG:
3896
                                hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_SIMPLE;
3897
                                break;
3898
                        case HEAD_OF_QUEUE_TAG:
3899
                                hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_HEAD_OF_Q;
3900
                                break;
3901
                        case  ORDERED_QUEUE_TAG:
3902
                                hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_ORDERED;
3903
                                break;
3904
                        default:
3905
                                if ((jiffies - hostdata->tag_ages[Cmnd->target]) > (5 * HZ)) {
3906
                                        hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_ORDERED;
3907
                                        hostdata->tag_ages[Cmnd->target] = jiffies;
3908
                                }
3909
                                else
3910
                                        hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_SIMPLE;
3911
                                break;
3912
                }
3913
        }
3914
        /*else
3915
                hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_UNTAGGED;
3916
        */
3917
 
3918
        hostdata->cmnd.fcp_addr[3] = 0;
3919
        hostdata->cmnd.fcp_addr[2] = 0;
3920
        hostdata->cmnd.fcp_addr[1] = 0;
3921
        hostdata->cmnd.fcp_addr[0] = htons(Cmnd->lun);
3922
 
3923
        memcpy(&hostdata->cmnd.fcp_cdb, Cmnd->cmnd, Cmnd->cmd_len);
3924
        hostdata->cmnd.fcp_data_len = htonl(Cmnd->request_bufflen);
3925
 
3926
        /* Get an used OX_ID. We could have pending commands.
3927
         */
3928
        if (get_scsi_oxid(fi)) {
3929
                spin_unlock_irqrestore(&fi->fc_lock, flags);
3930
                return 1;
3931
        }
3932
        fi->q.free_scsi_oxid[fi->g.scsi_oxid] = OXID_INUSE;
3933
 
3934
        /* Maintain a handler so that we can associate the done() function
3935
         * on completion of the SCSI command.
3936
         */
3937
        hostdata->cmnd_handler[fi->g.scsi_oxid] = Cmnd;
3938
 
3939
        switch(Cmnd->cmnd[0]) {
3940
                case WRITE_6:
3941
                case WRITE_10:
3942
                case WRITE_12:
3943
                        fi->g.type_of_frame = FC_SCSI_WRITE;
3944
                        hostdata->cmnd.fcp_cntl = htonl(FCP_CNTL_WRITE | hostdata->cmnd.fcp_cntl);
3945
                        break;
3946
                default:
3947
                        fi->g.type_of_frame = FC_SCSI_READ;
3948
                        hostdata->cmnd.fcp_cntl = htonl(FCP_CNTL_READ | hostdata->cmnd.fcp_cntl);
3949
        }
3950
 
3951
        memcpy(fi->q.ptr_fcp_cmnd[fi->q.fcp_cmnd_indx], &(hostdata->cmnd), sizeof(fcp_cmd));
3952
 
3953
        q = resolve_target(fi, Cmnd->target);
3954
 
3955
        if (q == NULL) {
3956
        u_int bad_id = fi->g.my_ddaa | 0xFE;
3957
                /* We transmit to an non-existant AL_PA so that the "done"
3958
                 * function can be called while receiving the interrupt
3959
                 * due to a Timeout for a bad AL_PA. In a PTP configuration,
3960
                 * the int_required field is set, since there is no notion
3961
                 * of AL_PAs. This approach sucks, but works alright!
3962
                 */
3963
                if (fi->g.ptp_up == TRUE)
3964
                        int_required = 1;
3965
                tx_exchange(fi, (char *)(&(hostdata->cmnd)), sizeof(fcp_cmd), r_ctl, type, bad_id, fi->g.my_mtu, int_required, ox_id, FC_SCSI_BAD_TARGET);
3966
                spin_unlock_irqrestore(&fi->fc_lock, flags);
3967
                DPRINTK1("Target ID %x not present", Cmnd->target);
3968
                return 0;
3969
        }
3970
        if (q->login == LOGIN_COMPLETED) {
3971
                if (add_to_sest(fi, Cmnd, q)) {
3972
                        DPRINTK1("add_to_sest() failed.");
3973
                        spin_unlock_irqrestore(&fi->fc_lock, flags);
3974
                        return 0;
3975
                }
3976
                tx_exchange(fi, (char *)(fi->q.ptr_fcp_cmnd[fi->q.fcp_cmnd_indx]), sizeof(fcp_cmd), r_ctl, type, q->d_id, q->mtu, int_required, ox_id, frame_class << 16);
3977
                update_FCP_CMND_indx(fi);
3978
        }
3979
        spin_unlock_irqrestore(&fi->fc_lock, flags);
3980
        /* If q != NULL, then we have a SCSI Target.
3981
         * If q->login != LOGIN_COMPLETED, then that device could be
3982
         * offline temporarily. So we let the command to time-out.
3983
         */
3984
        LEAVE("iph5526_queuecommand");
3985
        return 0;
3986
}
3987
 
3988
int iph5526_abort(Scsi_Cmnd *Cmnd)
3989
{
3990
struct Scsi_Host *host = Cmnd->host;
3991
struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
3992
struct fc_info *fi = hostdata->fi;
3993
struct fc_node_info *q;
3994
u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_COMMAND;
3995
u_int type = TYPE_FCP | SEQUENCE_INITIATIVE;
3996
u_short ox_id = OX_ID_FIRST_SEQUENCE;
3997
int int_required = 1, i, abort_status = FALSE;
3998
u_long flags;
3999
 
4000
        ENTER("iph5526_abort");
4001
 
4002
        spin_lock_irqsave(&fi->fc_lock, flags);
4003
 
4004
        q = resolve_target(fi, Cmnd->target);
4005
        if (q == NULL) {
4006
        u_int bad_id = fi->g.my_ddaa | 0xFE;
4007
                /* This should not happen as we should always be able to
4008
                 * resolve a target id. But, jus in case...
4009
                 * We transmit to an non-existant AL_PA so that the done
4010
                 * function can be called while receiving the interrupt
4011
                 * for a bad AL_PA.
4012
                 */
4013
                DPRINTK1("Unresolved Target ID!");
4014
                tx_exchange(fi, (char *)(&(hostdata->cmnd)), sizeof(fcp_cmd), r_ctl, type, bad_id, fi->g.my_mtu, int_required, ox_id, FC_SCSI_BAD_TARGET);
4015
                DPRINTK1("Target ID %x not present", Cmnd->target);
4016
                spin_unlock_irqrestore(&fi->fc_lock, flags);
4017
                return FAILED;
4018
        }
4019
 
4020
        /* If q != NULL, then we have a SCSI Target. If
4021
         * q->login != LOGIN_COMPLETED, then that device could
4022
         * be offline temporarily. So we let the command to time-out.
4023
         */
4024
 
4025
        /* Get the OX_ID for the Command to be aborted.
4026
         */
4027
        for (i = 0; i <= MAX_SCSI_XID; i++) {
4028
                if (hostdata->cmnd_handler[i] == Cmnd) {
4029
                        hostdata->cmnd_handler[i] = NULL;
4030
                        ox_id = i;
4031
                        break;
4032
                }
4033
        }
4034
        if (i > MAX_SCSI_XID) {
4035
                T_MSG("Command could not be resolved to OX_ID");
4036
                spin_unlock_irqrestore(&fi->fc_lock, flags);
4037
                return FAILED;
4038
        }
4039
 
4040
        switch(Cmnd->cmnd[0]) {
4041
                case WRITE_6:
4042
                case WRITE_10:
4043
                case WRITE_12:
4044
                        break;
4045
                default:
4046
                        ox_id |= SCSI_READ_BIT;
4047
        }
4048
        abort_status = abort_exchange(fi, ox_id);
4049
 
4050
        if ((q->login == LOGIN_COMPLETED) && (abort_status == TRUE)) {
4051
                /* Then, transmit an ABTS to the target. The rest
4052
                 * is done when the BA_ACC is received for the ABTS.
4053
                 */
4054
                tx_abts(fi, q->d_id, ox_id);
4055
        }
4056
        else {
4057
        u_int STE_bit;
4058
        u_short x_id;
4059
                /* Invalidate resources for that Exchange.
4060
                 */
4061
                x_id = ox_id & MAX_SCSI_XID;
4062
                STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
4063
                if (STE_bit & SEST_V) {
4064
                        *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
4065
                        invalidate_SEST_entry(fi, ox_id);
4066
                }
4067
        }
4068
 
4069
        LEAVE("iph5526_abort");
4070
        spin_unlock_irqrestore(&fi->fc_lock, flags);
4071
        return SUCCESS;
4072
}
4073
 
4074
static int abort_exchange(struct fc_info *fi, u_short ox_id)
4075
{
4076
u_short x_id;
4077
volatile u_int flush_SEST, STE_bit;
4078
        x_id = ox_id & MAX_SCSI_XID;
4079
        DPRINTK1("Aborting Exchange %x", ox_id);
4080
 
4081
        STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
4082
        /* Is the Exchange still active?.
4083
         */
4084
        if (STE_bit & SEST_V) {
4085
                if (ox_id & SCSI_READ_BIT) {
4086
                        /* If the Exchange to be aborted is Inbound,
4087
                         * Flush the SEST Entry from Tachyon's Cache.
4088
                         */
4089
                        *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
4090
                        flush_tachyon_cache(fi, ox_id);
4091
                        flush_SEST = readl(fi->t_r.ptr_tach_flush_oxid_reg);
4092
                        while ((flush_SEST & 0x80000000) != 0)
4093
                                flush_SEST = readl(fi->t_r.ptr_tach_flush_oxid_reg);
4094
                        STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
4095
                        while ((STE_bit & 0x80000000) != 0)
4096
                                STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
4097
                        flush_SEST = readl(fi->t_r.ptr_tach_flush_oxid_reg);
4098
                        invalidate_SEST_entry(fi, ox_id);
4099
                }
4100
                else {
4101
                int i;
4102
                u_int *ptr_edb;
4103
                        /* For In-Order Reassembly, the following is done:
4104
                         * First, write zero as the buffer length in the EDB.
4105
                         */
4106
                        ptr_edb = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 7)));
4107
                        for (i = 0; i < EDB_LEN; i++)
4108
                                if (fi->q.ptr_edb[i] == ptr_edb)
4109
                                        break;
4110
                        if (i < EDB_LEN)
4111
                                *ptr_edb = *ptr_edb & 0x0000FFFF;
4112
                        else
4113
                                T_MSG("EDB not found while clearing in abort_exchange()");
4114
                }
4115
                DPRINTK1("Exchange %x invalidated", ox_id);
4116
                return TRUE;
4117
        }
4118
        else {
4119
                DPRINTK1("SEST Entry for exchange %x not valid", ox_id);
4120
                return FALSE;
4121
        }
4122
}
4123
 
4124
static void flush_tachyon_cache(struct fc_info *fi, u_short ox_id)
4125
{
4126
volatile u_int tachyon_status;
4127
        if (fi->g.loop_up == TRUE) {
4128
                writel(HOST_CONTROL, fi->t_r.ptr_fm_control_reg);
4129
                /* Make sure that the Inbound FIFO is empty.
4130
                 */
4131
                do {
4132
                        tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
4133
                        udelay(200);
4134
                }while ((tachyon_status & RECEIVE_FIFO_EMPTY) == 0);
4135
                /* Ok. Go ahead and flushhhhhhhhh!
4136
                 */
4137
                writel(0x80000000 | ox_id, fi->t_r.ptr_tach_flush_oxid_reg);
4138
                writel(EXIT_HOST_CONTROL, fi->t_r.ptr_fm_control_reg);
4139
                return;
4140
        }
4141
        if (fi->g.ptp_up == TRUE) {
4142
                take_tachyon_offline(fi);
4143
                /* Make sure that the Inbound FIFO is empty.
4144
                 */
4145
                do {
4146
                        tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
4147
                        udelay(200);
4148
                }while ((tachyon_status & RECEIVE_FIFO_EMPTY) == 0);
4149
                writel(0x80000000 | ox_id, fi->t_r.ptr_tach_flush_oxid_reg);
4150
                /* Write the Initialize command to the FM Control reg.
4151
                 */
4152
                fi->g.n_port_try = TRUE;
4153
                DPRINTK1("In abort_exchange, TACHYON initializing as N_Port...\n");
4154
                writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
4155
        }
4156
}
4157
 
4158
static struct fc_node_info *resolve_target(struct fc_info *fi, u_char target)
4159
{
4160
struct fc_node_info *temp = fi->node_info_list;
4161
        while(temp != NULL)
4162
                if (temp->target_id == target) {
4163
                        if ((temp->scsi == TARGET) && (temp->login == LOGIN_COMPLETED))
4164
                                return temp;
4165
                        else {
4166
                                if (temp->login != LOGIN_COMPLETED) {
4167
                                        /* The Target is not currently logged in.
4168
                                         * It could be a Target on the Local Loop or
4169
                                         * on a Remote Loop connected through a switch.
4170
                                         * In either case, we will know whenever the Target
4171
                                         * comes On-Line again. We let the command to
4172
                                         * time-out so that it gets retried.
4173
                                         */
4174
                                        T_MSG("Target %d not logged in.", temp->target_id);
4175
                                        tx_logi(fi, ELS_PLOGI, temp->d_id);
4176
                                        return temp;
4177
                                }
4178
                                else {
4179
                                        if (temp->scsi != TARGET) {
4180
                                                /* For some reason, we did not get a response to
4181
                                                 * PRLI. Letz try it again...
4182
                                                 */
4183
                                                DPRINTK1("Node not PRLIied. Txing PRLI...");
4184
                                                tx_prli(fi, ELS_PRLI, temp->d_id, OX_ID_FIRST_SEQUENCE);
4185
                                        }
4186
                                }
4187
                                return temp;
4188
                        }
4189
                }
4190
                else
4191
                        temp = temp->next;
4192
        return NULL;
4193
}
4194
 
4195
static int add_to_sest(struct fc_info *fi, Scsi_Cmnd *Cmnd, struct fc_node_info *ni)
4196
{
4197
/* we have at least 1 buffer, the terminator */
4198
int no_of_sdb_buffers = 1, i;
4199
int no_of_edb_buffers = 0;
4200
u_int *req_buffer = (u_int *)Cmnd->request_buffer;
4201
u_int *ptr_sdb = NULL;
4202
struct scatterlist *sl1, *sl2 = NULL;
4203
int no_of_sg = 0;
4204
 
4205
        switch(fi->g.type_of_frame) {
4206
                case FC_SCSI_READ:
4207
                        fi->g.inb_sest_entry.flags_and_byte_offset = htonl(INB_SEST_VED);
4208
                        fi->g.inb_sest_entry.byte_count = 0;
4209
                        fi->g.inb_sest_entry.no_of_recvd_frames = 0;
4210
                        fi->g.inb_sest_entry.no_of_expected_frames = 0;
4211
                        fi->g.inb_sest_entry.last_fctl = 0;
4212
 
4213
                        if (Cmnd->use_sg) {
4214
                                no_of_sg = Cmnd->use_sg;
4215
                                sl1 = sl2 = (struct scatterlist *)Cmnd->request_buffer;
4216
                                for (i = 0; i < no_of_sg; i++) {
4217
                                        no_of_sdb_buffers += sl1->length / SEST_BUFFER_SIZE;
4218
                                        if (sl1->length % SEST_BUFFER_SIZE)
4219
                                                no_of_sdb_buffers++;
4220
                                        sl1++;
4221
                                }
4222
                        }
4223
                        else {
4224
                                no_of_sdb_buffers += Cmnd->request_bufflen / SEST_BUFFER_SIZE;
4225
                                if (Cmnd->request_bufflen % SEST_BUFFER_SIZE)
4226
                                        no_of_sdb_buffers++;
4227
                        } /* if !use_sg */
4228
 
4229
                        /* We are working with the premise that at the max we would
4230
                         * get a scatter-gather buffer containing 63 buffers
4231
                         * of size 1024 bytes each. Is it a _bad_ assumption?
4232
                         */
4233
                        if (no_of_sdb_buffers > 512) {
4234
                                T_MSG("Number of SDB buffers needed = %d", no_of_sdb_buffers);
4235
                                T_MSG("Disable Scatter-Gather!!!");
4236
                                return 1;
4237
                        }
4238
 
4239
 
4240
                        /* Store it in the sdb_table so that we can retrieve that
4241
                         * free up the memory when the Read Command completes.
4242
                         */
4243
                        if (get_free_SDB(fi))
4244
                                return 1;
4245
                        ptr_sdb = fi->q.ptr_sdb_slot[fi->q.sdb_indx];
4246
                        fi->q.sdb_slot_status[fi->q.sdb_indx] = SDB_BUSY;
4247
                        fi->g.inb_sest_entry.sdb_address = htonl(virt_to_bus(ptr_sdb));
4248
 
4249
                        if (Cmnd->use_sg) {
4250
                        int count = 0, j;
4251
                                for(i = 0; i < no_of_sg; i++) {
4252
                                char *addr_ptr = sl2->address;
4253
                                        count = sl2->length / SEST_BUFFER_SIZE;
4254
                                        if (sl2->length % SEST_BUFFER_SIZE)
4255
                                                count++;
4256
                                        for (j = 0; j < count; j++) {
4257
                                                *(ptr_sdb) = htonl(virt_to_bus(addr_ptr));
4258
                                                addr_ptr += SEST_BUFFER_SIZE;
4259
                                                ptr_sdb++;
4260
                                        }
4261
                                        count = 0;
4262
                                        sl2++;
4263
                                }
4264
                        }
4265
                        else {
4266
                                for (i = 0; i < no_of_sdb_buffers - 1; i++) {
4267
                                        *(ptr_sdb) = htonl(virt_to_bus(req_buffer));
4268
                                        req_buffer += SEST_BUFFER_SIZE/4;
4269
                                        ptr_sdb++;
4270
                                }
4271
                        }
4272
                        *(ptr_sdb) = htonl(0x1); /* Terminator */
4273
 
4274
                        /* The scratch pad is used to hold the index into the SDB.
4275
                         */
4276
                        fi->g.inb_sest_entry.scratch_pad = fi->q.sdb_indx;
4277
                        fi->g.inb_sest_entry.expected_ro = 0;
4278
                        fi->g.inb_sest_entry.buffer_index = 0;
4279
                        fi->g.inb_sest_entry.buffer_offset = 0;
4280
                        memcpy(fi->q.ptr_sest[fi->g.scsi_oxid], &fi->g.inb_sest_entry, sizeof(INB_SEST_ENTRY));
4281
                        break;
4282
                case FC_SCSI_WRITE:
4283
                        fi->g.outb_sest_entry.flags_and_did = htonl(OUTB_SEST_VED | ni->d_id);
4284
                        fi->g.outb_sest_entry.max_frame_len = htons(ni->mtu << 4);
4285
                        fi->g.outb_sest_entry.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | ODB_NO_INT | ODB_NO_COMP);
4286
                        fi->g.outb_sest_entry.total_seq_length = INV_SEQ_LEN;
4287
                        fi->g.outb_sest_entry.link = htons(OUTB_SEST_LINK);
4288
                        fi->g.outb_sest_entry.transaction_id = htonl(fi->g.scsi_oxid);
4289
                        fi->g.outb_sest_entry.seq_id = fi->g.seq_id;
4290
                        fi->g.outb_sest_entry.reserved = 0x0;
4291
                        fi->g.outb_sest_entry.header_length = htons(TACHYON_HEADER_LEN);
4292
 
4293
                        {
4294
                        u_char df_ctl = 0;
4295
                        u_short rx_id = RX_ID_FIRST_SEQUENCE;
4296
                        u_int r_ctl = FC4_DEVICE_DATA | SOLICITED_DATA;
4297
                        u_int type = TYPE_FCP | SEQUENCE_INITIATIVE;
4298
                                /* Multi Frame Sequence ? If yes, set RO bit.
4299
                                 */
4300
                                if (Cmnd->request_bufflen > ni->mtu)
4301
                                        type |= RELATIVE_OFF_PRESENT;
4302
                                build_tachyon_header(fi, fi->g.my_id, r_ctl, ni->d_id, type, fi->g.seq_id, df_ctl, fi->g.scsi_oxid, rx_id, NULL);
4303
                                if (get_free_header(fi) || get_free_EDB(fi))
4304
                                        return 1;
4305
                                memcpy(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx], &(fi->g.tach_header), TACHYON_HEADER_LEN);
4306
                                fi->g.outb_sest_entry.header_address = htonl(virt_to_bus(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx]));
4307
                                update_tachyon_header_indx(fi);
4308
                        }
4309
 
4310
                        if (Cmnd->use_sg) {
4311
                                no_of_sg = Cmnd->use_sg;
4312
                                sl1 = sl2 = (struct scatterlist *)Cmnd->request_buffer;
4313
                                for (i = 0; i < no_of_sg; i++) {
4314
                                        no_of_edb_buffers += sl1->length / SEST_BUFFER_SIZE;
4315
                                        if (sl1->length % SEST_BUFFER_SIZE)
4316
                                                no_of_edb_buffers++;
4317
                                        sl1++;
4318
                                }
4319
                        }
4320
                        else {
4321
                                no_of_edb_buffers += Cmnd->request_bufflen / SEST_BUFFER_SIZE;
4322
                                if (Cmnd->request_bufflen % SEST_BUFFER_SIZE)
4323
                                        no_of_edb_buffers++;
4324
                        } /* if !use_sg */
4325
 
4326
 
4327
                        /* We need "no_of_edb_buffers" _contiguous_ EDBs
4328
                         * that are FREE. Check for that first.
4329
                         */
4330
                        for (i = 0; i < no_of_edb_buffers; i++) {
4331
                        int j;
4332
                                if ((fi->q.edb_buffer_indx + no_of_edb_buffers) >= EDB_LEN)
4333
                                        fi->q.edb_buffer_indx = 0;
4334
                                if (fi->q.free_edb_list[fi->q.edb_buffer_indx + i] != EDB_FREE) {
4335
                                        for (j = 0; j < i; j++)
4336
                                                update_EDB_indx(fi);
4337
                                        if (get_free_EDB(fi))
4338
                                                return 1;
4339
                                        i = 0;
4340
                                }
4341
                        }
4342
 
4343
                        /* We got enuff FREE EDBs.
4344
                         */
4345
                        if (Cmnd->use_sg) {
4346
                                fi->g.outb_sest_entry.edb_address = htonl(virt_to_bus(fi->q.ptr_edb[fi->q.edb_buffer_indx]));
4347
                                sl1 = (struct scatterlist *)Cmnd->request_buffer;
4348
                                for(i = 0; i < no_of_sg; i++) {
4349
                                int count = 0, j;
4350
                                        count = sl1->length / SEST_BUFFER_SIZE;
4351
                                        for (j = 0; j < count; j++) {
4352
                                                build_EDB(fi, (char *)sl1->address, 0, SEST_BUFFER_SIZE);
4353
                                                memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB));
4354
                                                /* Mark this EDB as being in use */
4355
                                                fi->q.free_edb_list[fi->q.edb_buffer_indx] = EDB_BUSY;
4356
                                                /* We have already made sure that we have enuff
4357
                                                 * free EDBs that are contiguous. So this is
4358
                                                 * safe.
4359
                                                 */
4360
                                                update_EDB_indx(fi);
4361
                                                sl1->address += SEST_BUFFER_SIZE;
4362
                                        }
4363
                                        /* Just in case itz not a multiple of
4364
                                         * SEST_BUFFER_SIZE bytes.
4365
                                         */
4366
                                        if (sl1->length % SEST_BUFFER_SIZE) {
4367
                                                build_EDB(fi, (char *)sl1->address, 0, sl1->length % SEST_BUFFER_SIZE);
4368
                                                memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB));
4369
                                                fi->q.free_edb_list[fi->q.edb_buffer_indx] = EDB_BUSY;
4370
                                                update_EDB_indx(fi);
4371
                                        }
4372
                                        sl1++;
4373
                                }
4374
                                /* The last EDB is special. It needs the "end bit" to
4375
                                 * be set.
4376
                                 */
4377
                                *(fi->q.ptr_edb[fi->q.edb_buffer_indx - 1] + 1) = *(fi->q.ptr_edb[fi->q.edb_buffer_indx - 1] + 1) | ntohs(EDB_END);
4378
                        }
4379
                        else {
4380
                        int count = 0, j;
4381
                                fi->g.outb_sest_entry.edb_address = htonl(virt_to_bus(fi->q.ptr_edb[fi->q.edb_buffer_indx]));
4382
                                count = Cmnd->request_bufflen / SEST_BUFFER_SIZE;
4383
                                for (j = 0; j < count; j++) {
4384
                                        build_EDB(fi, (char *)req_buffer, 0, SEST_BUFFER_SIZE);
4385
                                        memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB));
4386
                                        /* Mark this EDB as being in use */
4387
                                        fi->q.free_edb_list[fi->q.edb_buffer_indx] = EDB_BUSY;
4388
                                        /* We have already made sure that we have enuff
4389
                                         * free EDBs that are contiguous. So this is
4390
                                         * safe.
4391
                                         */
4392
                                        update_EDB_indx(fi);
4393
                                        req_buffer += SEST_BUFFER_SIZE;
4394
                                }
4395
                                /* Just in case itz not a multiple of
4396
                                 * SEST_BUFFER_SIZE bytes.
4397
                                 */
4398
                                if (Cmnd->request_bufflen % SEST_BUFFER_SIZE) {
4399
                                        build_EDB(fi, (char *)req_buffer, EDB_END, Cmnd->request_bufflen % SEST_BUFFER_SIZE);
4400
                                        memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB));
4401
                                        fi->q.free_edb_list[fi->q.edb_buffer_indx] = EDB_BUSY;
4402
                                        update_EDB_indx(fi);
4403
                                }
4404
                                else {
4405
                                        /* Mark the last EDB as the "end edb".
4406
                                         */
4407
                                        *(fi->q.ptr_edb[fi->q.edb_buffer_indx - 1] + 1) = *(fi->q.ptr_edb[fi->q.edb_buffer_indx - 1] + 1) | htons(EDB_END);
4408
                                }
4409
                        }
4410
 
4411
                        /* Finally we have something to send!.
4412
                         */
4413
                        memcpy(fi->q.ptr_sest[fi->g.scsi_oxid], &fi->g.outb_sest_entry, sizeof(OUTB_SEST_ENTRY));
4414
                        break;
4415
                }
4416
        return 0;
4417
}
4418
 
4419
static void update_FCP_CMND_indx(struct fc_info *fi)
4420
{
4421
        fi->q.fcp_cmnd_indx++;
4422
        if (fi->q.fcp_cmnd_indx == NO_OF_FCP_CMNDS)
4423
                fi->q.fcp_cmnd_indx = 0;
4424
}
4425
 
4426
static int get_scsi_oxid(struct fc_info *fi)
4427
{
4428
u_short initial_oxid = fi->g.scsi_oxid;
4429
        /* Check if the OX_ID is in use.
4430
         * We could have an outstanding SCSI command.
4431
         */
4432
        while (fi->q.free_scsi_oxid[fi->g.scsi_oxid] != OXID_AVAILABLE) {
4433
                update_scsi_oxid(fi);
4434
                if (fi->g.scsi_oxid == initial_oxid) {
4435
                        T_MSG("No free OX_IDs avaliable")
4436
                        reset_tachyon(fi, SOFTWARE_RESET);
4437
                        return 1;
4438
                }
4439
        }
4440
        return 0;
4441
}
4442
 
4443
static void update_scsi_oxid(struct fc_info *fi)
4444
{
4445
        fi->g.scsi_oxid++;
4446
        if (fi->g.scsi_oxid == (MAX_SCSI_XID + 1))
4447
                fi->g.scsi_oxid = 0;
4448
}
4449
 
4450
static int get_free_SDB(struct fc_info *fi)
4451
{
4452
unsigned int initial_indx = fi->q.sdb_indx;
4453
        /* Check if the SDB is in use.
4454
         * We could have an outstanding SCSI Read command.
4455
         * We should find a free slot as we can queue a
4456
         * maximum of 32 SCSI commands only.
4457
         */
4458
        while (fi->q.sdb_slot_status[fi->q.sdb_indx] != SDB_FREE) {
4459
                update_SDB_indx(fi);
4460
                if (fi->q.sdb_indx == initial_indx) {
4461
                        T_MSG("No free SDB buffers avaliable")
4462
                        reset_tachyon(fi, SOFTWARE_RESET);
4463
                        return 1;
4464
                }
4465
        }
4466
        return 0;
4467
}
4468
 
4469
static void update_SDB_indx(struct fc_info *fi)
4470
{
4471
        fi->q.sdb_indx++;
4472
        if (fi->q.sdb_indx == NO_OF_SDB_ENTRIES)
4473
                fi->q.sdb_indx = 0;
4474
}
4475
 
4476
int iph5526_release(struct Scsi_Host *host)
4477
{
4478
struct iph5526_hostdata *hostdata = (struct iph5526_hostdata*)host->hostdata;
4479
struct fc_info *fi = hostdata->fi;
4480
        free_irq(host->irq, host);
4481
        iounmap(fi->g.mem_base);
4482
        return 0;
4483
}
4484
 
4485
const char *iph5526_info(struct Scsi_Host *host)
4486
{
4487
static char buf[80];
4488
        sprintf(buf, "Interphase 5526 Fibre Channel PCI SCSI Adapter using IRQ %d\n", host->irq);
4489
        return buf;
4490
}
4491
 
4492
#ifdef MODULE
4493
 
4494
#define NAMELEN         8       /* # of chars for storing dev->name */
4495
 
4496
static struct net_device *dev_fc[MAX_FC_CARDS];
4497
 
4498
static int io;
4499
static int irq;
4500
static int bad; /* 0xbad = bad sig or no reset ack */
4501
static int scsi_registered;
4502
 
4503
 
4504
int init_module(void)
4505
{
4506
int i = 0;
4507
 
4508
        driver_template.module = &__this_module;
4509
        scsi_register_module(MODULE_SCSI_HA, &driver_template);
4510
        if (driver_template.present)
4511
                scsi_registered = TRUE;
4512
        else {
4513
                printk("iph5526: SCSI registeration failed!!!\n");
4514
                scsi_registered = FALSE;
4515
                scsi_unregister_module(MODULE_SCSI_HA, &driver_template);
4516
        }
4517
 
4518
        while(fc[i] != NULL) {
4519
                dev_fc[i] = NULL;
4520
                dev_fc[i] = init_fcdev(dev_fc[i], 0);
4521
                if (dev_fc[i] == NULL) {
4522
                        printk("iph5526.c: init_fcdev failed for card #%d\n", i+1);
4523
                        break;
4524
                }
4525
                dev_fc[i]->irq = irq;
4526
                dev_fc[i]->mem_end = bad;
4527
                dev_fc[i]->base_addr = io;
4528
                dev_fc[i]->init = iph5526_probe;
4529
                dev_fc[i]->priv = fc[i];
4530
                fc[i]->dev = dev_fc[i];
4531
                if (register_fcdev(dev_fc[i]) != 0) {
4532
                        kfree(dev_fc[i]);
4533
                        dev_fc[i] = NULL;
4534
                        if (i == 0) {
4535
                                printk("iph5526.c: IP registeration failed!!!\n");
4536
                                return -ENODEV;
4537
                        }
4538
                }
4539
                i++;
4540
        }
4541
        if (i == 0)
4542
                return -ENODEV;
4543
 
4544
        return 0;
4545
}
4546
 
4547
void cleanup_module(void)
4548
{
4549
int i = 0;
4550
        while(fc[i] != NULL) {
4551
        struct net_device *dev = fc[i]->dev;
4552
        void *priv = dev->priv;
4553
                fc[i]->g.dont_init = TRUE;
4554
                take_tachyon_offline(fc[i]);
4555
                unregister_fcdev(dev);
4556
                clean_up_memory(fc[i]);
4557
                if (dev->priv)
4558
                        kfree(priv);
4559
                kfree(dev);
4560
                dev = NULL;
4561
                i++;
4562
        }
4563
        if (scsi_registered == TRUE)
4564
                scsi_unregister_module(MODULE_SCSI_HA, &driver_template);
4565
}
4566
#endif /* MODULE */
4567
 
4568
void clean_up_memory(struct fc_info *fi)
4569
{
4570
int i,j;
4571
        ENTER("clean_up_memory");
4572
        if (fi->q.ptr_mfsbq_base)
4573
                free_pages((u_long)bus_to_virt(ntohl(*(fi->q.ptr_mfsbq_base))), 5);
4574
        DPRINTK("after kfree2");
4575
        for (i = 0; i < SFSBQ_LENGTH; i++)
4576
                for (j = 0; j < NO_OF_ENTRIES; j++)
4577
                        if (fi->q.ptr_sfs_buffers[i*NO_OF_ENTRIES + j])
4578
                                kfree(fi->q.ptr_sfs_buffers[i*NO_OF_ENTRIES + j]);
4579
        DPRINTK("after kfree1");
4580
        if (fi->q.ptr_ocq_base)
4581
                free_page((u_long)fi->q.ptr_ocq_base);
4582
        if (fi->q.ptr_imq_base)
4583
                free_page((u_long)fi->q.ptr_imq_base);
4584
        if (fi->q.ptr_mfsbq_base)
4585
                free_page((u_long)fi->q.ptr_mfsbq_base);
4586
        if (fi->q.ptr_sfsbq_base)
4587
                free_page((u_long)fi->q.ptr_sfsbq_base);
4588
        if (fi->q.ptr_edb_base)
4589
                free_pages((u_long)fi->q.ptr_edb_base, 5);
4590
        if (fi->q.ptr_sest_base)
4591
                free_pages((u_long)fi->q.ptr_sest_base, 5);
4592
        if (fi->q.ptr_tachyon_header_base)
4593
                free_page((u_long)fi->q.ptr_tachyon_header_base);
4594
        if (fi->q.ptr_sdb_base)
4595
                free_pages((u_long)fi->q.ptr_sdb_base, 5);
4596
        if (fi->q.ptr_fcp_cmnd_base)
4597
                free_page((u_long)fi->q.ptr_fcp_cmnd_base);
4598
        DPRINTK("after free_pages");
4599
        if (fi->q.ptr_host_ocq_cons_indx)
4600
                kfree(fi->q.ptr_host_ocq_cons_indx);
4601
        if (fi->q.ptr_host_hpcq_cons_indx)
4602
                kfree(fi->q.ptr_host_hpcq_cons_indx);
4603
        if (fi->q.ptr_host_imq_prod_indx)
4604
                kfree(fi->q.ptr_host_imq_prod_indx);
4605
        DPRINTK("after kfree3");
4606
        while (fi->node_info_list) {
4607
        struct fc_node_info *temp_list = fi->node_info_list;
4608
                fi->node_info_list = fi->node_info_list->next;
4609
                kfree(temp_list);
4610
        }
4611
        while (fi->ox_id_list) {
4612
        struct ox_id_els_map *temp = fi->ox_id_list;
4613
                fi->ox_id_list = fi->ox_id_list->next;
4614
                kfree(temp);
4615
        }
4616
        LEAVE("clean_up_memory");
4617
}
4618
 
4619
static int initialize_register_pointers(struct fc_info *fi)
4620
{
4621
ENTER("initialize_register_pointers");
4622
if(fi->g.tachyon_base == 0)
4623
        return -ENOMEM;
4624
 
4625
fi->i_r.ptr_ichip_hw_control_reg        = ICHIP_HW_CONTROL_REG_OFF + fi->g.tachyon_base;
4626
fi->i_r.ptr_ichip_hw_status_reg = ICHIP_HW_STATUS_REG_OFF + fi->g.tachyon_base;
4627
fi->i_r.ptr_ichip_hw_addr_mask_reg = ICHIP_HW_ADDR_MASK_REG_OFF + fi->g.tachyon_base;
4628
fi->t_r.ptr_ocq_base_reg = OCQ_BASE_REGISTER_OFFSET + fi->g.tachyon_base;
4629
fi->t_r.ptr_ocq_len_reg = OCQ_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
4630
fi->t_r.ptr_ocq_prod_indx_reg = OCQ_PRODUCER_REGISTER_OFFSET + fi->g.tachyon_base;
4631
fi->t_r.ptr_ocq_cons_indx_reg = OCQ_CONSUMER_REGISTER_OFFSET + fi->g.tachyon_base;
4632
fi->t_r.ptr_imq_base_reg = IMQ_BASE_REGISTER_OFFSET + fi->g.tachyon_base;
4633
fi->t_r.ptr_imq_len_reg = IMQ_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
4634
fi->t_r.ptr_imq_cons_indx_reg = IMQ_CONSUMER_REGISTER_OFFSET + fi->g.tachyon_base;
4635
fi->t_r.ptr_imq_prod_indx_reg = IMQ_PRODUCER_REGISTER_OFFSET + fi->g.tachyon_base;
4636
fi->t_r.ptr_mfsbq_base_reg = MFSBQ_BASE_REGISTER_OFFSET + fi->g.tachyon_base;
4637
fi->t_r.ptr_mfsbq_len_reg = MFSBQ_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
4638
fi->t_r.ptr_mfsbq_prod_reg = MFSBQ_PRODUCER_REGISTER_OFFSET + fi->g.tachyon_base;
4639
fi->t_r.ptr_mfsbq_cons_reg = MFSBQ_CONSUMER_REGISTER_OFFSET + fi->g.tachyon_base;
4640
fi->t_r.ptr_mfsbuff_len_reg = MFS_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
4641
fi->t_r.ptr_sfsbq_base_reg = SFSBQ_BASE_REGISTER_OFFSET + fi->g.tachyon_base;
4642
fi->t_r.ptr_sfsbq_len_reg = SFSBQ_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
4643
fi->t_r.ptr_sfsbq_prod_reg = SFSBQ_PRODUCER_REGISTER_OFFSET + fi->g.tachyon_base;
4644
fi->t_r.ptr_sfsbq_cons_reg = SFSBQ_CONSUMER_REGISTER_OFFSET + fi->g.tachyon_base;
4645
fi->t_r.ptr_sfsbuff_len_reg = SFS_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
4646
fi->t_r.ptr_sest_base_reg = SEST_BASE_REGISTER_OFFSET + fi->g.tachyon_base;
4647
fi->t_r.ptr_sest_len_reg = SEST_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
4648
fi->t_r.ptr_scsibuff_len_reg = SCSI_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
4649
fi->t_r.ptr_tach_config_reg = TACHYON_CONFIG_REGISTER_OFFSET + fi->g.tachyon_base;
4650
fi->t_r.ptr_tach_control_reg = TACHYON_CONTROL_REGISTER_OFFSET + fi->g.tachyon_base;
4651
fi->t_r.ptr_tach_status_reg = TACHYON_STATUS_REGISTER_OFFSET + fi->g.tachyon_base;
4652
fi->t_r.ptr_tach_flush_oxid_reg = TACHYON_FLUSH_SEST_REGISTER_OFFSET + fi->g.tachyon_base;
4653
fi->t_r.ptr_fm_config_reg = FMGR_CONFIG_REGISTER_OFFSET + fi->g.tachyon_base;
4654
fi->t_r.ptr_fm_control_reg = FMGR_CONTROL_REGISTER_OFFSET + fi->g.tachyon_base;
4655
fi->t_r.ptr_fm_status_reg = FMGR_STATUS_REGISTER_OFFSET + fi->g.tachyon_base;
4656
fi->t_r.ptr_fm_tov_reg = FMGR_TIMER_REGISTER_OFFSET + fi->g.tachyon_base;
4657
fi->t_r.ptr_fm_wwn_hi_reg = FMGR_WWN_HI_REGISTER_OFFSET + fi->g.tachyon_base;
4658
fi->t_r.ptr_fm_wwn_low_reg = FMGR_WWN_LO_REGISTER_OFFSET + fi->g.tachyon_base;
4659
fi->t_r.ptr_fm_rx_al_pa_reg = FMGR_RCVD_ALPA_REGISTER_OFFSET + fi->g.tachyon_base;
4660
 
4661
LEAVE("initialize_register_pointers");
4662
return 1;
4663
}
4664
 
4665
 
4666
 
4667
/*
4668
 * Local variables:
4669
 *  compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -I/usr/src/linux/net/tcp -c iph5526.c"
4670
 *  version-control: t
4671
 *  kept-new-versions: 5
4672
 * End:
4673
 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.