[SCSI] lpfc: Remove $Id$ keyword strings.
[pandora-kernel.git] / drivers / scsi / lpfc / lpfc_mbox.c
1 /*******************************************************************
2  * This file is part of the Emulex Linux Device Driver for         *
3  * Enterprise Fibre Channel Host Bus Adapters.                     *
4  * Refer to the README file included with this package for         *
5  * driver version and adapter support.                             *
6  * Copyright (C) 2004 Emulex Corporation.                          *
7  * www.emulex.com                                                  *
8  *                                                                 *
9  * This program is free software; you can redistribute it and/or   *
10  * modify it under the terms of the GNU General Public License     *
11  * as published by the Free Software Foundation; either version 2  *
12  * of the License, or (at your option) any later version.          *
13  *                                                                 *
14  * This program is distributed in the hope that it will be useful, *
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of  *
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   *
17  * GNU General Public License for more details, a copy of which    *
18  * can be found in the file COPYING included with this package.    *
19  *******************************************************************/
20
21 #include <linux/blkdev.h>
22 #include <linux/pci.h>
23 #include <linux/interrupt.h>
24
25 #include "lpfc_hw.h"
26 #include "lpfc_sli.h"
27 #include "lpfc_disc.h"
28 #include "lpfc_scsi.h"
29 #include "lpfc.h"
30 #include "lpfc_logmsg.h"
31 #include "lpfc_crtn.h"
32 #include "lpfc_compat.h"
33
34 /**********************************************/
35
36 /*                mailbox command             */
37 /**********************************************/
38 void
39 lpfc_dump_mem(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint16_t offset)
40 {
41         MAILBOX_t *mb;
42         void *ctx;
43
44         mb = &pmb->mb;
45         ctx = pmb->context2;
46
47         /* Setup to dump VPD region */
48         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
49         mb->mbxCommand = MBX_DUMP_MEMORY;
50         mb->un.varDmp.cv = 1;
51         mb->un.varDmp.type = DMP_NV_PARAMS;
52         mb->un.varDmp.entry_index = offset;
53         mb->un.varDmp.region_id = DMP_REGION_VPD;
54         mb->un.varDmp.word_cnt = (DMP_RSP_SIZE / sizeof (uint32_t));
55         mb->un.varDmp.co = 0;
56         mb->un.varDmp.resp_offset = 0;
57         pmb->context2 = ctx;
58         mb->mbxOwner = OWN_HOST;
59         return;
60 }
61
62 /**********************************************/
63 /*  lpfc_read_nv  Issue a READ NVPARAM        */
64 /*                mailbox command             */
65 /**********************************************/
66 void
67 lpfc_read_nv(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
68 {
69         MAILBOX_t *mb;
70
71         mb = &pmb->mb;
72         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
73         mb->mbxCommand = MBX_READ_NV;
74         mb->mbxOwner = OWN_HOST;
75         return;
76 }
77
78 /**********************************************/
79 /*  lpfc_read_la  Issue a READ LA             */
80 /*                mailbox command             */
81 /**********************************************/
82 int
83 lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp)
84 {
85         MAILBOX_t *mb;
86         struct lpfc_sli *psli;
87
88         psli = &phba->sli;
89         mb = &pmb->mb;
90         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
91
92         INIT_LIST_HEAD(&mp->list);
93         mb->mbxCommand = MBX_READ_LA64;
94         mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128;
95         mb->un.varReadLA.un.lilpBde64.addrHigh = putPaddrHigh(mp->phys);
96         mb->un.varReadLA.un.lilpBde64.addrLow = putPaddrLow(mp->phys);
97
98         /* Save address for later completion and set the owner to host so that
99          * the FW knows this mailbox is available for processing.
100          */
101         pmb->context1 = (uint8_t *) mp;
102         mb->mbxOwner = OWN_HOST;
103         return (0);
104 }
105
106 /**********************************************/
107 /*  lpfc_clear_la  Issue a CLEAR LA           */
108 /*                 mailbox command            */
109 /**********************************************/
110 void
111 lpfc_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
112 {
113         MAILBOX_t *mb;
114
115         mb = &pmb->mb;
116         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
117
118         mb->un.varClearLA.eventTag = phba->fc_eventTag;
119         mb->mbxCommand = MBX_CLEAR_LA;
120         mb->mbxOwner = OWN_HOST;
121         return;
122 }
123
124 /**************************************************/
125 /*  lpfc_config_link  Issue a CONFIG LINK         */
126 /*                    mailbox command             */
127 /**************************************************/
128 void
129 lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
130 {
131         MAILBOX_t *mb = &pmb->mb;
132         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
133
134         /* NEW_FEATURE
135          * SLI-2, Coalescing Response Feature.
136          */
137         if (phba->cfg_cr_delay) {
138                 mb->un.varCfgLnk.cr = 1;
139                 mb->un.varCfgLnk.ci = 1;
140                 mb->un.varCfgLnk.cr_delay = phba->cfg_cr_delay;
141                 mb->un.varCfgLnk.cr_count = phba->cfg_cr_count;
142         }
143
144         mb->un.varCfgLnk.myId = phba->fc_myDID;
145         mb->un.varCfgLnk.edtov = phba->fc_edtov;
146         mb->un.varCfgLnk.arbtov = phba->fc_arbtov;
147         mb->un.varCfgLnk.ratov = phba->fc_ratov;
148         mb->un.varCfgLnk.rttov = phba->fc_rttov;
149         mb->un.varCfgLnk.altov = phba->fc_altov;
150         mb->un.varCfgLnk.crtov = phba->fc_crtov;
151         mb->un.varCfgLnk.citov = phba->fc_citov;
152
153         if (phba->cfg_ack0)
154                 mb->un.varCfgLnk.ack0_enable = 1;
155
156         mb->mbxCommand = MBX_CONFIG_LINK;
157         mb->mbxOwner = OWN_HOST;
158         return;
159 }
160
161 /**********************************************/
162 /*  lpfc_init_link  Issue an INIT LINK        */
163 /*                  mailbox command           */
164 /**********************************************/
165 void
166 lpfc_init_link(struct lpfc_hba * phba,
167                LPFC_MBOXQ_t * pmb, uint32_t topology, uint32_t linkspeed)
168 {
169         lpfc_vpd_t *vpd;
170         struct lpfc_sli *psli;
171         MAILBOX_t *mb;
172
173         mb = &pmb->mb;
174         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
175
176         psli = &phba->sli;
177         switch (topology) {
178         case FLAGS_TOPOLOGY_MODE_LOOP_PT:
179                 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
180                 mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
181                 break;
182         case FLAGS_TOPOLOGY_MODE_PT_PT:
183                 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
184                 break;
185         case FLAGS_TOPOLOGY_MODE_LOOP:
186                 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
187                 break;
188         case FLAGS_TOPOLOGY_MODE_PT_LOOP:
189                 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
190                 mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
191                 break;
192         }
193
194         /* NEW_FEATURE
195          * Setting up the link speed
196          */
197         vpd = &phba->vpd;
198         if (vpd->rev.feaLevelHigh >= 0x02){
199                 switch(linkspeed){
200                         case LINK_SPEED_1G:
201                         case LINK_SPEED_2G:
202                         case LINK_SPEED_4G:
203                                 mb->un.varInitLnk.link_flags |=
204                                                         FLAGS_LINK_SPEED;
205                                 mb->un.varInitLnk.link_speed = linkspeed;
206                         break;
207                         case LINK_SPEED_AUTO:
208                         default:
209                                 mb->un.varInitLnk.link_speed =
210                                                         LINK_SPEED_AUTO;
211                         break;
212                 }
213
214         }
215         else
216                 mb->un.varInitLnk.link_speed = LINK_SPEED_AUTO;
217
218         mb->mbxCommand = (volatile uint8_t)MBX_INIT_LINK;
219         mb->mbxOwner = OWN_HOST;
220         mb->un.varInitLnk.fabric_AL_PA = phba->fc_pref_ALPA;
221         return;
222 }
223
224 /**********************************************/
225 /*  lpfc_read_sparam  Issue a READ SPARAM     */
226 /*                    mailbox command         */
227 /**********************************************/
228 int
229 lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
230 {
231         struct lpfc_dmabuf *mp;
232         MAILBOX_t *mb;
233         struct lpfc_sli *psli;
234
235         psli = &phba->sli;
236         mb = &pmb->mb;
237         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
238
239         mb->mbxOwner = OWN_HOST;
240
241         /* Get a buffer to hold the HBAs Service Parameters */
242
243         if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == 0) ||
244             ((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) {
245                 if (mp)
246                         kfree(mp);
247                 mb->mbxCommand = MBX_READ_SPARM64;
248                 /* READ_SPARAM: no buffers */
249                 lpfc_printf_log(phba,
250                                 KERN_WARNING,
251                                 LOG_MBOX,
252                                 "%d:0301 READ_SPARAM: no buffers\n",
253                                 phba->brd_no);
254                 return (1);
255         }
256         INIT_LIST_HEAD(&mp->list);
257         mb->mbxCommand = MBX_READ_SPARM64;
258         mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
259         mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys);
260         mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys);
261
262         /* save address for completion */
263         pmb->context1 = mp;
264
265         return (0);
266 }
267
268 /********************************************/
269 /*  lpfc_unreg_did  Issue a UNREG_DID       */
270 /*                  mailbox command         */
271 /********************************************/
272 void
273 lpfc_unreg_did(struct lpfc_hba * phba, uint32_t did, LPFC_MBOXQ_t * pmb)
274 {
275         MAILBOX_t *mb;
276
277         mb = &pmb->mb;
278         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
279
280         mb->un.varUnregDID.did = did;
281
282         mb->mbxCommand = MBX_UNREG_D_ID;
283         mb->mbxOwner = OWN_HOST;
284         return;
285 }
286
287 /***********************************************/
288
289 /*                  command to write slim      */
290 /***********************************************/
291 void
292 lpfc_set_slim(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint32_t addr,
293               uint32_t value)
294 {
295         MAILBOX_t *mb;
296
297         mb = &pmb->mb;
298         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
299
300         /* addr = 0x090597 is AUTO ABTS disable for ELS commands */
301         /* addr = 0x052198 is DELAYED ABTS enable for ELS commands */
302
303         /*
304          * Always turn on DELAYED ABTS for ELS timeouts
305          */
306         if ((addr == 0x052198) && (value == 0))
307                 value = 1;
308
309         mb->un.varWords[0] = addr;
310         mb->un.varWords[1] = value;
311
312         mb->mbxCommand = MBX_SET_SLIM;
313         mb->mbxOwner = OWN_HOST;
314         return;
315 }
316
317 /**********************************************/
318 /*  lpfc_read_nv  Issue a READ CONFIG         */
319 /*                mailbox command             */
320 /**********************************************/
321 void
322 lpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
323 {
324         MAILBOX_t *mb;
325
326         mb = &pmb->mb;
327         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
328
329         mb->mbxCommand = MBX_READ_CONFIG;
330         mb->mbxOwner = OWN_HOST;
331         return;
332 }
333
334 /********************************************/
335 /*  lpfc_reg_login  Issue a REG_LOGIN       */
336 /*                  mailbox command         */
337 /********************************************/
338 int
339 lpfc_reg_login(struct lpfc_hba * phba,
340                uint32_t did, uint8_t * param, LPFC_MBOXQ_t * pmb, uint32_t flag)
341 {
342         uint8_t *sparam;
343         struct lpfc_dmabuf *mp;
344         MAILBOX_t *mb;
345         struct lpfc_sli *psli;
346
347         psli = &phba->sli;
348         mb = &pmb->mb;
349         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
350
351         mb->un.varRegLogin.rpi = 0;
352         mb->un.varRegLogin.did = did;
353         mb->un.varWords[30] = flag;     /* Set flag to issue action on cmpl */
354
355         mb->mbxOwner = OWN_HOST;
356
357         /* Get a buffer to hold NPorts Service Parameters */
358         if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == NULL) ||
359             ((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) {
360                 if (mp)
361                         kfree(mp);
362
363                 mb->mbxCommand = MBX_REG_LOGIN64;
364                 /* REG_LOGIN: no buffers */
365                 lpfc_printf_log(phba,
366                                KERN_WARNING,
367                                LOG_MBOX,
368                                "%d:0302 REG_LOGIN: no buffers Data x%x x%x\n",
369                                phba->brd_no,
370                                (uint32_t) did, (uint32_t) flag);
371                 return (1);
372         }
373         INIT_LIST_HEAD(&mp->list);
374         sparam = mp->virt;
375
376         /* Copy param's into a new buffer */
377         memcpy(sparam, param, sizeof (struct serv_parm));
378
379         /* save address for completion */
380         pmb->context1 = (uint8_t *) mp;
381
382         mb->mbxCommand = MBX_REG_LOGIN64;
383         mb->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
384         mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys);
385         mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys);
386
387         return (0);
388 }
389
390 /**********************************************/
391 /*  lpfc_unreg_login  Issue a UNREG_LOGIN     */
392 /*                    mailbox command         */
393 /**********************************************/
394 void
395 lpfc_unreg_login(struct lpfc_hba * phba, uint32_t rpi, LPFC_MBOXQ_t * pmb)
396 {
397         MAILBOX_t *mb;
398
399         mb = &pmb->mb;
400         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
401
402         mb->un.varUnregLogin.rpi = (uint16_t) rpi;
403         mb->un.varUnregLogin.rsvd1 = 0;
404
405         mb->mbxCommand = MBX_UNREG_LOGIN;
406         mb->mbxOwner = OWN_HOST;
407         return;
408 }
409
410 static void
411 lpfc_config_pcb_setup(struct lpfc_hba * phba)
412 {
413         struct lpfc_sli *psli = &phba->sli;
414         struct lpfc_sli_ring *pring;
415         PCB_t *pcbp = &phba->slim2p->pcb;
416         dma_addr_t pdma_addr;
417         uint32_t offset;
418         uint32_t iocbCnt;
419         int i;
420
421         pcbp->maxRing = (psli->num_rings - 1);
422
423         iocbCnt = 0;
424         for (i = 0; i < psli->num_rings; i++) {
425                 pring = &psli->ring[i];
426                 /* A ring MUST have both cmd and rsp entries defined to be
427                    valid */
428                 if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) {
429                         pcbp->rdsc[i].cmdEntries = 0;
430                         pcbp->rdsc[i].rspEntries = 0;
431                         pcbp->rdsc[i].cmdAddrHigh = 0;
432                         pcbp->rdsc[i].rspAddrHigh = 0;
433                         pcbp->rdsc[i].cmdAddrLow = 0;
434                         pcbp->rdsc[i].rspAddrLow = 0;
435                         pring->cmdringaddr = NULL;
436                         pring->rspringaddr = NULL;
437                         continue;
438                 }
439                 /* Command ring setup for ring */
440                 pring->cmdringaddr =
441                     (void *)&phba->slim2p->IOCBs[iocbCnt];
442                 pcbp->rdsc[i].cmdEntries = pring->numCiocb;
443
444                 offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] -
445                          (uint8_t *)phba->slim2p;
446                 pdma_addr = phba->slim2p_mapping + offset;
447                 pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr);
448                 pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr);
449                 iocbCnt += pring->numCiocb;
450
451                 /* Response ring setup for ring */
452                 pring->rspringaddr =
453                     (void *)&phba->slim2p->IOCBs[iocbCnt];
454
455                 pcbp->rdsc[i].rspEntries = pring->numRiocb;
456                 offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] -
457                          (uint8_t *)phba->slim2p;
458                 pdma_addr = phba->slim2p_mapping + offset;
459                 pcbp->rdsc[i].rspAddrHigh = putPaddrHigh(pdma_addr);
460                 pcbp->rdsc[i].rspAddrLow = putPaddrLow(pdma_addr);
461                 iocbCnt += pring->numRiocb;
462         }
463 }
464
465 void
466 lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
467 {
468         MAILBOX_t *mb;
469
470         mb = &pmb->mb;
471         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
472         mb->un.varRdRev.cv = 1;
473         mb->mbxCommand = MBX_READ_REV;
474         mb->mbxOwner = OWN_HOST;
475         return;
476 }
477
478 void
479 lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
480 {
481         int i;
482         MAILBOX_t *mb = &pmb->mb;
483         struct lpfc_sli *psli;
484         struct lpfc_sli_ring *pring;
485
486         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
487
488         mb->un.varCfgRing.ring = ring;
489         mb->un.varCfgRing.maxOrigXchg = 0;
490         mb->un.varCfgRing.maxRespXchg = 0;
491         mb->un.varCfgRing.recvNotify = 1;
492
493         psli = &phba->sli;
494         pring = &psli->ring[ring];
495         mb->un.varCfgRing.numMask = pring->num_mask;
496         mb->mbxCommand = MBX_CONFIG_RING;
497         mb->mbxOwner = OWN_HOST;
498
499         /* Is this ring configured for a specific profile */
500         if (pring->prt[0].profile) {
501                 mb->un.varCfgRing.profile = pring->prt[0].profile;
502                 return;
503         }
504
505         /* Otherwise we setup specific rctl / type masks for this ring */
506         for (i = 0; i < pring->num_mask; i++) {
507                 mb->un.varCfgRing.rrRegs[i].rval = pring->prt[i].rctl;
508                 if (mb->un.varCfgRing.rrRegs[i].rval != FC_ELS_REQ)
509                         mb->un.varCfgRing.rrRegs[i].rmask = 0xff;
510                 else
511                         mb->un.varCfgRing.rrRegs[i].rmask = 0xfe;
512                 mb->un.varCfgRing.rrRegs[i].tval = pring->prt[i].type;
513                 mb->un.varCfgRing.rrRegs[i].tmask = 0xff;
514         }
515
516         return;
517 }
518
519 void
520 lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
521 {
522         MAILBOX_t *mb = &pmb->mb;
523         dma_addr_t pdma_addr;
524         uint32_t bar_low, bar_high;
525         size_t offset;
526         struct lpfc_hgp hgp;
527         void __iomem *to_slim;
528
529         memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
530         mb->mbxCommand = MBX_CONFIG_PORT;
531         mb->mbxOwner = OWN_HOST;
532
533         mb->un.varCfgPort.pcbLen = sizeof(PCB_t);
534
535         offset = (uint8_t *)&phba->slim2p->pcb - (uint8_t *)phba->slim2p;
536         pdma_addr = phba->slim2p_mapping + offset;
537         mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr);
538         mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr);
539
540         /* Now setup pcb */
541         phba->slim2p->pcb.type = TYPE_NATIVE_SLI2;
542         phba->slim2p->pcb.feature = FEATURE_INITIAL_SLI2;
543
544         /* Setup Mailbox pointers */
545         phba->slim2p->pcb.mailBoxSize = sizeof(MAILBOX_t);
546         offset = (uint8_t *)&phba->slim2p->mbx - (uint8_t *)phba->slim2p;
547         pdma_addr = phba->slim2p_mapping + offset;
548         phba->slim2p->pcb.mbAddrHigh = putPaddrHigh(pdma_addr);
549         phba->slim2p->pcb.mbAddrLow = putPaddrLow(pdma_addr);
550
551         /*
552          * Setup Host Group ring pointer.
553          *
554          * For efficiency reasons, the ring get/put pointers can be
555          * placed in adapter memory (SLIM) rather than in host memory.
556          * This allows firmware to avoid PCI reads/writes when updating
557          * and checking pointers.
558          *
559          * The firmware recognizes the use of SLIM memory by comparing
560          * the address of the get/put pointers structure with that of
561          * the SLIM BAR (BAR0).
562          *
563          * Caution: be sure to use the PCI config space value of BAR0/BAR1
564          * (the hardware's view of the base address), not the OS's
565          * value of pci_resource_start() as the OS value may be a cookie
566          * for ioremap/iomap.
567          */
568
569
570         pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_0, &bar_low);
571         pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_1, &bar_high);
572
573
574         /* mask off BAR0's flag bits 0 - 3 */
575         phba->slim2p->pcb.hgpAddrLow = (bar_low & PCI_BASE_ADDRESS_MEM_MASK) +
576                                         (SLIMOFF*sizeof(uint32_t));
577         if (bar_low & PCI_BASE_ADDRESS_MEM_TYPE_64)
578                 phba->slim2p->pcb.hgpAddrHigh = bar_high;
579         else
580                 phba->slim2p->pcb.hgpAddrHigh = 0;
581         /* write HGP data to SLIM at the required longword offset */
582         memset(&hgp, 0, sizeof(struct lpfc_hgp));
583         to_slim = phba->MBslimaddr + (SLIMOFF*sizeof (uint32_t));
584         lpfc_memcpy_to_slim(to_slim, &hgp, sizeof(struct lpfc_hgp));
585
586         /* Setup Port Group ring pointer */
587         offset = (uint8_t *)&phba->slim2p->mbx.us.s2.port -
588                  (uint8_t *)phba->slim2p;
589         pdma_addr = phba->slim2p_mapping + offset;
590         phba->slim2p->pcb.pgpAddrHigh = putPaddrHigh(pdma_addr);
591         phba->slim2p->pcb.pgpAddrLow = putPaddrLow(pdma_addr);
592
593         /* Use callback routine to setp rings in the pcb */
594         lpfc_config_pcb_setup(phba);
595
596         /* special handling for LC HBAs */
597         if (lpfc_is_LC_HBA(phba->pcidev->device)) {
598                 uint32_t hbainit[5];
599
600                 lpfc_hba_init(phba, hbainit);
601
602                 memcpy(&mb->un.varCfgPort.hbainit, hbainit, 20);
603         }
604
605         /* Swap PCB if needed */
606         lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb,
607                                                                 sizeof (PCB_t));
608
609         lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
610                         "%d:0405 Service Level Interface (SLI) 2 selected\n",
611                         phba->brd_no);
612 }
613
614 void
615 lpfc_mbox_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
616 {
617         struct lpfc_sli *psli;
618
619         psli = &phba->sli;
620
621         list_add_tail(&mbq->list, &psli->mboxq);
622
623         psli->mboxq_cnt++;
624
625         return;
626 }
627
628 LPFC_MBOXQ_t *
629 lpfc_mbox_get(struct lpfc_hba * phba)
630 {
631         LPFC_MBOXQ_t *mbq = NULL;
632         struct lpfc_sli *psli = &phba->sli;
633
634         list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t,
635                          list);
636         if (mbq) {
637                 psli->mboxq_cnt--;
638         }
639
640         return mbq;
641 }