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