diff options
author | David S. Miller <davem@davemloft.net> | 2010-04-07 02:53:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-07 02:53:30 -0400 |
commit | 4a35ecf8bf1c4b039503fa554100fe85c761de76 (patch) | |
tree | 9b75f5d5636004d9a9aa496924377379be09aa1f /drivers/scsi/bfa/bfa_ioc_ct.c | |
parent | b4d562e3c3553ac58c7120555c4e4aefbb090a2a (diff) | |
parent | fb9e2d887243499b8d28efcf80821c4f6a092395 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/bonding/bond_main.c
drivers/net/via-velocity.c
drivers/net/wireless/iwlwifi/iwl-agn.c
Diffstat (limited to 'drivers/scsi/bfa/bfa_ioc_ct.c')
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc_ct.c | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c new file mode 100644 index 000000000000..20b58ad5f95c --- /dev/null +++ b/drivers/scsi/bfa/bfa_ioc_ct.c | |||
@@ -0,0 +1,423 @@ | |||
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 <bfa_ioc.h> | ||
20 | #include <bfa_fwimg_priv.h> | ||
21 | #include <cna/bfa_cna_trcmod.h> | ||
22 | #include <cs/bfa_debug.h> | ||
23 | #include <bfi/bfi_ioc.h> | ||
24 | #include <bfi/bfi_ctreg.h> | ||
25 | #include <log/bfa_log_hal.h> | ||
26 | #include <defs/bfa_defs_pci.h> | ||
27 | |||
28 | BFA_TRC_FILE(CNA, IOC_CT); | ||
29 | |||
30 | /* | ||
31 | * forward declarations | ||
32 | */ | ||
33 | static bfa_status_t bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc); | ||
34 | static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc); | ||
35 | static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc); | ||
36 | static u32* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, | ||
37 | u32 off); | ||
38 | static u32 bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc); | ||
39 | static void bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc); | ||
40 | static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc); | ||
41 | static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix); | ||
42 | static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc); | ||
43 | static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc); | ||
44 | |||
45 | struct bfa_ioc_hwif_s hwif_ct = { | ||
46 | bfa_ioc_ct_pll_init, | ||
47 | bfa_ioc_ct_firmware_lock, | ||
48 | bfa_ioc_ct_firmware_unlock, | ||
49 | bfa_ioc_ct_fwimg_get_chunk, | ||
50 | bfa_ioc_ct_fwimg_get_size, | ||
51 | bfa_ioc_ct_reg_init, | ||
52 | bfa_ioc_ct_map_port, | ||
53 | bfa_ioc_ct_isr_mode_set, | ||
54 | bfa_ioc_ct_notify_hbfail, | ||
55 | bfa_ioc_ct_ownership_reset, | ||
56 | }; | ||
57 | |||
58 | /** | ||
59 | * Called from bfa_ioc_attach() to map asic specific calls. | ||
60 | */ | ||
61 | void | ||
62 | bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc) | ||
63 | { | ||
64 | ioc->ioc_hwif = &hwif_ct; | ||
65 | } | ||
66 | |||
67 | static u32* | ||
68 | bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off) | ||
69 | { | ||
70 | return bfi_image_ct_get_chunk(off); | ||
71 | } | ||
72 | |||
73 | static u32 | ||
74 | bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc) | ||
75 | { | ||
76 | return bfi_image_ct_size; | ||
77 | } | ||
78 | |||
79 | /** | ||
80 | * Return true if firmware of current driver matches the running firmware. | ||
81 | */ | ||
82 | static bfa_boolean_t | ||
83 | bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc) | ||
84 | { | ||
85 | enum bfi_ioc_state ioc_fwstate; | ||
86 | u32 usecnt; | ||
87 | struct bfi_ioc_image_hdr_s fwhdr; | ||
88 | |||
89 | /** | ||
90 | * Firmware match check is relevant only for CNA. | ||
91 | */ | ||
92 | if (!ioc->cna) | ||
93 | return BFA_TRUE; | ||
94 | |||
95 | /** | ||
96 | * If bios boot (flash based) -- do not increment usage count | ||
97 | */ | ||
98 | if (bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) | ||
99 | return BFA_TRUE; | ||
100 | |||
101 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); | ||
102 | usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg); | ||
103 | |||
104 | /** | ||
105 | * If usage count is 0, always return TRUE. | ||
106 | */ | ||
107 | if (usecnt == 0) { | ||
108 | bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1); | ||
109 | bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); | ||
110 | bfa_trc(ioc, usecnt); | ||
111 | return BFA_TRUE; | ||
112 | } | ||
113 | |||
114 | ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate); | ||
115 | bfa_trc(ioc, ioc_fwstate); | ||
116 | |||
117 | /** | ||
118 | * Use count cannot be non-zero and chip in uninitialized state. | ||
119 | */ | ||
120 | bfa_assert(ioc_fwstate != BFI_IOC_UNINIT); | ||
121 | |||
122 | /** | ||
123 | * Check if another driver with a different firmware is active | ||
124 | */ | ||
125 | bfa_ioc_fwver_get(ioc, &fwhdr); | ||
126 | if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) { | ||
127 | bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); | ||
128 | bfa_trc(ioc, usecnt); | ||
129 | return BFA_FALSE; | ||
130 | } | ||
131 | |||
132 | /** | ||
133 | * Same firmware version. Increment the reference count. | ||
134 | */ | ||
135 | usecnt++; | ||
136 | bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt); | ||
137 | bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); | ||
138 | bfa_trc(ioc, usecnt); | ||
139 | return BFA_TRUE; | ||
140 | } | ||
141 | |||
142 | static void | ||
143 | bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc) | ||
144 | { | ||
145 | u32 usecnt; | ||
146 | |||
147 | /** | ||
148 | * Firmware lock is relevant only for CNA. | ||
149 | * If bios boot (flash based) -- do not decrement usage count | ||
150 | */ | ||
151 | if (!ioc->cna || bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) | ||
152 | return; | ||
153 | |||
154 | /** | ||
155 | * decrement usage count | ||
156 | */ | ||
157 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); | ||
158 | usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg); | ||
159 | bfa_assert(usecnt > 0); | ||
160 | |||
161 | usecnt--; | ||
162 | bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt); | ||
163 | bfa_trc(ioc, usecnt); | ||
164 | |||
165 | bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); | ||
166 | } | ||
167 | |||
168 | /** | ||
169 | * Notify other functions on HB failure. | ||
170 | */ | ||
171 | static void | ||
172 | bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc) | ||
173 | { | ||
174 | if (ioc->cna) { | ||
175 | bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P); | ||
176 | /* Wait for halt to take effect */ | ||
177 | bfa_reg_read(ioc->ioc_regs.ll_halt); | ||
178 | } else { | ||
179 | bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET); | ||
180 | bfa_reg_read(ioc->ioc_regs.err_set); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | /** | ||
185 | * Host to LPU mailbox message addresses | ||
186 | */ | ||
187 | static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = { | ||
188 | { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 }, | ||
189 | { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }, | ||
190 | { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 }, | ||
191 | { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 } | ||
192 | }; | ||
193 | |||
194 | /** | ||
195 | * Host <-> LPU mailbox command/status registers - port 0 | ||
196 | */ | ||
197 | static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = { | ||
198 | { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT }, | ||
199 | { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT }, | ||
200 | { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT }, | ||
201 | { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT } | ||
202 | }; | ||
203 | |||
204 | /** | ||
205 | * Host <-> LPU mailbox command/status registers - port 1 | ||
206 | */ | ||
207 | static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = { | ||
208 | { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT }, | ||
209 | { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT }, | ||
210 | { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT }, | ||
211 | { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT } | ||
212 | }; | ||
213 | |||
214 | static void | ||
215 | bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc) | ||
216 | { | ||
217 | bfa_os_addr_t rb; | ||
218 | int pcifn = bfa_ioc_pcifn(ioc); | ||
219 | |||
220 | rb = bfa_ioc_bar0(ioc); | ||
221 | |||
222 | ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox; | ||
223 | ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox; | ||
224 | ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn; | ||
225 | |||
226 | if (ioc->port_id == 0) { | ||
227 | ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG; | ||
228 | ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG; | ||
229 | ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn; | ||
230 | ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu; | ||
231 | ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0; | ||
232 | } else { | ||
233 | ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG); | ||
234 | ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG); | ||
235 | ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn; | ||
236 | ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu; | ||
237 | ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1; | ||
238 | } | ||
239 | |||
240 | /* | ||
241 | * PSS control registers | ||
242 | */ | ||
243 | ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); | ||
244 | ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG); | ||
245 | ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG); | ||
246 | ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG); | ||
247 | |||
248 | /* | ||
249 | * IOC semaphore registers and serialization | ||
250 | */ | ||
251 | ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG); | ||
252 | ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG); | ||
253 | ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG); | ||
254 | ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT); | ||
255 | |||
256 | /** | ||
257 | * sram memory access | ||
258 | */ | ||
259 | ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); | ||
260 | ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT; | ||
261 | |||
262 | /* | ||
263 | * err set reg : for notification of hb failure in fcmode | ||
264 | */ | ||
265 | ioc->ioc_regs.err_set = (rb + ERR_SET_REG); | ||
266 | } | ||
267 | |||
268 | /** | ||
269 | * Initialize IOC to port mapping. | ||
270 | */ | ||
271 | |||
272 | #define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8) | ||
273 | static void | ||
274 | bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc) | ||
275 | { | ||
276 | bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; | ||
277 | u32 r32; | ||
278 | |||
279 | /** | ||
280 | * For catapult, base port id on personality register and IOC type | ||
281 | */ | ||
282 | r32 = bfa_reg_read(rb + FNC_PERS_REG); | ||
283 | r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)); | ||
284 | ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH; | ||
285 | |||
286 | bfa_trc(ioc, bfa_ioc_pcifn(ioc)); | ||
287 | bfa_trc(ioc, ioc->port_id); | ||
288 | } | ||
289 | |||
290 | /** | ||
291 | * Set interrupt mode for a function: INTX or MSIX | ||
292 | */ | ||
293 | static void | ||
294 | bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix) | ||
295 | { | ||
296 | bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; | ||
297 | u32 r32, mode; | ||
298 | |||
299 | r32 = bfa_reg_read(rb + FNC_PERS_REG); | ||
300 | bfa_trc(ioc, r32); | ||
301 | |||
302 | mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) & | ||
303 | __F0_INTX_STATUS; | ||
304 | |||
305 | /** | ||
306 | * If already in desired mode, do not change anything | ||
307 | */ | ||
308 | if (!msix && mode) | ||
309 | return; | ||
310 | |||
311 | if (msix) | ||
312 | mode = __F0_INTX_STATUS_MSIX; | ||
313 | else | ||
314 | mode = __F0_INTX_STATUS_INTA; | ||
315 | |||
316 | r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); | ||
317 | r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); | ||
318 | bfa_trc(ioc, r32); | ||
319 | |||
320 | bfa_reg_write(rb + FNC_PERS_REG, r32); | ||
321 | } | ||
322 | |||
323 | static bfa_status_t | ||
324 | bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc) | ||
325 | { | ||
326 | bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; | ||
327 | u32 pll_sclk, pll_fclk, r32; | ||
328 | |||
329 | /* | ||
330 | * Hold semaphore so that nobody can access the chip during init. | ||
331 | */ | ||
332 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg); | ||
333 | |||
334 | pll_sclk = __APP_PLL_312_LRESETN | __APP_PLL_312_ENARST | | ||
335 | __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(3U) | | ||
336 | __APP_PLL_312_JITLMT0_1(3U) | | ||
337 | __APP_PLL_312_CNTLMT0_1(1U); | ||
338 | pll_fclk = __APP_PLL_425_LRESETN | __APP_PLL_425_ENARST | | ||
339 | __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) | | ||
340 | __APP_PLL_425_JITLMT0_1(3U) | | ||
341 | __APP_PLL_425_CNTLMT0_1(1U); | ||
342 | |||
343 | /** | ||
344 | * For catapult, choose operational mode FC/FCoE | ||
345 | */ | ||
346 | if (ioc->fcmode) { | ||
347 | bfa_reg_write((rb + OP_MODE), 0); | ||
348 | bfa_reg_write((rb + ETH_MAC_SER_REG), | ||
349 | __APP_EMS_CMLCKSEL | | ||
350 | __APP_EMS_REFCKBUFEN2 | | ||
351 | __APP_EMS_CHANNEL_SEL); | ||
352 | } else { | ||
353 | ioc->pllinit = BFA_TRUE; | ||
354 | bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE); | ||
355 | bfa_reg_write((rb + ETH_MAC_SER_REG), | ||
356 | __APP_EMS_REFCKBUFEN1); | ||
357 | } | ||
358 | |||
359 | bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT); | ||
360 | bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT); | ||
361 | |||
362 | bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); | ||
363 | bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); | ||
364 | bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); | ||
365 | bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); | ||
366 | bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); | ||
367 | bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); | ||
368 | |||
369 | bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk | | ||
370 | __APP_PLL_312_LOGIC_SOFT_RESET); | ||
371 | bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk | | ||
372 | __APP_PLL_425_LOGIC_SOFT_RESET); | ||
373 | bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk | | ||
374 | __APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE); | ||
375 | bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk | | ||
376 | __APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE); | ||
377 | |||
378 | /** | ||
379 | * Wait for PLLs to lock. | ||
380 | */ | ||
381 | bfa_reg_read(rb + HOSTFN0_INT_MSK); | ||
382 | bfa_os_udelay(2000); | ||
383 | bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); | ||
384 | bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); | ||
385 | |||
386 | bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk | | ||
387 | __APP_PLL_312_ENABLE); | ||
388 | bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk | | ||
389 | __APP_PLL_425_ENABLE); | ||
390 | |||
391 | bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START); | ||
392 | bfa_os_udelay(1000); | ||
393 | r32 = bfa_reg_read((rb + MBIST_STAT_REG)); | ||
394 | bfa_trc(ioc, r32); | ||
395 | /* | ||
396 | * release semaphore. | ||
397 | */ | ||
398 | bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg); | ||
399 | |||
400 | return BFA_STATUS_OK; | ||
401 | } | ||
402 | |||
403 | /** | ||
404 | * Cleanup hw semaphore and usecnt registers | ||
405 | */ | ||
406 | static void | ||
407 | bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc) | ||
408 | { | ||
409 | |||
410 | if (ioc->cna) { | ||
411 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); | ||
412 | bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 0); | ||
413 | bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); | ||
414 | } | ||
415 | |||
416 | /* | ||
417 | * Read the hw sem reg to make sure that it is locked | ||
418 | * before we clear it. If it is not locked, writing 1 | ||
419 | * will lock it instead of clearing it. | ||
420 | */ | ||
421 | bfa_reg_read(ioc->ioc_regs.ioc_sem_reg); | ||
422 | bfa_ioc_hw_sem_release(ioc); | ||
423 | } | ||