Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Krishna Gudipati and committed by
James Bottomley
ca6e0ea7 9afbcfab

+73 -28
+6 -7
drivers/scsi/bfa/bfa.h
··· 177 177 struct bfa_hwif_s { 178 178 void (*hw_reginit)(struct bfa_s *bfa); 179 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 181 void (*hw_msix_init)(struct bfa_s *bfa, int nvecs); 182 182 void (*hw_msix_ctrl_install)(struct bfa_s *bfa); 183 183 void (*hw_msix_queue_install)(struct bfa_s *bfa); ··· 268 268 ((__bfa)->iocfc.hwif.hw_msix_queue_install(__bfa)) 269 269 #define bfa_msix_uninstall(__bfa) \ 270 270 ((__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa)) 271 - #define bfa_isr_rspq_ack(__bfa, __queue) do { \ 272 - if ((__bfa)->iocfc.hwif.hw_rspq_ack) \ 273 - (__bfa)->iocfc.hwif.hw_rspq_ack(__bfa, __queue); \ 274 - } while (0) 271 + #define bfa_isr_rspq_ack(__bfa, __queue, __ci) \ 272 + ((__bfa)->iocfc.hwif.hw_rspq_ack(__bfa, __queue, __ci)) 275 273 #define bfa_isr_reqq_ack(__bfa, __queue) do { \ 276 274 if ((__bfa)->iocfc.hwif.hw_reqq_ack) \ 277 275 (__bfa)->iocfc.hwif.hw_reqq_ack(__bfa, __queue); \ ··· 309 311 void bfa_msix_lpu_err(struct bfa_s *bfa, int vec); 310 312 311 313 void bfa_hwcb_reginit(struct bfa_s *bfa); 312 - void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq); 314 + void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci); 313 315 void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs); 314 316 void bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa); 315 317 void bfa_hwcb_msix_queue_install(struct bfa_s *bfa); ··· 322 324 void bfa_hwct_reginit(struct bfa_s *bfa); 323 325 void bfa_hwct2_reginit(struct bfa_s *bfa); 324 326 void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq); 325 - void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq); 327 + void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci); 328 + void bfa_hwct2_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci); 326 329 void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs); 327 330 void bfa_hwct_msix_ctrl_install(struct bfa_s *bfa); 328 331 void bfa_hwct_msix_queue_install(struct bfa_s *bfa);
+9 -16
drivers/scsi/bfa/bfa_core.c
··· 237 237 u32 pi, ci; 238 238 struct list_head *waitq; 239 239 240 - bfa_isr_rspq_ack(bfa, qid); 241 - 242 240 ci = bfa_rspq_ci(bfa, qid); 243 241 pi = bfa_rspq_pi(bfa, qid); 244 242 ··· 249 251 } 250 252 251 253 /* 252 - * update CI 254 + * acknowledge RME completions and update CI 253 255 */ 254 - bfa_rspq_ci(bfa, qid) = pi; 255 - writel(pi, bfa->iocfc.bfa_regs.rme_q_ci[qid]); 256 - mmiowb(); 256 + bfa_isr_rspq_ack(bfa, qid, ci); 257 257 258 258 /* 259 259 * Resume any pending requests in the corresponding reqq. ··· 321 325 int queue; 322 326 323 327 intr = readl(bfa->iocfc.bfa_regs.intr_status); 324 - if (!intr) 325 - return BFA_FALSE; 326 328 327 329 qintr = intr & (__HFN_INT_RME_MASK | __HFN_INT_CPE_MASK); 328 330 if (qintr) 329 331 writel(qintr, bfa->iocfc.bfa_regs.intr_status); 330 332 331 333 /* 332 - * RME completion queue interrupt 334 + * Unconditional RME completion queue interrupt 333 335 */ 334 - qintr = intr & __HFN_INT_RME_MASK; 335 - if (qintr && bfa->queue_process) { 336 + if (bfa->queue_process) { 336 337 for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++) 337 338 bfa_isr_rspq(bfa, queue); 338 339 } 339 340 340 - intr &= ~qintr; 341 341 if (!intr) 342 342 return BFA_TRUE; 343 343 ··· 424 432 __HFN_INT_MBOX_LPU1_CT2); 425 433 intr &= __HFN_INT_ERR_MASK_CT2; 426 434 } else { 427 - halt_isr = intr & __HFN_INT_LL_HALT; 435 + halt_isr = bfa_asic_id_ct(bfa->ioc.pcidev.device_id) ? 436 + (intr & __HFN_INT_LL_HALT) : 0; 428 437 pss_isr = intr & __HFN_INT_ERR_PSS; 429 438 lpu_isr = intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1); 430 439 intr &= __HFN_INT_ERR_MASK; ··· 571 578 } else { 572 579 iocfc->hwif.hw_reginit = bfa_hwcb_reginit; 573 580 iocfc->hwif.hw_reqq_ack = NULL; 574 - iocfc->hwif.hw_rspq_ack = NULL; 581 + iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack; 575 582 iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init; 576 583 iocfc->hwif.hw_msix_ctrl_install = bfa_hwcb_msix_ctrl_install; 577 584 iocfc->hwif.hw_msix_queue_install = bfa_hwcb_msix_queue_install; ··· 588 595 if (bfa_asic_id_ct2(bfa_ioc_devid(&bfa->ioc))) { 589 596 iocfc->hwif.hw_reginit = bfa_hwct2_reginit; 590 597 iocfc->hwif.hw_isr_mode_set = NULL; 591 - iocfc->hwif.hw_rspq_ack = NULL; 598 + iocfc->hwif.hw_rspq_ack = bfa_hwct2_rspq_ack; 592 599 } 593 600 594 601 iocfc->hwif.hw_reginit(bfa); ··· 678 685 679 686 bfa->queue_process = BFA_TRUE; 680 687 for (i = 0; i < BFI_IOC_MAX_CQS; i++) 681 - bfa_isr_rspq_ack(bfa, i); 688 + bfa_isr_rspq_ack(bfa, i, bfa_rspq_ci(bfa, i)); 682 689 683 690 for (i = 0; hal_mods[i]; i++) 684 691 hal_mods[i]->start(bfa);
+34 -4
drivers/scsi/bfa/bfa_hw_cb.c
··· 42 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 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 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 77 void ··· 174 149 void 175 150 bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix) 176 151 { 177 - bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix; 178 - bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix; 152 + if (msix) { 153 + bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix; 154 + bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix; 155 + } else { 156 + bfa->iocfc.hwif.hw_reqq_ack = NULL; 157 + bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack; 158 + } 179 159 } 180 160 181 161 void
+24 -1
drivers/scsi/bfa/bfa_hw_ct.c
··· 64 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 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 76 u32 r32; 71 77 72 78 r32 = readl(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]); 73 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 99 void