xref: /linux/drivers/scsi/bfa/bfa_fcpim.c (revision a234ca0faa65dcd5cc473915bd925130ebb7b74b)
1 /*
2  * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3  * All rights reserved
4  * www.brocade.com
5  *
6  * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License (GPL) Version 2 as
10  * published by the Free Software Foundation
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  */
17 
18 #include <bfa.h>
19 #include <log/bfa_log_hal.h>
20 
21 BFA_TRC_FILE(HAL, FCPIM);
22 BFA_MODULE(fcpim);
23 
24 /**
25  *  hal_fcpim_mod BFA FCP Initiator Mode module
26  */
27 
28 /**
29  * 		Compute and return memory needed by FCP(im) module.
30  */
31 static void
32 bfa_fcpim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
33 		u32 *dm_len)
34 {
35 	bfa_itnim_meminfo(cfg, km_len, dm_len);
36 
37 	/**
38 	 * IO memory
39 	 */
40 	if (cfg->fwcfg.num_ioim_reqs < BFA_IOIM_MIN)
41 		cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN;
42 	else if (cfg->fwcfg.num_ioim_reqs > BFA_IOIM_MAX)
43 		cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MAX;
44 
45 	*km_len += cfg->fwcfg.num_ioim_reqs *
46 	  (sizeof(struct bfa_ioim_s) + sizeof(struct bfa_ioim_sp_s));
47 
48 	*dm_len += cfg->fwcfg.num_ioim_reqs * BFI_IOIM_SNSLEN;
49 
50 	/**
51 	 * task management command memory
52 	 */
53 	if (cfg->fwcfg.num_tskim_reqs < BFA_TSKIM_MIN)
54 		cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN;
55 	*km_len += cfg->fwcfg.num_tskim_reqs * sizeof(struct bfa_tskim_s);
56 }
57 
58 
59 static void
60 bfa_fcpim_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
61 		     struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
62 {
63 	struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
64 
65 	bfa_trc(bfa, cfg->drvcfg.path_tov);
66 	bfa_trc(bfa, cfg->fwcfg.num_rports);
67 	bfa_trc(bfa, cfg->fwcfg.num_ioim_reqs);
68 	bfa_trc(bfa, cfg->fwcfg.num_tskim_reqs);
69 
70 	fcpim->bfa            = bfa;
71 	fcpim->num_itnims     = cfg->fwcfg.num_rports;
72 	fcpim->num_ioim_reqs  = cfg->fwcfg.num_ioim_reqs;
73 	fcpim->num_tskim_reqs = cfg->fwcfg.num_tskim_reqs;
74 	fcpim->path_tov       = cfg->drvcfg.path_tov;
75 	fcpim->delay_comp	  = cfg->drvcfg.delay_comp;
76 
77 	bfa_itnim_attach(fcpim, meminfo);
78 	bfa_tskim_attach(fcpim, meminfo);
79 	bfa_ioim_attach(fcpim, meminfo);
80 }
81 
82 static void
83 bfa_fcpim_detach(struct bfa_s *bfa)
84 {
85 	struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
86 
87 	bfa_ioim_detach(fcpim);
88 	bfa_tskim_detach(fcpim);
89 }
90 
91 static void
92 bfa_fcpim_start(struct bfa_s *bfa)
93 {
94 }
95 
96 static void
97 bfa_fcpim_stop(struct bfa_s *bfa)
98 {
99 }
100 
101 static void
102 bfa_fcpim_iocdisable(struct bfa_s *bfa)
103 {
104 	struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
105 	struct bfa_itnim_s *itnim;
106 	struct list_head        *qe, *qen;
107 
108 	list_for_each_safe(qe, qen, &fcpim->itnim_q) {
109 		itnim = (struct bfa_itnim_s *) qe;
110 		bfa_itnim_iocdisable(itnim);
111 	}
112 }
113 
114 void
115 bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov)
116 {
117 	struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
118 
119 	fcpim->path_tov = path_tov * 1000;
120 	if (fcpim->path_tov > BFA_FCPIM_PATHTOV_MAX)
121 		fcpim->path_tov = BFA_FCPIM_PATHTOV_MAX;
122 }
123 
124 u16
125 bfa_fcpim_path_tov_get(struct bfa_s *bfa)
126 {
127 	struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
128 
129 	return fcpim->path_tov / 1000;
130 }
131 
132 bfa_status_t
133 bfa_fcpim_get_modstats(struct bfa_s *bfa, struct bfa_fcpim_stats_s *modstats)
134 {
135 	struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
136 
137 	*modstats = fcpim->stats;
138 
139 	return BFA_STATUS_OK;
140 }
141 
142 bfa_status_t
143 bfa_fcpim_clr_modstats(struct bfa_s *bfa)
144 {
145 	struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
146 
147 	memset(&fcpim->stats, 0, sizeof(struct bfa_fcpim_stats_s));
148 
149 	return BFA_STATUS_OK;
150 }
151 
152 void
153 bfa_fcpim_qdepth_set(struct bfa_s *bfa, u16 q_depth)
154 {
155 	struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
156 
157 	bfa_assert(q_depth <= BFA_IOCFC_QDEPTH_MAX);
158 
159 	fcpim->q_depth = q_depth;
160 }
161 
162 u16
163 bfa_fcpim_qdepth_get(struct bfa_s *bfa)
164 {
165 	struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
166 
167 	return fcpim->q_depth;
168 }
169 
170 void
171 bfa_fcpim_update_ioredirect(struct bfa_s *bfa)
172 {
173 	bfa_boolean_t ioredirect;
174 
175 	/*
176 	 * IO redirection is turned off when QoS is enabled and vice versa
177 	 */
178 	ioredirect = bfa_fcport_is_qos_enabled(bfa) ? BFA_FALSE : BFA_TRUE;
179 
180 	/*
181 	 * Notify the bfad module of a possible state change in
182 	 * IO redirection capability, due to a QoS state change. bfad will
183 	 * check on the support for io redirection and update the
184 	 * fcpim's ioredirect state accordingly.
185 	 */
186 	bfa_cb_ioredirect_state_change((void *)(bfa->bfad), ioredirect);
187 }
188 
189 void
190 bfa_fcpim_set_ioredirect(struct bfa_s *bfa, bfa_boolean_t state)
191 {
192 	struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
193 	fcpim->ioredirect = state;
194 }
195