aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2011-07-20 20:00:45 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-07-27 06:44:48 -0400
commitca6e0ea71cd0f442875b05357dd51774bd84b418 (patch)
treed57fc05d9bd1141d1c8a340347bdb28ea20b8e45 /drivers/scsi/bfa
parent9afbcfab74d26051702862b57c0115f71477a3cc (diff)
[SCSI] bfa: Update RME interrupt handling.
- Made changes to always acknowledge RME interrupt and update consumer index (CI) when RME interrupt is generated. - Made changes to have ASIC specific hw_rspq_ack() handler. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa')
-rw-r--r--drivers/scsi/bfa/bfa.h13
-rw-r--r--drivers/scsi/bfa/bfa_core.c25
-rw-r--r--drivers/scsi/bfa/bfa_hw_cb.c38
-rw-r--r--drivers/scsi/bfa/bfa_hw_ct.c25
4 files changed, 73 insertions, 28 deletions
diff --git a/drivers/scsi/bfa/bfa.h b/drivers/scsi/bfa/bfa.h
index 3b0af1102bf4..6e3869a41cb9 100644
--- a/drivers/scsi/bfa/bfa.h
+++ b/drivers/scsi/bfa/bfa.h
@@ -177,7 +177,7 @@ struct bfa_msix_s {
177struct bfa_hwif_s { 177struct bfa_hwif_s {
178 void (*hw_reginit)(struct bfa_s *bfa); 178 void (*hw_reginit)(struct bfa_s *bfa);
179 void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq); 179 void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq);
180 void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq); 180 void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq, u32 ci);
181 void (*hw_msix_init)(struct bfa_s *bfa, int nvecs); 181 void (*hw_msix_init)(struct bfa_s *bfa, int nvecs);
182 void (*hw_msix_ctrl_install)(struct bfa_s *bfa); 182 void (*hw_msix_ctrl_install)(struct bfa_s *bfa);
183 void (*hw_msix_queue_install)(struct bfa_s *bfa); 183 void (*hw_msix_queue_install)(struct bfa_s *bfa);
@@ -268,10 +268,8 @@ struct bfa_iocfc_s {
268 ((__bfa)->iocfc.hwif.hw_msix_queue_install(__bfa)) 268 ((__bfa)->iocfc.hwif.hw_msix_queue_install(__bfa))
269#define bfa_msix_uninstall(__bfa) \ 269#define bfa_msix_uninstall(__bfa) \
270 ((__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa)) 270 ((__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa))
271#define bfa_isr_rspq_ack(__bfa, __queue) do { \ 271#define bfa_isr_rspq_ack(__bfa, __queue, __ci) \
272 if ((__bfa)->iocfc.hwif.hw_rspq_ack) \ 272 ((__bfa)->iocfc.hwif.hw_rspq_ack(__bfa, __queue, __ci))
273 (__bfa)->iocfc.hwif.hw_rspq_ack(__bfa, __queue); \
274} while (0)
275#define bfa_isr_reqq_ack(__bfa, __queue) do { \ 273#define bfa_isr_reqq_ack(__bfa, __queue) do { \
276 if ((__bfa)->iocfc.hwif.hw_reqq_ack) \ 274 if ((__bfa)->iocfc.hwif.hw_reqq_ack) \
277 (__bfa)->iocfc.hwif.hw_reqq_ack(__bfa, __queue); \ 275 (__bfa)->iocfc.hwif.hw_reqq_ack(__bfa, __queue); \
@@ -311,7 +309,7 @@ void bfa_msix_rspq(struct bfa_s *bfa, int vec);
311void bfa_msix_lpu_err(struct bfa_s *bfa, int vec); 309void bfa_msix_lpu_err(struct bfa_s *bfa, int vec);
312 310
313void bfa_hwcb_reginit(struct bfa_s *bfa); 311void bfa_hwcb_reginit(struct bfa_s *bfa);
314void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq); 312void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci);
315void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs); 313void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs);
316void bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa); 314void bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa);
317void bfa_hwcb_msix_queue_install(struct bfa_s *bfa); 315void bfa_hwcb_msix_queue_install(struct bfa_s *bfa);
@@ -324,7 +322,8 @@ void bfa_hwcb_msix_get_rme_range(struct bfa_s *bfa, u32 *start,
324void bfa_hwct_reginit(struct bfa_s *bfa); 322void bfa_hwct_reginit(struct bfa_s *bfa);
325void bfa_hwct2_reginit(struct bfa_s *bfa); 323void bfa_hwct2_reginit(struct bfa_s *bfa);
326void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq); 324void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq);
327void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq); 325void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci);
326void bfa_hwct2_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci);
328void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs); 327void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs);
329void bfa_hwct_msix_ctrl_install(struct bfa_s *bfa); 328void bfa_hwct_msix_ctrl_install(struct bfa_s *bfa);
330void bfa_hwct_msix_queue_install(struct bfa_s *bfa); 329void bfa_hwct_msix_queue_install(struct bfa_s *bfa);
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
index c38e589105a5..0c236964c67e 100644
--- a/drivers/scsi/bfa/bfa_core.c
+++ b/drivers/scsi/bfa/bfa_core.c
@@ -237,8 +237,6 @@ bfa_isr_rspq(struct bfa_s *bfa, int qid)
237 u32 pi, ci; 237 u32 pi, ci;
238 struct list_head *waitq; 238 struct list_head *waitq;
239 239
240 bfa_isr_rspq_ack(bfa, qid);
241
242 ci = bfa_rspq_ci(bfa, qid); 240 ci = bfa_rspq_ci(bfa, qid);
243 pi = bfa_rspq_pi(bfa, qid); 241 pi = bfa_rspq_pi(bfa, qid);
244 242
@@ -251,11 +249,9 @@ bfa_isr_rspq(struct bfa_s *bfa, int qid)
251 } 249 }
252 250
253 /* 251 /*
254 * update CI 252 * acknowledge RME completions and update CI
255 */ 253 */
256 bfa_rspq_ci(bfa, qid) = pi; 254 bfa_isr_rspq_ack(bfa, qid, ci);
257 writel(pi, bfa->iocfc.bfa_regs.rme_q_ci[qid]);
258 mmiowb();
259 255
260 /* 256 /*
261 * Resume any pending requests in the corresponding reqq. 257 * Resume any pending requests in the corresponding reqq.
@@ -325,23 +321,19 @@ bfa_intx(struct bfa_s *bfa)
325 int queue; 321 int queue;
326 322
327 intr = readl(bfa->iocfc.bfa_regs.intr_status); 323 intr = readl(bfa->iocfc.bfa_regs.intr_status);
328 if (!intr)
329 return BFA_FALSE;
330 324
331 qintr = intr & (__HFN_INT_RME_MASK | __HFN_INT_CPE_MASK); 325 qintr = intr & (__HFN_INT_RME_MASK | __HFN_INT_CPE_MASK);
332 if (qintr) 326 if (qintr)
333 writel(qintr, bfa->iocfc.bfa_regs.intr_status); 327 writel(qintr, bfa->iocfc.bfa_regs.intr_status);
334 328
335 /* 329 /*
336 * RME completion queue interrupt 330 * Unconditional RME completion queue interrupt
337 */ 331 */
338 qintr = intr & __HFN_INT_RME_MASK; 332 if (bfa->queue_process) {
339 if (qintr && bfa->queue_process) {
340 for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++) 333 for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
341 bfa_isr_rspq(bfa, queue); 334 bfa_isr_rspq(bfa, queue);
342 } 335 }
343 336
344 intr &= ~qintr;
345 if (!intr) 337 if (!intr)
346 return BFA_TRUE; 338 return BFA_TRUE;
347 339
@@ -432,7 +424,8 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
432 __HFN_INT_MBOX_LPU1_CT2); 424 __HFN_INT_MBOX_LPU1_CT2);
433 intr &= __HFN_INT_ERR_MASK_CT2; 425 intr &= __HFN_INT_ERR_MASK_CT2;
434 } else { 426 } else {
435 halt_isr = intr & __HFN_INT_LL_HALT; 427 halt_isr = bfa_asic_id_ct(bfa->ioc.pcidev.device_id) ?
428 (intr & __HFN_INT_LL_HALT) : 0;
436 pss_isr = intr & __HFN_INT_ERR_PSS; 429 pss_isr = intr & __HFN_INT_ERR_PSS;
437 lpu_isr = intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1); 430 lpu_isr = intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1);
438 intr &= __HFN_INT_ERR_MASK; 431 intr &= __HFN_INT_ERR_MASK;
@@ -578,7 +571,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
578 } else { 571 } else {
579 iocfc->hwif.hw_reginit = bfa_hwcb_reginit; 572 iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
580 iocfc->hwif.hw_reqq_ack = NULL; 573 iocfc->hwif.hw_reqq_ack = NULL;
581 iocfc->hwif.hw_rspq_ack = NULL; 574 iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
582 iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init; 575 iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
583 iocfc->hwif.hw_msix_ctrl_install = bfa_hwcb_msix_ctrl_install; 576 iocfc->hwif.hw_msix_ctrl_install = bfa_hwcb_msix_ctrl_install;
584 iocfc->hwif.hw_msix_queue_install = bfa_hwcb_msix_queue_install; 577 iocfc->hwif.hw_msix_queue_install = bfa_hwcb_msix_queue_install;
@@ -595,7 +588,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
595 if (bfa_asic_id_ct2(bfa_ioc_devid(&bfa->ioc))) { 588 if (bfa_asic_id_ct2(bfa_ioc_devid(&bfa->ioc))) {
596 iocfc->hwif.hw_reginit = bfa_hwct2_reginit; 589 iocfc->hwif.hw_reginit = bfa_hwct2_reginit;
597 iocfc->hwif.hw_isr_mode_set = NULL; 590 iocfc->hwif.hw_isr_mode_set = NULL;
598 iocfc->hwif.hw_rspq_ack = NULL; 591 iocfc->hwif.hw_rspq_ack = bfa_hwct2_rspq_ack;
599 } 592 }
600 593
601 iocfc->hwif.hw_reginit(bfa); 594 iocfc->hwif.hw_reginit(bfa);
@@ -685,7 +678,7 @@ bfa_iocfc_start_submod(struct bfa_s *bfa)
685 678
686 bfa->queue_process = BFA_TRUE; 679 bfa->queue_process = BFA_TRUE;
687 for (i = 0; i < BFI_IOC_MAX_CQS; i++) 680 for (i = 0; i < BFI_IOC_MAX_CQS; i++)
688 bfa_isr_rspq_ack(bfa, i); 681 bfa_isr_rspq_ack(bfa, i, bfa_rspq_ci(bfa, i));
689 682
690 for (i = 0; hal_mods[i]; i++) 683 for (i = 0; hal_mods[i]; i++)
691 hal_mods[i]->start(bfa); 684 hal_mods[i]->start(bfa);
diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c
index e7ffd8205dc7..ea24d4c6e67a 100644
--- a/drivers/scsi/bfa/bfa_hw_cb.c
+++ b/drivers/scsi/bfa/bfa_hw_cb.c
@@ -42,11 +42,36 @@ bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq)
42 bfa->iocfc.bfa_regs.intr_status); 42 bfa->iocfc.bfa_regs.intr_status);
43} 43}
44 44
45/*
46 * Actions to respond RME Interrupt for Crossbow ASIC:
47 * - Write 1 to Interrupt Status register
48 * INTX - done in bfa_intx()
49 * MSIX - done in bfa_hwcb_rspq_ack_msix()
50 * - Update CI (only if new CI)
51 */
45static void 52static void
46bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq) 53bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq, u32 ci)
47{ 54{
48 writel(__HFN_INT_RME_Q0 << RME_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), rspq), 55 writel(__HFN_INT_RME_Q0 << RME_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), rspq),
49 bfa->iocfc.bfa_regs.intr_status); 56 bfa->iocfc.bfa_regs.intr_status);
57
58 if (bfa_rspq_ci(bfa, rspq) == ci)
59 return;
60
61 bfa_rspq_ci(bfa, rspq) = ci;
62 writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
63 mmiowb();
64}
65
66void
67bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci)
68{
69 if (bfa_rspq_ci(bfa, rspq) == ci)
70 return;
71
72 bfa_rspq_ci(bfa, rspq) = ci;
73 writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
74 mmiowb();
50} 75}
51 76
52void 77void
@@ -149,8 +174,13 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
149void 174void
150bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix) 175bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
151{ 176{
152 bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix; 177 if (msix) {
153 bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix; 178 bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix;
179 bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
180 } else {
181 bfa->iocfc.hwif.hw_reqq_ack = NULL;
182 bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
183 }
154} 184}
155 185
156void 186void
diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c
index 989bbce9b296..637527f48b40 100644
--- a/drivers/scsi/bfa/bfa_hw_ct.c
+++ b/drivers/scsi/bfa/bfa_hw_ct.c
@@ -64,13 +64,36 @@ bfa_hwct_reqq_ack(struct bfa_s *bfa, int reqq)
64 writel(r32, bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]); 64 writel(r32, bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]);
65} 65}
66 66
67/*
68 * Actions to respond RME Interrupt for Catapult ASIC:
69 * - Write 1 to Interrupt Status register (INTx only - done in bfa_intx())
70 * - Acknowledge by writing to RME Queue Control register
71 * - Update CI
72 */
67void 73void
68bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq) 74bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci)
69{ 75{
70 u32 r32; 76 u32 r32;
71 77
72 r32 = readl(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]); 78 r32 = readl(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]);
73 writel(r32, bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]); 79 writel(r32, bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]);
80
81 bfa_rspq_ci(bfa, rspq) = ci;
82 writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
83 mmiowb();
84}
85
86/*
87 * Actions to respond RME Interrupt for Catapult2 ASIC:
88 * - Write 1 to Interrupt Status register (INTx only - done in bfa_intx())
89 * - Update CI
90 */
91void
92bfa_hwct2_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci)
93{
94 bfa_rspq_ci(bfa, rspq) = ci;
95 writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
96 mmiowb();
74} 97}
75 98
76void 99void