]>
Commit | Line | Data |
---|---|---|
dea3101e JB |
1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | |
c44ce173 | 3 | * Fibre Channel Host Bus Adapters. * |
9413afff | 4 | * Copyright (C) 2004-2007 Emulex. All rights reserved. * |
c44ce173 | 5 | * EMULEX and SLI are trademarks of Emulex. * |
dea3101e | 6 | * www.emulex.com * |
c44ce173 | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
dea3101e JB |
8 | * * |
9 | * This program is free software; you can redistribute it and/or * | |
c44ce173 JSEC |
10 | * modify it under the terms of version 2 of the GNU General * |
11 | * Public License as published by the Free Software Foundation. * | |
12 | * This program is distributed in the hope that it will be useful. * | |
13 | * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * | |
14 | * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * | |
15 | * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * | |
16 | * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * | |
17 | * TO BE LEGALLY INVALID. See the GNU General Public License for * | |
18 | * more details, a copy of which can be found in the file COPYING * | |
19 | * included with this package. * | |
dea3101e JB |
20 | *******************************************************************/ |
21 | ||
dea3101e JB |
22 | #include <linux/blkdev.h> |
23 | #include <linux/pci.h> | |
24 | #include <linux/interrupt.h> | |
25 | ||
f888ba3c JSEC |
26 | #include <scsi/scsi_device.h> |
27 | #include <scsi/scsi_transport_fc.h> | |
28 | ||
91886523 JSEC |
29 | #include <scsi/scsi.h> |
30 | ||
dea3101e JB |
31 | #include "lpfc_hw.h" |
32 | #include "lpfc_sli.h" | |
33 | #include "lpfc_disc.h" | |
34 | #include "lpfc_scsi.h" | |
35 | #include "lpfc.h" | |
36 | #include "lpfc_logmsg.h" | |
37 | #include "lpfc_crtn.h" | |
38 | #include "lpfc_compat.h" | |
39 | ||
e59058c4 JS |
40 | /** |
41 | * lpfc_dump_mem: Prepare a mailbox command for retrieving HBA's VPD memory. | |
42 | * @phba: pointer to lpfc hba data structure. | |
43 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
44 | * @offset: offset for dumping VPD memory mailbox command. | |
45 | * | |
46 | * The dump mailbox command provides a method for the device driver to obtain | |
47 | * various types of information from the HBA device. | |
48 | * | |
49 | * This routine prepares the mailbox command for dumping HBA Vital Product | |
50 | * Data (VPD) memory. This mailbox command is to be used for retrieving a | |
51 | * portion (DMP_RSP_SIZE bytes) of a HBA's VPD from the HBA at an address | |
52 | * offset specified by the offset parameter. | |
53 | **/ | |
dea3101e JB |
54 | void |
55 | lpfc_dump_mem(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint16_t offset) | |
56 | { | |
57 | MAILBOX_t *mb; | |
58 | void *ctx; | |
59 | ||
60 | mb = &pmb->mb; | |
61 | ctx = pmb->context2; | |
62 | ||
63 | /* Setup to dump VPD region */ | |
64 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
65 | mb->mbxCommand = MBX_DUMP_MEMORY; | |
66 | mb->un.varDmp.cv = 1; | |
67 | mb->un.varDmp.type = DMP_NV_PARAMS; | |
68 | mb->un.varDmp.entry_index = offset; | |
69 | mb->un.varDmp.region_id = DMP_REGION_VPD; | |
70 | mb->un.varDmp.word_cnt = (DMP_RSP_SIZE / sizeof (uint32_t)); | |
71 | mb->un.varDmp.co = 0; | |
72 | mb->un.varDmp.resp_offset = 0; | |
73 | pmb->context2 = ctx; | |
74 | mb->mbxOwner = OWN_HOST; | |
75 | return; | |
76 | } | |
77 | ||
e59058c4 JS |
78 | /** |
79 | * lpfc_read_nv: Prepare a mailbox command for reading HBA's NVRAM param. | |
80 | * @phba: pointer to lpfc hba data structure. | |
81 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
82 | * | |
83 | * The read NVRAM mailbox command returns the HBA's non-volatile parameters | |
84 | * that are used as defaults when the Fibre Channel link is brought on-line. | |
85 | * | |
86 | * This routine prepares the mailbox command for reading information stored | |
87 | * in the HBA's NVRAM. Specifically, the HBA's WWNN and WWPN. | |
88 | **/ | |
dea3101e JB |
89 | void |
90 | lpfc_read_nv(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |
91 | { | |
92 | MAILBOX_t *mb; | |
93 | ||
94 | mb = &pmb->mb; | |
95 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
96 | mb->mbxCommand = MBX_READ_NV; | |
97 | mb->mbxOwner = OWN_HOST; | |
98 | return; | |
99 | } | |
100 | ||
e59058c4 JS |
101 | /** |
102 | * lpfc_config_async: Prepare a mailbox command for enabling HBA async event. | |
103 | * @phba: pointer to lpfc hba data structure. | |
104 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
105 | * @ring: ring number for the asynchronous event to be configured. | |
106 | * | |
107 | * The asynchronous event enable mailbox command is used to enable the | |
108 | * asynchronous event posting via the ASYNC_STATUS_CN IOCB response and | |
109 | * specifies the default ring to which events are posted. | |
110 | * | |
111 | * This routine prepares the mailbox command for enabling HBA asynchronous | |
112 | * event support on a IOCB ring. | |
113 | **/ | |
57127f15 JS |
114 | void |
115 | lpfc_config_async(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, | |
116 | uint32_t ring) | |
117 | { | |
118 | MAILBOX_t *mb; | |
119 | ||
120 | mb = &pmb->mb; | |
121 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
122 | mb->mbxCommand = MBX_ASYNCEVT_ENABLE; | |
123 | mb->un.varCfgAsyncEvent.ring = ring; | |
124 | mb->mbxOwner = OWN_HOST; | |
125 | return; | |
126 | } | |
127 | ||
e59058c4 JS |
128 | /** |
129 | * lpfc_heart_beat: Prepare a mailbox command for heart beat. | |
130 | * @phba: pointer to lpfc hba data structure. | |
131 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
132 | * | |
133 | * The heart beat mailbox command is used to detect an unresponsive HBA, which | |
134 | * is defined as any device where no error attention is sent and both mailbox | |
135 | * and rings are not processed. | |
136 | * | |
137 | * This routine prepares the mailbox command for issuing a heart beat in the | |
138 | * form of mailbox command to the HBA. The timely completion of the heart | |
139 | * beat mailbox command indicates the health of the HBA. | |
140 | **/ | |
858c9f6c JS |
141 | void |
142 | lpfc_heart_beat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |
143 | { | |
144 | MAILBOX_t *mb; | |
145 | ||
146 | mb = &pmb->mb; | |
147 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
148 | mb->mbxCommand = MBX_HEARTBEAT; | |
149 | mb->mbxOwner = OWN_HOST; | |
150 | return; | |
151 | } | |
152 | ||
e59058c4 JS |
153 | /** |
154 | * lpfc_read_la: Prepare a mailbox command for reading HBA link attention. | |
155 | * @phba: pointer to lpfc hba data structure. | |
156 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
157 | * @mp: DMA buffer memory for reading the link attention information into. | |
158 | * | |
159 | * The read link attention mailbox command is issued to read the Link Event | |
160 | * Attention information indicated by the HBA port when the Link Event bit | |
161 | * of the Host Attention (HSTATT) register is set to 1. A Link Event | |
162 | * Attention occurs based on an exception detected at the Fibre Channel link | |
163 | * interface. | |
164 | * | |
165 | * This routine prepares the mailbox command for reading HBA link attention | |
166 | * information. A DMA memory has been set aside and address passed to the | |
167 | * HBA through @mp for the HBA to DMA link attention information into the | |
168 | * memory as part of the execution of the mailbox command. | |
169 | * | |
170 | * Return codes | |
171 | * 0 - Success (currently always return 0) | |
172 | **/ | |
dea3101e JB |
173 | int |
174 | lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp) | |
175 | { | |
176 | MAILBOX_t *mb; | |
177 | struct lpfc_sli *psli; | |
178 | ||
179 | psli = &phba->sli; | |
180 | mb = &pmb->mb; | |
181 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
182 | ||
183 | INIT_LIST_HEAD(&mp->list); | |
184 | mb->mbxCommand = MBX_READ_LA64; | |
185 | mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128; | |
186 | mb->un.varReadLA.un.lilpBde64.addrHigh = putPaddrHigh(mp->phys); | |
187 | mb->un.varReadLA.un.lilpBde64.addrLow = putPaddrLow(mp->phys); | |
188 | ||
189 | /* Save address for later completion and set the owner to host so that | |
190 | * the FW knows this mailbox is available for processing. | |
191 | */ | |
192 | pmb->context1 = (uint8_t *) mp; | |
193 | mb->mbxOwner = OWN_HOST; | |
92d7f7b0 | 194 | return (0); |
dea3101e JB |
195 | } |
196 | ||
e59058c4 JS |
197 | /** |
198 | * lpfc_clear_la: Prepare a mailbox command for clearing HBA link attention. | |
199 | * @phba: pointer to lpfc hba data structure. | |
200 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
201 | * | |
202 | * The clear link attention mailbox command is issued to clear the link event | |
203 | * attention condition indicated by the Link Event bit of the Host Attention | |
204 | * (HSTATT) register. The link event attention condition is cleared only if | |
205 | * the event tag specified matches that of the current link event counter. | |
206 | * The current event tag is read using the read link attention event mailbox | |
207 | * command. | |
208 | * | |
209 | * This routine prepares the mailbox command for clearing HBA link attention | |
210 | * information. | |
211 | **/ | |
dea3101e JB |
212 | void |
213 | lpfc_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |
214 | { | |
215 | MAILBOX_t *mb; | |
216 | ||
217 | mb = &pmb->mb; | |
218 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
219 | ||
220 | mb->un.varClearLA.eventTag = phba->fc_eventTag; | |
221 | mb->mbxCommand = MBX_CLEAR_LA; | |
222 | mb->mbxOwner = OWN_HOST; | |
223 | return; | |
224 | } | |
225 | ||
e59058c4 JS |
226 | /** |
227 | * lpfc_config_link: Prepare a mailbox command for configuring link on a HBA. | |
228 | * @phba: pointer to lpfc hba data structure. | |
229 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
230 | * | |
231 | * The configure link mailbox command is used before the initialize link | |
232 | * mailbox command to override default value and to configure link-oriented | |
233 | * parameters such as DID address and various timers. Typically, this | |
234 | * command would be used after an F_Port login to set the returned DID address | |
235 | * and the fabric timeout values. This command is not valid before a configure | |
236 | * port command has configured the HBA port. | |
237 | * | |
238 | * This routine prepares the mailbox command for configuring link on a HBA. | |
239 | **/ | |
dea3101e JB |
240 | void |
241 | lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |
242 | { | |
2e0fef85 | 243 | struct lpfc_vport *vport = phba->pport; |
dea3101e JB |
244 | MAILBOX_t *mb = &pmb->mb; |
245 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
246 | ||
247 | /* NEW_FEATURE | |
248 | * SLI-2, Coalescing Response Feature. | |
249 | */ | |
250 | if (phba->cfg_cr_delay) { | |
251 | mb->un.varCfgLnk.cr = 1; | |
252 | mb->un.varCfgLnk.ci = 1; | |
253 | mb->un.varCfgLnk.cr_delay = phba->cfg_cr_delay; | |
254 | mb->un.varCfgLnk.cr_count = phba->cfg_cr_count; | |
255 | } | |
256 | ||
2e0fef85 | 257 | mb->un.varCfgLnk.myId = vport->fc_myDID; |
dea3101e JB |
258 | mb->un.varCfgLnk.edtov = phba->fc_edtov; |
259 | mb->un.varCfgLnk.arbtov = phba->fc_arbtov; | |
260 | mb->un.varCfgLnk.ratov = phba->fc_ratov; | |
261 | mb->un.varCfgLnk.rttov = phba->fc_rttov; | |
262 | mb->un.varCfgLnk.altov = phba->fc_altov; | |
263 | mb->un.varCfgLnk.crtov = phba->fc_crtov; | |
264 | mb->un.varCfgLnk.citov = phba->fc_citov; | |
265 | ||
266 | if (phba->cfg_ack0) | |
267 | mb->un.varCfgLnk.ack0_enable = 1; | |
268 | ||
269 | mb->mbxCommand = MBX_CONFIG_LINK; | |
270 | mb->mbxOwner = OWN_HOST; | |
271 | return; | |
272 | } | |
273 | ||
e59058c4 JS |
274 | /** |
275 | * lpfc_init_link: Prepare a mailbox command for initialize link on a HBA. | |
276 | * @phba: pointer to lpfc hba data structure. | |
277 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
278 | * @topology: the link topology for the link to be initialized to. | |
279 | * @linkspeed: the link speed for the link to be initialized to. | |
280 | * | |
281 | * The initialize link mailbox command is used to initialize the Fibre | |
282 | * Channel link. This command must follow a configure port command that | |
283 | * establishes the mode of operation. | |
284 | * | |
285 | * This routine prepares the mailbox command for initializing link on a HBA | |
286 | * with the specified link topology and speed. | |
287 | **/ | |
dea3101e JB |
288 | void |
289 | lpfc_init_link(struct lpfc_hba * phba, | |
290 | LPFC_MBOXQ_t * pmb, uint32_t topology, uint32_t linkspeed) | |
291 | { | |
292 | lpfc_vpd_t *vpd; | |
293 | struct lpfc_sli *psli; | |
294 | MAILBOX_t *mb; | |
295 | ||
296 | mb = &pmb->mb; | |
297 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
298 | ||
299 | psli = &phba->sli; | |
300 | switch (topology) { | |
301 | case FLAGS_TOPOLOGY_MODE_LOOP_PT: | |
302 | mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP; | |
303 | mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER; | |
304 | break; | |
305 | case FLAGS_TOPOLOGY_MODE_PT_PT: | |
306 | mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT; | |
307 | break; | |
308 | case FLAGS_TOPOLOGY_MODE_LOOP: | |
309 | mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP; | |
310 | break; | |
311 | case FLAGS_TOPOLOGY_MODE_PT_LOOP: | |
312 | mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT; | |
313 | mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER; | |
314 | break; | |
367c2713 JW |
315 | case FLAGS_LOCAL_LB: |
316 | mb->un.varInitLnk.link_flags = FLAGS_LOCAL_LB; | |
317 | break; | |
dea3101e JB |
318 | } |
319 | ||
4b0b91d4 JS |
320 | /* Enable asynchronous ABTS responses from firmware */ |
321 | mb->un.varInitLnk.link_flags |= FLAGS_IMED_ABORT; | |
322 | ||
dea3101e JB |
323 | /* NEW_FEATURE |
324 | * Setting up the link speed | |
325 | */ | |
326 | vpd = &phba->vpd; | |
327 | if (vpd->rev.feaLevelHigh >= 0x02){ | |
92d7f7b0 | 328 | switch(linkspeed){ |
dea3101e JB |
329 | case LINK_SPEED_1G: |
330 | case LINK_SPEED_2G: | |
331 | case LINK_SPEED_4G: | |
b87eab38 | 332 | case LINK_SPEED_8G: |
dea3101e JB |
333 | mb->un.varInitLnk.link_flags |= |
334 | FLAGS_LINK_SPEED; | |
335 | mb->un.varInitLnk.link_speed = linkspeed; | |
336 | break; | |
337 | case LINK_SPEED_AUTO: | |
338 | default: | |
339 | mb->un.varInitLnk.link_speed = | |
340 | LINK_SPEED_AUTO; | |
341 | break; | |
342 | } | |
343 | ||
344 | } | |
345 | else | |
346 | mb->un.varInitLnk.link_speed = LINK_SPEED_AUTO; | |
347 | ||
348 | mb->mbxCommand = (volatile uint8_t)MBX_INIT_LINK; | |
349 | mb->mbxOwner = OWN_HOST; | |
350 | mb->un.varInitLnk.fabric_AL_PA = phba->fc_pref_ALPA; | |
351 | return; | |
352 | } | |
353 | ||
e59058c4 JS |
354 | /** |
355 | * lpfc_read_sparam: Prepare a mailbox command for reading HBA parameters. | |
356 | * @phba: pointer to lpfc hba data structure. | |
357 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
358 | * @vpi: virtual N_Port identifier. | |
359 | * | |
360 | * The read service parameter mailbox command is used to read the HBA port | |
361 | * service parameters. The service parameters are read into the buffer | |
362 | * specified directly by a BDE in the mailbox command. These service | |
363 | * parameters may then be used to build the payload of an N_Port/F_POrt | |
364 | * login request and reply (LOGI/ACC). | |
365 | * | |
366 | * This routine prepares the mailbox command for reading HBA port service | |
367 | * parameters. The DMA memory is allocated in this function and the addresses | |
368 | * are populated into the mailbox command for the HBA to DMA the service | |
369 | * parameters into. | |
370 | * | |
371 | * Return codes | |
372 | * 0 - Success | |
373 | * 1 - DMA memory allocation failed | |
374 | **/ | |
dea3101e | 375 | int |
92d7f7b0 | 376 | lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi) |
dea3101e JB |
377 | { |
378 | struct lpfc_dmabuf *mp; | |
379 | MAILBOX_t *mb; | |
380 | struct lpfc_sli *psli; | |
381 | ||
382 | psli = &phba->sli; | |
383 | mb = &pmb->mb; | |
384 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
385 | ||
386 | mb->mbxOwner = OWN_HOST; | |
387 | ||
388 | /* Get a buffer to hold the HBAs Service Parameters */ | |
389 | ||
98c9ea5c JS |
390 | mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); |
391 | if (mp) | |
392 | mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys); | |
393 | if (!mp || !mp->virt) { | |
c9475cb0 | 394 | kfree(mp); |
dea3101e JB |
395 | mb->mbxCommand = MBX_READ_SPARM64; |
396 | /* READ_SPARAM: no buffers */ | |
e8b62011 JS |
397 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, |
398 | "0301 READ_SPARAM: no buffers\n"); | |
92d7f7b0 | 399 | return (1); |
dea3101e JB |
400 | } |
401 | INIT_LIST_HEAD(&mp->list); | |
402 | mb->mbxCommand = MBX_READ_SPARM64; | |
403 | mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm); | |
404 | mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys); | |
405 | mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys); | |
92d7f7b0 | 406 | mb->un.varRdSparm.vpi = vpi; |
dea3101e JB |
407 | |
408 | /* save address for completion */ | |
409 | pmb->context1 = mp; | |
410 | ||
92d7f7b0 | 411 | return (0); |
dea3101e JB |
412 | } |
413 | ||
e59058c4 JS |
414 | /** |
415 | * lpfc_unreg_did: Prepare a mailbox command for unregistering DID. | |
416 | * @phba: pointer to lpfc hba data structure. | |
417 | * @vpi: virtual N_Port identifier. | |
418 | * @did: remote port identifier. | |
419 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
420 | * | |
421 | * The unregister DID mailbox command is used to unregister an N_Port/F_Port | |
422 | * login for an unknown RPI by specifying the DID of a remote port. This | |
423 | * command frees an RPI context in the HBA port. This has the effect of | |
424 | * performing an implicit N_Port/F_Port logout. | |
425 | * | |
426 | * This routine prepares the mailbox command for unregistering a remote | |
427 | * N_Port/F_Port (DID) login. | |
428 | **/ | |
dea3101e | 429 | void |
92d7f7b0 JS |
430 | lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did, |
431 | LPFC_MBOXQ_t * pmb) | |
dea3101e JB |
432 | { |
433 | MAILBOX_t *mb; | |
434 | ||
435 | mb = &pmb->mb; | |
436 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
437 | ||
438 | mb->un.varUnregDID.did = did; | |
92d7f7b0 | 439 | mb->un.varUnregDID.vpi = vpi; |
dea3101e JB |
440 | |
441 | mb->mbxCommand = MBX_UNREG_D_ID; | |
442 | mb->mbxOwner = OWN_HOST; | |
443 | return; | |
444 | } | |
445 | ||
e59058c4 JS |
446 | /** |
447 | * lpfc_read_config: Prepare a mailbox command for reading HBA configuration. | |
448 | * @phba: pointer to lpfc hba data structure. | |
449 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
450 | * | |
451 | * The read configuration mailbox command is used to read the HBA port | |
452 | * configuration parameters. This mailbox command provides a method for | |
453 | * seeing any parameters that may have changed via various configuration | |
454 | * mailbox commands. | |
455 | * | |
456 | * This routine prepares the mailbox command for reading out HBA configuration | |
457 | * parameters. | |
458 | **/ | |
dea3101e JB |
459 | void |
460 | lpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |
461 | { | |
462 | MAILBOX_t *mb; | |
463 | ||
464 | mb = &pmb->mb; | |
465 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
466 | ||
467 | mb->mbxCommand = MBX_READ_CONFIG; | |
468 | mb->mbxOwner = OWN_HOST; | |
469 | return; | |
470 | } | |
471 | ||
e59058c4 JS |
472 | /** |
473 | * lpfc_read_lnk_stat: Prepare a mailbox command for reading HBA link stats. | |
474 | * @phba: pointer to lpfc hba data structure. | |
475 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
476 | * | |
477 | * The read link status mailbox command is used to read the link status from | |
478 | * the HBA. Link status includes all link-related error counters. These | |
479 | * counters are maintained by the HBA and originated in the link hardware | |
480 | * unit. Note that all of these counters wrap. | |
481 | * | |
482 | * This routine prepares the mailbox command for reading out HBA link status. | |
483 | **/ | |
7bb3b137 JW |
484 | void |
485 | lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |
486 | { | |
487 | MAILBOX_t *mb; | |
488 | ||
489 | mb = &pmb->mb; | |
490 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
491 | ||
492 | mb->mbxCommand = MBX_READ_LNK_STAT; | |
493 | mb->mbxOwner = OWN_HOST; | |
494 | return; | |
495 | } | |
496 | ||
e59058c4 JS |
497 | /** |
498 | * lpfc_reg_login: Prepare a mailbox command for registering remote login. | |
499 | * @phba: pointer to lpfc hba data structure. | |
500 | * @vpi: virtual N_Port identifier. | |
501 | * @did: remote port identifier. | |
502 | * @param: pointer to memory holding the server parameters. | |
503 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
504 | * @flag: action flag to be passed back for the complete function. | |
505 | * | |
506 | * The registration login mailbox command is used to register an N_Port or | |
507 | * F_Port login. This registration allows the HBA to cache the remote N_Port | |
508 | * service parameters internally and thereby make the appropriate FC-2 | |
509 | * decisions. The remote port service parameters are handed off by the driver | |
510 | * to the HBA using a descriptor entry that directly identifies a buffer in | |
511 | * host memory. In exchange, the HBA returns an RPI identifier. | |
512 | * | |
513 | * This routine prepares the mailbox command for registering remote port login. | |
514 | * The function allocates DMA buffer for passing the service parameters to the | |
515 | * HBA with the mailbox command. | |
516 | * | |
517 | * Return codes | |
518 | * 0 - Success | |
519 | * 1 - DMA memory allocation failed | |
520 | **/ | |
dea3101e | 521 | int |
92d7f7b0 JS |
522 | lpfc_reg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t did, |
523 | uint8_t *param, LPFC_MBOXQ_t *pmb, uint32_t flag) | |
dea3101e | 524 | { |
2e0fef85 | 525 | MAILBOX_t *mb = &pmb->mb; |
dea3101e JB |
526 | uint8_t *sparam; |
527 | struct lpfc_dmabuf *mp; | |
dea3101e | 528 | |
dea3101e JB |
529 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
530 | ||
531 | mb->un.varRegLogin.rpi = 0; | |
92d7f7b0 | 532 | mb->un.varRegLogin.vpi = vpi; |
dea3101e JB |
533 | mb->un.varRegLogin.did = did; |
534 | mb->un.varWords[30] = flag; /* Set flag to issue action on cmpl */ | |
535 | ||
536 | mb->mbxOwner = OWN_HOST; | |
537 | ||
538 | /* Get a buffer to hold NPorts Service Parameters */ | |
98c9ea5c JS |
539 | mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); |
540 | if (mp) | |
541 | mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys); | |
542 | if (!mp || !mp->virt) { | |
c9475cb0 | 543 | kfree(mp); |
dea3101e JB |
544 | mb->mbxCommand = MBX_REG_LOGIN64; |
545 | /* REG_LOGIN: no buffers */ | |
92d7f7b0 | 546 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, |
e8b62011 JS |
547 | "0302 REG_LOGIN: no buffers, VPI:%d DID:x%x, " |
548 | "flag x%x\n", vpi, did, flag); | |
92d7f7b0 | 549 | return (1); |
dea3101e JB |
550 | } |
551 | INIT_LIST_HEAD(&mp->list); | |
552 | sparam = mp->virt; | |
553 | ||
554 | /* Copy param's into a new buffer */ | |
555 | memcpy(sparam, param, sizeof (struct serv_parm)); | |
556 | ||
557 | /* save address for completion */ | |
558 | pmb->context1 = (uint8_t *) mp; | |
559 | ||
560 | mb->mbxCommand = MBX_REG_LOGIN64; | |
561 | mb->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm); | |
562 | mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys); | |
563 | mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys); | |
564 | ||
92d7f7b0 | 565 | return (0); |
dea3101e JB |
566 | } |
567 | ||
e59058c4 JS |
568 | /** |
569 | * lpfc_unreg_login: Prepare a mailbox command for unregistering remote login. | |
570 | * @phba: pointer to lpfc hba data structure. | |
571 | * @vpi: virtual N_Port identifier. | |
572 | * @rpi: remote port identifier | |
573 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
574 | * | |
575 | * The unregistration login mailbox command is used to unregister an N_Port | |
576 | * or F_Port login. This command frees an RPI context in the HBA. It has the | |
577 | * effect of performing an implicit N_Port/F_Port logout. | |
578 | * | |
579 | * This routine prepares the mailbox command for unregistering remote port | |
580 | * login. | |
581 | **/ | |
dea3101e | 582 | void |
92d7f7b0 JS |
583 | lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi, |
584 | LPFC_MBOXQ_t * pmb) | |
dea3101e JB |
585 | { |
586 | MAILBOX_t *mb; | |
587 | ||
588 | mb = &pmb->mb; | |
589 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
590 | ||
591 | mb->un.varUnregLogin.rpi = (uint16_t) rpi; | |
592 | mb->un.varUnregLogin.rsvd1 = 0; | |
92d7f7b0 | 593 | mb->un.varUnregLogin.vpi = vpi; |
dea3101e JB |
594 | |
595 | mb->mbxCommand = MBX_UNREG_LOGIN; | |
596 | mb->mbxOwner = OWN_HOST; | |
597 | return; | |
598 | } | |
599 | ||
e59058c4 JS |
600 | /** |
601 | * lpfc_reg_vpi: Prepare a mailbox command for registering vport identifier. | |
602 | * @phba: pointer to lpfc hba data structure. | |
603 | * @vpi: virtual N_Port identifier. | |
604 | * @sid: Fibre Channel S_ID (N_Port_ID assigned to a virtual N_Port). | |
605 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
606 | * | |
607 | * The registration vport identifier mailbox command is used to activate a | |
608 | * virtual N_Port after it has acquired an N_Port_ID. The HBA validates the | |
609 | * N_Port_ID against the information in the selected virtual N_Port context | |
610 | * block and marks it active to allow normal processing of IOCB commands and | |
611 | * received unsolicited exchanges. | |
612 | * | |
613 | * This routine prepares the mailbox command for registering a virtual N_Port. | |
614 | **/ | |
92d7f7b0 JS |
615 | void |
616 | lpfc_reg_vpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t sid, | |
617 | LPFC_MBOXQ_t *pmb) | |
618 | { | |
619 | MAILBOX_t *mb = &pmb->mb; | |
620 | ||
621 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
622 | ||
623 | mb->un.varRegVpi.vpi = vpi; | |
624 | mb->un.varRegVpi.sid = sid; | |
625 | ||
626 | mb->mbxCommand = MBX_REG_VPI; | |
627 | mb->mbxOwner = OWN_HOST; | |
628 | return; | |
629 | ||
630 | } | |
631 | ||
e59058c4 JS |
632 | /** |
633 | * lpfc_unreg_vpi: Prepare a mailbox command for unregistering vport id. | |
634 | * @phba: pointer to lpfc hba data structure. | |
635 | * @vpi: virtual N_Port identifier. | |
636 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
637 | * | |
638 | * The unregistration vport identifier mailbox command is used to inactivate | |
639 | * a virtual N_Port. The driver must have logged out and unregistered all | |
640 | * remote N_Ports to abort any activity on the virtual N_Port. The HBA will | |
641 | * unregisters any default RPIs associated with the specified vpi, aborting | |
642 | * any active exchanges. The HBA will post the mailbox response after making | |
643 | * the virtual N_Port inactive. | |
644 | * | |
645 | * This routine prepares the mailbox command for unregistering a virtual | |
646 | * N_Port. | |
647 | **/ | |
92d7f7b0 JS |
648 | void |
649 | lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb) | |
650 | { | |
651 | MAILBOX_t *mb = &pmb->mb; | |
652 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
653 | ||
654 | mb->un.varUnregVpi.vpi = vpi; | |
655 | ||
656 | mb->mbxCommand = MBX_UNREG_VPI; | |
657 | mb->mbxOwner = OWN_HOST; | |
658 | return; | |
659 | ||
660 | } | |
661 | ||
e59058c4 JS |
662 | /** |
663 | * lpfc_config_pcb_setup: Set up IOCB rings in the Port Control Block (PCB) | |
664 | * @phba: pointer to lpfc hba data structure. | |
665 | * | |
666 | * This routine sets up and initializes the IOCB rings in the Port Control | |
667 | * Block (PCB). | |
668 | **/ | |
dea3101e JB |
669 | static void |
670 | lpfc_config_pcb_setup(struct lpfc_hba * phba) | |
671 | { | |
672 | struct lpfc_sli *psli = &phba->sli; | |
673 | struct lpfc_sli_ring *pring; | |
674 | PCB_t *pcbp = &phba->slim2p->pcb; | |
675 | dma_addr_t pdma_addr; | |
676 | uint32_t offset; | |
2e0fef85 | 677 | uint32_t iocbCnt = 0; |
dea3101e JB |
678 | int i; |
679 | ||
dea3101e JB |
680 | pcbp->maxRing = (psli->num_rings - 1); |
681 | ||
dea3101e JB |
682 | for (i = 0; i < psli->num_rings; i++) { |
683 | pring = &psli->ring[i]; | |
2e0fef85 | 684 | |
ed957684 | 685 | pring->sizeCiocb = phba->sli_rev == 3 ? SLI3_IOCB_CMD_SIZE: |
92d7f7b0 | 686 | SLI2_IOCB_CMD_SIZE; |
ed957684 | 687 | pring->sizeRiocb = phba->sli_rev == 3 ? SLI3_IOCB_RSP_SIZE: |
92d7f7b0 | 688 | SLI2_IOCB_RSP_SIZE; |
dea3101e JB |
689 | /* A ring MUST have both cmd and rsp entries defined to be |
690 | valid */ | |
691 | if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) { | |
692 | pcbp->rdsc[i].cmdEntries = 0; | |
693 | pcbp->rdsc[i].rspEntries = 0; | |
694 | pcbp->rdsc[i].cmdAddrHigh = 0; | |
695 | pcbp->rdsc[i].rspAddrHigh = 0; | |
696 | pcbp->rdsc[i].cmdAddrLow = 0; | |
697 | pcbp->rdsc[i].rspAddrLow = 0; | |
698 | pring->cmdringaddr = NULL; | |
699 | pring->rspringaddr = NULL; | |
700 | continue; | |
701 | } | |
702 | /* Command ring setup for ring */ | |
92d7f7b0 | 703 | pring->cmdringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt]; |
dea3101e JB |
704 | pcbp->rdsc[i].cmdEntries = pring->numCiocb; |
705 | ||
92d7f7b0 JS |
706 | offset = (uint8_t *) &phba->slim2p->IOCBs[iocbCnt] - |
707 | (uint8_t *) phba->slim2p; | |
dea3101e JB |
708 | pdma_addr = phba->slim2p_mapping + offset; |
709 | pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr); | |
710 | pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr); | |
711 | iocbCnt += pring->numCiocb; | |
712 | ||
713 | /* Response ring setup for ring */ | |
92d7f7b0 | 714 | pring->rspringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt]; |
dea3101e JB |
715 | |
716 | pcbp->rdsc[i].rspEntries = pring->numRiocb; | |
717 | offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] - | |
718 | (uint8_t *)phba->slim2p; | |
719 | pdma_addr = phba->slim2p_mapping + offset; | |
720 | pcbp->rdsc[i].rspAddrHigh = putPaddrHigh(pdma_addr); | |
721 | pcbp->rdsc[i].rspAddrLow = putPaddrLow(pdma_addr); | |
722 | iocbCnt += pring->numRiocb; | |
723 | } | |
724 | } | |
725 | ||
e59058c4 JS |
726 | /** |
727 | * lpfc_read_rev: Prepare a mailbox command for reading HBA revision. | |
728 | * @phba: pointer to lpfc hba data structure. | |
729 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
730 | * | |
731 | * The read revision mailbox command is used to read the revision levels of | |
732 | * the HBA components. These components include hardware units, resident | |
733 | * firmware, and available firmware. HBAs that supports SLI-3 mode of | |
734 | * operation provide different response information depending on the version | |
735 | * requested by the driver. | |
736 | * | |
737 | * This routine prepares the mailbox command for reading HBA revision | |
738 | * information. | |
739 | **/ | |
dea3101e JB |
740 | void |
741 | lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |
742 | { | |
2e0fef85 | 743 | MAILBOX_t *mb = &pmb->mb; |
dea3101e JB |
744 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
745 | mb->un.varRdRev.cv = 1; | |
ed957684 | 746 | mb->un.varRdRev.v3req = 1; /* Request SLI3 info */ |
dea3101e JB |
747 | mb->mbxCommand = MBX_READ_REV; |
748 | mb->mbxOwner = OWN_HOST; | |
749 | return; | |
750 | } | |
751 | ||
e59058c4 JS |
752 | /** |
753 | * lpfc_build_hbq_profile2: Set up the HBQ Selection Profile 2. | |
754 | * @hbqmb: pointer to the HBQ configuration data structure in mailbox command. | |
755 | * @hbq_desc: pointer to the HBQ selection profile descriptor. | |
756 | * | |
757 | * The Host Buffer Queue (HBQ) Selection Profile 2 specifies that the HBA | |
758 | * tests the incoming frames' R_CTL/TYPE fields with works 10:15 and performs | |
759 | * the Sequence Length Test using the fields in the Selection Profile 2 | |
760 | * extension in words 20:31. | |
761 | **/ | |
ed957684 JS |
762 | static void |
763 | lpfc_build_hbq_profile2(struct config_hbq_var *hbqmb, | |
764 | struct lpfc_hbq_init *hbq_desc) | |
765 | { | |
766 | hbqmb->profiles.profile2.seqlenbcnt = hbq_desc->seqlenbcnt; | |
767 | hbqmb->profiles.profile2.maxlen = hbq_desc->maxlen; | |
768 | hbqmb->profiles.profile2.seqlenoff = hbq_desc->seqlenoff; | |
769 | } | |
770 | ||
e59058c4 JS |
771 | /** |
772 | * lpfc_build_hbq_profile3: Set up the HBQ Selection Profile 3. | |
773 | * @hbqmb: pointer to the HBQ configuration data structure in mailbox command. | |
774 | * @hbq_desc: pointer to the HBQ selection profile descriptor. | |
775 | * | |
776 | * The Host Buffer Queue (HBQ) Selection Profile 3 specifies that the HBA | |
777 | * tests the incoming frame's R_CTL/TYPE fields with words 10:15 and performs | |
778 | * the Sequence Length Test and Byte Field Test using the fields in the | |
779 | * Selection Profile 3 extension in words 20:31. | |
780 | **/ | |
ed957684 JS |
781 | static void |
782 | lpfc_build_hbq_profile3(struct config_hbq_var *hbqmb, | |
783 | struct lpfc_hbq_init *hbq_desc) | |
784 | { | |
785 | hbqmb->profiles.profile3.seqlenbcnt = hbq_desc->seqlenbcnt; | |
786 | hbqmb->profiles.profile3.maxlen = hbq_desc->maxlen; | |
787 | hbqmb->profiles.profile3.cmdcodeoff = hbq_desc->cmdcodeoff; | |
788 | hbqmb->profiles.profile3.seqlenoff = hbq_desc->seqlenoff; | |
789 | memcpy(&hbqmb->profiles.profile3.cmdmatch, hbq_desc->cmdmatch, | |
790 | sizeof(hbqmb->profiles.profile3.cmdmatch)); | |
791 | } | |
792 | ||
e59058c4 JS |
793 | /** |
794 | * lpfc_build_hbq_profile5: Set up the HBQ Selection Profile 5. | |
795 | * @hbqmb: pointer to the HBQ configuration data structure in mailbox command. | |
796 | * @hbq_desc: pointer to the HBQ selection profile descriptor. | |
797 | * | |
798 | * The Host Buffer Queue (HBQ) Selection Profile 5 specifies a header HBQ. The | |
799 | * HBA tests the initial frame of an incoming sequence using the frame's | |
800 | * R_CTL/TYPE fields with words 10:15 and performs the Sequence Length Test | |
801 | * and Byte Field Test using the fields in the Selection Profile 5 extension | |
802 | * words 20:31. | |
803 | **/ | |
ed957684 JS |
804 | static void |
805 | lpfc_build_hbq_profile5(struct config_hbq_var *hbqmb, | |
806 | struct lpfc_hbq_init *hbq_desc) | |
807 | { | |
808 | hbqmb->profiles.profile5.seqlenbcnt = hbq_desc->seqlenbcnt; | |
809 | hbqmb->profiles.profile5.maxlen = hbq_desc->maxlen; | |
810 | hbqmb->profiles.profile5.cmdcodeoff = hbq_desc->cmdcodeoff; | |
811 | hbqmb->profiles.profile5.seqlenoff = hbq_desc->seqlenoff; | |
812 | memcpy(&hbqmb->profiles.profile5.cmdmatch, hbq_desc->cmdmatch, | |
813 | sizeof(hbqmb->profiles.profile5.cmdmatch)); | |
814 | } | |
815 | ||
e59058c4 JS |
816 | /** |
817 | * lpfc_config_hbq: Prepare a mailbox command for configuring an HBQ. | |
818 | * @phba: pointer to lpfc hba data structure. | |
819 | * @id: HBQ identifier. | |
820 | * @hbq_desc: pointer to the HBA descriptor data structure. | |
821 | * @hbq_entry_index: index of the HBQ entry data structures. | |
822 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
823 | * | |
824 | * The configure HBQ (Host Buffer Queue) mailbox command is used to configure | |
825 | * an HBQ. The configuration binds events that require buffers to a particular | |
826 | * ring and HBQ based on a selection profile. | |
827 | * | |
828 | * This routine prepares the mailbox command for configuring an HBQ. | |
829 | **/ | |
ed957684 | 830 | void |
51ef4c26 JS |
831 | lpfc_config_hbq(struct lpfc_hba *phba, uint32_t id, |
832 | struct lpfc_hbq_init *hbq_desc, | |
ed957684 JS |
833 | uint32_t hbq_entry_index, LPFC_MBOXQ_t *pmb) |
834 | { | |
835 | int i; | |
836 | MAILBOX_t *mb = &pmb->mb; | |
837 | struct config_hbq_var *hbqmb = &mb->un.varCfgHbq; | |
838 | ||
839 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
51ef4c26 | 840 | hbqmb->hbqId = id; |
ed957684 JS |
841 | hbqmb->entry_count = hbq_desc->entry_count; /* # entries in HBQ */ |
842 | hbqmb->recvNotify = hbq_desc->rn; /* Receive | |
843 | * Notification */ | |
844 | hbqmb->numMask = hbq_desc->mask_count; /* # R_CTL/TYPE masks | |
845 | * # in words 0-19 */ | |
92d7f7b0 | 846 | hbqmb->profile = hbq_desc->profile; /* Selection profile: |
ed957684 JS |
847 | * 0 = all, |
848 | * 7 = logentry */ | |
849 | hbqmb->ringMask = hbq_desc->ring_mask; /* Binds HBQ to a ring | |
850 | * e.g. Ring0=b0001, | |
851 | * ring2=b0100 */ | |
852 | hbqmb->headerLen = hbq_desc->headerLen; /* 0 if not profile 4 | |
853 | * or 5 */ | |
854 | hbqmb->logEntry = hbq_desc->logEntry; /* Set to 1 if this | |
855 | * HBQ will be used | |
856 | * for LogEntry | |
857 | * buffers */ | |
858 | hbqmb->hbqaddrLow = putPaddrLow(phba->hbqslimp.phys) + | |
859 | hbq_entry_index * sizeof(struct lpfc_hbq_entry); | |
860 | hbqmb->hbqaddrHigh = putPaddrHigh(phba->hbqslimp.phys); | |
861 | ||
862 | mb->mbxCommand = MBX_CONFIG_HBQ; | |
863 | mb->mbxOwner = OWN_HOST; | |
864 | ||
92d7f7b0 JS |
865 | /* Copy info for profiles 2,3,5. Other |
866 | * profiles this area is reserved | |
867 | */ | |
ed957684 JS |
868 | if (hbq_desc->profile == 2) |
869 | lpfc_build_hbq_profile2(hbqmb, hbq_desc); | |
870 | else if (hbq_desc->profile == 3) | |
871 | lpfc_build_hbq_profile3(hbqmb, hbq_desc); | |
872 | else if (hbq_desc->profile == 5) | |
873 | lpfc_build_hbq_profile5(hbqmb, hbq_desc); | |
874 | ||
875 | /* Return if no rctl / type masks for this HBQ */ | |
876 | if (!hbq_desc->mask_count) | |
877 | return; | |
878 | ||
879 | /* Otherwise we setup specific rctl / type masks for this HBQ */ | |
880 | for (i = 0; i < hbq_desc->mask_count; i++) { | |
881 | hbqmb->hbqMasks[i].tmatch = hbq_desc->hbqMasks[i].tmatch; | |
882 | hbqmb->hbqMasks[i].tmask = hbq_desc->hbqMasks[i].tmask; | |
883 | hbqmb->hbqMasks[i].rctlmatch = hbq_desc->hbqMasks[i].rctlmatch; | |
884 | hbqmb->hbqMasks[i].rctlmask = hbq_desc->hbqMasks[i].rctlmask; | |
885 | } | |
886 | ||
887 | return; | |
888 | } | |
889 | ||
e59058c4 JS |
890 | /** |
891 | * lpfc_config_ring: Prepare a mailbox command for configuring an IOCB ring. | |
892 | * @phba: pointer to lpfc hba data structure. | |
893 | * @ring: | |
894 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
895 | * | |
896 | * The configure ring mailbox command is used to configure an IOCB ring. This | |
897 | * configuration binds from one to six of HBA RC_CTL/TYPE mask entries to the | |
898 | * ring. This is used to map incoming sequences to a particular ring whose | |
899 | * RC_CTL/TYPE mask entry matches that of the sequence. The driver should not | |
900 | * attempt to configure a ring whose number is greater than the number | |
901 | * specified in the Port Control Block (PCB). It is an error to issue the | |
902 | * configure ring command more than once with the same ring number. The HBA | |
903 | * returns an error if the driver attempts this. | |
904 | * | |
905 | * This routine prepares the mailbox command for configuring IOCB ring. | |
906 | **/ | |
dea3101e JB |
907 | void |
908 | lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb) | |
909 | { | |
910 | int i; | |
911 | MAILBOX_t *mb = &pmb->mb; | |
912 | struct lpfc_sli *psli; | |
913 | struct lpfc_sli_ring *pring; | |
914 | ||
915 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | |
916 | ||
917 | mb->un.varCfgRing.ring = ring; | |
918 | mb->un.varCfgRing.maxOrigXchg = 0; | |
919 | mb->un.varCfgRing.maxRespXchg = 0; | |
920 | mb->un.varCfgRing.recvNotify = 1; | |
921 | ||
922 | psli = &phba->sli; | |
923 | pring = &psli->ring[ring]; | |
924 | mb->un.varCfgRing.numMask = pring->num_mask; | |
925 | mb->mbxCommand = MBX_CONFIG_RING; | |
926 | mb->mbxOwner = OWN_HOST; | |
927 | ||
928 | /* Is this ring configured for a specific profile */ | |
929 | if (pring->prt[0].profile) { | |
930 | mb->un.varCfgRing.profile = pring->prt[0].profile; | |
931 | return; | |
932 | } | |
933 | ||
934 | /* Otherwise we setup specific rctl / type masks for this ring */ | |
935 | for (i = 0; i < pring->num_mask; i++) { | |
936 | mb->un.varCfgRing.rrRegs[i].rval = pring->prt[i].rctl; | |
937 | if (mb->un.varCfgRing.rrRegs[i].rval != FC_ELS_REQ) | |
938 | mb->un.varCfgRing.rrRegs[i].rmask = 0xff; | |
939 | else | |
940 | mb->un.varCfgRing.rrRegs[i].rmask = 0xfe; | |
941 | mb->un.varCfgRing.rrRegs[i].tval = pring->prt[i].type; | |
942 | mb->un.varCfgRing.rrRegs[i].tmask = 0xff; | |
943 | } | |
944 | ||
945 | return; | |
946 | } | |
947 | ||
e59058c4 JS |
948 | /** |
949 | * lpfc_config_port: Prepare a mailbox command for configuring port. | |
950 | * @phba: pointer to lpfc hba data structure. | |
951 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
952 | * | |
953 | * The configure port mailbox command is used to identify the Port Control | |
954 | * Block (PCB) in the driver memory. After this command is issued, the | |
955 | * driver must not access the mailbox in the HBA without first resetting | |
956 | * the HBA. The HBA may copy the PCB information to internal storage for | |
957 | * subsequent use; the driver can not change the PCB information unless it | |
958 | * resets the HBA. | |
959 | * | |
960 | * This routine prepares the mailbox command for configuring port. | |
961 | **/ | |
dea3101e | 962 | void |
92d7f7b0 | 963 | lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
dea3101e | 964 | { |
ed957684 | 965 | MAILBOX_t __iomem *mb_slim = (MAILBOX_t __iomem *) phba->MBslimaddr; |
dea3101e JB |
966 | MAILBOX_t *mb = &pmb->mb; |
967 | dma_addr_t pdma_addr; | |
968 | uint32_t bar_low, bar_high; | |
969 | size_t offset; | |
4cc2da1d | 970 | struct lpfc_hgp hgp; |
f91b392c | 971 | int i; |
ed957684 | 972 | uint32_t pgp_offset; |
dea3101e JB |
973 | |
974 | memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); | |
975 | mb->mbxCommand = MBX_CONFIG_PORT; | |
976 | mb->mbxOwner = OWN_HOST; | |
977 | ||
978 | mb->un.varCfgPort.pcbLen = sizeof(PCB_t); | |
979 | ||
980 | offset = (uint8_t *)&phba->slim2p->pcb - (uint8_t *)phba->slim2p; | |
981 | pdma_addr = phba->slim2p_mapping + offset; | |
982 | mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr); | |
983 | mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr); | |
984 | ||
ed957684 JS |
985 | /* If HBA supports SLI=3 ask for it */ |
986 | ||
92d7f7b0 | 987 | if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) { |
ed957684 | 988 | mb->un.varCfgPort.cerbm = 1; /* Request HBQs */ |
51ef4c26 | 989 | mb->un.varCfgPort.max_hbq = lpfc_sli_hbq_count(); |
78b2d852 | 990 | if (phba->max_vpi && phba->cfg_enable_npiv && |
92d7f7b0 JS |
991 | phba->vpd.sli3Feat.cmv) { |
992 | mb->un.varCfgPort.max_vpi = phba->max_vpi; | |
993 | mb->un.varCfgPort.cmv = 1; | |
994 | phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED; | |
995 | } else | |
996 | mb->un.varCfgPort.max_vpi = phba->max_vpi = 0; | |
997 | } else | |
998 | phba->sli_rev = 2; | |
999 | mb->un.varCfgPort.sli_mode = phba->sli_rev; | |
ed957684 | 1000 | |
dea3101e JB |
1001 | /* Now setup pcb */ |
1002 | phba->slim2p->pcb.type = TYPE_NATIVE_SLI2; | |
1003 | phba->slim2p->pcb.feature = FEATURE_INITIAL_SLI2; | |
1004 | ||
1005 | /* Setup Mailbox pointers */ | |
ed957684 JS |
1006 | phba->slim2p->pcb.mailBoxSize = offsetof(MAILBOX_t, us) + |
1007 | sizeof(struct sli2_desc); | |
dea3101e JB |
1008 | offset = (uint8_t *)&phba->slim2p->mbx - (uint8_t *)phba->slim2p; |
1009 | pdma_addr = phba->slim2p_mapping + offset; | |
1010 | phba->slim2p->pcb.mbAddrHigh = putPaddrHigh(pdma_addr); | |
1011 | phba->slim2p->pcb.mbAddrLow = putPaddrLow(pdma_addr); | |
1012 | ||
1013 | /* | |
1014 | * Setup Host Group ring pointer. | |
1015 | * | |
1016 | * For efficiency reasons, the ring get/put pointers can be | |
1017 | * placed in adapter memory (SLIM) rather than in host memory. | |
1018 | * This allows firmware to avoid PCI reads/writes when updating | |
1019 | * and checking pointers. | |
1020 | * | |
1021 | * The firmware recognizes the use of SLIM memory by comparing | |
1022 | * the address of the get/put pointers structure with that of | |
1023 | * the SLIM BAR (BAR0). | |
1024 | * | |
1025 | * Caution: be sure to use the PCI config space value of BAR0/BAR1 | |
1026 | * (the hardware's view of the base address), not the OS's | |
1027 | * value of pci_resource_start() as the OS value may be a cookie | |
1028 | * for ioremap/iomap. | |
1029 | */ | |
1030 | ||
1031 | ||
1032 | pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_0, &bar_low); | |
1033 | pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_1, &bar_high); | |
1034 | ||
ed957684 JS |
1035 | /* |
1036 | * Set up HGP - Port Memory | |
1037 | * | |
1038 | * The port expects the host get/put pointers to reside in memory | |
1039 | * following the "non-diagnostic" mode mailbox (32 words, 0x80 bytes) | |
1040 | * area of SLIM. In SLI-2 mode, there's an additional 16 reserved | |
1041 | * words (0x40 bytes). This area is not reserved if HBQs are | |
1042 | * configured in SLI-3. | |
1043 | * | |
1044 | * CR0Put - SLI2(no HBQs) = 0xc0, With HBQs = 0x80 | |
1045 | * RR0Get 0xc4 0x84 | |
1046 | * CR1Put 0xc8 0x88 | |
1047 | * RR1Get 0xcc 0x8c | |
1048 | * CR2Put 0xd0 0x90 | |
1049 | * RR2Get 0xd4 0x94 | |
1050 | * CR3Put 0xd8 0x98 | |
1051 | * RR3Get 0xdc 0x9c | |
1052 | * | |
1053 | * Reserved 0xa0-0xbf | |
1054 | * If HBQs configured: | |
1055 | * HBQ 0 Put ptr 0xc0 | |
1056 | * HBQ 1 Put ptr 0xc4 | |
1057 | * HBQ 2 Put ptr 0xc8 | |
1058 | * ...... | |
1059 | * HBQ(M-1)Put Pointer 0xc0+(M-1)*4 | |
1060 | * | |
1061 | */ | |
1062 | ||
1063 | if (phba->sli_rev == 3) { | |
1064 | phba->host_gp = &mb_slim->us.s3.host[0]; | |
1065 | phba->hbq_put = &mb_slim->us.s3.hbq_put[0]; | |
1066 | } else { | |
1067 | phba->host_gp = &mb_slim->us.s2.host[0]; | |
1068 | phba->hbq_put = NULL; | |
1069 | } | |
dea3101e JB |
1070 | |
1071 | /* mask off BAR0's flag bits 0 - 3 */ | |
1072 | phba->slim2p->pcb.hgpAddrLow = (bar_low & PCI_BASE_ADDRESS_MEM_MASK) + | |
ed957684 JS |
1073 | (void __iomem *) phba->host_gp - |
1074 | (void __iomem *)phba->MBslimaddr; | |
dea3101e JB |
1075 | if (bar_low & PCI_BASE_ADDRESS_MEM_TYPE_64) |
1076 | phba->slim2p->pcb.hgpAddrHigh = bar_high; | |
1077 | else | |
1078 | phba->slim2p->pcb.hgpAddrHigh = 0; | |
1079 | /* write HGP data to SLIM at the required longword offset */ | |
4cc2da1d | 1080 | memset(&hgp, 0, sizeof(struct lpfc_hgp)); |
f91b392c JSEC |
1081 | |
1082 | for (i=0; i < phba->sli.num_rings; i++) { | |
ed957684 JS |
1083 | lpfc_memcpy_to_slim(phba->host_gp + i, &hgp, |
1084 | sizeof(*phba->host_gp)); | |
f91b392c | 1085 | } |
dea3101e JB |
1086 | |
1087 | /* Setup Port Group ring pointer */ | |
ed957684 JS |
1088 | if (phba->sli_rev == 3) |
1089 | pgp_offset = (uint8_t *)&phba->slim2p->mbx.us.s3_pgp.port - | |
1090 | (uint8_t *)phba->slim2p; | |
1091 | else | |
1092 | pgp_offset = (uint8_t *)&phba->slim2p->mbx.us.s2.port - | |
1093 | (uint8_t *)phba->slim2p; | |
1094 | ||
1095 | pdma_addr = phba->slim2p_mapping + pgp_offset; | |
dea3101e JB |
1096 | phba->slim2p->pcb.pgpAddrHigh = putPaddrHigh(pdma_addr); |
1097 | phba->slim2p->pcb.pgpAddrLow = putPaddrLow(pdma_addr); | |
ed957684 | 1098 | phba->hbq_get = &phba->slim2p->mbx.us.s3_pgp.hbq_get[0]; |
dea3101e JB |
1099 | |
1100 | /* Use callback routine to setp rings in the pcb */ | |
1101 | lpfc_config_pcb_setup(phba); | |
1102 | ||
1103 | /* special handling for LC HBAs */ | |
1104 | if (lpfc_is_LC_HBA(phba->pcidev->device)) { | |
1105 | uint32_t hbainit[5]; | |
1106 | ||
1107 | lpfc_hba_init(phba, hbainit); | |
1108 | ||
1109 | memcpy(&mb->un.varCfgPort.hbainit, hbainit, 20); | |
1110 | } | |
1111 | ||
1112 | /* Swap PCB if needed */ | |
1113 | lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb, | |
92d7f7b0 | 1114 | sizeof(PCB_t)); |
dea3101e JB |
1115 | } |
1116 | ||
e59058c4 JS |
1117 | /** |
1118 | * lpfc_kill_board: Prepare a mailbox command for killing board. | |
1119 | * @phba: pointer to lpfc hba data structure. | |
1120 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
1121 | * | |
1122 | * The kill board mailbox command is used to tell firmware to perform a | |
1123 | * graceful shutdown of a channel on a specified board to prepare for reset. | |
1124 | * When the kill board mailbox command is received, the ER3 bit is set to 1 | |
1125 | * in the Host Status register and the ER Attention bit is set to 1 in the | |
1126 | * Host Attention register of the HBA function that received the kill board | |
1127 | * command. | |
1128 | * | |
1129 | * This routine prepares the mailbox command for killing the board in | |
1130 | * preparation for a graceful shutdown. | |
1131 | **/ | |
41415862 JW |
1132 | void |
1133 | lpfc_kill_board(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |
1134 | { | |
1135 | MAILBOX_t *mb = &pmb->mb; | |
1136 | ||
1137 | memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); | |
1138 | mb->mbxCommand = MBX_KILL_BOARD; | |
1139 | mb->mbxOwner = OWN_HOST; | |
1140 | return; | |
1141 | } | |
1142 | ||
e59058c4 JS |
1143 | /** |
1144 | * lpfc_mbox_put: Put a mailbox cmd into the tail of driver's mailbox queue. | |
1145 | * @phba: pointer to lpfc hba data structure. | |
1146 | * @mbq: pointer to the driver internal queue element for mailbox command. | |
1147 | * | |
1148 | * Driver maintains a internal mailbox command queue implemented as a linked | |
1149 | * list. When a mailbox command is issued, it shall be put into the mailbox | |
1150 | * command queue such that they shall be processed orderly as HBA can process | |
1151 | * one mailbox command at a time. | |
1152 | **/ | |
dea3101e JB |
1153 | void |
1154 | lpfc_mbox_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq) | |
1155 | { | |
1156 | struct lpfc_sli *psli; | |
1157 | ||
1158 | psli = &phba->sli; | |
1159 | ||
1160 | list_add_tail(&mbq->list, &psli->mboxq); | |
1161 | ||
1162 | psli->mboxq_cnt++; | |
1163 | ||
1164 | return; | |
1165 | } | |
1166 | ||
e59058c4 JS |
1167 | /** |
1168 | * lpfc_mbox_get: Remove a mailbox cmd from the head of driver's mailbox queue. | |
1169 | * @phba: pointer to lpfc hba data structure. | |
1170 | * | |
1171 | * Driver maintains a internal mailbox command queue implemented as a linked | |
1172 | * list. When a mailbox command is issued, it shall be put into the mailbox | |
1173 | * command queue such that they shall be processed orderly as HBA can process | |
1174 | * one mailbox command at a time. After HBA finished processing a mailbox | |
1175 | * command, the driver will remove a pending mailbox command from the head of | |
1176 | * the mailbox command queue and send to the HBA for processing. | |
1177 | * | |
1178 | * Return codes | |
1179 | * pointer to the driver internal queue element for mailbox command. | |
1180 | **/ | |
dea3101e JB |
1181 | LPFC_MBOXQ_t * |
1182 | lpfc_mbox_get(struct lpfc_hba * phba) | |
1183 | { | |
1184 | LPFC_MBOXQ_t *mbq = NULL; | |
1185 | struct lpfc_sli *psli = &phba->sli; | |
1186 | ||
2e0fef85 | 1187 | list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, list); |
92d7f7b0 | 1188 | if (mbq) |
dea3101e | 1189 | psli->mboxq_cnt--; |
dea3101e JB |
1190 | |
1191 | return mbq; | |
1192 | } | |
a309a6b6 | 1193 | |
e59058c4 JS |
1194 | /** |
1195 | * lpfc_mbox_cmpl_put: Put mailbox command into mailbox command complete list. | |
1196 | * @phba: pointer to lpfc hba data structure. | |
1197 | * @mbq: pointer to the driver internal queue element for mailbox command. | |
1198 | * | |
1199 | * This routine put the completed mailbox command into the mailbox command | |
1200 | * complete list. This routine is called from driver interrupt handler | |
1201 | * context.The mailbox complete list is used by the driver worker thread | |
1202 | * to process mailbox complete callback functions outside the driver interrupt | |
1203 | * handler. | |
1204 | **/ | |
92d7f7b0 JS |
1205 | void |
1206 | lpfc_mbox_cmpl_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq) | |
1207 | { | |
b1c11812 | 1208 | /* This function expects to be called from interrupt context */ |
92d7f7b0 JS |
1209 | spin_lock(&phba->hbalock); |
1210 | list_add_tail(&mbq->list, &phba->sli.mboxq_cmpl); | |
1211 | spin_unlock(&phba->hbalock); | |
1212 | return; | |
1213 | } | |
1214 | ||
e59058c4 JS |
1215 | /** |
1216 | * lpfc_mbox_tmo_val: Retrieve mailbox command timeout value. | |
1217 | * @phba: pointer to lpfc hba data structure. | |
1218 | * @cmd: mailbox command code. | |
1219 | * | |
1220 | * This routine retrieves the proper timeout value according to the mailbox | |
1221 | * command code. | |
1222 | * | |
1223 | * Return codes | |
1224 | * Timeout value to be used for the given mailbox command | |
1225 | **/ | |
a309a6b6 JS |
1226 | int |
1227 | lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd) | |
1228 | { | |
1229 | switch (cmd) { | |
1230 | case MBX_WRITE_NV: /* 0x03 */ | |
1231 | case MBX_UPDATE_CFG: /* 0x1B */ | |
1232 | case MBX_DOWN_LOAD: /* 0x1C */ | |
1233 | case MBX_DEL_LD_ENTRY: /* 0x1D */ | |
1234 | case MBX_LOAD_AREA: /* 0x81 */ | |
09372820 | 1235 | case MBX_WRITE_WWN: /* 0x98 */ |
a309a6b6 JS |
1236 | case MBX_LOAD_EXP_ROM: /* 0x9C */ |
1237 | return LPFC_MBOX_TMO_FLASH_CMD; | |
1238 | } | |
1239 | return LPFC_MBOX_TMO; | |
1240 | } |