diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2011-07-20 20:00:45 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-07-27 06:44:48 -0400 |
commit | ca6e0ea71cd0f442875b05357dd51774bd84b418 (patch) | |
tree | d57fc05d9bd1141d1c8a340347bdb28ea20b8e45 /drivers/scsi/bfa | |
parent | 9afbcfab74d26051702862b57c0115f71477a3cc (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.h | 13 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_core.c | 25 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_hw_cb.c | 38 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_hw_ct.c | 25 |
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 { | |||
177 | struct bfa_hwif_s { | 177 | struct 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); | |||
311 | void bfa_msix_lpu_err(struct bfa_s *bfa, int vec); | 309 | void bfa_msix_lpu_err(struct bfa_s *bfa, int vec); |
312 | 310 | ||
313 | void bfa_hwcb_reginit(struct bfa_s *bfa); | 311 | void bfa_hwcb_reginit(struct bfa_s *bfa); |
314 | void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq); | 312 | void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci); |
315 | void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs); | 313 | void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs); |
316 | void bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa); | 314 | void bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa); |
317 | void bfa_hwcb_msix_queue_install(struct bfa_s *bfa); | 315 | void 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, | |||
324 | void bfa_hwct_reginit(struct bfa_s *bfa); | 322 | void bfa_hwct_reginit(struct bfa_s *bfa); |
325 | void bfa_hwct2_reginit(struct bfa_s *bfa); | 323 | void bfa_hwct2_reginit(struct bfa_s *bfa); |
326 | void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq); | 324 | void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq); |
327 | void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq); | 325 | void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci); |
326 | void bfa_hwct2_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci); | ||
328 | void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs); | 327 | void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs); |
329 | void bfa_hwct_msix_ctrl_install(struct bfa_s *bfa); | 328 | void bfa_hwct_msix_ctrl_install(struct bfa_s *bfa); |
330 | void bfa_hwct_msix_queue_install(struct bfa_s *bfa); | 329 | void 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 | */ | ||
45 | static void | 52 | static void |
46 | bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq) | 53 | bfa_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 | |||
66 | void | ||
67 | bfa_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 | ||
52 | void | 77 | void |
@@ -149,8 +174,13 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa) | |||
149 | void | 174 | void |
150 | bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix) | 175 | bfa_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 | ||
156 | void | 186 | void |
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 | */ | ||
67 | void | 73 | void |
68 | bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq) | 74 | bfa_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 | */ | ||
91 | void | ||
92 | bfa_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 | ||
76 | void | 99 | void |