Linux Audio

Check our new training course

In-person Linux kernel drivers training

Jun 16-20, 2025
Register
Loading...
v4.10.11
 
  1/*
  2 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
  3 * Copyright (c) 2014- QLogic Corporation.
  4 * All rights reserved
  5 * www.qlogic.com
  6 *
  7 * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
  8 *
  9 * This program is free software; you can redistribute it and/or modify it
 10 * under the terms of the GNU General Public License (GPL) Version 2 as
 11 * published by the Free Software Foundation
 12 *
 13 * This program is distributed in the hope that it will be useful, but
 14 * WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16 * General Public License for more details.
 17 */
 18
 19#include "bfad_drv.h"
 20#include "bfa_modules.h"
 21#include "bfi_reg.h"
 22
 23void
 24bfa_hwcb_reginit(struct bfa_s *bfa)
 25{
 26	struct bfa_iocfc_regs_s	*bfa_regs = &bfa->iocfc.bfa_regs;
 27	void __iomem *kva = bfa_ioc_bar0(&bfa->ioc);
 28	int	fn = bfa_ioc_pcifn(&bfa->ioc);
 29
 30	if (fn == 0) {
 31		bfa_regs->intr_status = (kva + HOSTFN0_INT_STATUS);
 32		bfa_regs->intr_mask   = (kva + HOSTFN0_INT_MSK);
 33	} else {
 34		bfa_regs->intr_status = (kva + HOSTFN1_INT_STATUS);
 35		bfa_regs->intr_mask   = (kva + HOSTFN1_INT_MSK);
 36	}
 37}
 38
 39static void
 40bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq)
 41{
 42	writel(__HFN_INT_CPE_Q0 << CPE_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), reqq),
 43			bfa->iocfc.bfa_regs.intr_status);
 44}
 45
 46/*
 47 * Actions to respond RME Interrupt for Crossbow ASIC:
 48 * - Write 1 to Interrupt Status register
 49 *              INTX - done in bfa_intx()
 50 *              MSIX - done in bfa_hwcb_rspq_ack_msix()
 51 * - Update CI (only if new CI)
 52 */
 53static void
 54bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq, u32 ci)
 55{
 56	writel(__HFN_INT_RME_Q0 << RME_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), rspq),
 57		bfa->iocfc.bfa_regs.intr_status);
 58
 59	if (bfa_rspq_ci(bfa, rspq) == ci)
 60		return;
 61
 62	bfa_rspq_ci(bfa, rspq) = ci;
 63	writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
 64	mmiowb();
 65}
 66
 67void
 68bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci)
 69{
 70	if (bfa_rspq_ci(bfa, rspq) == ci)
 71		return;
 72
 73	bfa_rspq_ci(bfa, rspq) = ci;
 74	writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
 75	mmiowb();
 76}
 77
 78void
 79bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap,
 80		 u32 *num_vecs, u32 *max_vec_bit)
 81{
 82#define __HFN_NUMINTS	13
 83	if (bfa_ioc_pcifn(&bfa->ioc) == 0) {
 84		*msix_vecs_bmap = (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 |
 85				   __HFN_INT_CPE_Q2 | __HFN_INT_CPE_Q3 |
 86				   __HFN_INT_RME_Q0 | __HFN_INT_RME_Q1 |
 87				   __HFN_INT_RME_Q2 | __HFN_INT_RME_Q3 |
 88				   __HFN_INT_MBOX_LPU0);
 89		*max_vec_bit = __HFN_INT_MBOX_LPU0;
 90	} else {
 91		*msix_vecs_bmap = (__HFN_INT_CPE_Q4 | __HFN_INT_CPE_Q5 |
 92				   __HFN_INT_CPE_Q6 | __HFN_INT_CPE_Q7 |
 93				   __HFN_INT_RME_Q4 | __HFN_INT_RME_Q5 |
 94				   __HFN_INT_RME_Q6 | __HFN_INT_RME_Q7 |
 95				   __HFN_INT_MBOX_LPU1);
 96		*max_vec_bit = __HFN_INT_MBOX_LPU1;
 97	}
 98
 99	*msix_vecs_bmap |= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
100			    __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS);
101	*num_vecs = __HFN_NUMINTS;
102}
103
104/*
105 * Dummy interrupt handler for handling spurious interrupts.
106 */
107static void
108bfa_hwcb_msix_dummy(struct bfa_s *bfa, int vec)
109{
110}
111
112/*
113 * No special setup required for crossbow -- vector assignments are implicit.
114 */
115void
116bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs)
117{
118	WARN_ON((nvecs != 1) && (nvecs != __HFN_NUMINTS));
119
120	bfa->msix.nvecs = nvecs;
121	bfa_hwcb_msix_uninstall(bfa);
122}
123
124void
125bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa)
126{
127	int i;
128
129	if (bfa->msix.nvecs == 0)
130		return;
131
132	if (bfa->msix.nvecs == 1) {
133		for (i = BFI_MSIX_CPE_QMIN_CB; i < BFI_MSIX_CB_MAX; i++)
134			bfa->msix.handler[i] = bfa_msix_all;
135		return;
136	}
137
138	for (i = BFI_MSIX_RME_QMAX_CB+1; i < BFI_MSIX_CB_MAX; i++)
139		bfa->msix.handler[i] = bfa_msix_lpu_err;
140}
141
142void
143bfa_hwcb_msix_queue_install(struct bfa_s *bfa)
144{
145	int i;
146
147	if (bfa->msix.nvecs == 0)
148		return;
149
150	if (bfa->msix.nvecs == 1) {
151		for (i = BFI_MSIX_CPE_QMIN_CB; i <= BFI_MSIX_RME_QMAX_CB; i++)
152			bfa->msix.handler[i] = bfa_msix_all;
153		return;
154	}
155
156	for (i = BFI_MSIX_CPE_QMIN_CB; i <= BFI_MSIX_CPE_QMAX_CB; i++)
157		bfa->msix.handler[i] = bfa_msix_reqq;
158
159	for (i = BFI_MSIX_RME_QMIN_CB; i <= BFI_MSIX_RME_QMAX_CB; i++)
160		bfa->msix.handler[i] = bfa_msix_rspq;
161}
162
163void
164bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
165{
166	int i;
167
168	for (i = 0; i < BFI_MSIX_CB_MAX; i++)
169		bfa->msix.handler[i] = bfa_hwcb_msix_dummy;
170}
171
172/*
173 * No special enable/disable -- vector assignments are implicit.
174 */
175void
176bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
177{
178	if (msix) {
179		bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix;
180		bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
181	} else {
182		bfa->iocfc.hwif.hw_reqq_ack = NULL;
183		bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
184	}
185}
186
187void
188bfa_hwcb_msix_get_rme_range(struct bfa_s *bfa, u32 *start, u32 *end)
189{
190	*start = BFI_MSIX_RME_QMIN_CB;
191	*end = BFI_MSIX_RME_QMAX_CB;
192}
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
  4 * Copyright (c) 2014- QLogic Corporation.
  5 * All rights reserved
  6 * www.qlogic.com
  7 *
  8 * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
 
 
 
 
 
 
 
 
 
  9 */
 10
 11#include "bfad_drv.h"
 12#include "bfa_modules.h"
 13#include "bfi_reg.h"
 14
 15void
 16bfa_hwcb_reginit(struct bfa_s *bfa)
 17{
 18	struct bfa_iocfc_regs_s	*bfa_regs = &bfa->iocfc.bfa_regs;
 19	void __iomem *kva = bfa_ioc_bar0(&bfa->ioc);
 20	int	fn = bfa_ioc_pcifn(&bfa->ioc);
 21
 22	if (fn == 0) {
 23		bfa_regs->intr_status = (kva + HOSTFN0_INT_STATUS);
 24		bfa_regs->intr_mask   = (kva + HOSTFN0_INT_MSK);
 25	} else {
 26		bfa_regs->intr_status = (kva + HOSTFN1_INT_STATUS);
 27		bfa_regs->intr_mask   = (kva + HOSTFN1_INT_MSK);
 28	}
 29}
 30
 31static void
 32bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq)
 33{
 34	writel(__HFN_INT_CPE_Q0 << CPE_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), reqq),
 35			bfa->iocfc.bfa_regs.intr_status);
 36}
 37
 38/*
 39 * Actions to respond RME Interrupt for Crossbow ASIC:
 40 * - Write 1 to Interrupt Status register
 41 *              INTX - done in bfa_intx()
 42 *              MSIX - done in bfa_hwcb_rspq_ack_msix()
 43 * - Update CI (only if new CI)
 44 */
 45static void
 46bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq, u32 ci)
 47{
 48	writel(__HFN_INT_RME_Q0 << RME_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), rspq),
 49		bfa->iocfc.bfa_regs.intr_status);
 50
 51	if (bfa_rspq_ci(bfa, rspq) == ci)
 52		return;
 53
 54	bfa_rspq_ci(bfa, rspq) = ci;
 55	writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
 
 56}
 57
 58void
 59bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci)
 60{
 61	if (bfa_rspq_ci(bfa, rspq) == ci)
 62		return;
 63
 64	bfa_rspq_ci(bfa, rspq) = ci;
 65	writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
 
 66}
 67
 68void
 69bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap,
 70		 u32 *num_vecs, u32 *max_vec_bit)
 71{
 72#define __HFN_NUMINTS	13
 73	if (bfa_ioc_pcifn(&bfa->ioc) == 0) {
 74		*msix_vecs_bmap = (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 |
 75				   __HFN_INT_CPE_Q2 | __HFN_INT_CPE_Q3 |
 76				   __HFN_INT_RME_Q0 | __HFN_INT_RME_Q1 |
 77				   __HFN_INT_RME_Q2 | __HFN_INT_RME_Q3 |
 78				   __HFN_INT_MBOX_LPU0);
 79		*max_vec_bit = __HFN_INT_MBOX_LPU0;
 80	} else {
 81		*msix_vecs_bmap = (__HFN_INT_CPE_Q4 | __HFN_INT_CPE_Q5 |
 82				   __HFN_INT_CPE_Q6 | __HFN_INT_CPE_Q7 |
 83				   __HFN_INT_RME_Q4 | __HFN_INT_RME_Q5 |
 84				   __HFN_INT_RME_Q6 | __HFN_INT_RME_Q7 |
 85				   __HFN_INT_MBOX_LPU1);
 86		*max_vec_bit = __HFN_INT_MBOX_LPU1;
 87	}
 88
 89	*msix_vecs_bmap |= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
 90			    __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS);
 91	*num_vecs = __HFN_NUMINTS;
 92}
 93
 94/*
 95 * Dummy interrupt handler for handling spurious interrupts.
 96 */
 97static void
 98bfa_hwcb_msix_dummy(struct bfa_s *bfa, int vec)
 99{
100}
101
102/*
103 * No special setup required for crossbow -- vector assignments are implicit.
104 */
105void
106bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs)
107{
108	WARN_ON((nvecs != 1) && (nvecs != __HFN_NUMINTS));
109
110	bfa->msix.nvecs = nvecs;
111	bfa_hwcb_msix_uninstall(bfa);
112}
113
114void
115bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa)
116{
117	int i;
118
119	if (bfa->msix.nvecs == 0)
120		return;
121
122	if (bfa->msix.nvecs == 1) {
123		for (i = BFI_MSIX_CPE_QMIN_CB; i < BFI_MSIX_CB_MAX; i++)
124			bfa->msix.handler[i] = bfa_msix_all;
125		return;
126	}
127
128	for (i = BFI_MSIX_RME_QMAX_CB+1; i < BFI_MSIX_CB_MAX; i++)
129		bfa->msix.handler[i] = bfa_msix_lpu_err;
130}
131
132void
133bfa_hwcb_msix_queue_install(struct bfa_s *bfa)
134{
135	int i;
136
137	if (bfa->msix.nvecs == 0)
138		return;
139
140	if (bfa->msix.nvecs == 1) {
141		for (i = BFI_MSIX_CPE_QMIN_CB; i <= BFI_MSIX_RME_QMAX_CB; i++)
142			bfa->msix.handler[i] = bfa_msix_all;
143		return;
144	}
145
146	for (i = BFI_MSIX_CPE_QMIN_CB; i <= BFI_MSIX_CPE_QMAX_CB; i++)
147		bfa->msix.handler[i] = bfa_msix_reqq;
148
149	for (i = BFI_MSIX_RME_QMIN_CB; i <= BFI_MSIX_RME_QMAX_CB; i++)
150		bfa->msix.handler[i] = bfa_msix_rspq;
151}
152
153void
154bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
155{
156	int i;
157
158	for (i = 0; i < BFI_MSIX_CB_MAX; i++)
159		bfa->msix.handler[i] = bfa_hwcb_msix_dummy;
160}
161
162/*
163 * No special enable/disable -- vector assignments are implicit.
164 */
165void
166bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
167{
168	if (msix) {
169		bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix;
170		bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
171	} else {
172		bfa->iocfc.hwif.hw_reqq_ack = NULL;
173		bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
174	}
175}
176
177void
178bfa_hwcb_msix_get_rme_range(struct bfa_s *bfa, u32 *start, u32 *end)
179{
180	*start = BFI_MSIX_RME_QMIN_CB;
181	*end = BFI_MSIX_RME_QMAX_CB;
182}