Blame view

drivers/scsi/bfa/bfa_ioc_cb.c 8.87 KB
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
1
  /*
a36c61f90   Krishna Gudipati   [SCSI] bfa: clean...
2
   * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
3
4
5
6
7
8
9
10
11
12
13
14
15
16
   * All rights reserved
   * www.brocade.com
   *
   * Linux driver for Brocade Fibre Channel Host Bus Adapter.
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License (GPL) Version 2 as
   * published by the Free Software Foundation
   *
   * This program is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * General Public License for more details.
   */
f16a17507   Maggie Zhang   [SCSI] bfa: remov...
17
  #include "bfad_drv.h"
a36c61f90   Krishna Gudipati   [SCSI] bfa: clean...
18
  #include "bfa_ioc.h"
111892082   Krishna Gudipati   [SCSI] bfa: Broca...
19
  #include "bfi_reg.h"
a36c61f90   Krishna Gudipati   [SCSI] bfa: clean...
20
  #include "bfa_defs.h"
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
21
22
23
24
25
26
  
  BFA_TRC_FILE(CNA, IOC_CB);
  
  /*
   * forward declarations
   */
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
27
28
  static bfa_boolean_t bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc);
  static void bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc);
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
29
30
31
  static void bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc);
  static void bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc);
  static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
f1d584d70   Krishna Gudipati   [SCSI] bfa: IOC a...
32
  static void bfa_ioc_cb_notify_fail(struct bfa_ioc_s *ioc);
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
33
  static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc);
45d7f0cc5   Jing Huang   [SCSI] bfa: kdump...
34
  static bfa_boolean_t bfa_ioc_cb_sync_start(struct bfa_ioc_s *ioc);
f1d584d70   Krishna Gudipati   [SCSI] bfa: IOC a...
35
36
37
38
  static void bfa_ioc_cb_sync_join(struct bfa_ioc_s *ioc);
  static void bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc);
  static void bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc);
  static bfa_boolean_t bfa_ioc_cb_sync_complete(struct bfa_ioc_s *ioc);
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
39

52f94b6fd   Maggie   [SCSI] bfa: fix r...
40
  static struct bfa_ioc_hwif_s hwif_cb;
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
41

5fbe25c7a   Jing Huang   [SCSI] bfa: fix c...
42
  /*
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
43
44
45
46
47
   * Called from bfa_ioc_attach() to map asic specific calls.
   */
  void
  bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc)
  {
293f82d59   Jing Huang   [SCSI] bfa: enabl...
48
49
50
51
52
53
  	hwif_cb.ioc_pll_init = bfa_ioc_cb_pll_init;
  	hwif_cb.ioc_firmware_lock = bfa_ioc_cb_firmware_lock;
  	hwif_cb.ioc_firmware_unlock = bfa_ioc_cb_firmware_unlock;
  	hwif_cb.ioc_reg_init = bfa_ioc_cb_reg_init;
  	hwif_cb.ioc_map_port = bfa_ioc_cb_map_port;
  	hwif_cb.ioc_isr_mode_set = bfa_ioc_cb_isr_mode_set;
f1d584d70   Krishna Gudipati   [SCSI] bfa: IOC a...
54
  	hwif_cb.ioc_notify_fail = bfa_ioc_cb_notify_fail;
293f82d59   Jing Huang   [SCSI] bfa: enabl...
55
  	hwif_cb.ioc_ownership_reset = bfa_ioc_cb_ownership_reset;
45d7f0cc5   Jing Huang   [SCSI] bfa: kdump...
56
  	hwif_cb.ioc_sync_start = bfa_ioc_cb_sync_start;
f1d584d70   Krishna Gudipati   [SCSI] bfa: IOC a...
57
58
59
60
  	hwif_cb.ioc_sync_join = bfa_ioc_cb_sync_join;
  	hwif_cb.ioc_sync_leave = bfa_ioc_cb_sync_leave;
  	hwif_cb.ioc_sync_ack = bfa_ioc_cb_sync_ack;
  	hwif_cb.ioc_sync_complete = bfa_ioc_cb_sync_complete;
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
61

293f82d59   Jing Huang   [SCSI] bfa: enabl...
62
  	ioc->ioc_hwif = &hwif_cb;
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
63
  }
8f4bfadd2   Jing Huang   [SCSI] bfa: remov...
64
  /*
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
65
66
67
68
69
70
71
72
73
74
75
76
   * Return true if firmware of current driver matches the running firmware.
   */
  static bfa_boolean_t
  bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc)
  {
  	return BFA_TRUE;
  }
  
  static void
  bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc)
  {
  }
5fbe25c7a   Jing Huang   [SCSI] bfa: fix c...
77
  /*
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
78
79
80
   * Notify other functions on HB failure.
   */
  static void
f1d584d70   Krishna Gudipati   [SCSI] bfa: IOC a...
81
  bfa_ioc_cb_notify_fail(struct bfa_ioc_s *ioc)
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
82
  {
111892082   Krishna Gudipati   [SCSI] bfa: Broca...
83
  	writel(~0U, ioc->ioc_regs.err_set);
534402606   Jing Huang   [SCSI] bfa: remov...
84
  	readl(ioc->ioc_regs.err_set);
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
85
  }
5fbe25c7a   Jing Huang   [SCSI] bfa: fix c...
86
  /*
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
87
88
   * Host to LPU mailbox message addresses
   */
d1c61f8ef   Krishna Gudipati   [SCSI] bfa: Remov...
89
  static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
90
91
92
  	{ HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
  	{ HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }
  };
5fbe25c7a   Jing Huang   [SCSI] bfa: fix c...
93
  /*
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
94
95
   * Host <-> LPU mailbox command/status registers
   */
d1c61f8ef   Krishna Gudipati   [SCSI] bfa: Remov...
96
  static struct { u32 hfn, lpu; } iocreg_mbcmd[] = {
a36c61f90   Krishna Gudipati   [SCSI] bfa: clean...
97

0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
98
99
100
101
102
103
104
  	{ HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT },
  	{ HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT }
  };
  
  static void
  bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc)
  {
534402606   Jing Huang   [SCSI] bfa: remov...
105
  	void __iomem *rb;
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
106
107
108
109
110
111
112
113
114
115
116
  	int		pcifn = bfa_ioc_pcifn(ioc);
  
  	rb = bfa_ioc_bar0(ioc);
  
  	ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
  	ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
  	ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
  
  	if (ioc->port_id == 0) {
  		ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
  		ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
f1d584d70   Krishna Gudipati   [SCSI] bfa: IOC a...
117
  		ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC1_STATE_REG;
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
118
119
120
  	} else {
  		ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
  		ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
f1d584d70   Krishna Gudipati   [SCSI] bfa: IOC a...
121
  		ioc->ioc_regs.alt_ioc_fwstate = (rb + BFA_IOC0_STATE_REG);
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
122
  	}
5fbe25c7a   Jing Huang   [SCSI] bfa: fix c...
123
  	/*
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
124
125
126
127
128
129
130
131
132
  	 * Host <-> LPU mailbox command/status registers
  	 */
  	ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd[pcifn].hfn;
  	ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd[pcifn].lpu;
  
  	/*
  	 * PSS control registers
  	 */
  	ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
8b651b429   Krishna Gudipati   [SCSI] bfa: Clear...
133
  	ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
111892082   Krishna Gudipati   [SCSI] bfa: Broca...
134
135
  	ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_LCLK_CTL_REG);
  	ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_SCLK_CTL_REG);
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
136
137
138
139
140
141
  
  	/*
  	 * IOC semaphore registers and serialization
  	 */
  	ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
  	ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
5fbe25c7a   Jing Huang   [SCSI] bfa: fix c...
142
  	/*
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
143
144
145
146
147
148
149
150
151
152
  	 * sram memory access
  	 */
  	ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
  	ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
  
  	/*
  	 * err set reg : for notification of hb failure
  	 */
  	ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
  }
5fbe25c7a   Jing Huang   [SCSI] bfa: fix c...
153
  /*
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
154
155
   * Initialize IOC to port mapping.
   */
a36c61f90   Krishna Gudipati   [SCSI] bfa: clean...
156

0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
157
158
159
  static void
  bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc)
  {
5fbe25c7a   Jing Huang   [SCSI] bfa: fix c...
160
  	/*
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
161
162
163
  	 * For crossbow, port id is same as pci function.
  	 */
  	ioc->port_id = bfa_ioc_pcifn(ioc);
a36c61f90   Krishna Gudipati   [SCSI] bfa: clean...
164

0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
165
166
  	bfa_trc(ioc, ioc->port_id);
  }
5fbe25c7a   Jing Huang   [SCSI] bfa: fix c...
167
  /*
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
168
169
170
171
172
173
   * Set interrupt mode for a function: INTX or MSIX
   */
  static void
  bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
  {
  }
5fbe25c7a   Jing Huang   [SCSI] bfa: fix c...
174
  /*
45d7f0cc5   Jing Huang   [SCSI] bfa: kdump...
175
176
177
178
179
180
181
182
183
   * Synchronized IOC failure processing routines
   */
  static bfa_boolean_t
  bfa_ioc_cb_sync_start(struct bfa_ioc_s *ioc)
  {
  	return bfa_ioc_cb_sync_complete(ioc);
  }
  
  /*
a36c61f90   Krishna Gudipati   [SCSI] bfa: clean...
184
185
186
187
   * Cleanup hw semaphore and usecnt registers
   */
  static void
  bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc)
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
188
  {
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
189
190
  
  	/*
a36c61f90   Krishna Gudipati   [SCSI] bfa: clean...
191
192
193
  	 * Read the hw sem reg to make sure that it is locked
  	 * before we clear it. If it is not locked, writing 1
  	 * will lock it instead of clearing it.
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
194
  	 */
534402606   Jing Huang   [SCSI] bfa: remov...
195
  	readl(ioc->ioc_regs.ioc_sem_reg);
f7f73812e   Maggie Zhang   [SCSI] bfa: clean...
196
  	writel(1, ioc->ioc_regs.ioc_sem_reg);
a36c61f90   Krishna Gudipati   [SCSI] bfa: clean...
197
  }
8f4bfadd2   Jing Huang   [SCSI] bfa: remov...
198
  /*
f1d584d70   Krishna Gudipati   [SCSI] bfa: IOC a...
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
   * Synchronized IOC failure processing routines
   */
  static void
  bfa_ioc_cb_sync_join(struct bfa_ioc_s *ioc)
  {
  }
  
  static void
  bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc)
  {
  }
  
  static void
  bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc)
  {
  	writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
  }
  
  static bfa_boolean_t
  bfa_ioc_cb_sync_complete(struct bfa_ioc_s *ioc)
  {
  	uint32_t fwstate, alt_fwstate;
  	fwstate = readl(ioc->ioc_regs.ioc_fwstate);
a36c61f90   Krishna Gudipati   [SCSI] bfa: clean...
222

8f4bfadd2   Jing Huang   [SCSI] bfa: remov...
223
  	/*
f1d584d70   Krishna Gudipati   [SCSI] bfa: IOC a...
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
  	 * At this point, this IOC is hoding the hw sem in the
  	 * start path (fwcheck) OR in the disable/enable path
  	 * OR to check if the other IOC has acknowledged failure.
  	 *
  	 * So, this IOC can be in UNINIT, INITING, DISABLED, FAIL
  	 * or in MEMTEST states. In a normal scenario, this IOC
  	 * can not be in OP state when this function is called.
  	 *
  	 * However, this IOC could still be in OP state when
  	 * the OS driver is starting up, if the OptROM code has
  	 * left it in that state.
  	 *
  	 * If we had marked this IOC's fwstate as BFI_IOC_FAIL
  	 * in the failure case and now, if the fwstate is not
  	 * BFI_IOC_FAIL it implies that the other PCI fn have
  	 * reinitialized the ASIC or this IOC got disabled, so
  	 * return TRUE.
  	 */
  	if (fwstate == BFI_IOC_UNINIT ||
  		fwstate == BFI_IOC_INITING ||
  		fwstate == BFI_IOC_DISABLED ||
  		fwstate == BFI_IOC_MEMTEST ||
  		fwstate == BFI_IOC_OP)
  		return BFA_TRUE;
  	else {
  		alt_fwstate = readl(ioc->ioc_regs.alt_ioc_fwstate);
  		if (alt_fwstate == BFI_IOC_FAIL ||
  			alt_fwstate == BFI_IOC_DISABLED ||
  			alt_fwstate == BFI_IOC_UNINIT ||
  			alt_fwstate == BFI_IOC_INITING ||
  			alt_fwstate == BFI_IOC_MEMTEST)
  			return BFA_TRUE;
  		else
  			return BFA_FALSE;
  	}
  }
a36c61f90   Krishna Gudipati   [SCSI] bfa: clean...
260
261
  
  bfa_status_t
111892082   Krishna Gudipati   [SCSI] bfa: Broca...
262
  bfa_ioc_cb_pll_init(void __iomem *rb, enum bfi_asic_mode fcmode)
a36c61f90   Krishna Gudipati   [SCSI] bfa: clean...
263
264
  {
  	u32	pll_sclk, pll_fclk;
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
265

111892082   Krishna Gudipati   [SCSI] bfa: Broca...
266
267
268
269
270
271
272
273
  	pll_sclk = __APP_PLL_SCLK_ENABLE | __APP_PLL_SCLK_LRESETN |
  		__APP_PLL_SCLK_P0_1(3U) |
  		__APP_PLL_SCLK_JITLMT0_1(3U) |
  		__APP_PLL_SCLK_CNTLMT0_1(3U);
  	pll_fclk = __APP_PLL_LCLK_ENABLE | __APP_PLL_LCLK_LRESETN |
  		__APP_PLL_LCLK_RSEL200500 | __APP_PLL_LCLK_P0_1(3U) |
  		__APP_PLL_LCLK_JITLMT0_1(3U) |
  		__APP_PLL_LCLK_CNTLMT0_1(3U);
534402606   Jing Huang   [SCSI] bfa: remov...
274
275
276
277
278
279
280
281
  	writel(BFI_IOC_UNINIT, (rb + BFA_IOC0_STATE_REG));
  	writel(BFI_IOC_UNINIT, (rb + BFA_IOC1_STATE_REG));
  	writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
  	writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
  	writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
  	writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
  	writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
  	writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
111892082   Krishna Gudipati   [SCSI] bfa: Broca...
282
283
284
285
286
287
  	writel(__APP_PLL_SCLK_LOGIC_SOFT_RESET, rb + APP_PLL_SCLK_CTL_REG);
  	writel(__APP_PLL_SCLK_BYPASS | __APP_PLL_SCLK_LOGIC_SOFT_RESET,
  			rb + APP_PLL_SCLK_CTL_REG);
  	writel(__APP_PLL_LCLK_LOGIC_SOFT_RESET, rb + APP_PLL_LCLK_CTL_REG);
  	writel(__APP_PLL_LCLK_BYPASS | __APP_PLL_LCLK_LOGIC_SOFT_RESET,
  			rb + APP_PLL_LCLK_CTL_REG);
6a18b1675   Jing Huang   [SCSI] bfa: remov...
288
  	udelay(2);
111892082   Krishna Gudipati   [SCSI] bfa: Broca...
289
290
291
292
293
294
  	writel(__APP_PLL_SCLK_LOGIC_SOFT_RESET, rb + APP_PLL_SCLK_CTL_REG);
  	writel(__APP_PLL_LCLK_LOGIC_SOFT_RESET, rb + APP_PLL_LCLK_CTL_REG);
  	writel(pll_sclk | __APP_PLL_SCLK_LOGIC_SOFT_RESET,
  			rb + APP_PLL_SCLK_CTL_REG);
  	writel(pll_fclk | __APP_PLL_LCLK_LOGIC_SOFT_RESET,
  			rb + APP_PLL_LCLK_CTL_REG);
6a18b1675   Jing Huang   [SCSI] bfa: remov...
295
  	udelay(2000);
534402606   Jing Huang   [SCSI] bfa: remov...
296
297
  	writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
  	writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
111892082   Krishna Gudipati   [SCSI] bfa: Broca...
298
299
  	writel(pll_sclk, (rb + APP_PLL_SCLK_CTL_REG));
  	writel(pll_fclk, (rb + APP_PLL_LCLK_CTL_REG));
0a20de446   Krishna Gudipati   [SCSI] bfa: IOC c...
300
301
302
  
  	return BFA_STATUS_OK;
  }