iph5526.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:148k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /**********************************************************************
  2.  * iph5526.c: IP/SCSI driver for the Interphase 5526 PCI Fibre Channel
  3.  *   Card.
  4.  * Copyright (C) 1999 Vineet M Abraham <vmabraham@hotmail.com>
  5.  *
  6.  * This program is free software; you can redistribute it and/or 
  7.  * modify it under the terms of the GNU General Public License as 
  8.  * published by the Free Software Foundation; either version 2, or 
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful, but
  12.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * General Public License for more details.
  15.  *********************************************************************/
  16. /**********************************************************************
  17. Log:
  18. Vineet M Abraham
  19. 02.12.99 Support multiple cards.
  20. 03.15.99 Added Fabric support.
  21. 04.04.99 Added N_Port support.
  22. 04.15.99 Added SCSI support.
  23. 06.18.99 Added ABTS Protocol.
  24. 06.24.99 Fixed data corruption when multiple XFER_RDYs are received.
  25. 07.07.99 Can be loaded as part of the Kernel. Changed semaphores. Added
  26.          more checks before invalidating SEST entries.
  27. 07.08.99 Added Broadcast IP stuff and fixed an unicast timeout bug.
  28. ***********************************************************************/
  29. /* TODO:
  30. R_T_TOV set to 15msec in Loop topology. Need to be 100 msec.
  31.     SMP testing.
  32. Fix ADISC Tx before completing FLOGI. 
  33. */
  34. static const char *version =
  35.     "iph5526.c:v1.0 07.08.99 Vineet Abraham (vmabraham@hotmail.com)n";
  36. #include <linux/module.h>
  37. #include <linux/kernel.h>
  38. #include <linux/sched.h>
  39. #include <linux/errno.h>
  40. #include <linux/pci.h>
  41. #include <linux/init.h>
  42. #include <linux/mm.h>
  43. #include <linux/delay.h>
  44. #include <linux/skbuff.h>
  45. #include <linux/if_arp.h>
  46. #include <linux/timer.h>
  47. #include <linux/spinlock.h>
  48. #include <asm/system.h>
  49. #include <asm/io.h>
  50. #include <linux/netdevice.h>
  51. #include <linux/fcdevice.h> /* had the declarations for init_fcdev among others + includes if_fcdevice.h */
  52. #include <linux/blk.h>
  53. #include "../../scsi/sd.h"
  54. #include "../../scsi/scsi.h"
  55. #include "../../scsi/hosts.h"
  56. #include "../../fc4/fcp.h"
  57. /* driver specific header files */
  58. #include "tach.h"
  59. #include "tach_structs.h"
  60. #include "iph5526_ip.h"
  61. #include "iph5526_scsi.h"
  62. #include "iph5526_novram.c"
  63. #define RUN_AT(x) (jiffies + (x))
  64. #define DEBUG_5526_0 0
  65. #define DEBUG_5526_1 0
  66. #define DEBUG_5526_2 0
  67. #if DEBUG_5526_0
  68. #define DPRINTK(format, a...) {printk("%s: ", fi->name); 
  69.    printk(format, ##a); 
  70.    printk("n");}
  71. #define ENTER(x) {printk("%s: ", fi->name); 
  72.  printk("iph5526.c : entering %s()n", x);}
  73. #define LEAVE(x) {printk("%s: ", fi->name); 
  74.  printk("iph5526.c : leaving %s()n",x);}
  75. #else
  76. #define DPRINTK(format, a...) {}
  77. #define ENTER(x) {}
  78. #define LEAVE(x) {}
  79. #endif
  80. #if DEBUG_5526_1
  81. #define DPRINTK1(format, a...) {printk("%s: ", fi->name); 
  82.    printk(format, ##a); 
  83.    printk("n");}
  84. #else
  85. #define DPRINTK1(format, a...) {}
  86. #endif
  87. #if DEBUG_5526_2
  88. #define DPRINTK2(format, a...) {printk("%s: ", fi->name); 
  89.    printk(format, ##a); 
  90.    printk("n");}
  91. #else
  92. #define DPRINTK2(format, a...) {}
  93. #endif
  94. #define T_MSG(format, a...) {printk("%s: ", fi->name); 
  95.  printk(format, ##a);
  96.  printk("n");}
  97. #define ALIGNED_SFS_ADDR(addr) ((((unsigned long)(addr) + (SFS_BUFFER_SIZE - 1)) & ~(SFS_BUFFER_SIZE - 1)) - (unsigned long)(addr))
  98. #define ALIGNED_ADDR(addr, len) ((((unsigned long)(addr) + (len - 1)) & ~(len - 1)) - (unsigned long)(addr))
  99. static struct pci_device_id iph5526_pci_tbl[] __initdata = {
  100. { PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_5526, PCI_ANY_ID, PCI_ANY_ID, },
  101. { PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_55x6, PCI_ANY_ID, PCI_ANY_ID, },
  102. { } /* Terminating entry */
  103. };
  104. MODULE_DEVICE_TABLE(pci, iph5526_pci_tbl);
  105. MODULE_LICENSE("GPL");
  106. #define MAX_FC_CARDS 2
  107. static struct fc_info *fc[MAX_FC_CARDS+1];
  108. static unsigned int pci_irq_line;
  109. static struct {
  110. unsigned short vendor_id;
  111. unsigned short device_id;
  112. char *name;
  113. }
  114. clone_list[] __initdata  = {
  115. {PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_5526, "Interphase Fibre Channel HBA"},
  116. {PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_55x6, "Interphase Fibre Channel HBA"},
  117. {0,}
  118. };
  119. static void tachyon_interrupt(int irq, void *dev_id, struct pt_regs *regs);
  120. static void tachyon_interrupt_handler(int irq, void* dev_id, struct pt_regs* regs);
  121. static int initialize_register_pointers(struct fc_info *fi);
  122. void clean_up_memory(struct fc_info *fi);
  123. static int tachyon_init(struct fc_info *fi);
  124. static int build_queues(struct fc_info *fi);
  125. 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);
  126. static int get_free_header(struct fc_info *fi);
  127. static void build_EDB(struct fc_info *fi, char *data, u_short flags, u_short len);
  128. static int get_free_EDB(struct fc_info *fi);
  129. 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);
  130. static void write_to_tachyon_registers(struct fc_info *fi);
  131. static void reset_latch(struct fc_info *fi);
  132. static void reset_tachyon(struct fc_info *fi, u_int value);
  133. static void take_tachyon_offline(struct fc_info *fi);
  134. static void read_novram(struct fc_info *fi);
  135. static void reset_ichip(struct fc_info *fi);
  136. static void update_OCQ_indx(struct fc_info *fi);
  137. static void update_IMQ_indx(struct fc_info *fi, int count);
  138. static void update_SFSBQ_indx(struct fc_info *fi);
  139. static void update_MFSBQ_indx(struct fc_info *fi, int count);
  140. static void update_tachyon_header_indx(struct fc_info *fi);
  141. static void update_EDB_indx(struct fc_info *fi);
  142. static void handle_FM_interrupt(struct fc_info *fi);
  143. static void handle_MFS_interrupt(struct fc_info *fi);
  144. static void handle_OOO_interrupt(struct fc_info *fi);
  145. static void handle_SFS_interrupt(struct fc_info *fi);
  146. static void handle_OCI_interrupt(struct fc_info *fi);
  147. static void handle_SFS_BUF_WARN_interrupt(struct fc_info *fi);
  148. static void handle_MFS_BUF_WARN_interrupt(struct fc_info *fi);
  149. static void handle_IMQ_BUF_WARN_interrupt(struct fc_info *fi);
  150. static void handle_Unknown_Frame_interrupt(struct fc_info *fi);
  151. static void handle_Busied_Frame_interrupt(struct fc_info *fi);
  152. static void handle_Bad_SCSI_Frame_interrupt(struct fc_info *fi);
  153. static void handle_Inbound_SCSI_Status_interrupt(struct fc_info *fi);
  154. static void handle_Inbound_SCSI_Command_interrupt(struct fc_info *fi);
  155. static void completion_message_handler(struct fc_info *fi, u_int imq_int_type);
  156. static void fill_login_frame(struct fc_info *fi, u_int logi);
  157. 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);
  158. 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);
  159. static int validate_login(struct fc_info *fi, u_int *base_ptr);
  160. static void add_to_address_cache(struct fc_info *fi, u_int *base_ptr);
  161. static void remove_from_address_cache(struct fc_info *fi, u_int *data, u_int cmnd_code);
  162. static int node_logged_in_prev(struct fc_info *fi, u_int *buff_addr);
  163. static int sid_logged_in(struct fc_info *fi, u_int s_id);
  164. static struct fc_node_info *look_up_cache(struct fc_info *fi, char *data);
  165. static int display_cache(struct fc_info *fi);
  166. static void tx_logi(struct fc_info *fi, u_int logi, u_int d_id);
  167. static void tx_logi_acc(struct fc_info *fi, u_int logi, u_int d_id, u_short received_ox_id);
  168. static void tx_prli(struct fc_info *fi, u_int command_code, u_int d_id, u_short received_ox_id);
  169. static void tx_logo(struct fc_info *fi, u_int d_id, u_short received_ox_id);
  170. static void tx_adisc(struct fc_info *fi, u_int cmnd_code, u_int d_id, u_short received_ox_id);
  171. 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);
  172. static u_int plogi_ok(struct fc_info *fi, u_int *buff_addr, int size);
  173. static void tx_acc(struct fc_info *fi, u_int d_id, u_short received_ox_id);
  174. static void tx_name_server_req(struct fc_info *fi, u_int req);
  175. static void rscn_handler(struct fc_info *fi, u_int node_id);
  176. static void tx_scr(struct fc_info *fi);
  177. static void scr_timer(unsigned long data);
  178. static void explore_fabric(struct fc_info *fi, u_int *buff_addr);
  179. static void perform_adisc(struct fc_info *fi);
  180. static void local_port_discovery(struct fc_info *fi);
  181. static void add_to_ox_id_list(struct fc_info *fi, u_int transaction_id, u_int cmnd_code);
  182. static u_int remove_from_ox_id_list(struct fc_info *fi, u_short received_ox_id);
  183. static void add_display_cache_timer(struct fc_info *fi);
  184. /* Timers... */
  185. static void nos_ols_timer(unsigned long data);
  186. static void loop_timer(unsigned long data);
  187. static void fabric_explore_timer(unsigned long data);
  188. static void port_discovery_timer(unsigned long data);
  189. static void display_cache_timer(unsigned long data);
  190. /* SCSI Stuff */
  191. static int add_to_sest(struct fc_info *fi, Scsi_Cmnd *Cmnd, struct fc_node_info *ni);
  192. static struct fc_node_info *resolve_target(struct fc_info *fi, u_char target);
  193. static void update_FCP_CMND_indx(struct fc_info *fi);
  194. static int get_free_SDB(struct fc_info *fi);
  195. static void update_SDB_indx(struct fc_info *fi);
  196. static void mark_scsi_sid(struct fc_info *fi, u_int *buff_addr, u_char action);
  197. static void invalidate_SEST_entry(struct fc_info *fi, u_short received_ox_id);
  198. static int abort_exchange(struct fc_info *fi, u_short ox_id);
  199. static void flush_tachyon_cache(struct fc_info *fi, u_short ox_id);
  200. static int get_scsi_oxid(struct fc_info *fi);
  201. static void update_scsi_oxid(struct fc_info *fi);
  202. static Scsi_Host_Template driver_template = IPH5526_SCSI_FC;
  203. static void iph5526_timeout(struct net_device *dev);
  204. static int iph5526_probe_pci(struct net_device *dev);
  205. int __init iph5526_probe(struct net_device *dev)
  206. {
  207. if (pci_present() && (iph5526_probe_pci(dev) == 0))
  208. return 0;
  209.     return -ENODEV;
  210. }
  211. static int __init iph5526_probe_pci(struct net_device *dev)
  212. {
  213. #ifdef MODULE
  214. struct fc_info *fi = (struct fc_info *)dev->priv;
  215. #else
  216. struct fc_info *fi;
  217. static int count;
  218.  
  219. if(fc[count] != NULL) {
  220. if (dev == NULL) {
  221. dev = init_fcdev(NULL, 0);
  222. if (dev == NULL)
  223. return -ENOMEM;
  224. }
  225. fi = fc[count];
  226. #endif
  227. fi->dev = dev;
  228. dev->base_addr = fi->base_addr;
  229. dev->irq = fi->irq;
  230. if (dev->priv == NULL) 
  231. dev->priv = fi; 
  232. fcdev_init(dev);
  233. /* Assign ur MAC address.
  234.  */
  235. dev->dev_addr[0] = (fi->g.my_port_name_high & 0x0000FF00) >> 8;
  236. dev->dev_addr[1] = fi->g.my_port_name_high;
  237. dev->dev_addr[2] = (fi->g.my_port_name_low & 0xFF000000) >> 24;
  238. dev->dev_addr[3] = (fi->g.my_port_name_low & 0x00FF0000) >> 16;
  239. dev->dev_addr[4] = (fi->g.my_port_name_low & 0x0000FF00) >> 8;
  240. dev->dev_addr[5] = fi->g.my_port_name_low;
  241. #ifndef MODULE
  242. count++;
  243. }
  244. else
  245. return -ENODEV;
  246. #endif
  247. display_cache(fi);
  248. return 0;
  249. }
  250. static int __init fcdev_init(struct net_device *dev)
  251. {
  252. dev->open = iph5526_open;
  253. dev->stop = iph5526_close;
  254. dev->hard_start_xmit = iph5526_send_packet;
  255. dev->get_stats = iph5526_get_stats;
  256. dev->set_multicast_list = NULL;
  257. dev->change_mtu = iph5526_change_mtu; 
  258. dev->tx_timeout = iph5526_timeout;
  259. dev->watchdog_timeo = 5*HZ;
  260. #ifndef MODULE
  261. fc_setup(dev);
  262. #endif
  263. return 0;
  264. }
  265. /* initialize tachyon and take it OnLine */
  266. static int tachyon_init(struct fc_info *fi)
  267. {
  268. ENTER("tachyon_init");
  269. if (build_queues(fi) == 0) {
  270. T_MSG("build_queues() failed");
  271. return 0;
  272. }
  273. /* Retrieve your port/node name.
  274.  */
  275. read_novram(fi);
  276. reset_ichip(fi);
  277. reset_tachyon(fi, SOFTWARE_RESET);
  278. LEAVE("tachyon_init");
  279. return 1;
  280. }
  281. /* Build the 4 Qs - IMQ, OCQ, MFSBQ, SFSBQ */
  282. /* Lots of dma_pages needed as Tachyon DMAs almost everything into 
  283.  * host memory.
  284.  */
  285. static int build_queues(struct fc_info *fi)
  286. {
  287. int i,j;
  288. u_char *addr;
  289. ENTER("build_queues");
  290. /* Initializing Queue Variables.
  291.  */
  292. fi->q.ptr_host_ocq_cons_indx = NULL;
  293. fi->q.ptr_host_hpcq_cons_indx = NULL;
  294. fi->q.ptr_host_imq_prod_indx = NULL;
  295. fi->q.ptr_ocq_base = NULL;
  296. fi->q.ocq_len = 0;
  297. fi->q.ocq_end = 0;
  298. fi->q.ocq_prod_indx = 0;
  299. fi->q.ptr_imq_base = NULL;
  300. fi->q.imq_len = 0;
  301. fi->q.imq_end = 0;
  302. fi->q.imq_cons_indx = 0;
  303. fi->q.imq_prod_indx = 0;
  304. fi->q.ptr_mfsbq_base = NULL;
  305. fi->q.mfsbq_len = 0;
  306. fi->q.mfsbq_end = 0;
  307. fi->q.mfsbq_prod_indx = 0;
  308. fi->q.mfsbq_cons_indx = 0;
  309. fi->q.mfsbuff_len = 0;
  310. fi->q.mfsbuff_end = 0;
  311. fi->g.mfs_buffer_count = 0;
  312. fi->q.ptr_sfsbq_base = NULL;
  313. fi->q.sfsbq_len = 0;
  314. fi->q.sfsbq_end = 0;
  315. fi->q.sfsbq_prod_indx = 0;
  316. fi->q.sfsbq_cons_indx = 0;
  317. fi->q.sfsbuff_len = 0;
  318. fi->q.sfsbuff_end = 0;
  319. fi->q.sdb_indx = 0;
  320. fi->q.fcp_cmnd_indx = 0;
  321. fi->q.ptr_edb_base = NULL;
  322. fi->q.edb_buffer_indx = 0;
  323. fi->q.ptr_tachyon_header_base = NULL;
  324. fi->q.tachyon_header_indx = 0;
  325. fi->node_info_list = NULL;
  326. fi->ox_id_list = NULL;
  327. fi->g.loop_up = FALSE;
  328. fi->g.ptp_up = FALSE;
  329. fi->g.link_up = FALSE;
  330. fi->g.fabric_present = FALSE;
  331. fi->g.n_port_try = FALSE;
  332. fi->g.dont_init = FALSE;
  333. fi->g.nport_timer_set = FALSE;
  334. fi->g.lport_timer_set = FALSE;
  335. fi->g.no_of_targets = 0;
  336. fi->g.sem = 0;
  337. fi->g.perform_adisc = FALSE;
  338. fi->g.e_i = 0;
  339. /* build OCQ */
  340. if ( (fi->q.ptr_ocq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) {
  341. T_MSG("failed to get OCQ page");
  342. return 0;
  343. }
  344. /* set up the OCQ structures */
  345. for (i = 0; i < OCQ_LENGTH; i++)
  346. fi->q.ptr_odb[i] = fi->q.ptr_ocq_base + NO_OF_ENTRIES*i;
  347. /* build IMQ */
  348. if ( (fi->q.ptr_imq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) {
  349. T_MSG("failed to get IMQ page");
  350. return 0;
  351. }
  352. for (i = 0; i < IMQ_LENGTH; i++)
  353. fi->q.ptr_imqe[i] = fi->q.ptr_imq_base + NO_OF_ENTRIES*i;
  354. /* build MFSBQ */
  355. if ( (fi->q.ptr_mfsbq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) {
  356. T_MSG("failed to get MFSBQ page");
  357. return 0;
  358. }
  359. memset((char *)fi->q.ptr_mfsbq_base, 0, MFSBQ_LENGTH * 32);
  360. /* Allocate one huge chunk of memory... helps while reassembling
  361.  * frames.
  362.  */
  363. if ( (addr = (u_char *)__get_free_pages(GFP_KERNEL, 5) ) == 0) {
  364. T_MSG("failed to get MFSBQ page");
  365. return 0;
  366. }
  367. /* fill in addresses of empty buffers */
  368. for (i = 0; i < MFSBQ_LENGTH; i++) {
  369. for (j = 0; j < NO_OF_ENTRIES; j++) {
  370. *(fi->q.ptr_mfsbq_base + i*NO_OF_ENTRIES + j) = htonl(virt_to_bus(addr));
  371. addr += MFS_BUFFER_SIZE;
  372. }
  373. }
  374. /* The number of entries in each MFS buffer is 8. There are 8
  375.  * MFS buffers. That leaves us with 4096-256 bytes. We use them
  376.  * as temporary space for ELS frames. This is done to make sure that
  377.  * the addresses are aligned.
  378.  */
  379. fi->g.els_buffer[0] = fi->q.ptr_mfsbq_base + MFSBQ_LENGTH*NO_OF_ENTRIES;
  380. for (i = 1; i < MAX_PENDING_FRAMES; i++)
  381. fi->g.els_buffer[i] = fi->g.els_buffer[i-1] + 64;
  382. /* build SFSBQ */
  383. if ( (fi->q.ptr_sfsbq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) {
  384. T_MSG("failed to get SFSBQ page");
  385. return 0;
  386. }
  387. memset((char *)fi->q.ptr_sfsbq_base, 0, SFSBQ_LENGTH * 32);
  388. /* fill in addresses of empty buffers */
  389. for (i = 0; i < SFSBQ_LENGTH; i++)
  390. for (j = 0; j < NO_OF_ENTRIES; j++){
  391. addr = kmalloc(SFS_BUFFER_SIZE*2, GFP_KERNEL);
  392. if (addr == NULL){ 
  393. T_MSG("ptr_sfs_buffer : memory not allocated");
  394. return 0;
  395. }
  396. else {
  397. int offset = ALIGNED_SFS_ADDR(addr);
  398. memset((char *)addr, 0, SFS_BUFFER_SIZE);
  399. fi->q.ptr_sfs_buffers[i*NO_OF_ENTRIES +j] = (u_int *)addr;
  400. addr += offset;
  401. *(fi->q.ptr_sfsbq_base + i*NO_OF_ENTRIES + j) = htonl(virt_to_bus(addr));
  402. }
  403. }
  404. /* The number of entries in each SFS buffer is 8. There are 8
  405.  * MFS buffers. That leaves us with 4096-256 bytes. We use them
  406.  * as temporary space for ARP frames. This is done inorder to 
  407.  * support HW_Types of 0x1 and 0x6. 
  408.  */
  409. fi->g.arp_buffer = (char *)fi->q.ptr_sfsbq_base + SFSBQ_LENGTH*NO_OF_ENTRIES*4;
  410. /* build EDB */
  411. if ((fi->q.ptr_edb_base = (u_int *)__get_free_pages(GFP_KERNEL, 5) ) == 0) {
  412. T_MSG("failed to get EDB page");
  413. return 0;
  414. }
  415. for (i = 0; i < EDB_LEN; i++)
  416. fi->q.ptr_edb[i] = fi->q.ptr_edb_base + 2*i;
  417. /* build SEST */
  418. /* OX_IDs range from 0x0 - 0x4FFF.
  419.  */
  420. if ((fi->q.ptr_sest_base = (u_int *)__get_free_pages(GFP_KERNEL, 5)) == 0) {
  421. T_MSG("failed to get SEST page");
  422. return 0;
  423. }
  424. for (i = 0; i < SEST_LENGTH; i++)
  425. fi->q.ptr_sest[i] = fi->q.ptr_sest_base + NO_OF_ENTRIES*i;
  426. if ((fi->q.ptr_sdb_base = (u_int *)__get_free_pages(GFP_KERNEL, 5)) == 0) {
  427. T_MSG("failed to get SDB page");
  428. return 0;
  429. }
  430. for (i = 0 ; i < NO_OF_SDB_ENTRIES; i++)
  431. fi->q.ptr_sdb_slot[i] = fi->q.ptr_sdb_base + (SDB_SIZE/4)*i;
  432. if ((fi->q.ptr_fcp_cmnd_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) {
  433. T_MSG("failed to get FCP_CMND page");
  434. return 0;
  435. }
  436. for (i = 0; i < NO_OF_FCP_CMNDS; i++)
  437. fi->q.ptr_fcp_cmnd[i] = fi->q.ptr_fcp_cmnd_base + NO_OF_ENTRIES*i;
  438. /* Allocate space for Tachyon Header as well... 
  439.  */
  440. if ((fi->q.ptr_tachyon_header_base = (u_int *)__get_free_pages(GFP_KERNEL, 0) ) == 0) {
  441. T_MSG("failed to get tachyon_header page");
  442. return 0;
  443. }
  444. for (i = 0; i < NO_OF_TACH_HEADERS; i++) 
  445. fi->q.ptr_tachyon_header[i] = fi->q.ptr_tachyon_header_base + 16*i;
  446. /* Allocate memory for indices.
  447.  * Indices should be aligned on 32 byte boundries. 
  448.  */
  449. fi->q.host_ocq_cons_indx = kmalloc(2*32, GFP_KERNEL);
  450. if (fi->q.host_ocq_cons_indx == NULL){ 
  451. T_MSG("fi->q.host_ocq_cons_indx : memory not allocated");
  452. return 0;
  453. }
  454. fi->q.ptr_host_ocq_cons_indx = fi->q.host_ocq_cons_indx; 
  455. if ((u_long)(fi->q.host_ocq_cons_indx) % 32)
  456. fi->q.host_ocq_cons_indx++;
  457. fi->q.host_hpcq_cons_indx = kmalloc(2*32, GFP_KERNEL);
  458. if (fi->q.host_hpcq_cons_indx == NULL){ 
  459. T_MSG("fi->q.host_hpcq_cons_indx : memory not allocated");
  460. return 0;
  461. }
  462. fi->q.ptr_host_hpcq_cons_indx= fi->q.host_hpcq_cons_indx;
  463. if ((u_long)(fi->q.host_hpcq_cons_indx) % 32)
  464. fi->q.host_hpcq_cons_indx++;
  465. fi->q.host_imq_prod_indx = kmalloc(2*32, GFP_KERNEL);
  466. if (fi->q.host_imq_prod_indx == NULL){ 
  467. T_MSG("fi->q.host_imq_prod_indx : memory not allocated");
  468. return 0;
  469. }
  470. fi->q.ptr_host_imq_prod_indx = fi->q.host_imq_prod_indx;
  471. if ((u_long)(fi->q.host_imq_prod_indx) % 32)
  472. fi->q.host_imq_prod_indx++;
  473. LEAVE("build_queues");
  474. return 1;
  475. }
  476. static void write_to_tachyon_registers(struct fc_info *fi)
  477. {
  478. u_int bus_addr, bus_indx_addr, i;
  479. ENTER("write_to_tachyon_registers");
  480. /* Clear Queues each time Tachyon is reset */
  481. memset((char *)fi->q.ptr_ocq_base, 0, OCQ_LENGTH * 32);
  482. memset((char *)fi->q.ptr_imq_base, 0, IMQ_LENGTH * 32);
  483. memset((char *)fi->q.ptr_edb_base, 0, EDB_LEN * 8);
  484. memset((char *)fi->q.ptr_sest_base, 0, SEST_LENGTH * 32);
  485. memset((char *)fi->q.ptr_sdb_base, 0, NO_OF_SDB_ENTRIES * SDB_SIZE);
  486. memset((char *)fi->q.ptr_tachyon_header_base, 0xFF, NO_OF_TACH_HEADERS * TACH_HEADER_SIZE);
  487. for (i = 0; i < SEST_LENGTH; i++)
  488. fi->q.free_scsi_oxid[i] = OXID_AVAILABLE;
  489. for (i = 0; i < NO_OF_SDB_ENTRIES; i++)
  490. fi->q.sdb_slot_status[i] = SDB_FREE;
  491. take_tachyon_offline(fi);
  492. 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);
  493. /* Write OCQ registers */
  494. fi->q.ocq_prod_indx = 0;
  495. *(fi->q.host_ocq_cons_indx) = 0;
  496. /* The Tachyon needs to be passed the "real" address */
  497. bus_addr = virt_to_bus(fi->q.ptr_ocq_base);
  498. writel(bus_addr, fi->t_r.ptr_ocq_base_reg);
  499. writel(OCQ_LENGTH - 1, fi->t_r. ptr_ocq_len_reg);
  500. bus_indx_addr = virt_to_bus(fi->q.host_ocq_cons_indx);
  501. writel(bus_indx_addr, fi->t_r.ptr_ocq_cons_indx_reg);
  502. /* Write IMQ registers */
  503. fi->q.imq_cons_indx = 0;
  504. *(fi->q.host_imq_prod_indx) = 0;
  505. bus_addr = virt_to_bus(fi->q.ptr_imq_base);
  506. writel(bus_addr, fi->t_r.ptr_imq_base_reg);
  507. writel(IMQ_LENGTH - 1, fi->t_r.ptr_imq_len_reg);
  508. bus_indx_addr = virt_to_bus(fi->q.host_imq_prod_indx);
  509. writel(bus_indx_addr, fi->t_r.ptr_imq_prod_indx_reg);
  510. /* Write MFSBQ registers */
  511. fi->q.mfsbq_prod_indx = MFSBQ_LENGTH - 1;
  512. fi->q.mfsbuff_end = MFS_BUFFER_SIZE - 1;
  513. fi->q.mfsbq_cons_indx = 0;
  514. bus_addr = virt_to_bus(fi->q.ptr_mfsbq_base);
  515. writel(bus_addr, fi->t_r.ptr_mfsbq_base_reg);
  516. writel(MFSBQ_LENGTH - 1, fi->t_r.ptr_mfsbq_len_reg);
  517. writel(fi->q.mfsbuff_end, fi->t_r.ptr_mfsbuff_len_reg);
  518. /* Do this last as tachyon will prefetch the 
  519.  * first entry as soon as we write to it.
  520.  */
  521. writel(fi->q.mfsbq_prod_indx, fi->t_r.ptr_mfsbq_prod_reg);
  522. /* Write SFSBQ registers */
  523. fi->q.sfsbq_prod_indx = SFSBQ_LENGTH - 1;
  524. fi->q.sfsbuff_end = SFS_BUFFER_SIZE - 1;
  525. fi->q.sfsbq_cons_indx = 0;
  526. bus_addr = virt_to_bus(fi->q.ptr_sfsbq_base);
  527. writel(bus_addr, fi->t_r.ptr_sfsbq_base_reg);
  528. writel(SFSBQ_LENGTH - 1, fi->t_r.ptr_sfsbq_len_reg);
  529. writel(fi->q.sfsbuff_end, fi->t_r.ptr_sfsbuff_len_reg);
  530. /* Do this last as tachyon will prefetch the first 
  531.  * entry as soon as we write to it. 
  532.  */
  533. writel(fi->q.sfsbq_prod_indx, fi->t_r.ptr_sfsbq_prod_reg);
  534. /* Write SEST registers */
  535. bus_addr = virt_to_bus(fi->q.ptr_sest_base);
  536. writel(bus_addr, fi->t_r.ptr_sest_base_reg);
  537. writel(SEST_LENGTH - 1, fi->t_r.ptr_sest_len_reg);
  538. /* the last 2 bits _should_ be 1 */
  539. writel(SEST_BUFFER_SIZE - 1, fi->t_r.ptr_scsibuff_len_reg);
  540. /* write AL_TIME & E_D_TOV into the registers */
  541. writel(TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
  542. /* Tell Tachyon to pick a Soft Assigned AL_PA */
  543. writel(LOOP_INIT_SOFT_ADDRESS, fi->t_r.ptr_fm_config_reg);
  544. /* Read the WWN from EEPROM . But, for now we assign it here. */
  545. writel(WORLD_WIDE_NAME_LOW, fi->t_r.ptr_fm_wwn_low_reg);
  546. writel(WORLD_WIDE_NAME_HIGH, fi->t_r.ptr_fm_wwn_hi_reg);
  547. DPRINTK1("TACHYON initializing as L_Port...n");
  548. writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
  549. LEAVE("write_to_tachyon_registers");
  550. }
  551. static void tachyon_interrupt(int irq, void* dev_id, struct pt_regs* regs)
  552. {
  553. struct Scsi_Host *host = dev_id;
  554. struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
  555. struct fc_info *fi = hostdata->fi; 
  556. u_long flags;
  557. spin_lock_irqsave(&fi->fc_lock, flags);
  558. tachyon_interrupt_handler(irq, dev_id, regs);
  559. spin_unlock_irqrestore(&fi->fc_lock, flags);
  560. }
  561. static void tachyon_interrupt_handler(int irq, void* dev_id, struct pt_regs* regs)
  562. {
  563. struct Scsi_Host *host = dev_id;
  564. struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
  565. struct fc_info *fi = hostdata->fi; 
  566. u_int *ptr_imq_entry;
  567. u_int imq_int_type, current_IMQ_index = 0, prev_IMQ_index;
  568. int index, no_of_entries = 0;
  569. DPRINTK("n");
  570. ENTER("tachyon_interrupt");
  571. if (fi->q.host_imq_prod_indx != NULL) {
  572. current_IMQ_index =  ntohl(*(fi->q.host_imq_prod_indx));
  573. }
  574. else {
  575. /* _Should not_ happen */
  576. T_MSG("IMQ_indx NULL. DISABLING INTERRUPTS!!!n");
  577. writel(0x0, fi->i_r.ptr_ichip_hw_control_reg);
  578. }
  579. if (current_IMQ_index > fi->q.imq_cons_indx)
  580. no_of_entries = current_IMQ_index - fi->q.imq_cons_indx;
  581. else
  582. if (current_IMQ_index < fi->q.imq_cons_indx)
  583. no_of_entries = IMQ_LENGTH - (fi->q.imq_cons_indx - current_IMQ_index);
  584. if (no_of_entries == 0) {
  585. u_int ichip_status;
  586. ichip_status = readl(fi->i_r.ptr_ichip_hw_status_reg);
  587. if (ichip_status & 0x20) {
  588. /* Should _never_ happen. Might require a hard reset */
  589. T_MSG("Too bad... PCI Bus Error. Resetting (i)chip"); 
  590. reset_ichip(fi);
  591. T_MSG("DISABLING INTERRUPTS!!!n");
  592. writel(0x0, fi->i_r.ptr_ichip_hw_control_reg);
  593. }
  594. }
  595. prev_IMQ_index = current_IMQ_index;
  596. for (index = 0; index < no_of_entries; index++) {
  597. ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
  598. imq_int_type = ntohl(*ptr_imq_entry);
  599. completion_message_handler(fi, imq_int_type);
  600. if ((fi->g.link_up == FALSE) && ((imq_int_type == MFS_BUF_WARN) || (imq_int_type == SFS_BUF_WARN) || (imq_int_type == IMQ_BUF_WARN))) 
  601. break;
  602. update_IMQ_indx(fi, 1);
  603. /* Check for more entries */
  604. current_IMQ_index =  ntohl(*(fi->q.host_imq_prod_indx));
  605. if (current_IMQ_index != prev_IMQ_index) {
  606. no_of_entries++;
  607. prev_IMQ_index = current_IMQ_index;
  608. }
  609. } /*end of for loop*/
  610. return;
  611. LEAVE("tachyon_interrupt");
  612. }
  613. static void handle_SFS_BUF_WARN_interrupt(struct fc_info *fi)
  614. {
  615. int i;
  616. ENTER("handle_SFS_BUF_WARN_interrupt");
  617. if (fi->g.link_up == FALSE) {
  618. reset_tachyon(fi, SOFTWARE_RESET);
  619. return;
  620. }
  621. /* Free up all but one entry in the Q. 
  622.  */
  623. for (i = 0; i < ((SFSBQ_LENGTH - 1) * NO_OF_ENTRIES); i++) {
  624. handle_SFS_interrupt(fi);
  625. update_IMQ_indx(fi, 1);
  626. }
  627. LEAVE("handle_SFS_BUF_WARN_interrupt");
  628. }
  629. /* Untested_Code_Begin */ 
  630. static void handle_MFS_BUF_WARN_interrupt(struct fc_info *fi)
  631. {
  632. int i;
  633. ENTER("handle_MFS_BUF_WARN_interrupt");
  634. if (fi->g.link_up == FALSE) {
  635. reset_tachyon(fi, SOFTWARE_RESET);
  636. return;
  637. }
  638. /* FIXME: freeing up 8 entries. 
  639.  */
  640. for (i = 0; i < NO_OF_ENTRIES; i++) {
  641. handle_MFS_interrupt(fi);
  642. update_IMQ_indx(fi, 1);
  643. }
  644. LEAVE("handle_MFS_BUF_WARN_interrupt");
  645. }
  646. /*Untested_Code_End */
  647. static void handle_IMQ_BUF_WARN_interrupt(struct fc_info *fi)
  648. {
  649. u_int *ptr_imq_entry;
  650. u_int imq_int_type, current_IMQ_index = 0, temp_imq_cons_indx;
  651. int index, no_of_entries = 0;
  652. ENTER("handle_IMQ_BUF_WARN_interrupt");
  653. if (fi->g.link_up == FALSE) {
  654. reset_tachyon(fi, SOFTWARE_RESET);
  655. return;
  656. }
  657. current_IMQ_index =  ntohl(*(fi->q.host_imq_prod_indx));
  658. if (current_IMQ_index > fi->q.imq_cons_indx)
  659.   no_of_entries = current_IMQ_index - fi->q.imq_cons_indx;
  660. else
  661. if (current_IMQ_index < fi->q.imq_cons_indx)
  662. no_of_entries = IMQ_LENGTH - (fi->q.imq_cons_indx - current_IMQ_index);
  663. /* We dont want to look at the same IMQ entry again. 
  664.  */
  665. temp_imq_cons_indx = fi->q.imq_cons_indx + 1;
  666. if (no_of_entries != 0)
  667. no_of_entries -= 1;
  668. for (index = 0; index < no_of_entries; index++) {
  669. ptr_imq_entry = fi->q.ptr_imqe[temp_imq_cons_indx];
  670. imq_int_type = ntohl(*ptr_imq_entry);
  671. if (imq_int_type != IMQ_BUF_WARN)
  672. completion_message_handler(fi, imq_int_type);
  673. temp_imq_cons_indx++;
  674. if (temp_imq_cons_indx == IMQ_LENGTH)
  675. temp_imq_cons_indx = 0;
  676. } /*end of for loop*/
  677. if (no_of_entries != 0)
  678. update_IMQ_indx(fi, no_of_entries);
  679. LEAVE("handle_IMQ_BUF_WARN_interrupt");
  680. }
  681. static void completion_message_handler(struct fc_info *fi, u_int imq_int_type)
  682. {
  683. switch(imq_int_type) {
  684. case OUTBOUND_COMPLETION:
  685. DPRINTK("OUTBOUND_COMPLETION message received");
  686. break;
  687. case OUTBOUND_COMPLETION_I:
  688. DPRINTK("OUTBOUND_COMPLETION_I message received");
  689. handle_OCI_interrupt(fi);
  690. break;
  691. case OUT_HI_PRI_COMPLETION:
  692. DPRINTK("OUT_HI_PRI_COMPLETION message received");
  693. break;
  694. case OUT_HI_PRI_COMPLETION_I:
  695. DPRINTK("OUT_HI_PRI_COMPLETION_I message received");
  696. break;
  697. case INBOUND_MFS_COMPLETION:
  698. DPRINTK("INBOUND_MFS_COMPLETION message received");
  699. handle_MFS_interrupt(fi);
  700. break;
  701. case INBOUND_OOO_COMPLETION:
  702. DPRINTK("INBOUND_OOO_COMPLETION message received");
  703. handle_OOO_interrupt(fi);
  704. break;
  705. case INBOUND_SFS_COMPLETION:
  706. DPRINTK("INBOUND_SFS_COMPLETION message received");
  707. handle_SFS_interrupt(fi);
  708. break;
  709. case INBOUND_UNKNOWN_FRAME_I:
  710. DPRINTK("INBOUND_UNKNOWN_FRAME message received");
  711. handle_Unknown_Frame_interrupt(fi);
  712. break;
  713. case INBOUND_BUSIED_FRAME:
  714. DPRINTK("INBOUND_BUSIED_FRAME message received");
  715. handle_Busied_Frame_interrupt(fi);
  716. break;
  717. case FRAME_MGR_INTERRUPT:
  718. DPRINTK("FRAME_MGR_INTERRUPT message received");
  719. handle_FM_interrupt(fi);
  720. break;
  721. case READ_STATUS:
  722. DPRINTK("READ_STATUS message received");
  723. break;
  724. case SFS_BUF_WARN:
  725. DPRINTK("SFS_BUF_WARN message received");
  726. handle_SFS_BUF_WARN_interrupt(fi);
  727. break;
  728. case MFS_BUF_WARN:
  729. DPRINTK("MFS_BUF_WARN message received");
  730. handle_MFS_BUF_WARN_interrupt(fi);
  731. break;
  732. case IMQ_BUF_WARN:
  733. DPRINTK("IMQ_BUF_WARN message received");
  734. handle_IMQ_BUF_WARN_interrupt(fi);
  735. break;
  736. case INBOUND_C1_TIMEOUT:
  737. DPRINTK("INBOUND_C1_TIMEOUT message received");
  738. break;
  739. case BAD_SCSI_FRAME:
  740. DPRINTK("BAD_SCSI_FRAME message received");
  741. handle_Bad_SCSI_Frame_interrupt(fi);
  742. break;
  743. case INB_SCSI_STATUS_COMPLETION:
  744. DPRINTK("INB_SCSI_STATUS_COMPL message received");
  745. handle_Inbound_SCSI_Status_interrupt(fi);
  746. break;
  747. case INBOUND_SCSI_COMMAND:
  748. DPRINTK("INBOUND_SCSI_COMMAND message received");
  749. handle_Inbound_SCSI_Command_interrupt(fi);
  750. break;
  751. case INBOUND_SCSI_DATA_COMPLETION:
  752. DPRINTK("INBOUND_SCSI_DATA message received");
  753. /* Only for targets */
  754. break;
  755. default:
  756. T_MSG("DEFAULT message received, type = %x", imq_int_type);
  757. return;
  758. }
  759. reset_latch(fi);
  760. }
  761. static void handle_OCI_interrupt(struct fc_info *fi)
  762. {
  763. u_int *ptr_imq_entry;
  764. u_long transaction_id = 0;
  765. unsigned short status, seq_count, transmitted_ox_id;
  766. struct Scsi_Host *host = fi->host;
  767. struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
  768. Scsi_Cmnd *Cmnd;
  769. u_int tag;
  770. ENTER("handle_OCI_interrupt");
  771. ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
  772. transaction_id = ntohl(*(ptr_imq_entry + 1));
  773. status = ntohl(*(ptr_imq_entry + 2)) >> 16;
  774. seq_count = ntohl(*(ptr_imq_entry + 3));
  775. DPRINTK("transaction_id= %x", (u_int)transaction_id);
  776. tag = transaction_id & 0xFFFF0000;
  777. transmitted_ox_id = transaction_id;
  778. /* The INT could be either due to TIME_OUT | BAD_ALPA. 
  779.  * But we check only for TimeOuts. Bad AL_PA will 
  780.  * caught by FM_interrupt handler. 
  781.  */
  782. if ((status == OCM_TIMEOUT_OR_BAD_ALPA) && (!fi->g.port_discovery) && (!fi->g.perform_adisc)){
  783. DPRINTK("Frame TimeOut on OX_ID = %x", (u_int)transaction_id);
  784. /* Is it a SCSI frame that is timing out ? Not a very good check... 
  785.  */
  786. if ((transmitted_ox_id <= MAX_SCSI_OXID) && ((tag == FC_SCSI_BAD_TARGET) || (tag < 0x00FF0000))) {
  787. /* If it is a Bad AL_PA, we report it as BAD_TARGET.
  788.  * Else, we allow the command to time-out. A Link
  789.  * re-initialization could be taking place.
  790.  */
  791. if (tag == FC_SCSI_BAD_TARGET) {
  792. Cmnd = hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID];
  793. hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID] = NULL;
  794. if (Cmnd != NULL) {
  795. Cmnd->result = DID_BAD_TARGET << 16;
  796. (*Cmnd->scsi_done) (Cmnd);
  797. }
  798. else
  799. T_MSG("NULL Command out of handler!");
  800. } /* if Bad Target */
  801. else {
  802. u_char missing_target = tag >> 16;
  803. struct fc_node_info *q = fi->node_info_list;
  804. /* A Node that we thought was logged in has gone
  805.  * away. We are the optimistic kind and we keep
  806.  * hoping that our dear little Target will come back
  807.  * to us. For now we log him out.
  808.  */
  809. DPRINTK2("Missing Target = %d", missing_target);
  810. while (q != NULL) {
  811. if (q->target_id == missing_target) {
  812. T_MSG("Target %d Logged out", q->target_id);
  813. q->login = LOGIN_ATTEMPTED;
  814. if (fi->num_nodes > 0)
  815. fi->num_nodes--;
  816. tx_logi(fi, ELS_PLOGI, q->d_id);
  817. break;
  818. }
  819. else
  820. q = q->next;
  821. }
  822. }
  823. } /* End of SCSI frame timing out. */
  824. else {
  825. if (seq_count > 1) {
  826. /* An IP frame was transmitted to a Bad AL_PA. Free up
  827.    * the skb used.
  828.    */
  829. dev_kfree_skb_irq((struct sk_buff *)(bus_to_virt(transaction_id)));
  830. netif_wake_queue(fi->dev);
  831. }
  832. } /* End of IP frame timing out. */
  833. } /* End of frame timing out. */
  834. else {
  835. /* Frame was transmitted successfully. Check if it was an ELS
  836.  * frame or an IP frame or a Bad_Target_Notification frame (in
  837.  * case of a ptp_link). Ugly!
  838.  */
  839. if ((status == 0) && (seq_count == 0)) {
  840. u_int tag = transaction_id & 0xFFFF0000;
  841. /* Continue with port discovery after an ELS is successfully 
  842.  * transmitted. (status == 0). 
  843.  */
  844. DPRINTK("tag = %x", tag);
  845. switch(tag) {
  846. case ELS_FLOGI:
  847. /* Letz use the Name Server instead */
  848. fi->g.explore_fabric = TRUE;
  849. fi->g.port_discovery = FALSE;
  850. fi->g.alpa_list_index = MAX_NODES;
  851. add_to_ox_id_list(fi, transaction_id, tag);
  852. break;
  853. case ELS_PLOGI:
  854. if (fi->g.fabric_present && (fi->g.name_server == FALSE))
  855. add_to_ox_id_list(fi,transaction_id,ELS_NS_PLOGI);
  856. else
  857. add_to_ox_id_list(fi, transaction_id, tag);
  858. break;
  859. case FC_SCSI_BAD_TARGET:
  860. Cmnd = hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID];
  861. hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID] = NULL;
  862. if (Cmnd != NULL) {
  863. Cmnd->result = DID_BAD_TARGET << 16;
  864. (*Cmnd->scsi_done) (Cmnd);
  865. }
  866. else
  867. T_MSG("NULL Command out of handler!");
  868. break;
  869. default:
  870. add_to_ox_id_list(fi, transaction_id, tag);
  871. }
  872. if (fi->g.alpa_list_index >= MAX_NODES) {
  873. if (fi->g.port_discovery == TRUE) {
  874. fi->g.port_discovery = FALSE;
  875. add_display_cache_timer(fi);
  876. }
  877. fi->g.alpa_list_index = MAX_NODES;
  878. }
  879. if (fi->g.port_discovery == TRUE) 
  880. local_port_discovery(fi);
  881. }
  882. else {
  883. /* An IP frame has been successfully transmitted.
  884.  * Free the skb that was used for this IP frame.
  885.  */
  886. if ((status == 0) && (seq_count > 1)) {
  887. dev_kfree_skb_irq((struct sk_buff *)(bus_to_virt(transaction_id)));
  888. netif_wake_queue(fi->dev);
  889. }
  890. }
  891. }
  892. LEAVE("handle_OCI_interrupt");
  893. }
  894. /* Right now we discard OOO frames */
  895. static void handle_OOO_interrupt(struct fc_info *fi)
  896. {
  897. u_int *ptr_imq_entry;
  898. int queue_indx, offset, payload_size;
  899. int no_of_buffers = 1; /* header is in a separate buffer */
  900. ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
  901. offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
  902. queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
  903. queue_indx = queue_indx >> 16;
  904. payload_size = ntohl(*(ptr_imq_entry + 2)) - TACHYON_HEADER_LEN;
  905. /* Calculate total number of buffers */
  906. no_of_buffers += payload_size / MFS_BUFFER_SIZE;
  907. if (payload_size % MFS_BUFFER_SIZE)
  908. no_of_buffers++;
  909. /* provide Tachyon will another set of buffers */
  910. fi->g.mfs_buffer_count += no_of_buffers;
  911. if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) {
  912. int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES;
  913. fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count;
  914. update_MFSBQ_indx(fi, count);
  915. }
  916. }
  917. static void handle_MFS_interrupt(struct fc_info *fi)
  918. {
  919. u_int *ptr_imq_entry, *buff_addr;
  920. u_int type_of_frame, s_id;
  921. int queue_indx, offset, payload_size, starting_indx, starting_offset;
  922. u_short received_ox_id;
  923. int no_of_buffers = 1; /* header is in a separate buffer */
  924. struct sk_buff *skb;
  925. int wrap_around = FALSE, no_of_wrap_buffs = NO_OF_ENTRIES - 1;
  926. ENTER("handle_MFS_interrupt");
  927. ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
  928. offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
  929. queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
  930. queue_indx = queue_indx >> 16;
  931. DPRINTK("queue_indx = %d, offset  = %dn", queue_indx, offset);
  932. payload_size = ntohl(*(ptr_imq_entry + 2)) - TACHYON_HEADER_LEN;
  933. DPRINTK("payload_size = %d", payload_size);
  934. /* Calculate total number of buffers */
  935. no_of_buffers += payload_size / MFS_BUFFER_SIZE;
  936. if (payload_size % MFS_BUFFER_SIZE)
  937. no_of_buffers++;
  938. DPRINTK("no_of_buffers = %d", no_of_buffers);
  939. if ((no_of_buffers - 1) <= offset) {
  940. starting_offset = offset - (no_of_buffers - 1);
  941. starting_indx = queue_indx;
  942. }
  943. else {
  944. int temp = no_of_buffers - (offset + 1);
  945. int no_of_queues = temp / NO_OF_ENTRIES;
  946. starting_offset = temp % NO_OF_ENTRIES;
  947. if (starting_offset != 0) {
  948. no_of_wrap_buffs = starting_offset - 1; //exclude header
  949. starting_offset = NO_OF_ENTRIES - starting_offset;
  950. no_of_queues++;
  951. }
  952. starting_indx = queue_indx - no_of_queues;
  953. if (starting_indx < 0) {
  954. no_of_wrap_buffs -= (starting_indx + 1) * NO_OF_ENTRIES; 
  955. starting_indx = MFSBQ_LENGTH + starting_indx;
  956. wrap_around = TRUE;
  957. }
  958. }
  959. DPRINTK("starting_indx = %d, starting offset = %d no_of_wrap_buffs = %dn", starting_indx, starting_offset, no_of_wrap_buffs);
  960. /* Get Tachyon Header from first buffer */
  961. buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_mfsbq_base + starting_indx*NO_OF_ENTRIES + starting_offset)));
  962. /* extract Type of Frame */
  963. type_of_frame = (u_int)ntohl(*(buff_addr + 4)) & 0xFF000000;
  964. s_id = (u_int)ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
  965. received_ox_id = ntohl(*(buff_addr + 6)) >> 16;
  966. buff_addr += MFS_BUFFER_SIZE/4;
  967. DPRINTK("type_of_frame = %x, s_id = %x, ox_id = %x", type_of_frame, s_id, received_ox_id);
  968.   switch(type_of_frame) {
  969.   case TYPE_LLC_SNAP:
  970. skb = dev_alloc_skb(payload_size);
  971. if (skb == NULL) {
  972. printk(KERN_NOTICE "%s: In handle_MFS_interrupt() Memory squeeze, dropping packet.n", fi->name);
  973. fi->fc_stats.rx_dropped++;
  974. fi->g.mfs_buffer_count += no_of_buffers;
  975. if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) {
  976. int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES;
  977. fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count;
  978. update_MFSBQ_indx(fi, count);
  979. }
  980. return;
  981. }
  982. if (wrap_around) {
  983. int wrap_size = no_of_wrap_buffs * MFS_BUFFER_SIZE;
  984. int tail_size = payload_size - wrap_size;
  985. DPRINTK("wrap_size = %d, tail_size = %dn", wrap_size, tail_size);
  986. if (no_of_wrap_buffs) 
  987. memcpy(skb_put(skb, wrap_size), buff_addr, wrap_size);
  988. buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_mfsbq_base)));
  989. memcpy(skb_put(skb, tail_size), buff_addr, tail_size);
  990. }
  991. else
  992. memcpy(skb_put(skb, payload_size), buff_addr, payload_size);
  993. rx_net_mfs_packet(fi, skb);
  994.    break;
  995. default:
  996. T_MSG("Unknown Frame Type received. Type = %x", type_of_frame);
  997. }
  998. /* provide Tachyon will another set of buffers */
  999. fi->g.mfs_buffer_count += no_of_buffers;
  1000. if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) {
  1001. int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES;
  1002. fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count;
  1003. update_MFSBQ_indx(fi, count);
  1004. }
  1005. LEAVE("handle_MFS_interrupt");
  1006. }
  1007. static void handle_Unknown_Frame_interrupt(struct fc_info *fi)
  1008. {
  1009. u_int *ptr_imq_entry;
  1010. int queue_indx, offset;
  1011. ENTER("handle_Unknown_Frame_interrupt");
  1012. ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
  1013. offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
  1014. queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
  1015. queue_indx = queue_indx >> 16;
  1016. /* We discard the "unknown" frame */
  1017. /* provide Tachyon will another set of buffers */
  1018. if (offset == (NO_OF_ENTRIES - 1))
  1019. update_SFSBQ_indx(fi);
  1020. LEAVE("handle_Unknown_Frame_interrupt");
  1021. }
  1022. static void handle_Busied_Frame_interrupt(struct fc_info *fi)
  1023. {
  1024. u_int *ptr_imq_entry;
  1025. int queue_indx, offset;
  1026. ENTER("handle_Busied_Frame_interrupt");
  1027. ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
  1028. offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
  1029. queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
  1030. queue_indx = queue_indx >> 16;
  1031. /* We discard the "busied" frame */
  1032. /* provide Tachyon will another set of buffers */
  1033. if (offset == (NO_OF_ENTRIES - 1))
  1034. update_SFSBQ_indx(fi);
  1035. LEAVE("handle_Busied_Frame_interrupt");
  1036. }
  1037. static void handle_Bad_SCSI_Frame_interrupt(struct fc_info *fi)
  1038. {
  1039. u_int *ptr_imq_entry, *buff_addr, *tach_header, *ptr_edb;
  1040. u_int s_id, rctl, frame_class, burst_len, transfered_len, len = 0;
  1041. int queue_indx, offset, payload_size, i;
  1042. u_short ox_id, rx_id, x_id, mtu = 512;
  1043. u_char target_id = 0xFF;
  1044. ENTER("handle_Bad_SCSI_Frame_interrupt");
  1045. ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
  1046. offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
  1047. queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
  1048. queue_indx = queue_indx >> 16;
  1049. payload_size = ntohl(*(ptr_imq_entry + 2));
  1050. buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset)));
  1051. rctl = ntohl(*(buff_addr + 2)) & 0xFF000000;
  1052. s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
  1053. ox_id = ntohl(*(buff_addr + 6)) >> 16;
  1054. rx_id = ntohl(*(buff_addr + 6));
  1055. x_id = ox_id & MAX_SCSI_XID;
  1056. /* Any frame that comes in with OX_ID that matches an OX_ID 
  1057.  * that has been allocated for SCSI, will be called a Bad
  1058.  * SCSI frame if the Exchange is not valid any more.
  1059.  *
  1060.  * We will also get a Bad SCSI frame interrupt if we receive
  1061.  * a XFER_RDY with offset != 0. Tachyon washes its hands off
  1062.  * this Exchange. We have to take care of ourselves. Grrr...
  1063.  */
  1064. if (rctl == DATA_DESCRIPTOR) {
  1065. struct fc_node_info *q = fi->node_info_list;
  1066. while (q != NULL) {
  1067. if (q->d_id == s_id) {
  1068. target_id = q->target_id;
  1069. mtu = q->mtu;
  1070. break;
  1071. }
  1072. else
  1073. q = q->next;
  1074. }
  1075. frame_class = target_id;
  1076. transfered_len = ntohl(*(buff_addr + 8));
  1077. burst_len = ntohl(*(buff_addr + 9));
  1078. build_ODB(fi, fi->g.seq_id, s_id, burst_len, 0, mtu, ox_id, rx_id, 0, 0, frame_class << 16);
  1079. /* Update the SEQ_ID and Relative Offset in the 
  1080.  * Tachyon Header Structure.
  1081.  */
  1082. tach_header = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 5)));
  1083. *(tach_header + 5) = htonl(fi->g.seq_id << 24);
  1084. *(tach_header + 7) = htonl(transfered_len);
  1085. fi->g.odb.hdr_addr = *(fi->q.ptr_sest[x_id] + 5);
  1086. /* Invalidate the EDBs used 
  1087.  */
  1088. ptr_edb = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 7)));
  1089. for (i = 0; i < EDB_LEN; i++)
  1090. if (fi->q.ptr_edb[i] == ptr_edb)
  1091. break;
  1092. ptr_edb--;
  1093. if (i < EDB_LEN) {
  1094. int j;
  1095. do {
  1096. ptr_edb += 2;
  1097. len += (htonl(*ptr_edb) & 0xFFFF);
  1098. j = i;
  1099. fi->q.free_edb_list[i++] = EDB_FREE;
  1100. if (i == EDB_LEN) {
  1101. i = 0;
  1102. ptr_edb = fi->q.ptr_edb_base - 1;
  1103. }
  1104. } while (len < transfered_len);
  1105. if (len > transfered_len) {
  1106. ptr_edb--;
  1107. fi->q.free_edb_list[j] = EDB_BUSY;
  1108. }
  1109. else
  1110. ptr_edb++;
  1111. }
  1112. else {
  1113. T_MSG("EDB not found while freeing");
  1114. if (offset == (NO_OF_ENTRIES - 1))
  1115. update_SFSBQ_indx(fi);
  1116. return;
  1117. }
  1118. /* Update the EDB pointer in the ODB.
  1119.  */
  1120. fi->g.odb.edb_addr = htonl(virt_to_bus(ptr_edb));
  1121. memcpy(fi->q.ptr_odb[fi->q.ocq_prod_indx], &(fi->g.odb), sizeof(ODB));
  1122. /* Update the EDB pointer in the SEST entry. We might need
  1123.  * this if get another XFER_RDY for the same Exchange.
  1124.  */
  1125. *(fi->q.ptr_sest[x_id] + 7) = htonl(virt_to_bus(ptr_edb));
  1126. update_OCQ_indx(fi);
  1127. if (fi->g.seq_id == MAX_SEQ_ID)
  1128. fi->g.seq_id = 0;
  1129. else
  1130. fi->g.seq_id++;
  1131. }
  1132. else 
  1133. /* Could be a BA_ACC or a BA_RJT.
  1134.  */
  1135. if (rctl == RCTL_BASIC_ACC) {
  1136. u_int bls_type = remove_from_ox_id_list(fi, ox_id);
  1137. DPRINTK1("BA_ACC received from S_ID 0x%x with OX_ID = %x in response to %x", s_id, ox_id, bls_type);
  1138. if (bls_type == RCTL_BASIC_ABTS) {
  1139. u_int STE_bit;
  1140. /* Invalidate resources for that Exchange.
  1141.  */
  1142. STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
  1143. if (STE_bit & SEST_V) {
  1144. *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
  1145. invalidate_SEST_entry(fi, ox_id);
  1146. }
  1147. }
  1148. }
  1149. else
  1150. if (rctl == RCTL_BASIC_RJT) {
  1151. u_int bls_type = remove_from_ox_id_list(fi, ox_id);
  1152. DPRINTK1("BA_RJT received from S_ID 0x%x with OX_ID = %x in response to %x", s_id, ox_id, bls_type);
  1153. if (bls_type == RCTL_BASIC_ABTS) {
  1154. u_int STE_bit;
  1155. /* Invalidate resources for that Exchange.
  1156.  */
  1157. STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
  1158. if (STE_bit & SEST_V) {
  1159. *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
  1160. invalidate_SEST_entry(fi, ox_id);
  1161. }
  1162. }
  1163. }
  1164. else
  1165. DPRINTK1("Frame with R_CTL = %x received from S_ID 0x%x with OX_ID %x", rctl, s_id, ox_id);
  1166. /* Else, discard the "Bad" SCSI frame.
  1167.  */
  1168. /* provide Tachyon will another set of buffers 
  1169.  */
  1170. if (offset == (NO_OF_ENTRIES - 1))
  1171. update_SFSBQ_indx(fi);
  1172. LEAVE("handle_Bad_SCSI_Frame_interrupt");
  1173. }
  1174. static void handle_Inbound_SCSI_Status_interrupt(struct fc_info *fi)
  1175. {
  1176. struct Scsi_Host *host = fi->host;
  1177. struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
  1178. u_int *ptr_imq_entry, *buff_addr, *ptr_rsp_info, *ptr_sense_info = NULL;
  1179. int queue_indx, offset, payload_size;
  1180. u_short received_ox_id, x_id;
  1181. Scsi_Cmnd *Cmnd;
  1182. u_int fcp_status, fcp_rsp_info_len = 0, fcp_sense_info_len = 0, s_id;
  1183. ENTER("handle_SCSI_status_interrupt");
  1184. ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
  1185. offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
  1186. queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
  1187. queue_indx = queue_indx >> 16;
  1188. buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset)));
  1189. payload_size = ntohl(*(ptr_imq_entry + 2));
  1190. received_ox_id = ntohl(*(buff_addr + 6)) >> 16;
  1191. buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset)));
  1192. fcp_status = ntohl(*(buff_addr + 10));
  1193. ptr_rsp_info = buff_addr + 14;
  1194. if (fcp_status & FCP_STATUS_RSP_LEN)
  1195. fcp_rsp_info_len = ntohl(*(buff_addr + 13));
  1196. if (fcp_status & FCP_STATUS_SENSE_LEN) {
  1197. ptr_sense_info = ptr_rsp_info + fcp_rsp_info_len / 4;
  1198. fcp_sense_info_len = ntohl(*(buff_addr + 12));
  1199. DPRINTK("sense_info = %x", (u_int)ntohl(*ptr_sense_info));
  1200. }
  1201. DPRINTK("fcp_status = %x, fcp_rsp_len = %x", fcp_status, fcp_rsp_info_len);
  1202. x_id = received_ox_id & MAX_SCSI_XID;
  1203. Cmnd = hostdata->cmnd_handler[x_id];
  1204. hostdata->cmnd_handler[x_id] = NULL;
  1205. if (Cmnd != NULL) {
  1206. memset(Cmnd->sense_buffer, 0, sizeof(Cmnd->sense_buffer));
  1207. /* Check if there is a Sense field */
  1208. if (fcp_status & FCP_STATUS_SENSE_LEN) {
  1209. int size = sizeof(Cmnd->sense_buffer);
  1210. if (fcp_sense_info_len < size)
  1211. size = fcp_sense_info_len;
  1212. memcpy(Cmnd->sense_buffer, (char *)ptr_sense_info, size);
  1213. }
  1214. Cmnd->result = fcp_status & FCP_STATUS_MASK;
  1215. (*Cmnd->scsi_done) (Cmnd);
  1216. }
  1217. else
  1218. T_MSG("NULL Command out of handler!");
  1219. invalidate_SEST_entry(fi, received_ox_id);
  1220. s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
  1221. fi->q.free_scsi_oxid[x_id] = OXID_AVAILABLE;
  1222. /* provide Tachyon will another set of buffers */
  1223. if (offset == (NO_OF_ENTRIES - 1))
  1224. update_SFSBQ_indx(fi);
  1225. LEAVE("handle_SCSI_status_interrupt");
  1226. }
  1227. static void invalidate_SEST_entry(struct fc_info *fi, u_short received_ox_id)
  1228. {
  1229. u_short x_id = received_ox_id & MAX_SCSI_XID;
  1230. /* Invalidate SEST entry if it is an OutBound SEST Entry 
  1231.  */
  1232. if (!(received_ox_id & SCSI_READ_BIT)) {
  1233. u_int *ptr_tach_header, *ptr_edb;
  1234. u_short temp_ox_id = NOT_SCSI_XID;
  1235. int i;
  1236. *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
  1237. /* Invalidate the Tachyon Header structure 
  1238.  */
  1239. ptr_tach_header = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 5)));
  1240. for (i = 0; i < NO_OF_TACH_HEADERS; i++) 
  1241. if(fi->q.ptr_tachyon_header[i] == ptr_tach_header)
  1242. break;
  1243. if (i < NO_OF_TACH_HEADERS) 
  1244. memset(ptr_tach_header, 0xFF, 32);
  1245. else
  1246. T_MSG("Tachyon Header not found while freeing in invalidate_SEST_entry()");
  1247. /* Invalidate the EDB used 
  1248.  */
  1249. ptr_edb = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 7)));
  1250. for (i = 0; i < EDB_LEN; i++)
  1251. if (fi->q.ptr_edb[i] == ptr_edb)
  1252. break;
  1253. ptr_edb--;
  1254. if (i < EDB_LEN) {
  1255. do {
  1256. ptr_edb += 2;
  1257. fi->q.free_edb_list[i++] = EDB_FREE;
  1258. if (i == EDB_LEN) {
  1259. i = 0;
  1260. ptr_edb = fi->q.ptr_edb_base - 1;
  1261. }
  1262. } while ((htonl(*ptr_edb) & 0x80000000) != 0x80000000);
  1263. }
  1264. else
  1265. T_MSG("EDB not found while freeing in invalidate_SEST_entry()");
  1266. /* Search for its other header structure and destroy it! 
  1267.  */
  1268. if ((ptr_tach_header + 16) < (fi->q.ptr_tachyon_header_base + (MY_PAGE_SIZE/4)))
  1269. ptr_tach_header += 16;
  1270. else
  1271. ptr_tach_header = fi->q.ptr_tachyon_header_base;
  1272. while (temp_ox_id != x_id) {
  1273. temp_ox_id = ntohl(*(ptr_tach_header + 6)) >> 16;
  1274. if (temp_ox_id == x_id) {
  1275. /* Paranoid checking...
  1276.  */
  1277. for (i = 0; i < NO_OF_TACH_HEADERS; i++) 
  1278. if(fi->q.ptr_tachyon_header[i] == ptr_tach_header)
  1279. break;
  1280. if (i < NO_OF_TACH_HEADERS)
  1281. memset(ptr_tach_header, 0xFF, 32);
  1282. else
  1283. T_MSG("Tachyon Header not found while freeing in invalidate_SEST_entry()");
  1284. break;
  1285. }
  1286. else {
  1287. if ((ptr_tach_header + 16) < (fi->q.ptr_tachyon_header_base + (MY_PAGE_SIZE/4)))
  1288. ptr_tach_header += 16;
  1289. else
  1290. ptr_tach_header = fi->q.ptr_tachyon_header_base;
  1291. }
  1292. }
  1293. }
  1294. else {
  1295. u_short sdb_table_indx;
  1296. /* An Inbound Command has completed or needs to be Aborted. 
  1297.    * Clear up the SDB buffers.
  1298.  */
  1299. sdb_table_indx = *(fi->q.ptr_sest[x_id] + 5);
  1300. fi->q.sdb_slot_status[sdb_table_indx] = SDB_FREE;
  1301. }
  1302. }
  1303. static void handle_Inbound_SCSI_Command_interrupt(struct fc_info *fi)
  1304. {
  1305. u_int *ptr_imq_entry;
  1306. int queue_indx, offset;
  1307. ENTER("handle_Inbound_SCSI_Command_interrupt");
  1308. ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
  1309. offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
  1310. queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
  1311. queue_indx = queue_indx >> 16;
  1312. /* We discard the SCSI frame as we shouldn't be receiving
  1313.  * a SCSI Command in the first place 
  1314.  */
  1315. /* provide Tachyon will another set of buffers */
  1316. if (offset == (NO_OF_ENTRIES - 1))
  1317. update_SFSBQ_indx(fi);
  1318. LEAVE("handle_Inbound_SCSI_Command_interrupt");
  1319. }
  1320. static void handle_SFS_interrupt(struct fc_info *fi)
  1321. {
  1322. u_int *ptr_imq_entry, *buff_addr;
  1323. u_int class_of_frame, type_of_frame, s_id, els_type = 0, rctl;
  1324. int queue_indx, offset, payload_size, login_state;
  1325. u_short received_ox_id, fs_cmnd_code;
  1326. ENTER("handle_SFS_interrupt");
  1327. ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
  1328. offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
  1329. queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
  1330. queue_indx = queue_indx >> 16;
  1331. DPRINTK("queue_indx = %d, offset  = %dn", queue_indx, offset);
  1332. payload_size = ntohl(*(ptr_imq_entry + 2));
  1333. DPRINTK("payload_size = %d", payload_size);
  1334. buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset)));
  1335. /* extract Type of Frame */
  1336. type_of_frame = ntohl(*(buff_addr + 4)) & 0xFF000000;
  1337. s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
  1338. received_ox_id = ntohl(*(buff_addr + 6)) >> 16;
  1339. switch(type_of_frame) {
  1340. case TYPE_BLS:
  1341. rctl = ntohl(*(buff_addr + 2)) & 0xFF000000;
  1342. switch(rctl) {
  1343. case RCTL_BASIC_ABTS:
  1344. /* As an Initiator, we should never be receiving 
  1345.  * this.
  1346.    */
  1347. DPRINTK1("ABTS received from S_ID 0x%x with OX_ID = %x", s_id, received_ox_id);
  1348. break;
  1349. }
  1350. break;
  1351. case TYPE_ELS:
  1352. class_of_frame = ntohl(*(buff_addr + 8));
  1353. login_state = sid_logged_in(fi, s_id);
  1354. switch(class_of_frame & 0xFF000000) {
  1355. case ELS_PLOGI:
  1356. if (s_id != fi->g.my_id) {
  1357. u_int ret_code;
  1358. DPRINTK1("PLOGI received from D_ID 0x%x with 0X_ID = %x", s_id, received_ox_id);
  1359. if ((ret_code = plogi_ok(fi, buff_addr, payload_size)) == 0){
  1360. tx_logi_acc(fi, ELS_ACC, s_id, received_ox_id);
  1361. add_to_address_cache(fi, buff_addr);
  1362. }
  1363. else {
  1364. u_short cmnd_code = ret_code >> 16;
  1365. u_short expln_code =  ret_code;
  1366. tx_ls_rjt(fi, s_id, received_ox_id, cmnd_code, expln_code);
  1367. }
  1368. }
  1369. break;
  1370. case ELS_ACC:
  1371. els_type = remove_from_ox_id_list(fi, received_ox_id);
  1372. DPRINTK1("ELS_ACC received from D_ID 0x%x in response to ELS %x", s_id, els_type);
  1373. switch(els_type) {
  1374. case ELS_PLOGI:
  1375. add_to_address_cache(fi, buff_addr);
  1376. tx_prli(fi, ELS_PRLI, s_id, OX_ID_FIRST_SEQUENCE);
  1377. break;
  1378. case ELS_FLOGI:
  1379. add_to_address_cache(fi, buff_addr);
  1380. fi->g.my_id = ntohl(*(buff_addr + 2)) & 0x00FFFFFF;
  1381. fi->g.fabric_present = TRUE;
  1382. fi->g.my_ddaa = fi->g.my_id & 0xFFFF00;
  1383. /* Login to the Name Server 
  1384.  */
  1385. tx_logi(fi, ELS_PLOGI, DIRECTORY_SERVER); 
  1386. break;
  1387. case ELS_NS_PLOGI:
  1388. fi->g.name_server = TRUE;
  1389. add_to_address_cache(fi, buff_addr);
  1390. tx_name_server_req(fi, FCS_RFC_4);
  1391. tx_scr(fi);
  1392. /* Some devices have a delay before 
  1393.  * registering with the Name Server 
  1394.  */
  1395. udelay(500); 
  1396. tx_name_server_req(fi, FCS_GP_ID4);
  1397. break;
  1398. case ELS_PRLI:
  1399. mark_scsi_sid(fi, buff_addr, ADD_ENTRY);
  1400. break;
  1401. case ELS_ADISC:
  1402. if (!(validate_login(fi, buff_addr)))
  1403. tx_logo(fi, s_id, OX_ID_FIRST_SEQUENCE);
  1404. break;
  1405. }
  1406. break;
  1407. case ELS_PDISC:
  1408. DPRINTK1("ELS_PDISC received from D_ID 0x%x", s_id);
  1409. tx_logo(fi, s_id, received_ox_id);
  1410. break;
  1411. case ELS_ADISC:
  1412. DPRINTK1("ELS_ADISC received from D_ID 0x%x", s_id);
  1413. if (node_logged_in_prev(fi, buff_addr))
  1414. tx_adisc(fi, ELS_ACC, s_id, received_ox_id);
  1415. else
  1416. tx_logo(fi, s_id, received_ox_id);
  1417. break;
  1418. case ELS_PRLI:
  1419. DPRINTK1("ELS_PRLI received from D_ID 0x%x", s_id);
  1420. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) {
  1421. tx_prli(fi, ELS_ACC, s_id, received_ox_id);
  1422. mark_scsi_sid(fi, buff_addr, ADD_ENTRY);
  1423. }
  1424. else
  1425. tx_logo(fi, s_id, received_ox_id);
  1426. break;
  1427. case ELS_PRLO:
  1428. DPRINTK1("ELS_PRLO received from D_ID 0x%x", s_id);
  1429. if ((login_state == NODE_LOGGED_OUT) || (login_state == NODE_NOT_PRESENT))
  1430. tx_logo(fi, s_id, received_ox_id);
  1431. else
  1432. if (login_state == NODE_LOGGED_IN)
  1433. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1434. else
  1435. if (login_state == NODE_PROCESS_LOGGED_IN) {
  1436. tx_prli(fi, ELS_ACC, s_id, received_ox_id);
  1437. mark_scsi_sid(fi, buff_addr, DELETE_ENTRY);
  1438. }
  1439. break;
  1440. case ELS_LS_RJT:
  1441. els_type = remove_from_ox_id_list(fi, received_ox_id);
  1442. DPRINTK1("ELS_LS_RJT received from D_ID 0x%x in response to %x", s_id, els_type);
  1443. /* We should be chking the reason code.
  1444.  */
  1445. switch (els_type) {
  1446. case ELS_ADISC:
  1447. tx_logi(fi, ELS_PLOGI, s_id);
  1448. break;
  1449. }
  1450. break;
  1451. case ELS_LOGO:
  1452. els_type = remove_from_ox_id_list(fi, received_ox_id);
  1453. DPRINTK1("ELS_LOGO received from D_ID 0x%x in response to %x", s_id, els_type);
  1454. remove_from_address_cache(fi, buff_addr, ELS_LOGO);
  1455. tx_acc(fi, s_id, received_ox_id);
  1456. if (els_type == ELS_ADISC)
  1457. tx_logi(fi, ELS_PLOGI, s_id);
  1458. break;
  1459. case ELS_RSCN:
  1460. DPRINTK1("ELS_RSCN received from D_ID 0x%x", s_id);
  1461. tx_acc(fi, s_id, received_ox_id);
  1462. remove_from_address_cache(fi, buff_addr, ELS_RSCN);
  1463. break;
  1464. case ELS_FARP_REQ:
  1465. /* We do not support FARP.
  1466.    So, silently discard it */
  1467. DPRINTK1("ELS_FARP_REQ received from D_ID 0x%x", s_id);
  1468. break;
  1469. case ELS_ABTX:
  1470. DPRINTK1("ELS_ABTX received from D_ID 0x%x", s_id);
  1471. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1472. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1473. else
  1474. tx_logo(fi, s_id, received_ox_id);
  1475. break;
  1476. case ELS_FLOGI:
  1477. DPRINTK1("ELS_FLOGI received from D_ID 0x%x", s_id);
  1478. if (fi->g.ptp_up == TRUE) {
  1479. /* The node could have come up as an N_Port
  1480.  * in a Loop! So,try initializing as an NL_port
  1481.  */
  1482. take_tachyon_offline(fi);
  1483. /* write AL_TIME & E_D_TOV into the registers */
  1484. writel(TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
  1485. writel(LOOP_INIT_SOFT_ADDRESS, fi->t_r.ptr_fm_config_reg);
  1486. DPRINTK1("FLOGI received, TACHYON initializing as L_Port...n");
  1487. writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
  1488. }
  1489. else {
  1490. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1491. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1492. else
  1493. tx_logo(fi, s_id, received_ox_id);
  1494. }
  1495. break;
  1496. case ELS_ADVC:
  1497. DPRINTK1("ELS_ADVC received from D_ID 0x%x", s_id);
  1498. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1499. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1500. else
  1501. tx_logo(fi, s_id, received_ox_id);
  1502. break;
  1503. case ELS_ECHO:
  1504. DPRINTK1("ELS_ECHO received from D_ID 0x%x", s_id);
  1505. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1506. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1507. else
  1508. tx_logo(fi, s_id, received_ox_id);
  1509. break;
  1510. case ELS_ESTC:
  1511. DPRINTK1("ELS_ESTC received from D_ID 0x%x", s_id);
  1512. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1513. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1514. else
  1515. tx_logo(fi, s_id, received_ox_id);
  1516. break;
  1517. case ELS_ESTS:
  1518. DPRINTK1("ELS_ESTS received from D_ID 0x%x", s_id);
  1519. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1520. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1521. else
  1522. tx_logo(fi, s_id, received_ox_id);
  1523. break;
  1524. case ELS_RCS:
  1525. DPRINTK1("ELS_RCS received from D_ID 0x%x", s_id);
  1526. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1527. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1528. else
  1529. tx_logo(fi, s_id, received_ox_id);
  1530. break;
  1531. case ELS_RES:
  1532. DPRINTK1("ELS_RES received from D_ID 0x%x", s_id);
  1533. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1534. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1535. else
  1536. tx_logo(fi, s_id, received_ox_id);
  1537. break;
  1538. case ELS_RLS:
  1539. DPRINTK1("ELS_RLS received from D_ID 0x%x", s_id);
  1540. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1541. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1542. else
  1543. tx_logo(fi, s_id, received_ox_id);
  1544. break;
  1545. case ELS_RRQ:
  1546. DPRINTK1("ELS_RRQ received from D_ID 0x%x", s_id);
  1547. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1548. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1549. else
  1550. tx_logo(fi, s_id, received_ox_id);
  1551. break;
  1552. case ELS_RSS:
  1553. DPRINTK1("ELS_RSS received from D_ID 0x%x", s_id);
  1554. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1555. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1556. else
  1557. tx_logo(fi, s_id, received_ox_id);
  1558. break;
  1559. case ELS_RTV:
  1560. DPRINTK1("ELS_RTV received from D_ID 0x%x", s_id);
  1561. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1562. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1563. else
  1564. tx_logo(fi, s_id, received_ox_id);
  1565. break;
  1566. case ELS_RSI:
  1567. DPRINTK1("ELS_RSI received from D_ID 0x%x", s_id);
  1568. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1569. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1570. else
  1571. tx_logo(fi, s_id, received_ox_id);
  1572. break;
  1573. case ELS_TEST:
  1574. /* No reply sequence */
  1575. DPRINTK1("ELS_TEST received from D_ID 0x%x", s_id);
  1576. break;
  1577. case ELS_RNC:
  1578. DPRINTK1("ELS_RNC received from D_ID 0x%x", s_id);
  1579. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1580. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1581. else
  1582. tx_logo(fi, s_id, received_ox_id);
  1583. break;
  1584. case ELS_RVCS:
  1585. DPRINTK1("ELS_RVCS received from D_ID 0x%x", s_id);
  1586. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1587. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1588. else
  1589. tx_logo(fi, s_id, received_ox_id);
  1590. break;
  1591. case ELS_TPLS:
  1592. DPRINTK1("ELS_TPLS received from D_ID 0x%x", s_id);
  1593. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1594. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1595. else
  1596. tx_logo(fi, s_id, received_ox_id);
  1597. break;
  1598. case ELS_GAID:
  1599. DPRINTK1("ELS_GAID received from D_ID 0x%x", s_id);
  1600. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1601. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1602. else
  1603. tx_logo(fi, s_id, received_ox_id);
  1604. break;
  1605. case ELS_FACT:
  1606. DPRINTK1("ELS_FACT received from D_ID 0x%x", s_id);
  1607. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1608. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1609. else
  1610. tx_logo(fi, s_id, received_ox_id);
  1611. break;
  1612. case ELS_FAN:
  1613. /* Hmmm... You don't support FAN ??? */
  1614. DPRINTK1("ELS_FAN received from D_ID 0x%x", s_id);
  1615. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1616. break;
  1617. case ELS_FDACT:
  1618. DPRINTK1("ELS_FDACT received from D_ID 0x%x", s_id);
  1619. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1620. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1621. else
  1622. tx_logo(fi, s_id, received_ox_id);
  1623. break;
  1624. case ELS_NACT:
  1625. DPRINTK1("ELS_NACT received from D_ID 0x%x", s_id);
  1626. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
  1627. tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
  1628. else
  1629. tx_logo(fi, s_id, received_ox_id);
  1630. break;
  1631. case ELS_NDACT:
  1632. DPRINTK1("ELS_NDACT 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_QoSR:
  1639. DPRINTK1("ELS_QoSR 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_FDISC:
  1646. DPRINTK1("ELS_FDISC 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. default:
  1653. DPRINTK1("ELS Frame %x received from D_ID 0x%x", class_of_frame, 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. }
  1660. break;
  1661. case TYPE_FC_SERVICES:
  1662. fs_cmnd_code = (ntohl(*(buff_addr + 10)) & 0xFFFF0000) >>16;
  1663. switch(fs_cmnd_code) {
  1664. case FCS_ACC:
  1665. els_type = remove_from_ox_id_list(fi, received_ox_id);
  1666. DPRINTK1("FCS_ACC received from D_ID 0x%x in response to %x", s_id, els_type);
  1667. if (els_type == FCS_GP_ID4) 
  1668. explore_fabric(fi, buff_addr);
  1669. break;
  1670. case FCS_REJECT:
  1671. DPRINTK1("FCS_REJECT received from D_ID 0x%x in response to %x", s_id, els_type);
  1672. break;
  1673. }
  1674. break;
  1675. case TYPE_LLC_SNAP:
  1676. rx_net_packet(fi, (u_char *)buff_addr, payload_size);
  1677. break;
  1678. default:
  1679. T_MSG("Frame Type %x received from %x", type_of_frame, s_id);
  1680. }
  1681. /* provide Tachyon will another set of buffers */
  1682. if (offset == (NO_OF_ENTRIES - 1))
  1683. update_SFSBQ_indx(fi);
  1684. LEAVE("handle_SFS_interrupt");
  1685. }
  1686. static void handle_FM_interrupt(struct fc_info *fi)
  1687. {
  1688. u_int fm_status;
  1689. u_int tachyon_status;
  1690. ENTER("handle_FM_interrupt");
  1691. fm_status = readl(fi->t_r.ptr_fm_status_reg);
  1692. tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
  1693. DPRINTK("FM_status = %x, Tachyon_status = %x", fm_status, tachyon_status);
  1694. if (fm_status & LINK_DOWN) {
  1695. T_MSG("Fibre Channel Link DOWN");
  1696. fm_status = readl(fi->t_r.ptr_fm_status_reg);
  1697. del_timer(&fi->explore_timer);
  1698. del_timer(&fi->nport_timer);
  1699. del_timer(&fi->lport_timer);
  1700. del_timer(&fi->display_cache_timer);
  1701. fi->g.link_up = FALSE;
  1702. if (fi->g.ptp_up == TRUE)
  1703. fi->g.n_port_try = FALSE;
  1704. fi->g.ptp_up = FALSE;
  1705. fi->g.port_discovery = FALSE;
  1706. fi->g.explore_fabric = FALSE;
  1707. fi->g.perform_adisc = FALSE;
  1708. /* Logout will all nodes */
  1709. if (fi->node_info_list) {
  1710. struct fc_node_info *temp_list = fi->node_info_list;
  1711. while(temp_list) {
  1712. temp_list->login = LOGIN_ATTEMPTED;
  1713. temp_list = temp_list->next;
  1714. }
  1715. fi->num_nodes = 0;
  1716. }
  1717. if ((fi->g.n_port_try == FALSE) && (fi->g.dont_init == FALSE)){
  1718. take_tachyon_offline(fi);
  1719. /* write AL_TIME & E_D_TOV into the registers */
  1720. writel(TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
  1721. if ((fi->g.fabric_present == TRUE) && (fi->g.loop_up == TRUE)) {
  1722. u_int al_pa = fi->g.my_id & 0xFF;
  1723. writel((al_pa << 24) | LOOP_INIT_FABRIC_ADDRESS | LOOP_INIT_PREVIOUS_ADDRESS, fi->t_r.ptr_fm_config_reg);
  1724. }
  1725. else 
  1726. if (fi->g.loop_up == TRUE) {
  1727. u_int al_pa = fi->g.my_id & 0xFF;
  1728. writel((al_pa << 24) | LOOP_INIT_PREVIOUS_ADDRESS, fi->t_r.ptr_fm_config_reg);
  1729. }
  1730. else 
  1731. writel(LOOP_INIT_SOFT_ADDRESS, fi->t_r.ptr_fm_config_reg);
  1732. fi->g.loop_up = FALSE;
  1733. DPRINTK1("In LDWN TACHYON initializing as L_Port...n");
  1734. writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
  1735. }
  1736. }
  1737.     if (fm_status & NON_PARTICIPATING) {
  1738.    T_MSG("Did not acquire an AL_PA. I am not participating");
  1739.     }
  1740. else
  1741. if ((fm_status & LINK_UP) && ((fm_status & LINK_DOWN) == 0)) {
  1742.   T_MSG("Fibre Channel Link UP");
  1743.   if ((fm_status & NON_PARTICIPATING) != TRUE) {
  1744. fi->g.link_up = TRUE;
  1745. if (tachyon_status & OSM_FROZEN) {
  1746. reset_tachyon(fi, ERROR_RELEASE);
  1747. reset_tachyon(fi, OCQ_RESET);
  1748. }
  1749. init_timer(&fi->explore_timer);
  1750. init_timer(&fi->nport_timer);
  1751. init_timer(&fi->lport_timer);
  1752. init_timer(&fi->display_cache_timer);
  1753. if ((fm_status & OLD_PORT) == 0) {
  1754. fi->g.loop_up = TRUE;
  1755. fi->g.ptp_up = FALSE;
  1756. fi->g.my_id = readl(fi->t_r.ptr_fm_config_reg) >> 24;
  1757. DPRINTK1("My AL_PA = %x", fi->g.my_id);
  1758. fi->g.port_discovery = TRUE;
  1759. fi->g.explore_fabric = FALSE;
  1760. }
  1761. else
  1762. if (((fm_status & 0xF0) == OLD_PORT) && ((fm_status & 0x0F) == PORT_STATE_ACTIVE)) {
  1763. fi->g.loop_up = FALSE;
  1764. fi->g.my_id = 0x0;
  1765. /* In a point-to-point configuration, we expect to be
  1766.  * connected to an F_Port. This driver does not yet support
  1767.  * a configuration where it is connected to another N_Port
  1768.  * directly.
  1769.  */
  1770. fi->g.explore_fabric = TRUE;
  1771. fi->g.port_discovery = FALSE;
  1772. if (fi->g.n_port_try == FALSE) {
  1773. take_tachyon_offline(fi);
  1774. /* write R_T_TOV & E_D_TOV into the registers */
  1775. writel(PTP_TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
  1776. writel(BB_CREDIT | NPORT, fi->t_r.ptr_fm_config_reg);
  1777. fi->g.n_port_try = TRUE;
  1778. DPRINTK1("In LUP TACHYON initializing as N_Port...n");
  1779. writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
  1780. }
  1781. else {
  1782. fi->g.ptp_up = TRUE;
  1783. tx_logi(fi, ELS_FLOGI, F_PORT); 
  1784. }
  1785. }
  1786. fi->g.my_ddaa = 0x0;
  1787. fi->g.fabric_present = FALSE; 
  1788. /* We havn't sent out any Name Server Reqs */
  1789. fi->g.name_server = FALSE;
  1790. fi->g.alpa_list_index = 0;
  1791. fi->g.ox_id = NOT_SCSI_XID;
  1792. fi->g.my_mtu = TACH_FRAME_SIZE;
  1793. /* Implicitly LOGO with all logged-in nodes. 
  1794.  */
  1795. if (fi->node_info_list) {
  1796. struct fc_node_info *temp_list = fi->node_info_list;
  1797. while(temp_list) {
  1798. temp_list->login = LOGIN_ATTEMPTED;
  1799. temp_list = temp_list->next;
  1800. }
  1801. fi->num_nodes = 0;
  1802. fi->g.perform_adisc = TRUE;
  1803. //fi->g.perform_adisc = FALSE;
  1804. fi->g.port_discovery = FALSE;
  1805. tx_logi(fi, ELS_FLOGI, F_PORT); 
  1806. }
  1807. else { 
  1808. /* If Link coming up for the _first_ time or no nodes
  1809.  * were logged in before...
  1810.  */
  1811. fi->g.scsi_oxid = 0;
  1812. fi->g.seq_id = 0x00;
  1813. fi->g.perform_adisc = FALSE;
  1814. }
  1815. /* reset OX_ID table */
  1816. while (fi->ox_id_list) {
  1817. struct ox_id_els_map *temp = fi->ox_id_list;
  1818. fi->ox_id_list = fi->ox_id_list->next;
  1819. kfree(temp);
  1820. }
  1821. fi->ox_id_list = NULL;
  1822.   } /* End of if partipating */
  1823. }
  1824. if (fm_status & ELASTIC_STORE_ERROR) {
  1825. /* Too much junk on the Link 
  1826.  */
  1827. /* Trying to clear it up by Txing PLOGI to urself */
  1828. if (fi->g.link_up == TRUE)
  1829. tx_logi(fi, ELS_PLOGI, fi->g.my_id); 
  1830. }
  1831. if (fm_status & LOOP_UP) {
  1832. if (tachyon_status & OSM_FROZEN) {
  1833. reset_tachyon(fi, ERROR_RELEASE);
  1834. reset_tachyon(fi, OCQ_RESET);
  1835. }
  1836. }
  1837. if (fm_status & NOS_OLS_RECEIVED){
  1838. if (fi->g.nport_timer_set == FALSE) {
  1839. DPRINTK("NOS/OLS Received");
  1840. DPRINTK("FM_status = %x", fm_status);
  1841. fi->nport_timer.function = nos_ols_timer;
  1842. fi->nport_timer.data = (unsigned long)fi;
  1843. fi->nport_timer.expires = RUN_AT((3*HZ)/100); /* 30 msec */
  1844. init_timer(&fi->nport_timer);
  1845. add_timer(&fi->nport_timer);
  1846. fi->g.nport_timer_set = TRUE;
  1847. }
  1848. }
  1849. if (((fm_status & 0xF0) == OLD_PORT) && (((fm_status & 0x0F) == PORT_STATE_LF1) || ((fm_status & 0x0F) == PORT_STATE_LF2))) {
  1850. DPRINTK1("Link Fail-I in OLD-PORT.");
  1851. take_tachyon_offline(fi);
  1852. reset_tachyon(fi, SOFTWARE_RESET);
  1853. }
  1854. if (fm_status & LOOP_STATE_TIMEOUT){
  1855. if ((fm_status & 0xF0) == ARBITRATING) 
  1856. DPRINTK1("ED_TOV timesout.In ARBITRATING state...");
  1857. if ((fm_status & 0xF0) == ARB_WON)
  1858. DPRINTK1("ED_TOV timesout.In ARBITRATION WON state...");
  1859. if ((fm_status & 0xF0) == OPEN)
  1860. DPRINTK1("ED_TOV timesout.In OPEN state...");
  1861. if ((fm_status & 0xF0) == OPENED)
  1862. DPRINTK1("ED_TOV timesout.In OPENED state...");
  1863. if ((fm_status & 0xF0) == TX_CLS)
  1864. DPRINTK1("ED_TOV timesout.In XMITTED CLOSE state...");
  1865. if ((fm_status & 0xF0) == RX_CLS)
  1866. DPRINTK1("ED_TOV timesout.In RECEIVED CLOSE state...");
  1867. if ((fm_status & 0xF0) == INITIALIZING)
  1868. DPRINTK1("ED_TOV timesout.In INITIALIZING state...");
  1869. DPRINTK1("Initializing Loop...");
  1870. writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
  1871. }
  1872. if ((fm_status & BAD_ALPA) && (fi->g.loop_up == TRUE)) {
  1873. u_char bad_alpa = (readl(fi->t_r.ptr_fm_rx_al_pa_reg) & 0xFF00) >> 8;
  1874. if (tachyon_status & OSM_FROZEN) {
  1875. reset_tachyon(fi, ERROR_RELEASE);
  1876. reset_tachyon(fi, OCQ_RESET);
  1877. }
  1878. /* Fix for B34 */
  1879. tx_logi(fi, ELS_PLOGI, fi->g.my_id); 
  1880. if (!fi->g.port_discovery && !fi->g.perform_adisc) {
  1881. if (bad_alpa != 0xFE)
  1882. DPRINTK("Bad AL_PA = %x", bad_alpa);
  1883. }
  1884. else {
  1885. if ((fi->g.perform_adisc == TRUE) && (bad_alpa == 0x00)) {
  1886. DPRINTK1("Performing ADISC...");
  1887. fi->g.fabric_present = FALSE;
  1888. perform_adisc(fi);
  1889. }
  1890. }
  1891. }
  1892. if (fm_status & LIPF_RECEIVED){
  1893. DPRINTK("LIP(F8) Received");
  1894. }
  1895. if (fm_status & LINK_FAILURE) {
  1896. if (fm_status & LOSS_OF_SIGNAL)
  1897. DPRINTK1("Detected Loss of Signal.");
  1898. if (fm_status & OUT_OF_SYNC)
  1899. DPRINTK1("Detected Loss of Synchronization.");
  1900. }
  1901. if (fm_status & TRANSMIT_PARITY_ERROR) {
  1902. /* Bad! Should not happen. Solution-> Hard Reset.
  1903.  */
  1904. T_MSG("Parity Error. Perform Hard Reset!");
  1905. }
  1906. if (fi->g.alpa_list_index >= MAX_NODES){
  1907. if (fi->g.port_discovery == TRUE) {
  1908. fi->g.port_discovery = FALSE;
  1909. add_display_cache_timer(fi);
  1910. }
  1911. fi->g.alpa_list_index = MAX_NODES;
  1912. }
  1913. if (fi->g.port_discovery == TRUE) 
  1914. local_port_discovery(fi);
  1915. LEAVE("handle_FM_interrupt");
  1916. return;
  1917. }
  1918. static void local_port_discovery(struct fc_info *fi)
  1919. {
  1920. if (fi->g.loop_up == TRUE) {
  1921. /* If this is not here, some of the Bad AL_PAs are missed. 
  1922.  */
  1923. udelay(20); 
  1924. if ((fi->g.alpa_list_index == 0) && (fi->g.fabric_present == FALSE)){
  1925. tx_logi(fi, ELS_FLOGI, F_PORT); 
  1926. }
  1927. else {
  1928. int login_state = sid_logged_in(fi, fi->g.my_ddaa | alpa_list[fi->g.alpa_list_index]);
  1929. 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)))))
  1930. fi->g.alpa_list_index++;
  1931. if (fi->g.alpa_list_index < MAX_NODES)
  1932. tx_logi(fi, ELS_PLOGI, alpa_list[fi->g.alpa_list_index]); 
  1933. }
  1934. fi->g.alpa_list_index++;
  1935. if (fi->g.alpa_list_index >= MAX_NODES){
  1936. if (fi->g.port_discovery == TRUE) {
  1937. fi->g.port_discovery = FALSE;
  1938. add_display_cache_timer(fi);
  1939. }
  1940. fi->g.alpa_list_index = MAX_NODES;
  1941. }
  1942. }
  1943. }
  1944. static void nos_ols_timer(unsigned long data)
  1945. {
  1946. struct fc_info *fi = (struct fc_info*)data;
  1947. u_int fm_status;
  1948. fm_status = readl(fi->t_r.ptr_fm_status_reg);
  1949. DPRINTK1("FM_status in timer= %x", fm_status);
  1950. fi->g.nport_timer_set = FALSE;
  1951. del_timer(&fi->nport_timer);
  1952. if ((fi->g.ptp_up == TRUE) || (fi->g.loop_up == TRUE))
  1953. return;
  1954. if (((fm_status & 0xF0) == OLD_PORT) && (((fm_status & 0x0F) == PORT_STATE_ACTIVE) || ((fm_status & 0x0F) == PORT_STATE_OFFLINE))) {
  1955. DPRINTK1("In OLD-PORT after E_D_TOV.");
  1956. take_tachyon_offline(fi);
  1957. /* write R_T_TOV & E_D_TOV into the registers */
  1958. writel(PTP_TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
  1959. writel(BB_CREDIT | NPORT, fi->t_r.ptr_fm_config_reg);
  1960. fi->g.n_port_try = TRUE;
  1961. DPRINTK1("In timer, TACHYON initializing as N_Port...n");
  1962. writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
  1963. }
  1964. else
  1965. if ((fi->g.lport_timer_set == FALSE) && ((fm_status & 0xF0) == LOOP_FAIL)) {
  1966. DPRINTK1("Loop Fail after E_D_TOV.");
  1967. fi->lport_timer.function = loop_timer;
  1968. fi->lport_timer.data = (unsigned long)fi;
  1969. fi->lport_timer.expires = RUN_AT((8*HZ)/100); 
  1970. init_timer(&fi->lport_timer);
  1971. add_timer(&fi->lport_timer);
  1972. fi->g.lport_timer_set = TRUE;
  1973. take_tachyon_offline(fi);
  1974. reset_tachyon(fi, SOFTWARE_RESET);
  1975. }
  1976. else
  1977. if (((fm_status & 0xF0) == OLD_PORT) && (((fm_status & 0x0F) == PORT_STATE_LF1) || ((fm_status & 0x0F) == PORT_STATE_LF2))) {
  1978. DPRINTK1("Link Fail-II in OLD-PORT.");
  1979. take_tachyon_offline(fi);
  1980. reset_tachyon(fi, SOFTWARE_RESET);
  1981. }
  1982. }
  1983. static void loop_timer(unsigned long data)
  1984. {
  1985. struct fc_info *fi = (struct fc_info*)data;
  1986. fi->g.lport_timer_set = FALSE;
  1987. del_timer(&fi->lport_timer);
  1988. if ((fi->g.ptp_up == TRUE) || (fi->g.loop_up == TRUE))
  1989. return;
  1990. }
  1991. static void add_display_cache_timer(struct fc_info *fi)
  1992. {
  1993. fi->display_cache_timer.function = display_cache_timer;
  1994. fi->display_cache_timer.data = (unsigned long)fi;
  1995. fi->display_cache_timer.expires = RUN_AT(fi->num_nodes * HZ); 
  1996. init_timer(&fi->display_cache_timer);
  1997. add_timer(&fi->display_cache_timer);
  1998. }
  1999. static void display_cache_timer(unsigned long data)
  2000. {
  2001. struct fc_info *fi = (struct fc_info*)data;
  2002. del_timer(&fi->display_cache_timer);
  2003. display_cache(fi);
  2004. return;
  2005. }
  2006. static void reset_tachyon(struct fc_info *fi, u_int value)
  2007. {
  2008. u_int tachyon_status, reset_done = OCQ_RESET_STATUS | SCSI_FREEZE_STATUS;
  2009. int not_done = 1, i = 0;
  2010. writel(value, fi->t_r.ptr_tach_control_reg);
  2011. if (value == OCQ_RESET) 
  2012. fi->q.ocq_prod_indx = 0;
  2013. tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
  2014. /* Software resets are immediately done, whereas other aren't. It 
  2015. about 30 clocks to do the reset */
  2016. if (value != SOFTWARE_RESET) {
  2017. while(not_done) {
  2018. if (i++ > 100000) {
  2019. T_MSG("Reset was unsuccessful! Tachyon Status = %x", tachyon_status);
  2020. break;
  2021. }
  2022. tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
  2023. if ((tachyon_status & reset_done) == 0)
  2024. not_done = 0;
  2025. }
  2026. }
  2027. else {
  2028. write_to_tachyon_registers(fi);
  2029. }
  2030. }
  2031. static void take_tachyon_offline(struct fc_info *fi)
  2032. {
  2033. u_int fm_status = readl(fi->t_r.ptr_fm_status_reg);
  2034. /* The first two conditions will never be true. The Manual and
  2035.  * the errata say this. But the current implementation is
  2036.  * decently stable.
  2037.  */  
  2038. //if ((fm_status & 0xF0) == LOOP_FAIL) {
  2039. if (fm_status == LOOP_FAIL) {
  2040. // workaround as in P. 89 
  2041. writel(HOST_CONTROL, fi->t_r.ptr_fm_control_reg);
  2042. if (fi->g.loop_up == TRUE)
  2043. writel(SOFTWARE_RESET, fi->t_r.ptr_tach_control_reg);
  2044. else {
  2045. writel(OFFLINE, fi->t_r.ptr_fm_control_reg);
  2046. writel(EXIT_HOST_CONTROL, fi->t_r.ptr_fm_control_reg);
  2047. }
  2048. }
  2049. else
  2050. //if ((fm_status & LOOP_UP) == LOOP_UP) {
  2051. if (fm_status == LOOP_UP) {
  2052. writel(SOFTWARE_RESET, fi->t_r.ptr_tach_control_reg);
  2053. }
  2054. else
  2055. writel(OFFLINE, fi->t_r.ptr_fm_control_reg);
  2056. }
  2057. static void read_novram(struct fc_info *fi)
  2058. {
  2059. int off = 0;
  2060. fi->n_r.ptr_novram_hw_control_reg = fi->i_r.ptr_ichip_hw_control_reg; 
  2061. fi->n_r.ptr_novram_hw_status_reg = fi->i_r.ptr_ichip_hw_status_reg; 
  2062. iph5526_nr_do_init(fi);
  2063. if (fi->clone_id == PCI_VENDOR_ID_INTERPHASE)
  2064. off = 32;
  2065. fi->g.my_node_name_high = (fi->n_r.data[off] << 16) | fi->n_r.data[off+1];
  2066. fi->g.my_node_name_low = (fi->n_r.data[off+2] << 16) | fi->n_r.data[off+3];
  2067. fi->g.my_port_name_high = (fi->n_r.data[off+4] << 16) | fi->n_r.data[off+5];
  2068. fi->g.my_port_name_low = (fi->n_r.data[off+6] << 16) | fi->n_r.data[off+7];
  2069. DPRINTK("node_name = %x %x", fi->g.my_node_name_high, fi->g.my_node_name_low);
  2070. DPRINTK("port_name = %x %x", fi->g.my_port_name_high, fi->g.my_port_name_low);
  2071. }
  2072. static void reset_ichip(struct fc_info *fi)
  2073. {
  2074. /* (i)chip reset */
  2075. writel(ICHIP_HCR_RESET, fi->i_r.ptr_ichip_hw_control_reg);
  2076. /*wait for chip to get reset */
  2077. mdelay(10);
  2078. /*de-assert reset */
  2079. writel(ICHIP_HCR_DERESET, fi->i_r.ptr_ichip_hw_control_reg);
  2080. /* enable INT lines on the (i)chip */
  2081. writel(ICHIP_HCR_ENABLE_INTA , fi->i_r.ptr_ichip_hw_control_reg);
  2082. /* enable byte swap */
  2083. writel(ICHIP_HAMR_BYTE_SWAP_ADDR_TR, fi->i_r.ptr_ichip_hw_addr_mask_reg);
  2084. }
  2085. static void tx_logi(struct fc_info *fi, u_int logi, u_int d_id)
  2086. {
  2087. int int_required = 1;
  2088. u_short ox_id = OX_ID_FIRST_SEQUENCE;
  2089. u_int r_ctl = RCTL_ELS_UCTL;
  2090. u_int type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
  2091. u_int my_mtu = fi->g.my_mtu;
  2092. ENTER("tx_logi");
  2093. /* We dont want interrupted for our own logi. 
  2094.  * It screws up the port discovery process. 
  2095.  */
  2096. if (d_id == fi->g.my_id)
  2097. int_required = 0;
  2098. fill_login_frame(fi, logi);
  2099. fi->g.type_of_frame = FC_ELS;
  2100. memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.login, sizeof(LOGIN));
  2101. 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);
  2102. fi->g.e_i++;
  2103. if (fi->g.e_i == MAX_PENDING_FRAMES)
  2104. fi->g.e_i = 0;
  2105. LEAVE("tx_logi");
  2106. return;
  2107. }
  2108. static void tx_logi_acc(struct fc_info *fi, u_int logi, u_int d_id, u_short received_ox_id)
  2109. {
  2110. int int_required = 0;
  2111. u_int r_ctl = RCTL_ELS_SCTL;
  2112. u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE;
  2113. u_int my_mtu = fi->g.my_mtu;
  2114. ENTER("tx_logi_acc");
  2115. fill_login_frame(fi, logi);
  2116. fi->g.type_of_frame = FC_ELS;
  2117. memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.login, sizeof(LOGIN));
  2118. 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);
  2119. fi->g.e_i++;
  2120. if (fi->g.e_i == MAX_PENDING_FRAMES)
  2121. fi->g.e_i = 0;
  2122. LEAVE("tx_logi_acc");
  2123. return;
  2124. }
  2125. static void tx_prli(struct fc_info *fi, u_int command_code, u_int d_id, u_short received_ox_id)
  2126. {
  2127. int int_required = 1;
  2128. u_int r_ctl = RCTL_ELS_UCTL;
  2129. u_int type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
  2130. u_int my_mtu = fi->g.my_mtu;
  2131. ENTER("tx_prli");
  2132. if (command_code == ELS_PRLI)
  2133. fi->g.prli.cmnd_code = htons((ELS_PRLI | PAGE_LEN) >> 16);
  2134. else {
  2135. fi->g.prli.cmnd_code = htons((ELS_ACC | PAGE_LEN) >> 16);
  2136. int_required = 0;
  2137. type  = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE;
  2138. r_ctl = RCTL_ELS_SCTL;
  2139. }
  2140. fi->g.prli.payload_length = htons(PRLI_LEN);
  2141. fi->g.prli.type_code = htons(FCP_TYPE_CODE);
  2142. fi->g.prli.est_image_pair = htons(IMAGE_PAIR);
  2143. fi->g.prli.responder_pa = 0;
  2144. fi->g.prli.originator_pa = 0;
  2145. fi->g.prli.service_params = htonl(INITIATOR_FUNC | READ_XFER_RDY_DISABLED);
  2146. fi->g.type_of_frame = FC_ELS;
  2147. memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.prli, sizeof(PRLI));
  2148. 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);
  2149. fi->g.e_i++;
  2150. if (fi->g.e_i == MAX_PENDING_FRAMES)
  2151. fi->g.e_i = 0;
  2152. LEAVE("tx_prli");
  2153. return;
  2154. }
  2155. static void tx_logo(struct fc_info *fi, u_int d_id, u_short received_ox_id)
  2156. {
  2157. int int_required = 1;
  2158. u_int r_ctl = RCTL_ELS_UCTL;
  2159. u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | SEQUENCE_RESPONDER | FIRST_SEQUENCE | END_SEQUENCE | SEQUENCE_INITIATIVE;
  2160. int size = sizeof(LOGO);
  2161. char fc_id[3];
  2162. u_int my_mtu = fi->g.my_mtu;
  2163. ENTER("tx_logo");
  2164. fi->g.logo.logo_cmnd = htonl(ELS_LOGO);
  2165. fi->g.logo.reserved = 0;
  2166. memcpy(fc_id, &(fi->g.my_id), 3);
  2167. fi->g.logo.n_port_id_0 = fc_id[0];
  2168. fi->g.logo.n_port_id_1 = fc_id[1];
  2169. fi->g.logo.n_port_id_2 = fc_id[2];
  2170. fi->g.logo.port_name_up = htonl(N_PORT_NAME_HIGH);
  2171. fi->g.logo.port_name_low = htonl(N_PORT_NAME_LOW);
  2172. fi->g.type_of_frame = FC_ELS;
  2173. memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.logo, sizeof(LOGO));
  2174. 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);
  2175. fi->g.e_i++;
  2176. if (fi->g.e_i == MAX_PENDING_FRAMES)