xref: /freebsd/sys/dev/pms/RefTisa/sallsdk/spc/saphy.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
1*4e1bc9a0SAchim Leubner /*******************************************************************************
2*4e1bc9a0SAchim Leubner *Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
3*4e1bc9a0SAchim Leubner *
4*4e1bc9a0SAchim Leubner *Redistribution and use in source and binary forms, with or without modification, are permitted provided
5*4e1bc9a0SAchim Leubner *that the following conditions are met:
6*4e1bc9a0SAchim Leubner *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7*4e1bc9a0SAchim Leubner *following disclaimer.
8*4e1bc9a0SAchim Leubner *2. Redistributions in binary form must reproduce the above copyright notice,
9*4e1bc9a0SAchim Leubner *this list of conditions and the following disclaimer in the documentation and/or other materials provided
10*4e1bc9a0SAchim Leubner *with the distribution.
11*4e1bc9a0SAchim Leubner *
12*4e1bc9a0SAchim Leubner *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13*4e1bc9a0SAchim Leubner *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14*4e1bc9a0SAchim Leubner *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15*4e1bc9a0SAchim Leubner *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16*4e1bc9a0SAchim Leubner *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17*4e1bc9a0SAchim Leubner *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18*4e1bc9a0SAchim Leubner *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19*4e1bc9a0SAchim Leubner *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20*4e1bc9a0SAchim Leubner 
21*4e1bc9a0SAchim Leubner ********************************************************************************/
22*4e1bc9a0SAchim Leubner /*******************************************************************************/
23*4e1bc9a0SAchim Leubner /*! \file saphy.c
24*4e1bc9a0SAchim Leubner  *  \brief The file implements the functions to Start, Stop a phy
25*4e1bc9a0SAchim Leubner  *
26*4e1bc9a0SAchim Leubner  *
27*4e1bc9a0SAchim Leubner  */
28*4e1bc9a0SAchim Leubner /******************************************************************************/
29*4e1bc9a0SAchim Leubner #include <sys/cdefs.h>
30*4e1bc9a0SAchim Leubner #include <dev/pms/config.h>
31*4e1bc9a0SAchim Leubner 
32*4e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
33*4e1bc9a0SAchim Leubner #ifdef SA_ENABLE_TRACE_FUNCTIONS
34*4e1bc9a0SAchim Leubner #ifdef siTraceFileID
35*4e1bc9a0SAchim Leubner #undef siTraceFileID
36*4e1bc9a0SAchim Leubner #endif
37*4e1bc9a0SAchim Leubner #define siTraceFileID 'K'
38*4e1bc9a0SAchim Leubner #endif
39*4e1bc9a0SAchim Leubner 
40*4e1bc9a0SAchim Leubner 
41*4e1bc9a0SAchim Leubner extern bit32 gFPGA_TEST;
42*4e1bc9a0SAchim Leubner /******************************************************************************/
43*4e1bc9a0SAchim Leubner /*! \brief Start a Phy
44*4e1bc9a0SAchim Leubner  *
45*4e1bc9a0SAchim Leubner  *  Start a Phy
46*4e1bc9a0SAchim Leubner  *
47*4e1bc9a0SAchim Leubner  *  \param agRoot handles for this instance of SAS/SATA hardware
48*4e1bc9a0SAchim Leubner  *  \param agContext
49*4e1bc9a0SAchim Leubner  *  \param phyId the phy id of the link will be started
50*4e1bc9a0SAchim Leubner  *  \param agPhyConfig the phy configuration
51*4e1bc9a0SAchim Leubner  *  \param agSASIdentify the SAS identify frame will be sent by the phy
52*4e1bc9a0SAchim Leubner  *
53*4e1bc9a0SAchim Leubner  *  \return If phy is started successfully
54*4e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS phy is started successfully
55*4e1bc9a0SAchim Leubner  *          - \e AGSA_RC_BUSY phy is already started or starting
56*4e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE phy is not started successfully
57*4e1bc9a0SAchim Leubner  */
58*4e1bc9a0SAchim Leubner /*******************************************************************************/
saPhyStart(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,bit32 phyId,agsaPhyConfig_t * agPhyConfig,agsaSASIdentify_t * agSASIdentify)59*4e1bc9a0SAchim Leubner GLOBAL bit32 saPhyStart(
60*4e1bc9a0SAchim Leubner   agsaRoot_t         *agRoot,
61*4e1bc9a0SAchim Leubner   agsaContext_t      *agContext,
62*4e1bc9a0SAchim Leubner   bit32              queueNum,
63*4e1bc9a0SAchim Leubner   bit32              phyId,
64*4e1bc9a0SAchim Leubner   agsaPhyConfig_t    *agPhyConfig,
65*4e1bc9a0SAchim Leubner   agsaSASIdentify_t  *agSASIdentify
66*4e1bc9a0SAchim Leubner   )
67*4e1bc9a0SAchim Leubner {
68*4e1bc9a0SAchim Leubner   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
69*4e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequest;
70*4e1bc9a0SAchim Leubner   bit32               ret = AGSA_RC_SUCCESS;
71*4e1bc9a0SAchim Leubner   bit32               using_reserved = agFALSE;
72*4e1bc9a0SAchim Leubner 
73*4e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD, "7a");
74*4e1bc9a0SAchim Leubner 
75*4e1bc9a0SAchim Leubner   /* sanity check */
76*4e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
77*4e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agSASIdentify), "");
78*4e1bc9a0SAchim Leubner 
79*4e1bc9a0SAchim Leubner   SA_DBG3(("saPhyStart: phy%d started with ID %08X:%08X\n",
80*4e1bc9a0SAchim Leubner     phyId,
81*4e1bc9a0SAchim Leubner     SA_IDFRM_GET_SAS_ADDRESSHI(agSASIdentify),
82*4e1bc9a0SAchim Leubner     SA_IDFRM_GET_SAS_ADDRESSLO(agSASIdentify)));
83*4e1bc9a0SAchim Leubner 
84*4e1bc9a0SAchim Leubner   /* If phyId is invalid, return failure */
85*4e1bc9a0SAchim Leubner   if ( phyId >= saRoot->phyCount )
86*4e1bc9a0SAchim Leubner   {
87*4e1bc9a0SAchim Leubner     ret = AGSA_RC_FAILURE;
88*4e1bc9a0SAchim Leubner   }
89*4e1bc9a0SAchim Leubner   /* If phyId is valid */
90*4e1bc9a0SAchim Leubner   else
91*4e1bc9a0SAchim Leubner   {
92*4e1bc9a0SAchim Leubner     /* Get request from free IORequests */
93*4e1bc9a0SAchim Leubner     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
94*4e1bc9a0SAchim Leubner     pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /* */
95*4e1bc9a0SAchim Leubner     /* If no LL Control request entry available */
96*4e1bc9a0SAchim Leubner     if ( agNULL == pRequest )
97*4e1bc9a0SAchim Leubner     {
98*4e1bc9a0SAchim Leubner       pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
99*4e1bc9a0SAchim Leubner       /* If no LL Control request entry available */
100*4e1bc9a0SAchim Leubner       if(agNULL != pRequest)
101*4e1bc9a0SAchim Leubner       {
102*4e1bc9a0SAchim Leubner         using_reserved = agTRUE;
103*4e1bc9a0SAchim Leubner         SA_DBG1(("saPhyStart, using saRoot->freeReservedRequests\n"));
104*4e1bc9a0SAchim Leubner       }
105*4e1bc9a0SAchim Leubner       else
106*4e1bc9a0SAchim Leubner       {
107*4e1bc9a0SAchim Leubner         ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
108*4e1bc9a0SAchim Leubner         SA_DBG1(("saPhyStart, No request from free list Not using saRoot->freeReservedRequests\n"));
109*4e1bc9a0SAchim Leubner         smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "7a");
110*4e1bc9a0SAchim Leubner         return AGSA_RC_BUSY;
111*4e1bc9a0SAchim Leubner       }
112*4e1bc9a0SAchim Leubner     }
113*4e1bc9a0SAchim Leubner     SA_ASSERT((!pRequest->valid), "The pRequest is in use");
114*4e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
115*4e1bc9a0SAchim Leubner     /* If LL Control request entry avaliable */
116*4e1bc9a0SAchim Leubner     if( using_reserved )
117*4e1bc9a0SAchim Leubner     {
118*4e1bc9a0SAchim Leubner       saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
119*4e1bc9a0SAchim Leubner     }
120*4e1bc9a0SAchim Leubner     else
121*4e1bc9a0SAchim Leubner     {
122*4e1bc9a0SAchim Leubner       /* Remove the request from free list */
123*4e1bc9a0SAchim Leubner       saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
124*4e1bc9a0SAchim Leubner     }
125*4e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
126*4e1bc9a0SAchim Leubner 
127*4e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
128*4e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
129*4e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].agContext = agContext;
130*4e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
131*4e1bc9a0SAchim Leubner 
132*4e1bc9a0SAchim Leubner     /* Build the Phy Start IOMB command and send to SPC */
133*4e1bc9a0SAchim Leubner 
134*4e1bc9a0SAchim Leubner     smTrace(hpDBG_VERY_LOUD,"P2", phyId);
135*4e1bc9a0SAchim Leubner     /* TP:P2 phyId */
136*4e1bc9a0SAchim Leubner 
137*4e1bc9a0SAchim Leubner     ret = mpiPhyStartCmd(agRoot, pRequest->HTag, phyId, agPhyConfig, agSASIdentify, queueNum);
138*4e1bc9a0SAchim Leubner     if (AGSA_RC_SUCCESS != ret)
139*4e1bc9a0SAchim Leubner     {
140*4e1bc9a0SAchim Leubner       /* remove the request from IOMap */
141*4e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
142*4e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
143*4e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
144*4e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
145*4e1bc9a0SAchim Leubner 
146*4e1bc9a0SAchim Leubner       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
147*4e1bc9a0SAchim Leubner       /* return the request to free pool */
148*4e1bc9a0SAchim Leubner       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
149*4e1bc9a0SAchim Leubner       {
150*4e1bc9a0SAchim Leubner         SA_DBG1(("saPhyStart: saving pRequest (%p) for later use\n", pRequest));
151*4e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
152*4e1bc9a0SAchim Leubner       }
153*4e1bc9a0SAchim Leubner       else
154*4e1bc9a0SAchim Leubner       {
155*4e1bc9a0SAchim Leubner         /* return the request to free pool */
156*4e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
157*4e1bc9a0SAchim Leubner       }
158*4e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
159*4e1bc9a0SAchim Leubner       SA_DBG1(("saPhyStart, sending IOMB failed\n" ));
160*4e1bc9a0SAchim Leubner     }
161*4e1bc9a0SAchim Leubner   }
162*4e1bc9a0SAchim Leubner 
163*4e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "7a");
164*4e1bc9a0SAchim Leubner 
165*4e1bc9a0SAchim Leubner   return ret;
166*4e1bc9a0SAchim Leubner }
167*4e1bc9a0SAchim Leubner 
168*4e1bc9a0SAchim Leubner /******************************************************************************/
169*4e1bc9a0SAchim Leubner /*! \brief Stop a Phy
170*4e1bc9a0SAchim Leubner  *
171*4e1bc9a0SAchim Leubner  *  Stop a Phy
172*4e1bc9a0SAchim Leubner  *
173*4e1bc9a0SAchim Leubner  *  \param agRoot handles for this instance of SAS/SATA hardware
174*4e1bc9a0SAchim Leubner  *  \param agContext the context of this API
175*4e1bc9a0SAchim Leubner  *  \param phyId the phy id of the link will be stopped
176*4e1bc9a0SAchim Leubner  *
177*4e1bc9a0SAchim Leubner  *  \return If phy is stopped successfully
178*4e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS phy is stopped successfully
179*4e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE phy is not stopped successfully
180*4e1bc9a0SAchim Leubner  */
181*4e1bc9a0SAchim Leubner /*******************************************************************************/
saPhyStop(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,bit32 phyId)182*4e1bc9a0SAchim Leubner GLOBAL bit32 saPhyStop(
183*4e1bc9a0SAchim Leubner   agsaRoot_t      *agRoot,
184*4e1bc9a0SAchim Leubner   agsaContext_t   *agContext,
185*4e1bc9a0SAchim Leubner   bit32           queueNum,
186*4e1bc9a0SAchim Leubner   bit32           phyId
187*4e1bc9a0SAchim Leubner   )
188*4e1bc9a0SAchim Leubner {
189*4e1bc9a0SAchim Leubner   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
190*4e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequest;
191*4e1bc9a0SAchim Leubner   bit32               ret = AGSA_RC_SUCCESS;
192*4e1bc9a0SAchim Leubner   bit32               using_reserved = agFALSE;
193*4e1bc9a0SAchim Leubner 
194*4e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"7b");
195*4e1bc9a0SAchim Leubner 
196*4e1bc9a0SAchim Leubner   /* sanity check */
197*4e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
198*4e1bc9a0SAchim Leubner 
199*4e1bc9a0SAchim Leubner   SA_DBG2(("saPhyStop: phy%d stop\n", phyId));
200*4e1bc9a0SAchim Leubner 
201*4e1bc9a0SAchim Leubner   if(1)
202*4e1bc9a0SAchim Leubner   {
203*4e1bc9a0SAchim Leubner     mpiOCQueue_t         *circularQ;
204*4e1bc9a0SAchim Leubner     int i;
205*4e1bc9a0SAchim Leubner     SA_DBG4(("saPhyStop:\n"));
206*4e1bc9a0SAchim Leubner     for ( i = 0; i < saRoot->QueueConfig.numOutboundQueues; i++ )
207*4e1bc9a0SAchim Leubner     {
208*4e1bc9a0SAchim Leubner       circularQ = &saRoot->outboundQueue[i];
209*4e1bc9a0SAchim Leubner       OSSA_READ_LE_32(circularQ->agRoot, &circularQ->producerIdx, circularQ->piPointer, 0);
210*4e1bc9a0SAchim Leubner       if(circularQ->producerIdx != circularQ->consumerIdx)
211*4e1bc9a0SAchim Leubner       {
212*4e1bc9a0SAchim Leubner         SA_DBG1(("saPhyStop: PI 0x%03x CI 0x%03x\n",circularQ->producerIdx, circularQ->consumerIdx ));
213*4e1bc9a0SAchim Leubner       }
214*4e1bc9a0SAchim Leubner     }
215*4e1bc9a0SAchim Leubner   }
216*4e1bc9a0SAchim Leubner 
217*4e1bc9a0SAchim Leubner   if(smIS_SPC(agRoot))
218*4e1bc9a0SAchim Leubner   {
219*4e1bc9a0SAchim Leubner     phyId &= 0xF;
220*4e1bc9a0SAchim Leubner   }
221*4e1bc9a0SAchim Leubner   /* If phyId is invalid, return failure */
222*4e1bc9a0SAchim Leubner   if ( (phyId & 0xF) >= saRoot->phyCount )
223*4e1bc9a0SAchim Leubner   {
224*4e1bc9a0SAchim Leubner     ret = AGSA_RC_FAILURE;
225*4e1bc9a0SAchim Leubner     SA_DBG1(("saPhyStop: phy%d - failure with phyId\n", phyId));
226*4e1bc9a0SAchim Leubner   }
227*4e1bc9a0SAchim Leubner   else
228*4e1bc9a0SAchim Leubner   {
229*4e1bc9a0SAchim Leubner     /* If phyId is valid */
230*4e1bc9a0SAchim Leubner     /* Get request from free IORequests */
231*4e1bc9a0SAchim Leubner     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
232*4e1bc9a0SAchim Leubner     pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
233*4e1bc9a0SAchim Leubner     /* If no LL Control request entry available */
234*4e1bc9a0SAchim Leubner     if ( agNULL == pRequest )
235*4e1bc9a0SAchim Leubner     {
236*4e1bc9a0SAchim Leubner       pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
237*4e1bc9a0SAchim Leubner       /* If no LL Control request entry available */
238*4e1bc9a0SAchim Leubner       if(agNULL != pRequest)
239*4e1bc9a0SAchim Leubner       {
240*4e1bc9a0SAchim Leubner         using_reserved = agTRUE;
241*4e1bc9a0SAchim Leubner         SA_DBG1(("saPhyStop: using saRoot->freeReservedRequests\n"));
242*4e1bc9a0SAchim Leubner       }
243*4e1bc9a0SAchim Leubner       else
244*4e1bc9a0SAchim Leubner       {
245*4e1bc9a0SAchim Leubner         ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
246*4e1bc9a0SAchim Leubner         SA_DBG1(("saPhyStop, No request from free list Not using saRoot->freeReservedRequests\n"));
247*4e1bc9a0SAchim Leubner         smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "7b");
248*4e1bc9a0SAchim Leubner         return AGSA_RC_BUSY;
249*4e1bc9a0SAchim Leubner       }
250*4e1bc9a0SAchim Leubner     }
251*4e1bc9a0SAchim Leubner     /* Remove the request from free list */
252*4e1bc9a0SAchim Leubner     if( using_reserved )
253*4e1bc9a0SAchim Leubner     {
254*4e1bc9a0SAchim Leubner       saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
255*4e1bc9a0SAchim Leubner     }
256*4e1bc9a0SAchim Leubner     else
257*4e1bc9a0SAchim Leubner     {
258*4e1bc9a0SAchim Leubner       saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
259*4e1bc9a0SAchim Leubner     }
260*4e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
261*4e1bc9a0SAchim Leubner     SA_ASSERT((!pRequest->valid), "The pRequest is in use");
262*4e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
263*4e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
264*4e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].agContext = agContext;
265*4e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
266*4e1bc9a0SAchim Leubner 
267*4e1bc9a0SAchim Leubner     /* build IOMB command and send to SPC */
268*4e1bc9a0SAchim Leubner     ret = mpiPhyStopCmd(agRoot, pRequest->HTag, phyId, queueNum);
269*4e1bc9a0SAchim Leubner     if (AGSA_RC_SUCCESS != ret)
270*4e1bc9a0SAchim Leubner     {
271*4e1bc9a0SAchim Leubner       /* remove the request from IOMap */
272*4e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
273*4e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
274*4e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
275*4e1bc9a0SAchim Leubner 
276*4e1bc9a0SAchim Leubner       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
277*4e1bc9a0SAchim Leubner       /* return the request to free pool */
278*4e1bc9a0SAchim Leubner       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
279*4e1bc9a0SAchim Leubner       {
280*4e1bc9a0SAchim Leubner         SA_DBG2(("saPhyStop: saving pRequest (%p) for later use\n", pRequest));
281*4e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
282*4e1bc9a0SAchim Leubner       }
283*4e1bc9a0SAchim Leubner       else
284*4e1bc9a0SAchim Leubner       {
285*4e1bc9a0SAchim Leubner         /* return the request to free pool */
286*4e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
287*4e1bc9a0SAchim Leubner       }
288*4e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
289*4e1bc9a0SAchim Leubner       SA_DBG1(("saPhyStop, sending IOMB failed\n" ));
290*4e1bc9a0SAchim Leubner     }
291*4e1bc9a0SAchim Leubner   }
292*4e1bc9a0SAchim Leubner 
293*4e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "7b");
294*4e1bc9a0SAchim Leubner 
295*4e1bc9a0SAchim Leubner   return ret;
296*4e1bc9a0SAchim Leubner }
297*4e1bc9a0SAchim Leubner 
298*4e1bc9a0SAchim Leubner /******************************************************************************/
299*4e1bc9a0SAchim Leubner /*! \brief CallBack Routine to stop a Phy
300*4e1bc9a0SAchim Leubner  *
301*4e1bc9a0SAchim Leubner  *  CallBack for Stop a Phy
302*4e1bc9a0SAchim Leubner  *
303*4e1bc9a0SAchim Leubner  *  \param agRoot handles for this instance of SAS/SATA hardware
304*4e1bc9a0SAchim Leubner  *  \param phyId the phy id of the link will be stopped
305*4e1bc9a0SAchim Leubner  *  \param status the status of the phy
306*4e1bc9a0SAchim Leubner  *  \param agContext the context of the saPhyStop
307*4e1bc9a0SAchim Leubner  *
308*4e1bc9a0SAchim Leubner  *  \return If phy is stopped successfully
309*4e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS phy is stopped successfully
310*4e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE phy is not stopped successfully
311*4e1bc9a0SAchim Leubner  */
312*4e1bc9a0SAchim Leubner /*******************************************************************************/
siPhyStopCB(agsaRoot_t * agRoot,bit32 phyId,bit32 status,agsaContext_t * agContext,bit32 portId,bit32 npipps)313*4e1bc9a0SAchim Leubner GLOBAL bit32 siPhyStopCB(
314*4e1bc9a0SAchim Leubner   agsaRoot_t    *agRoot,
315*4e1bc9a0SAchim Leubner   bit32         phyId,
316*4e1bc9a0SAchim Leubner   bit32         status,
317*4e1bc9a0SAchim Leubner   agsaContext_t *agContext,
318*4e1bc9a0SAchim Leubner   bit32         portId,
319*4e1bc9a0SAchim Leubner   bit32         npipps
320*4e1bc9a0SAchim Leubner   )
321*4e1bc9a0SAchim Leubner {
322*4e1bc9a0SAchim Leubner   agsaLLRoot_t            *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
323*4e1bc9a0SAchim Leubner   agsaPhy_t               *pPhy;
324*4e1bc9a0SAchim Leubner   agsaPort_t              *pPort;
325*4e1bc9a0SAchim Leubner   bit32                   ret = AGSA_RC_SUCCESS;
326*4e1bc9a0SAchim Leubner   bit32                   iomb_status = status;
327*4e1bc9a0SAchim Leubner 
328*4e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"7c");
329*4e1bc9a0SAchim Leubner 
330*4e1bc9a0SAchim Leubner   /* sanity check */
331*4e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
332*4e1bc9a0SAchim Leubner 
333*4e1bc9a0SAchim Leubner   /* If phyId is invalid, return failure */
334*4e1bc9a0SAchim Leubner   if ( phyId >= saRoot->phyCount )
335*4e1bc9a0SAchim Leubner   {
336*4e1bc9a0SAchim Leubner     ret = AGSA_RC_FAILURE;
337*4e1bc9a0SAchim Leubner     SA_DBG1(("siPhyStopCB: phy%d - failure with phyId\n", phyId));
338*4e1bc9a0SAchim Leubner     /* makeup for CB */
339*4e1bc9a0SAchim Leubner     status = (status << SHIFT8) | phyId;
340*4e1bc9a0SAchim Leubner     status |= ((npipps & PORT_STATE_MASK) << SHIFT16);
341*4e1bc9a0SAchim Leubner     ossaHwCB(agRoot, agNULL, OSSA_HW_EVENT_PHY_STOP_STATUS, status, agContext, agNULL);
342*4e1bc9a0SAchim Leubner   }
343*4e1bc9a0SAchim Leubner   /* If phyId is valid */
344*4e1bc9a0SAchim Leubner   else
345*4e1bc9a0SAchim Leubner   {
346*4e1bc9a0SAchim Leubner     pPhy = &(saRoot->phys[phyId]);
347*4e1bc9a0SAchim Leubner 
348*4e1bc9a0SAchim Leubner     /* get the port of the phy */
349*4e1bc9a0SAchim Leubner     pPort = pPhy->pPort;
350*4e1bc9a0SAchim Leubner 
351*4e1bc9a0SAchim Leubner     /* makeup for CB */
352*4e1bc9a0SAchim Leubner     status = (status << SHIFT8) | phyId;
353*4e1bc9a0SAchim Leubner     status |= ((npipps & PORT_STATE_MASK) << SHIFT16);
354*4e1bc9a0SAchim Leubner     /* Callback to stop phy */
355*4e1bc9a0SAchim Leubner     if ( agNULL != pPort )
356*4e1bc9a0SAchim Leubner     {
357*4e1bc9a0SAchim Leubner       if ( iomb_status == OSSA_SUCCESS && (OSSA_PORT_INVALID == (npipps & PORT_STATE_MASK) ))
358*4e1bc9a0SAchim Leubner       {
359*4e1bc9a0SAchim Leubner         SA_DBG1(("siPhyStopCB: phy%d invalidating port\n", phyId));
360*4e1bc9a0SAchim Leubner         /* invalid port state, remove the port */
361*4e1bc9a0SAchim Leubner         pPort->status |= PORT_INVALIDATING;
362*4e1bc9a0SAchim Leubner         saRoot->PortMap[portId].PortStatus  |= PORT_INVALIDATING;
363*4e1bc9a0SAchim Leubner         /* invalid the port */
364*4e1bc9a0SAchim Leubner         siPortInvalid(agRoot, pPort);
365*4e1bc9a0SAchim Leubner         /* map out the portmap */
366*4e1bc9a0SAchim Leubner         saRoot->PortMap[pPort->portId].PortContext = agNULL;
367*4e1bc9a0SAchim Leubner         saRoot->PortMap[pPort->portId].PortID = PORT_MARK_OFF;
368*4e1bc9a0SAchim Leubner         saRoot->PortMap[pPort->portId].PortStatus  |= PORT_INVALIDATING;
369*4e1bc9a0SAchim Leubner       }
370*4e1bc9a0SAchim Leubner       ossaHwCB(agRoot, &(pPort->portContext), OSSA_HW_EVENT_PHY_STOP_STATUS, status, agContext, agNULL);
371*4e1bc9a0SAchim Leubner     }
372*4e1bc9a0SAchim Leubner     else
373*4e1bc9a0SAchim Leubner     {
374*4e1bc9a0SAchim Leubner       SA_DBG1(("siPhyStopCB: phy%d - Port is not established\n", phyId));
375*4e1bc9a0SAchim Leubner       ossaHwCB(agRoot, agNULL, OSSA_HW_EVENT_PHY_STOP_STATUS, status, agContext, agNULL);
376*4e1bc9a0SAchim Leubner     }
377*4e1bc9a0SAchim Leubner 
378*4e1bc9a0SAchim Leubner     /* set PHY_STOPPED status */
379*4e1bc9a0SAchim Leubner     PHY_STATUS_SET(pPhy, PHY_STOPPED);
380*4e1bc9a0SAchim Leubner 
381*4e1bc9a0SAchim Leubner     /* Exclude the phy from a port */
382*4e1bc9a0SAchim Leubner     if ( agNULL != pPort )
383*4e1bc9a0SAchim Leubner     {
384*4e1bc9a0SAchim Leubner       /* Acquire port list lock */
385*4e1bc9a0SAchim Leubner       ossaSingleThreadedEnter(agRoot, LL_PORT_LOCK);
386*4e1bc9a0SAchim Leubner 
387*4e1bc9a0SAchim Leubner       /* Delete the phy from the port */
388*4e1bc9a0SAchim Leubner       pPort->phyMap[phyId] = agFALSE;
389*4e1bc9a0SAchim Leubner       saRoot->phys[phyId].pPort = agNULL;
390*4e1bc9a0SAchim Leubner 
391*4e1bc9a0SAchim Leubner       /* Release port list lock */
392*4e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_PORT_LOCK);
393*4e1bc9a0SAchim Leubner     }
394*4e1bc9a0SAchim Leubner   }
395*4e1bc9a0SAchim Leubner 
396*4e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "7c");
397*4e1bc9a0SAchim Leubner 
398*4e1bc9a0SAchim Leubner   /* return */
399*4e1bc9a0SAchim Leubner   return ret;
400*4e1bc9a0SAchim Leubner }
401*4e1bc9a0SAchim Leubner 
402*4e1bc9a0SAchim Leubner /******************************************************************************/
403*4e1bc9a0SAchim Leubner /*! \brief Initiate a Local PHY control command
404*4e1bc9a0SAchim Leubner  *
405*4e1bc9a0SAchim Leubner  *  This function is called to initiate a PHY control command to the local PHY.
406*4e1bc9a0SAchim Leubner  *  The completion of this function is reported in ossaLocalPhyControlCB()
407*4e1bc9a0SAchim Leubner 
408*4e1bc9a0SAchim Leubner  *
409*4e1bc9a0SAchim Leubner  *  \param agRoot handles for this instance of SAS/SATA hardware
410*4e1bc9a0SAchim Leubner  *  \param agContext the context of this API
411*4e1bc9a0SAchim Leubner  *  \param phyId  phy number
412*4e1bc9a0SAchim Leubner  *  \param phyOperation
413*4e1bc9a0SAchim Leubner  *    one of AGSA_PHY_LINK_RESET, AGSA_PHY_HARD_RESET, AGSA_PHY_ENABLE_SPINUP
414*4e1bc9a0SAchim Leubner  *
415*4e1bc9a0SAchim Leubner  *  \return
416*4e1bc9a0SAchim Leubner  *          - none
417*4e1bc9a0SAchim Leubner  */
418*4e1bc9a0SAchim Leubner /*******************************************************************************/
saLocalPhyControl(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,bit32 phyId,bit32 phyOperation,ossaLocalPhyControlCB_t agCB)419*4e1bc9a0SAchim Leubner GLOBAL bit32 saLocalPhyControl(
420*4e1bc9a0SAchim Leubner   agsaRoot_t             *agRoot,
421*4e1bc9a0SAchim Leubner   agsaContext_t          *agContext,
422*4e1bc9a0SAchim Leubner   bit32                   queueNum,
423*4e1bc9a0SAchim Leubner   bit32                   phyId,
424*4e1bc9a0SAchim Leubner   bit32                   phyOperation,
425*4e1bc9a0SAchim Leubner   ossaLocalPhyControlCB_t agCB
426*4e1bc9a0SAchim Leubner   )
427*4e1bc9a0SAchim Leubner {
428*4e1bc9a0SAchim Leubner   agsaLLRoot_t         *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
429*4e1bc9a0SAchim Leubner   agsaIORequestDesc_t  *pRequest;
430*4e1bc9a0SAchim Leubner   agsaPhyErrCounters_t errorParam;
431*4e1bc9a0SAchim Leubner   bit32                ret = AGSA_RC_SUCCESS;
432*4e1bc9a0SAchim Leubner   bit32                value, value1, value2, copyPhyId;
433*4e1bc9a0SAchim Leubner   bit32                count = 100;
434*4e1bc9a0SAchim Leubner   bit32                using_reserved = agFALSE;
435*4e1bc9a0SAchim Leubner 
436*4e1bc9a0SAchim Leubner 
437*4e1bc9a0SAchim Leubner   /* sanity check */
438*4e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != saRoot), "");
439*4e1bc9a0SAchim Leubner   if(saRoot == agNULL)
440*4e1bc9a0SAchim Leubner   {
441*4e1bc9a0SAchim Leubner     SA_DBG1(("saLocalPhyControl: saRoot == agNULL\n"));
442*4e1bc9a0SAchim Leubner     return(AGSA_RC_FAILURE);
443*4e1bc9a0SAchim Leubner   }
444*4e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"7d");
445*4e1bc9a0SAchim Leubner 
446*4e1bc9a0SAchim Leubner   si_memset(&errorParam,0,sizeof(agsaPhyErrCounters_t));
447*4e1bc9a0SAchim Leubner   SA_DBG2(("saLocalPhyControl: phy%d operation %08X\n", phyId, phyOperation));
448*4e1bc9a0SAchim Leubner 
449*4e1bc9a0SAchim Leubner   switch(phyOperation)
450*4e1bc9a0SAchim Leubner   {
451*4e1bc9a0SAchim Leubner     case AGSA_PHY_LINK_RESET:
452*4e1bc9a0SAchim Leubner     case AGSA_PHY_HARD_RESET:
453*4e1bc9a0SAchim Leubner     case AGSA_PHY_NOTIFY_ENABLE_SPINUP:
454*4e1bc9a0SAchim Leubner     case AGSA_PHY_BROADCAST_ASYNCH_EVENT:
455*4e1bc9a0SAchim Leubner     case AGSA_PHY_COMINIT_OOB:
456*4e1bc9a0SAchim Leubner     {
457*4e1bc9a0SAchim Leubner       /* Get request from free IORequests */
458*4e1bc9a0SAchim Leubner       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
459*4e1bc9a0SAchim Leubner       pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
460*4e1bc9a0SAchim Leubner 
461*4e1bc9a0SAchim Leubner       /* If no LL Control request entry available */
462*4e1bc9a0SAchim Leubner       if ( agNULL == pRequest )
463*4e1bc9a0SAchim Leubner       {
464*4e1bc9a0SAchim Leubner         pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
465*4e1bc9a0SAchim Leubner         /* If no LL Control request entry available */
466*4e1bc9a0SAchim Leubner         if(agNULL != pRequest)
467*4e1bc9a0SAchim Leubner         {
468*4e1bc9a0SAchim Leubner           using_reserved = agTRUE;
469*4e1bc9a0SAchim Leubner           SA_DBG1(("saLocalPhyControl, using saRoot->freeReservedRequests\n"));
470*4e1bc9a0SAchim Leubner         }
471*4e1bc9a0SAchim Leubner         else
472*4e1bc9a0SAchim Leubner         {
473*4e1bc9a0SAchim Leubner           ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
474*4e1bc9a0SAchim Leubner           SA_DBG1(("saLocalPhyControl, No request from free list Not using saRoot->freeReservedRequests\n"));
475*4e1bc9a0SAchim Leubner           smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "7d");
476*4e1bc9a0SAchim Leubner           return AGSA_RC_BUSY;
477*4e1bc9a0SAchim Leubner         }
478*4e1bc9a0SAchim Leubner       }
479*4e1bc9a0SAchim Leubner       if( using_reserved )
480*4e1bc9a0SAchim Leubner       {
481*4e1bc9a0SAchim Leubner         saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
482*4e1bc9a0SAchim Leubner       }
483*4e1bc9a0SAchim Leubner       else
484*4e1bc9a0SAchim Leubner       {
485*4e1bc9a0SAchim Leubner         saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
486*4e1bc9a0SAchim Leubner       }
487*4e1bc9a0SAchim Leubner       /* Remove the request from free list */
488*4e1bc9a0SAchim Leubner       SA_ASSERT((!pRequest->valid), "The pRequest is in use");
489*4e1bc9a0SAchim Leubner       pRequest->completionCB = (void*)agCB;
490*4e1bc9a0SAchim Leubner       //  pRequest->abortCompletionCB = agCB;
491*4e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
492*4e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
493*4e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agContext;
494*4e1bc9a0SAchim Leubner       pRequest->valid = agTRUE;
495*4e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
496*4e1bc9a0SAchim Leubner 
497*4e1bc9a0SAchim Leubner       /* Build the local phy control IOMB command and send to SPC */
498*4e1bc9a0SAchim Leubner       ret = mpiLocalPhyControlCmd(agRoot, pRequest->HTag, phyId, phyOperation, queueNum);
499*4e1bc9a0SAchim Leubner       if (AGSA_RC_SUCCESS != ret)
500*4e1bc9a0SAchim Leubner       {
501*4e1bc9a0SAchim Leubner         /* remove the request from IOMap */
502*4e1bc9a0SAchim Leubner         saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
503*4e1bc9a0SAchim Leubner         saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
504*4e1bc9a0SAchim Leubner         saRoot->IOMap[pRequest->HTag].agContext = agNULL;
505*4e1bc9a0SAchim Leubner         pRequest->valid = agFALSE;
506*4e1bc9a0SAchim Leubner 
507*4e1bc9a0SAchim Leubner         ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
508*4e1bc9a0SAchim Leubner         /* return the request to free pool */
509*4e1bc9a0SAchim Leubner         if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
510*4e1bc9a0SAchim Leubner         {
511*4e1bc9a0SAchim Leubner           SA_DBG1(("saLocalPhyControl: saving pRequest (%p) for later use\n", pRequest));
512*4e1bc9a0SAchim Leubner           saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
513*4e1bc9a0SAchim Leubner         }
514*4e1bc9a0SAchim Leubner         else
515*4e1bc9a0SAchim Leubner         {
516*4e1bc9a0SAchim Leubner           /* return the request to free pool */
517*4e1bc9a0SAchim Leubner           saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
518*4e1bc9a0SAchim Leubner         }
519*4e1bc9a0SAchim Leubner         SA_DBG1(("saLocalPhyControl, sending IOMB failed\n" ));
520*4e1bc9a0SAchim Leubner         ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
521*4e1bc9a0SAchim Leubner         return ret;
522*4e1bc9a0SAchim Leubner       }
523*4e1bc9a0SAchim Leubner     }
524*4e1bc9a0SAchim Leubner     break;
525*4e1bc9a0SAchim Leubner     case AGSA_PHY_GET_ERROR_COUNTS:
526*4e1bc9a0SAchim Leubner     {
527*4e1bc9a0SAchim Leubner       if(smIS_SPCV(agRoot))
528*4e1bc9a0SAchim Leubner       {
529*4e1bc9a0SAchim Leubner 
530*4e1bc9a0SAchim Leubner         SA_ASSERT((smIS_SPC(agRoot)), "SPC only");
531*4e1bc9a0SAchim Leubner         SA_DBG1(("saLocalPhyControl: V AGSA_PHY_GET_ERROR_COUNTS\n" ));
532*4e1bc9a0SAchim Leubner         smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "7d");
533*4e1bc9a0SAchim Leubner         return AGSA_RC_FAILURE;
534*4e1bc9a0SAchim Leubner       }
535*4e1bc9a0SAchim Leubner       /* If phyId is invalid, return failure */
536*4e1bc9a0SAchim Leubner       if ( phyId >= saRoot->phyCount )
537*4e1bc9a0SAchim Leubner       {
538*4e1bc9a0SAchim Leubner         ret = AGSA_RC_FAILURE;
539*4e1bc9a0SAchim Leubner         si_memset(&errorParam, 0, sizeof(agsaPhyErrCounters_t));
540*4e1bc9a0SAchim Leubner         SA_DBG1(("saLocalPhyControl: phy%d - failure with phyId\n", phyId));
541*4e1bc9a0SAchim Leubner         /* call back with the status */
542*4e1bc9a0SAchim Leubner 
543*4e1bc9a0SAchim Leubner         if( agCB == agNULL )
544*4e1bc9a0SAchim Leubner         {
545*4e1bc9a0SAchim Leubner           ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
546*4e1bc9a0SAchim Leubner         }
547*4e1bc9a0SAchim Leubner         else
548*4e1bc9a0SAchim Leubner         {
549*4e1bc9a0SAchim Leubner           agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
550*4e1bc9a0SAchim Leubner         }
551*4e1bc9a0SAchim Leubner         smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "7d");
552*4e1bc9a0SAchim Leubner         return ret;
553*4e1bc9a0SAchim Leubner       }
554*4e1bc9a0SAchim Leubner       /* save phyId */
555*4e1bc9a0SAchim Leubner       copyPhyId = phyId;
556*4e1bc9a0SAchim Leubner       /* map 0x030000 or 0x040000 based on phyId to BAR4(0x20), BAT2(win) to access the register  */
557*4e1bc9a0SAchim Leubner       if (phyId < 4)
558*4e1bc9a0SAchim Leubner       {
559*4e1bc9a0SAchim Leubner         /* for phyId = 0, 1, 2, 3 */
560*4e1bc9a0SAchim Leubner         value = 0x030000;
561*4e1bc9a0SAchim Leubner       }
562*4e1bc9a0SAchim Leubner       else
563*4e1bc9a0SAchim Leubner       {
564*4e1bc9a0SAchim Leubner         /* for phyId = 4, 5, 6, 7 */
565*4e1bc9a0SAchim Leubner         phyId = phyId - 4;
566*4e1bc9a0SAchim Leubner         value = 0x040000;
567*4e1bc9a0SAchim Leubner       }
568*4e1bc9a0SAchim Leubner 
569*4e1bc9a0SAchim Leubner       /* Need to make sure DEVICE_LCLK_GENERATION register bit 6 is 0 */
570*4e1bc9a0SAchim Leubner       value1 = ossaHwRegReadExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK);
571*4e1bc9a0SAchim Leubner 
572*4e1bc9a0SAchim Leubner       SA_DBG3(("saLocalPhyControl: TOP DEVICE LCLK Register value = %08X\n", value1));
573*4e1bc9a0SAchim Leubner       /* If LCLK_CLEAR bit set then disable it */
574*4e1bc9a0SAchim Leubner       if (value1 & DEVICE_LCLK_CLEAR)
575*4e1bc9a0SAchim Leubner       {
576*4e1bc9a0SAchim Leubner         ossaHwRegWriteExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK, (value1 & 0xFFFFFFBF) );
577*4e1bc9a0SAchim Leubner         SA_DBG3(("saLocalPhyControl: TOP DEVICE LCLK value = %08X\n", (value1 & 0xFFFFFFBF)));
578*4e1bc9a0SAchim Leubner       }
579*4e1bc9a0SAchim Leubner 
580*4e1bc9a0SAchim Leubner       if (AGSA_RC_FAILURE == siBar4Shift(agRoot, value))
581*4e1bc9a0SAchim Leubner       {
582*4e1bc9a0SAchim Leubner         SA_DBG1(("saLocalPhyControl:Shift Bar4 to 0x%x failed\n", value));
583*4e1bc9a0SAchim Leubner         phyId = copyPhyId;
584*4e1bc9a0SAchim Leubner         /* call back with the status */
585*4e1bc9a0SAchim Leubner 
586*4e1bc9a0SAchim Leubner         if( agCB == agNULL )
587*4e1bc9a0SAchim Leubner         {
588*4e1bc9a0SAchim Leubner           ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
589*4e1bc9a0SAchim Leubner         }
590*4e1bc9a0SAchim Leubner         else
591*4e1bc9a0SAchim Leubner         {
592*4e1bc9a0SAchim Leubner           agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
593*4e1bc9a0SAchim Leubner         }
594*4e1bc9a0SAchim Leubner 
595*4e1bc9a0SAchim Leubner         smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "7d");
596*4e1bc9a0SAchim Leubner         return AGSA_RC_FAILURE;
597*4e1bc9a0SAchim Leubner       }
598*4e1bc9a0SAchim Leubner 
599*4e1bc9a0SAchim Leubner       /* set LCLK = 1 and LCLK_CLEAR = 0 */
600*4e1bc9a0SAchim Leubner       SPC_WRITE_COUNTER_CNTL(phyId, LCLK);
601*4e1bc9a0SAchim Leubner 
602*4e1bc9a0SAchim Leubner       /* LCLK bit should be low to be able to read error registers */
603*4e1bc9a0SAchim Leubner       while((value = SPC_READ_COUNTER_CNTL(phyId)) & LCLK)
604*4e1bc9a0SAchim Leubner       {
605*4e1bc9a0SAchim Leubner         if(--count == 0)
606*4e1bc9a0SAchim Leubner         {
607*4e1bc9a0SAchim Leubner           SA_DBG1(("saLocalPhyControl: Timeout,SPC_COUNTER_CNTL value = %08X\n", value));
608*4e1bc9a0SAchim Leubner           ret = AGSA_RC_FAILURE;
609*4e1bc9a0SAchim Leubner           break;
610*4e1bc9a0SAchim Leubner         }
611*4e1bc9a0SAchim Leubner       } /* while */
612*4e1bc9a0SAchim Leubner 
613*4e1bc9a0SAchim Leubner       value = SPC_READ_COUNTER_CNTL(phyId);
614*4e1bc9a0SAchim Leubner       SA_DBG3(("saLocalPhyControl: SPC_COUNTER_CNTL value = %08X\n", value));
615*4e1bc9a0SAchim Leubner 
616*4e1bc9a0SAchim Leubner       /* invalidDword */
617*4e1bc9a0SAchim Leubner       errorParam.invalidDword = SPC_READ_INV_DW_COUNT(phyId);
618*4e1bc9a0SAchim Leubner       /* runningDisparityError */
619*4e1bc9a0SAchim Leubner       errorParam.runningDisparityError = SPC_READ_DISP_ERR_COUNT(phyId);
620*4e1bc9a0SAchim Leubner       /* lossOfDwordSynch */
621*4e1bc9a0SAchim Leubner       errorParam.lossOfDwordSynch = SPC_READ_LOSS_DW_COUNT(phyId);
622*4e1bc9a0SAchim Leubner       /* phyResetProblem */
623*4e1bc9a0SAchim Leubner       errorParam.phyResetProblem = SPC_READ_PHY_RESET_COUNT(phyId);
624*4e1bc9a0SAchim Leubner       /* codeViolation */
625*4e1bc9a0SAchim Leubner       errorParam.codeViolation = SPC_READ_CODE_VIO_COUNT(phyId);
626*4e1bc9a0SAchim Leubner       /* never occurred in SPC8x6G */
627*4e1bc9a0SAchim Leubner       errorParam.elasticityBufferOverflow = 0;
628*4e1bc9a0SAchim Leubner       errorParam.receivedErrorPrimitive = 0;
629*4e1bc9a0SAchim Leubner       errorParam.inboundCRCError = 0;
630*4e1bc9a0SAchim Leubner 
631*4e1bc9a0SAchim Leubner       SA_DBG3(("saLocalPhyControl:INV_DW_COUNT         0x%x\n", SPC_READ_INV_DW_COUNT(phyId)));
632*4e1bc9a0SAchim Leubner       SA_DBG3(("saLocalPhyControl:DISP_ERR_COUNT       0x%x\n", SPC_READ_DISP_ERR_COUNT(phyId)));
633*4e1bc9a0SAchim Leubner       SA_DBG3(("saLocalPhyControl:LOSS_DW_COUNT        0x%x\n", SPC_READ_LOSS_DW_COUNT(phyId)));
634*4e1bc9a0SAchim Leubner       SA_DBG3(("saLocalPhyControl:PHY_RESET_COUNT      0x%x\n", SPC_READ_PHY_RESET_COUNT(phyId)));
635*4e1bc9a0SAchim Leubner       SA_DBG3(("saLocalPhyControl:CODE_VIOLATION_COUNT 0x%x\n", SPC_READ_CODE_VIO_COUNT(phyId)));
636*4e1bc9a0SAchim Leubner 
637*4e1bc9a0SAchim Leubner       /* Shift back to BAR4 original address */
638*4e1bc9a0SAchim Leubner       if (AGSA_RC_FAILURE == siBar4Shift(agRoot, 0x0))
639*4e1bc9a0SAchim Leubner       {
640*4e1bc9a0SAchim Leubner         SA_DBG1(("saLocalPhyControl:Shift Bar4 to 0x%x failed\n", 0x0));
641*4e1bc9a0SAchim Leubner         ret = AGSA_RC_FAILURE;
642*4e1bc9a0SAchim Leubner       }
643*4e1bc9a0SAchim Leubner 
644*4e1bc9a0SAchim Leubner       /* restore back the Top Device LCLK generation register value */
645*4e1bc9a0SAchim Leubner       ossaHwRegWriteExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK, value1);
646*4e1bc9a0SAchim Leubner 
647*4e1bc9a0SAchim Leubner       /* restore phyId */
648*4e1bc9a0SAchim Leubner       phyId = copyPhyId;
649*4e1bc9a0SAchim Leubner       /* call back with the status */
650*4e1bc9a0SAchim Leubner 
651*4e1bc9a0SAchim Leubner       if (AGSA_RC_SUCCESS == ret)
652*4e1bc9a0SAchim Leubner       {
653*4e1bc9a0SAchim Leubner         if( agCB == agNULL )
654*4e1bc9a0SAchim Leubner         {
655*4e1bc9a0SAchim Leubner           ossaLocalPhyControlCB(agRoot, agContext, copyPhyId, phyOperation, OSSA_SUCCESS, (void *)&errorParam);
656*4e1bc9a0SAchim Leubner         }
657*4e1bc9a0SAchim Leubner         else
658*4e1bc9a0SAchim Leubner         {
659*4e1bc9a0SAchim Leubner           agCB(agRoot, agContext, copyPhyId, phyOperation, OSSA_SUCCESS, (void *)&errorParam);
660*4e1bc9a0SAchim Leubner         }
661*4e1bc9a0SAchim Leubner       }
662*4e1bc9a0SAchim Leubner       else
663*4e1bc9a0SAchim Leubner       {
664*4e1bc9a0SAchim Leubner         if( agCB == agNULL )
665*4e1bc9a0SAchim Leubner         {
666*4e1bc9a0SAchim Leubner           ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
667*4e1bc9a0SAchim Leubner         }
668*4e1bc9a0SAchim Leubner         else
669*4e1bc9a0SAchim Leubner         {
670*4e1bc9a0SAchim Leubner           agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
671*4e1bc9a0SAchim Leubner         }
672*4e1bc9a0SAchim Leubner       }
673*4e1bc9a0SAchim Leubner       break;
674*4e1bc9a0SAchim Leubner     }
675*4e1bc9a0SAchim Leubner     case AGSA_PHY_CLEAR_ERROR_COUNTS:
676*4e1bc9a0SAchim Leubner     {
677*4e1bc9a0SAchim Leubner       if(smIS_SPCV(agRoot))
678*4e1bc9a0SAchim Leubner       {
679*4e1bc9a0SAchim Leubner 
680*4e1bc9a0SAchim Leubner         SA_ASSERT((smIS_SPC(agRoot)), "SPC only");
681*4e1bc9a0SAchim Leubner         SA_DBG1(("saLocalPhyControl: V AGSA_PHY_CLEAR_ERROR_COUNTS\n" ));
682*4e1bc9a0SAchim Leubner         smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "7d");
683*4e1bc9a0SAchim Leubner         return AGSA_RC_FAILURE;
684*4e1bc9a0SAchim Leubner       }
685*4e1bc9a0SAchim Leubner       /* If phyId is invalid, return failure */
686*4e1bc9a0SAchim Leubner       if ( phyId >= saRoot->phyCount )
687*4e1bc9a0SAchim Leubner       {
688*4e1bc9a0SAchim Leubner         si_memset(&errorParam, 0, sizeof(agsaPhyErrCountersPage_t));
689*4e1bc9a0SAchim Leubner         SA_DBG3(("saLocalPhyControl(CLEAR): phy%d - failure with phyId\n", phyId));
690*4e1bc9a0SAchim Leubner         /* call back with the status */
691*4e1bc9a0SAchim Leubner         if( agCB == agNULL )
692*4e1bc9a0SAchim Leubner         {
693*4e1bc9a0SAchim Leubner           ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
694*4e1bc9a0SAchim Leubner         }
695*4e1bc9a0SAchim Leubner         else
696*4e1bc9a0SAchim Leubner         {
697*4e1bc9a0SAchim Leubner           agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
698*4e1bc9a0SAchim Leubner         }
699*4e1bc9a0SAchim Leubner         smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "7d");
700*4e1bc9a0SAchim Leubner         return AGSA_RC_FAILURE;
701*4e1bc9a0SAchim Leubner       }
702*4e1bc9a0SAchim Leubner       /* save phyId */
703*4e1bc9a0SAchim Leubner       copyPhyId = phyId;
704*4e1bc9a0SAchim Leubner       /* map 0x030000 or 0x040000 based on phyId to BAR4(0x20), BAT2(win) to access the register  */
705*4e1bc9a0SAchim Leubner       if (phyId < 4)
706*4e1bc9a0SAchim Leubner       {
707*4e1bc9a0SAchim Leubner         /* for phyId = 0, 1, 2, 3 */
708*4e1bc9a0SAchim Leubner         value = 0x030000;
709*4e1bc9a0SAchim Leubner       }
710*4e1bc9a0SAchim Leubner       else
711*4e1bc9a0SAchim Leubner       {
712*4e1bc9a0SAchim Leubner         /* for phyId = 4, 5, 6, 7 */
713*4e1bc9a0SAchim Leubner         phyId = phyId - 4;
714*4e1bc9a0SAchim Leubner         value = 0x040000;
715*4e1bc9a0SAchim Leubner       }
716*4e1bc9a0SAchim Leubner       /* Need to make sure DEVICE_LCLK_GENERATION register bit 6 is 1 */
717*4e1bc9a0SAchim Leubner       value2 = ossaHwRegReadExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK);
718*4e1bc9a0SAchim Leubner 
719*4e1bc9a0SAchim Leubner       SA_DBG3(("saLocalPhyControl: TOP DEVICE LCLK Register value = %08X\n", value2));
720*4e1bc9a0SAchim Leubner       /* If LCLK_CLEAR bit not set then set it */
721*4e1bc9a0SAchim Leubner       if ((value2 & DEVICE_LCLK_CLEAR) == 0)
722*4e1bc9a0SAchim Leubner       {
723*4e1bc9a0SAchim Leubner         ossaHwRegWriteExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK, (value2 | DEVICE_LCLK_CLEAR) );
724*4e1bc9a0SAchim Leubner         SA_DBG3(("saLocalPhyControl: TOP DEVICE LCLK value = %08X\n", (value2 & 0xFFFFFFBF)));
725*4e1bc9a0SAchim Leubner       }
726*4e1bc9a0SAchim Leubner 
727*4e1bc9a0SAchim Leubner       if (AGSA_RC_FAILURE == siBar4Shift(agRoot, value))
728*4e1bc9a0SAchim Leubner       {
729*4e1bc9a0SAchim Leubner         SA_DBG1(("saLocalPhyControl(CLEAR):Shift Bar4 to 0x%x failed\n", value));
730*4e1bc9a0SAchim Leubner         phyId = copyPhyId;
731*4e1bc9a0SAchim Leubner         /* call back with the status */
732*4e1bc9a0SAchim Leubner         if( agCB == agNULL )
733*4e1bc9a0SAchim Leubner         {
734*4e1bc9a0SAchim Leubner           ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
735*4e1bc9a0SAchim Leubner         }
736*4e1bc9a0SAchim Leubner         else
737*4e1bc9a0SAchim Leubner         {
738*4e1bc9a0SAchim Leubner           agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
739*4e1bc9a0SAchim Leubner         }
740*4e1bc9a0SAchim Leubner         smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "7d");
741*4e1bc9a0SAchim Leubner         return AGSA_RC_FAILURE;
742*4e1bc9a0SAchim Leubner       }
743*4e1bc9a0SAchim Leubner 
744*4e1bc9a0SAchim Leubner       /* read Counter Control register */
745*4e1bc9a0SAchim Leubner       value1 = SPC_READ_COUNTER_CNTL(phyId);
746*4e1bc9a0SAchim Leubner       SA_DBG3(("saLocalPhyControl(CLEAR): SPC_COUNTER_CNTL value = %08X\n", value1));
747*4e1bc9a0SAchim Leubner       /* set LCLK and LCLK_CLEAR */
748*4e1bc9a0SAchim Leubner       SPC_WRITE_COUNTER_CNTL(phyId, (LCLK_CLEAR | LCLK));
749*4e1bc9a0SAchim Leubner       /* read back the value of register */
750*4e1bc9a0SAchim Leubner       /* poll LCLK bit = 0 */
751*4e1bc9a0SAchim Leubner       while((value = SPC_READ_COUNTER_CNTL(phyId)) & LCLK)
752*4e1bc9a0SAchim Leubner       {
753*4e1bc9a0SAchim Leubner         if(--count == 0)
754*4e1bc9a0SAchim Leubner         {
755*4e1bc9a0SAchim Leubner           SA_DBG1(("saLocalPhyControl: Timeout,SPC_COUNTER_CNTL value = %08X\n", value));
756*4e1bc9a0SAchim Leubner           ret = AGSA_RC_FAILURE;
757*4e1bc9a0SAchim Leubner           break;
758*4e1bc9a0SAchim Leubner         }
759*4e1bc9a0SAchim Leubner       } /* while */
760*4e1bc9a0SAchim Leubner 
761*4e1bc9a0SAchim Leubner       value = SPC_READ_COUNTER_CNTL(phyId);
762*4e1bc9a0SAchim Leubner       SA_DBG3(("saLocalPhyControl(CLEAR): SPC_COUNTER_CNTL value = %08X\n", value));
763*4e1bc9a0SAchim Leubner 
764*4e1bc9a0SAchim Leubner       /* restore the value */
765*4e1bc9a0SAchim Leubner       SPC_WRITE_COUNTER_CNTL(phyId, value1);
766*4e1bc9a0SAchim Leubner 
767*4e1bc9a0SAchim Leubner       /* Shift back to BAR4 original address */
768*4e1bc9a0SAchim Leubner       if (AGSA_RC_FAILURE == siBar4Shift(agRoot, 0x0))
769*4e1bc9a0SAchim Leubner       {
770*4e1bc9a0SAchim Leubner         SA_DBG1(("saLocalPhyControl:Shift Bar4 to 0x%x failed\n", 0x0));
771*4e1bc9a0SAchim Leubner         ret = AGSA_RC_FAILURE;
772*4e1bc9a0SAchim Leubner       }
773*4e1bc9a0SAchim Leubner 
774*4e1bc9a0SAchim Leubner       /* restore back the Top Device LCLK generation register value */
775*4e1bc9a0SAchim Leubner       ossaHwRegWriteExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK, value2);
776*4e1bc9a0SAchim Leubner 
777*4e1bc9a0SAchim Leubner       /* restore phyId */
778*4e1bc9a0SAchim Leubner       phyId = copyPhyId;
779*4e1bc9a0SAchim Leubner       /* call back with the status */
780*4e1bc9a0SAchim Leubner       if (AGSA_RC_SUCCESS == ret)
781*4e1bc9a0SAchim Leubner       {
782*4e1bc9a0SAchim Leubner         if( agCB == agNULL )
783*4e1bc9a0SAchim Leubner         {
784*4e1bc9a0SAchim Leubner           ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_SUCCESS, agNULL);
785*4e1bc9a0SAchim Leubner         }
786*4e1bc9a0SAchim Leubner         else
787*4e1bc9a0SAchim Leubner         {
788*4e1bc9a0SAchim Leubner           agCB(agRoot, agContext, phyId, phyOperation, OSSA_SUCCESS, agNULL);
789*4e1bc9a0SAchim Leubner         }
790*4e1bc9a0SAchim Leubner       }
791*4e1bc9a0SAchim Leubner       else
792*4e1bc9a0SAchim Leubner       {
793*4e1bc9a0SAchim Leubner         if( agCB == agNULL )
794*4e1bc9a0SAchim Leubner         {
795*4e1bc9a0SAchim Leubner           ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
796*4e1bc9a0SAchim Leubner         }
797*4e1bc9a0SAchim Leubner         else
798*4e1bc9a0SAchim Leubner         {
799*4e1bc9a0SAchim Leubner           agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
800*4e1bc9a0SAchim Leubner         }
801*4e1bc9a0SAchim Leubner       }
802*4e1bc9a0SAchim Leubner       break;
803*4e1bc9a0SAchim Leubner     }
804*4e1bc9a0SAchim Leubner     case AGSA_PHY_GET_BW_COUNTS:
805*4e1bc9a0SAchim Leubner     {
806*4e1bc9a0SAchim Leubner       SA_ASSERT((smIS_SPC(agRoot)), "SPCv only");
807*4e1bc9a0SAchim Leubner       SA_DBG1(("saLocalPhyControl: AGSA_PHY_GET_BW_COUNTS\n" ));
808*4e1bc9a0SAchim Leubner       break;
809*4e1bc9a0SAchim Leubner     }
810*4e1bc9a0SAchim Leubner 
811*4e1bc9a0SAchim Leubner     default:
812*4e1bc9a0SAchim Leubner       ret = AGSA_RC_FAILURE;
813*4e1bc9a0SAchim Leubner       SA_ASSERT(agFALSE, "(saLocalPhyControl) Unknown operation");
814*4e1bc9a0SAchim Leubner       break;
815*4e1bc9a0SAchim Leubner   }
816*4e1bc9a0SAchim Leubner 
817*4e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "7d");
818*4e1bc9a0SAchim Leubner   return ret;
819*4e1bc9a0SAchim Leubner }
820*4e1bc9a0SAchim Leubner 
821*4e1bc9a0SAchim Leubner 
saGetPhyProfile(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,bit32 ppc,bit32 phyId)822*4e1bc9a0SAchim Leubner GLOBAL bit32 saGetPhyProfile(
823*4e1bc9a0SAchim Leubner                       agsaRoot_t    *agRoot,
824*4e1bc9a0SAchim Leubner                       agsaContext_t *agContext,
825*4e1bc9a0SAchim Leubner                       bit32         queueNum,
826*4e1bc9a0SAchim Leubner                       bit32         ppc,
827*4e1bc9a0SAchim Leubner                       bit32         phyId
828*4e1bc9a0SAchim Leubner                       )
829*4e1bc9a0SAchim Leubner {
830*4e1bc9a0SAchim Leubner   bit32 ret = AGSA_RC_SUCCESS;
831*4e1bc9a0SAchim Leubner 
832*4e1bc9a0SAchim Leubner   agsaLLRoot_t            *saRoot = agNULL;
833*4e1bc9a0SAchim Leubner   agsaPhyErrCountersPage_t errorParam;
834*4e1bc9a0SAchim Leubner 
835*4e1bc9a0SAchim Leubner   ossaLocalPhyControlCB_t agCB = ossaGetPhyProfileCB;
836*4e1bc9a0SAchim Leubner 
837*4e1bc9a0SAchim Leubner   /* sanity check */
838*4e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
839*4e1bc9a0SAchim Leubner   saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
840*4e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != saRoot), "");
841*4e1bc9a0SAchim Leubner 
842*4e1bc9a0SAchim Leubner   if(saRoot == agNULL)
843*4e1bc9a0SAchim Leubner   {
844*4e1bc9a0SAchim Leubner     SA_DBG3(("saGetPhyProfile : saRoot is NULL"));
845*4e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
846*4e1bc9a0SAchim Leubner   }
847*4e1bc9a0SAchim Leubner 
848*4e1bc9a0SAchim Leubner   SA_DBG1(("saGetPhyProfile: ppc 0x%x phyID %d\n", ppc,phyId));
849*4e1bc9a0SAchim Leubner 
850*4e1bc9a0SAchim Leubner   switch(ppc)
851*4e1bc9a0SAchim Leubner   {
852*4e1bc9a0SAchim Leubner     case AGSA_SAS_PHY_ERR_COUNTERS_PAGE:
853*4e1bc9a0SAchim Leubner     {
854*4e1bc9a0SAchim Leubner       if(smIS_SPCV(agRoot))
855*4e1bc9a0SAchim Leubner       {
856*4e1bc9a0SAchim Leubner 
857*4e1bc9a0SAchim Leubner         SA_DBG1(("saGetPhyProfile: V AGSA_SAS_PHY_ERR_COUNTERS_PAGE\n" ));
858*4e1bc9a0SAchim Leubner 
859*4e1bc9a0SAchim Leubner         ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB);
860*4e1bc9a0SAchim Leubner         smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "7d");
861*4e1bc9a0SAchim Leubner         return ret;
862*4e1bc9a0SAchim Leubner       }
863*4e1bc9a0SAchim Leubner     }
864*4e1bc9a0SAchim Leubner     case AGSA_SAS_PHY_ERR_COUNTERS_CLR_PAGE:
865*4e1bc9a0SAchim Leubner     {
866*4e1bc9a0SAchim Leubner       /* If phyId is invalid, return failure */
867*4e1bc9a0SAchim Leubner       if ( phyId >= saRoot->phyCount )
868*4e1bc9a0SAchim Leubner       {
869*4e1bc9a0SAchim Leubner         si_memset(&errorParam, 0, sizeof(agsaPhyErrCountersPage_t));
870*4e1bc9a0SAchim Leubner         SA_DBG3(("saGetPhyProfile(CLEAR): phy%d - failure with phyId\n", phyId));
871*4e1bc9a0SAchim Leubner         /* call back with the status */
872*4e1bc9a0SAchim Leubner         ossaGetPhyProfileCB(agRoot, agContext, phyId, ppc, OSSA_FAILURE, (void *)&errorParam);
873*4e1bc9a0SAchim Leubner         smTraceFuncExit(hpDBG_VERY_LOUD, 'j', "7d");
874*4e1bc9a0SAchim Leubner         return AGSA_RC_FAILURE;
875*4e1bc9a0SAchim Leubner       }
876*4e1bc9a0SAchim Leubner       if(smIS_SPCV(agRoot))
877*4e1bc9a0SAchim Leubner       {
878*4e1bc9a0SAchim Leubner         SA_DBG1(("saGetPhyProfile: V AGSA_SAS_PHY_ERR_COUNTERS_CLR_PAGE\n" ));
879*4e1bc9a0SAchim Leubner 
880*4e1bc9a0SAchim Leubner         ret = mpiGetPhyProfileCmd( agRoot,agContext, ppc,phyId,agCB);
881*4e1bc9a0SAchim Leubner         smTraceFuncExit(hpDBG_VERY_LOUD, 'k', "7d");
882*4e1bc9a0SAchim Leubner         return ret;
883*4e1bc9a0SAchim Leubner       }
884*4e1bc9a0SAchim Leubner 
885*4e1bc9a0SAchim Leubner     }
886*4e1bc9a0SAchim Leubner     case AGSA_SAS_PHY_BW_COUNTERS_PAGE:
887*4e1bc9a0SAchim Leubner     {
888*4e1bc9a0SAchim Leubner       SA_DBG1(("saGetPhyProfile: AGSA_SAS_PHY_BW_COUNTERS_PAGE\n" ));
889*4e1bc9a0SAchim Leubner       ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB);
890*4e1bc9a0SAchim Leubner       break;
891*4e1bc9a0SAchim Leubner     }
892*4e1bc9a0SAchim Leubner     case AGSA_SAS_PHY_ANALOG_SETTINGS_PAGE:
893*4e1bc9a0SAchim Leubner     {
894*4e1bc9a0SAchim Leubner       SA_DBG1(("saGetPhyProfile: AGSA_SAS_PHY_ANALOG_SETTINGS_PAGE\n" ));
895*4e1bc9a0SAchim Leubner       ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB);
896*4e1bc9a0SAchim Leubner       break;
897*4e1bc9a0SAchim Leubner     }
898*4e1bc9a0SAchim Leubner 
899*4e1bc9a0SAchim Leubner     case AGSA_SAS_PHY_GENERAL_STATUS_PAGE:
900*4e1bc9a0SAchim Leubner     {
901*4e1bc9a0SAchim Leubner       SA_DBG1(("saGetPhyProfile: AGSA_SAS_PHY_GENERAL_STATUS_PAGE\n" ));
902*4e1bc9a0SAchim Leubner       ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB);
903*4e1bc9a0SAchim Leubner       break;
904*4e1bc9a0SAchim Leubner     }
905*4e1bc9a0SAchim Leubner     case AGSA_PHY_SNW3_PAGE:
906*4e1bc9a0SAchim Leubner     {
907*4e1bc9a0SAchim Leubner       SA_DBG1(("saGetPhyProfile: AGSA_PHY_SNW3_PAGE\n" ));
908*4e1bc9a0SAchim Leubner       ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB);
909*4e1bc9a0SAchim Leubner       break;
910*4e1bc9a0SAchim Leubner     }
911*4e1bc9a0SAchim Leubner     case AGSA_PHY_RATE_CONTROL_PAGE:
912*4e1bc9a0SAchim Leubner     {
913*4e1bc9a0SAchim Leubner       SA_DBG1(("saGetPhyProfile: AGSA_PHY_RATE_CONTROL_PAGE\n" ));
914*4e1bc9a0SAchim Leubner       ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB);
915*4e1bc9a0SAchim Leubner       break;
916*4e1bc9a0SAchim Leubner     }
917*4e1bc9a0SAchim Leubner     case AGSA_SAS_PHY_OPEN_REJECT_RETRY_BACKOFF_THRESHOLD_PAGE:
918*4e1bc9a0SAchim Leubner     {
919*4e1bc9a0SAchim Leubner       SA_DBG1(("saGetPhyProfile: AGSA_SAS_PHY_OPEN_REJECT_RETRY_BACKOFF_THRESHOLD_PAGE\n" ));
920*4e1bc9a0SAchim Leubner       ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB);
921*4e1bc9a0SAchim Leubner       break;
922*4e1bc9a0SAchim Leubner     }
923*4e1bc9a0SAchim Leubner 
924*4e1bc9a0SAchim Leubner     default:
925*4e1bc9a0SAchim Leubner       SA_DBG1(("saGetPhyProfile: Unknown operation 0x%X\n",ppc ));
926*4e1bc9a0SAchim Leubner       SA_ASSERT(agFALSE, "saGetPhyProfile Unknown operation " );
927*4e1bc9a0SAchim Leubner       break;
928*4e1bc9a0SAchim Leubner 
929*4e1bc9a0SAchim Leubner   }
930*4e1bc9a0SAchim Leubner   return ret;
931*4e1bc9a0SAchim Leubner 
932*4e1bc9a0SAchim Leubner }
933*4e1bc9a0SAchim Leubner 
934*4e1bc9a0SAchim Leubner 
saSetPhyProfile(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,bit32 ppc,bit32 length,void * buffer,bit32 phyID)935*4e1bc9a0SAchim Leubner GLOBAL bit32 saSetPhyProfile (
936*4e1bc9a0SAchim Leubner                       agsaRoot_t    *agRoot,
937*4e1bc9a0SAchim Leubner                       agsaContext_t *agContext,
938*4e1bc9a0SAchim Leubner                       bit32         queueNum,
939*4e1bc9a0SAchim Leubner                       bit32         ppc,
940*4e1bc9a0SAchim Leubner                       bit32         length,
941*4e1bc9a0SAchim Leubner                       void          *buffer,
942*4e1bc9a0SAchim Leubner                       bit32         phyID
943*4e1bc9a0SAchim Leubner                       )
944*4e1bc9a0SAchim Leubner {
945*4e1bc9a0SAchim Leubner   bit32 ret = AGSA_RC_SUCCESS;
946*4e1bc9a0SAchim Leubner 
947*4e1bc9a0SAchim Leubner   SA_DBG1(("saSetPhyProfile: ppc 0x%x length 0x%x phyID %d\n", ppc,length,phyID));
948*4e1bc9a0SAchim Leubner 
949*4e1bc9a0SAchim Leubner   switch(ppc)
950*4e1bc9a0SAchim Leubner   {
951*4e1bc9a0SAchim Leubner     case AGSA_SAS_PHY_ANALOG_SETTINGS_PAGE:
952*4e1bc9a0SAchim Leubner     {
953*4e1bc9a0SAchim Leubner       SA_DBG1(("saSetPhyProfile: AGSA_SAS_PHY_ANALOG_SETTINGS_PAGE\n" ));
954*4e1bc9a0SAchim Leubner       ret = mpiSetPhyProfileCmd( agRoot,agContext,ppc ,phyID,length,buffer);
955*4e1bc9a0SAchim Leubner       break;
956*4e1bc9a0SAchim Leubner     }
957*4e1bc9a0SAchim Leubner     case AGSA_PHY_SNW3_PAGE:
958*4e1bc9a0SAchim Leubner     {
959*4e1bc9a0SAchim Leubner       SA_DBG1(("saSetPhyProfile: AGSA_PHY_SNW3_PAGE\n" ));
960*4e1bc9a0SAchim Leubner       ret = mpiSetPhyProfileCmd( agRoot,agContext,ppc ,phyID,length,buffer);
961*4e1bc9a0SAchim Leubner       break;
962*4e1bc9a0SAchim Leubner     }
963*4e1bc9a0SAchim Leubner     case AGSA_PHY_RATE_CONTROL_PAGE:
964*4e1bc9a0SAchim Leubner     {
965*4e1bc9a0SAchim Leubner       SA_DBG1(("saSetPhyProfile: AGSA_PHY_RATE_CONTROL_PAGE\n" ));
966*4e1bc9a0SAchim Leubner       ret = mpiSetPhyProfileCmd( agRoot,agContext,ppc ,phyID,length,buffer);
967*4e1bc9a0SAchim Leubner       break;
968*4e1bc9a0SAchim Leubner     }
969*4e1bc9a0SAchim Leubner     case AGSA_SAS_PHY_MISC_PAGE:
970*4e1bc9a0SAchim Leubner     {
971*4e1bc9a0SAchim Leubner       SA_DBG1(("saSetPhyProfile: AGSA_SAS_PHY_MISC_PAGE\n"));
972*4e1bc9a0SAchim Leubner       ret = mpiSetPhyProfileCmd( agRoot,agContext,ppc ,phyID,length,buffer);
973*4e1bc9a0SAchim Leubner       break;
974*4e1bc9a0SAchim Leubner     }
975*4e1bc9a0SAchim Leubner 
976*4e1bc9a0SAchim Leubner     default:
977*4e1bc9a0SAchim Leubner       SA_DBG1(("saSetPhyProfile: Unknown operation 0x%X\n",ppc ));
978*4e1bc9a0SAchim Leubner       SA_ASSERT(agFALSE, "saSetPhyProfile Unknown operation " );
979*4e1bc9a0SAchim Leubner       ret = AGSA_RC_FAILURE;
980*4e1bc9a0SAchim Leubner       break;
981*4e1bc9a0SAchim Leubner   }
982*4e1bc9a0SAchim Leubner   return ret;
983*4e1bc9a0SAchim Leubner }
984*4e1bc9a0SAchim Leubner 
985*4e1bc9a0SAchim Leubner 
986*4e1bc9a0SAchim Leubner /******************************************************************************/
987*4e1bc9a0SAchim Leubner /*! \brief Initiate a HW Event Ack command
988*4e1bc9a0SAchim Leubner  *
989*4e1bc9a0SAchim Leubner  *  This function is called to initiate a HW Event Ack command to the SPC.
990*4e1bc9a0SAchim Leubner  *  The completion of this function is reported in ossaHwEventAckCB().
991*4e1bc9a0SAchim Leubner  *
992*4e1bc9a0SAchim Leubner  *  \param agRoot      handles for this instance of SAS/SATA hardware
993*4e1bc9a0SAchim Leubner  *  \param agContext   the context of this API
994*4e1bc9a0SAchim Leubner  *  \param queueNum    queue number
995*4e1bc9a0SAchim Leubner  *  \param eventSource point to the event source structure
996*4e1bc9a0SAchim Leubner  *  \param param0
997*4e1bc9a0SAchim Leubner  *  \param param1
998*4e1bc9a0SAchim Leubner  *
999*4e1bc9a0SAchim Leubner  *  \return
1000*4e1bc9a0SAchim Leubner  *          - none
1001*4e1bc9a0SAchim Leubner  */
1002*4e1bc9a0SAchim Leubner /*******************************************************************************/
saHwEventAck(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaEventSource_t * eventSource,bit32 param0,bit32 param1)1003*4e1bc9a0SAchim Leubner GLOBAL bit32 saHwEventAck(
1004*4e1bc9a0SAchim Leubner                       agsaRoot_t        *agRoot,
1005*4e1bc9a0SAchim Leubner                       agsaContext_t     *agContext,
1006*4e1bc9a0SAchim Leubner                       bit32             queueNum,
1007*4e1bc9a0SAchim Leubner                       agsaEventSource_t *eventSource,
1008*4e1bc9a0SAchim Leubner                       bit32             param0,
1009*4e1bc9a0SAchim Leubner                       bit32             param1
1010*4e1bc9a0SAchim Leubner                       )
1011*4e1bc9a0SAchim Leubner {
1012*4e1bc9a0SAchim Leubner   agsaLLRoot_t           *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
1013*4e1bc9a0SAchim Leubner   agsaIORequestDesc_t    *pRequest;
1014*4e1bc9a0SAchim Leubner   agsaPortContext_t      *agPortContext;
1015*4e1bc9a0SAchim Leubner   agsaPort_t             *pPort = agNULL;
1016*4e1bc9a0SAchim Leubner   agsaSASHwEventAckCmd_t payload;
1017*4e1bc9a0SAchim Leubner   bit32                  phyportid;
1018*4e1bc9a0SAchim Leubner   bit32                  ret = AGSA_RC_SUCCESS;
1019*4e1bc9a0SAchim Leubner   bit32                  using_reserved = agFALSE;
1020*4e1bc9a0SAchim Leubner 
1021*4e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"7e");
1022*4e1bc9a0SAchim Leubner 
1023*4e1bc9a0SAchim Leubner   /* sanity check */
1024*4e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != saRoot), "");
1025*4e1bc9a0SAchim Leubner   if(saRoot == agNULL)
1026*4e1bc9a0SAchim Leubner   {
1027*4e1bc9a0SAchim Leubner     SA_DBG1(("saHwEventAck: saRoot == agNULL\n"));
1028*4e1bc9a0SAchim Leubner     return(AGSA_RC_FAILURE);
1029*4e1bc9a0SAchim Leubner   }
1030*4e1bc9a0SAchim Leubner 
1031*4e1bc9a0SAchim Leubner   SA_DBG2(("saHwEventAck: agContext %p eventSource %p\n", agContext, eventSource));
1032*4e1bc9a0SAchim Leubner   SA_DBG1(("saHwEventAck: event 0x%x param0 0x%x param1 0x%x\n", eventSource->event, param0, param1));
1033*4e1bc9a0SAchim Leubner 
1034*4e1bc9a0SAchim Leubner   agPortContext = eventSource->agPortContext;
1035*4e1bc9a0SAchim Leubner 
1036*4e1bc9a0SAchim Leubner   /* Get request from free IORequests */
1037*4e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1038*4e1bc9a0SAchim Leubner   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
1039*4e1bc9a0SAchim Leubner 
1040*4e1bc9a0SAchim Leubner   /* If no LL Control request entry available */
1041*4e1bc9a0SAchim Leubner   if ( agNULL == pRequest )
1042*4e1bc9a0SAchim Leubner   {
1043*4e1bc9a0SAchim Leubner     pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); /**/
1044*4e1bc9a0SAchim Leubner     if(agNULL != pRequest)
1045*4e1bc9a0SAchim Leubner     {
1046*4e1bc9a0SAchim Leubner       using_reserved = agTRUE;
1047*4e1bc9a0SAchim Leubner       SA_DBG1(("saHwEventAck, using saRoot->freeReservedRequests\n"));
1048*4e1bc9a0SAchim Leubner     }
1049*4e1bc9a0SAchim Leubner     else
1050*4e1bc9a0SAchim Leubner     {
1051*4e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1052*4e1bc9a0SAchim Leubner       /* If no LL Control request entry available */
1053*4e1bc9a0SAchim Leubner       SA_DBG1(("saHwEventAck, No request from free list Not using saRoot->freeReservedRequests\n"));
1054*4e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "7e");
1055*4e1bc9a0SAchim Leubner       return AGSA_RC_BUSY;
1056*4e1bc9a0SAchim Leubner     }
1057*4e1bc9a0SAchim Leubner   }
1058*4e1bc9a0SAchim Leubner   if( using_reserved )
1059*4e1bc9a0SAchim Leubner   {
1060*4e1bc9a0SAchim Leubner     saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1061*4e1bc9a0SAchim Leubner   }
1062*4e1bc9a0SAchim Leubner   else
1063*4e1bc9a0SAchim Leubner   {
1064*4e1bc9a0SAchim Leubner     /* Remove the request from free list */
1065*4e1bc9a0SAchim Leubner     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1066*4e1bc9a0SAchim Leubner   }
1067*4e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1068*4e1bc9a0SAchim Leubner   SA_ASSERT((!pRequest->valid), "The pRequest is in use");
1069*4e1bc9a0SAchim Leubner 
1070*4e1bc9a0SAchim Leubner   SA_DBG2(("saHwEventAck: queueNum 0x%x HTag 0x%x\n",queueNum ,pRequest->HTag));
1071*4e1bc9a0SAchim Leubner 
1072*4e1bc9a0SAchim Leubner   saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1073*4e1bc9a0SAchim Leubner   saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1074*4e1bc9a0SAchim Leubner   saRoot->IOMap[pRequest->HTag].agContext = agContext;
1075*4e1bc9a0SAchim Leubner   pRequest->valid = agTRUE;
1076*4e1bc9a0SAchim Leubner 
1077*4e1bc9a0SAchim Leubner   /* build IOMB command and send to SPC */
1078*4e1bc9a0SAchim Leubner   /* set payload to zeros */
1079*4e1bc9a0SAchim Leubner   si_memset(&payload, 0, sizeof(agsaSASHwEventAckCmd_t));
1080*4e1bc9a0SAchim Leubner 
1081*4e1bc9a0SAchim Leubner   /* find port id */
1082*4e1bc9a0SAchim Leubner   if (agPortContext)
1083*4e1bc9a0SAchim Leubner   {
1084*4e1bc9a0SAchim Leubner     pPort = (agsaPort_t *) (agPortContext->sdkData);
1085*4e1bc9a0SAchim Leubner     if (pPort)
1086*4e1bc9a0SAchim Leubner     {
1087*4e1bc9a0SAchim Leubner       if(eventSource->event == OSSA_HW_EVENT_PHY_DOWN)
1088*4e1bc9a0SAchim Leubner       {
1089*4e1bc9a0SAchim Leubner         pPort->tobedeleted = agTRUE;
1090*4e1bc9a0SAchim Leubner       }
1091*4e1bc9a0SAchim Leubner       SA_DBG3(("saHwEventAck,pPort->portId %X\n",pPort->portId));
1092*4e1bc9a0SAchim Leubner 
1093*4e1bc9a0SAchim Leubner       if(smIS_SPC(agRoot))
1094*4e1bc9a0SAchim Leubner       {
1095*4e1bc9a0SAchim Leubner         /* fillup PORT_ID field */
1096*4e1bc9a0SAchim Leubner         phyportid = pPort->portId & 0xF;
1097*4e1bc9a0SAchim Leubner       }
1098*4e1bc9a0SAchim Leubner       else
1099*4e1bc9a0SAchim Leubner       {
1100*4e1bc9a0SAchim Leubner         /* fillup PORT_ID field */
1101*4e1bc9a0SAchim Leubner         phyportid = pPort->portId & 0xFF;
1102*4e1bc9a0SAchim Leubner 
1103*4e1bc9a0SAchim Leubner       }
1104*4e1bc9a0SAchim Leubner     }
1105*4e1bc9a0SAchim Leubner     else
1106*4e1bc9a0SAchim Leubner     {
1107*4e1bc9a0SAchim Leubner       /*  pPort is NULL - set PORT_ID to not intialized  */
1108*4e1bc9a0SAchim Leubner       if(smIS_SPC(agRoot))
1109*4e1bc9a0SAchim Leubner       {
1110*4e1bc9a0SAchim Leubner         phyportid = 0xF;
1111*4e1bc9a0SAchim Leubner       }
1112*4e1bc9a0SAchim Leubner       else
1113*4e1bc9a0SAchim Leubner       {
1114*4e1bc9a0SAchim Leubner         phyportid = 0xFF;
1115*4e1bc9a0SAchim Leubner       }
1116*4e1bc9a0SAchim Leubner     }
1117*4e1bc9a0SAchim Leubner   }
1118*4e1bc9a0SAchim Leubner   else
1119*4e1bc9a0SAchim Leubner   {
1120*4e1bc9a0SAchim Leubner     /* agPortContext is NULL - set PORT_ID to not intialized  */
1121*4e1bc9a0SAchim Leubner     if(smIS_SPC(agRoot))
1122*4e1bc9a0SAchim Leubner     {
1123*4e1bc9a0SAchim Leubner       phyportid = 0xF;
1124*4e1bc9a0SAchim Leubner     }
1125*4e1bc9a0SAchim Leubner     else
1126*4e1bc9a0SAchim Leubner     {
1127*4e1bc9a0SAchim Leubner       phyportid = 0xFF;
1128*4e1bc9a0SAchim Leubner     }
1129*4e1bc9a0SAchim Leubner   }
1130*4e1bc9a0SAchim Leubner 
1131*4e1bc9a0SAchim Leubner   pRequest->pPort = pPort;
1132*4e1bc9a0SAchim Leubner 
1133*4e1bc9a0SAchim Leubner   SA_DBG3(("saHwEventAck,eventSource->param 0x%X\n",eventSource->param));
1134*4e1bc9a0SAchim Leubner   SA_DBG3(("saHwEventAck,eventSource->event 0x%X\n",eventSource->event));
1135*4e1bc9a0SAchim Leubner 
1136*4e1bc9a0SAchim Leubner   if(smIS_SPC(agRoot))
1137*4e1bc9a0SAchim Leubner   {
1138*4e1bc9a0SAchim Leubner     /* fillup up PHY_ID */
1139*4e1bc9a0SAchim Leubner     phyportid |= ((eventSource->param & 0x0000000F) << 4);
1140*4e1bc9a0SAchim Leubner     /* fillup SEA field */
1141*4e1bc9a0SAchim Leubner     phyportid |= (eventSource->event & 0x0000FFFF) << 8;
1142*4e1bc9a0SAchim Leubner     SA_DBG3(("saHwEventAck: portId 0x%x phyId 0x%x SEA 0x%x\n", phyportid & 0xF,
1143*4e1bc9a0SAchim Leubner       eventSource->param & 0x0000000F, eventSource->event & 0x0000FFFF));
1144*4e1bc9a0SAchim Leubner   }
1145*4e1bc9a0SAchim Leubner   else
1146*4e1bc9a0SAchim Leubner   {
1147*4e1bc9a0SAchim Leubner     /* fillup up PHY_ID */
1148*4e1bc9a0SAchim Leubner     phyportid |= ((eventSource->param & 0x000000FF) << SHIFT24);
1149*4e1bc9a0SAchim Leubner     /* fillup SEA field */
1150*4e1bc9a0SAchim Leubner     phyportid |= (eventSource->event & 0x00FFFFFF) << SHIFT8;
1151*4e1bc9a0SAchim Leubner     SA_DBG3(("saHwEventAck: portId 0x%x phyId 0x%x SEA 0x%x\n", phyportid & 0xFF,
1152*4e1bc9a0SAchim Leubner       eventSource->param & 0x0000000F, eventSource->event & 0x0000FFFF));
1153*4e1bc9a0SAchim Leubner   }
1154*4e1bc9a0SAchim Leubner 
1155*4e1bc9a0SAchim Leubner   pRequest->HwAckType =  (bit16)phyportid;
1156*4e1bc9a0SAchim Leubner 
1157*4e1bc9a0SAchim Leubner   SA_DBG1(("saHwEventAck,phyportid 0x%X HwAckType 0x%X\n",phyportid,pRequest->HwAckType));
1158*4e1bc9a0SAchim Leubner   /* set tag */
1159*4e1bc9a0SAchim Leubner   OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASHwEventAckCmd_t, tag), pRequest->HTag);
1160*4e1bc9a0SAchim Leubner   OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASHwEventAckCmd_t, sEaPhyIdPortId), phyportid);
1161*4e1bc9a0SAchim Leubner   OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASHwEventAckCmd_t, Param0), param0);
1162*4e1bc9a0SAchim Leubner   OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASHwEventAckCmd_t, Param1), param1);
1163*4e1bc9a0SAchim Leubner 
1164*4e1bc9a0SAchim Leubner   /* build IOMB command and send to SPC */
1165*4e1bc9a0SAchim Leubner 
1166*4e1bc9a0SAchim Leubner   if(smIS_SPC(agRoot))
1167*4e1bc9a0SAchim Leubner   {
1168*4e1bc9a0SAchim Leubner     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SPC_SAS_HW_EVENT_ACK, IOMB_SIZE64, queueNum);
1169*4e1bc9a0SAchim Leubner   }
1170*4e1bc9a0SAchim Leubner   else
1171*4e1bc9a0SAchim Leubner   {
1172*4e1bc9a0SAchim Leubner     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SAS_HW_EVENT_ACK, IOMB_SIZE64, queueNum);
1173*4e1bc9a0SAchim Leubner   }
1174*4e1bc9a0SAchim Leubner 
1175*4e1bc9a0SAchim Leubner   if (AGSA_RC_SUCCESS != ret)
1176*4e1bc9a0SAchim Leubner   {
1177*4e1bc9a0SAchim Leubner     /* remove the request from IOMap */
1178*4e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1179*4e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1180*4e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1181*4e1bc9a0SAchim Leubner     pRequest->valid = agFALSE;
1182*4e1bc9a0SAchim Leubner 
1183*4e1bc9a0SAchim Leubner     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1184*4e1bc9a0SAchim Leubner     /* return the request to free pool */
1185*4e1bc9a0SAchim Leubner     if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1186*4e1bc9a0SAchim Leubner     {
1187*4e1bc9a0SAchim Leubner       SA_DBG1(("saHwEventAck: saving pRequest (%p) for later use\n", pRequest));
1188*4e1bc9a0SAchim Leubner       saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1189*4e1bc9a0SAchim Leubner     }
1190*4e1bc9a0SAchim Leubner     else
1191*4e1bc9a0SAchim Leubner     {
1192*4e1bc9a0SAchim Leubner       /* return the request to free pool */
1193*4e1bc9a0SAchim Leubner       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1194*4e1bc9a0SAchim Leubner     }
1195*4e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1196*4e1bc9a0SAchim Leubner     SA_DBG1(("saHwEventAck, sending IOMB failed\n" ));
1197*4e1bc9a0SAchim Leubner   }
1198*4e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "7e");
1199*4e1bc9a0SAchim Leubner 
1200*4e1bc9a0SAchim Leubner   return ret;
1201*4e1bc9a0SAchim Leubner }
1202*4e1bc9a0SAchim Leubner 
1203*4e1bc9a0SAchim Leubner 
saVhistCapture(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,bit32 Channel,bit32 NumBitLo,bit32 NumBitHi,bit32 PcieAddrLo,bit32 PcieAddrHi,bit32 ByteCount)1204*4e1bc9a0SAchim Leubner GLOBAL bit32 saVhistCapture(
1205*4e1bc9a0SAchim Leubner                           agsaRoot_t    *agRoot,
1206*4e1bc9a0SAchim Leubner                           agsaContext_t *agContext,
1207*4e1bc9a0SAchim Leubner                           bit32         queueNum,
1208*4e1bc9a0SAchim Leubner                           bit32         Channel,
1209*4e1bc9a0SAchim Leubner                           bit32         NumBitLo,
1210*4e1bc9a0SAchim Leubner                           bit32         NumBitHi,
1211*4e1bc9a0SAchim Leubner                           bit32         PcieAddrLo,
1212*4e1bc9a0SAchim Leubner                           bit32         PcieAddrHi,
1213*4e1bc9a0SAchim Leubner                           bit32         ByteCount )
1214*4e1bc9a0SAchim Leubner {
1215*4e1bc9a0SAchim Leubner 
1216*4e1bc9a0SAchim Leubner   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
1217*4e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequest;
1218*4e1bc9a0SAchim Leubner   bit32               ret = AGSA_RC_SUCCESS;
1219*4e1bc9a0SAchim Leubner   bit32               using_reserved = agFALSE;
1220*4e1bc9a0SAchim Leubner 
1221*4e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"3N");
1222*4e1bc9a0SAchim Leubner 
1223*4e1bc9a0SAchim Leubner   /* sanity check */
1224*4e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
1225*4e1bc9a0SAchim Leubner 
1226*4e1bc9a0SAchim Leubner   SA_DBG1(("saVhistCapture:Channel 0x%08X 0x%08X%08X 0x%08X%08X  count 0x%X\n",Channel, NumBitHi, NumBitLo ,PcieAddrHi,PcieAddrLo,ByteCount));
1227*4e1bc9a0SAchim Leubner 
1228*4e1bc9a0SAchim Leubner   {
1229*4e1bc9a0SAchim Leubner     /* Get request from free IORequests */
1230*4e1bc9a0SAchim Leubner     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1231*4e1bc9a0SAchim Leubner     pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /* */
1232*4e1bc9a0SAchim Leubner     /* If no LL Control request entry available */
1233*4e1bc9a0SAchim Leubner     if ( agNULL == pRequest )
1234*4e1bc9a0SAchim Leubner     {
1235*4e1bc9a0SAchim Leubner       pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
1236*4e1bc9a0SAchim Leubner       /* If no LL Control request entry available */
1237*4e1bc9a0SAchim Leubner       if(agNULL != pRequest)
1238*4e1bc9a0SAchim Leubner       {
1239*4e1bc9a0SAchim Leubner         using_reserved = agTRUE;
1240*4e1bc9a0SAchim Leubner         SA_DBG1((", using saRoot->freeReservedRequests\n"));
1241*4e1bc9a0SAchim Leubner       }
1242*4e1bc9a0SAchim Leubner       else
1243*4e1bc9a0SAchim Leubner       {
1244*4e1bc9a0SAchim Leubner         ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1245*4e1bc9a0SAchim Leubner         SA_DBG1(("saVhistCapture: No request from free list Not using saRoot->freeReservedRequests\n"));
1246*4e1bc9a0SAchim Leubner         smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "3N");
1247*4e1bc9a0SAchim Leubner         return AGSA_RC_BUSY;
1248*4e1bc9a0SAchim Leubner       }
1249*4e1bc9a0SAchim Leubner     }
1250*4e1bc9a0SAchim Leubner     SA_ASSERT((!pRequest->valid), "The pRequest is in use");
1251*4e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
1252*4e1bc9a0SAchim Leubner     /* If LL Control request entry avaliable */
1253*4e1bc9a0SAchim Leubner     if( using_reserved )
1254*4e1bc9a0SAchim Leubner     {
1255*4e1bc9a0SAchim Leubner       saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1256*4e1bc9a0SAchim Leubner     }
1257*4e1bc9a0SAchim Leubner     else
1258*4e1bc9a0SAchim Leubner     {
1259*4e1bc9a0SAchim Leubner       /* Remove the request from free list */
1260*4e1bc9a0SAchim Leubner       saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1261*4e1bc9a0SAchim Leubner     }
1262*4e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1263*4e1bc9a0SAchim Leubner 
1264*4e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1265*4e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1266*4e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].agContext = agContext;
1267*4e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
1268*4e1bc9a0SAchim Leubner 
1269*4e1bc9a0SAchim Leubner     /* Build the VhisCapture IOMB command and send to SPCv */
1270*4e1bc9a0SAchim Leubner 
1271*4e1bc9a0SAchim Leubner     ret = mpiVHistCapCmd(agRoot,agContext, queueNum, Channel, NumBitLo, NumBitHi ,PcieAddrLo, PcieAddrHi, ByteCount);
1272*4e1bc9a0SAchim Leubner     if (AGSA_RC_SUCCESS != ret)
1273*4e1bc9a0SAchim Leubner     {
1274*4e1bc9a0SAchim Leubner       /* remove the request from IOMap */
1275*4e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1276*4e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1277*4e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1278*4e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
1279*4e1bc9a0SAchim Leubner 
1280*4e1bc9a0SAchim Leubner       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1281*4e1bc9a0SAchim Leubner       /* return the request to free pool */
1282*4e1bc9a0SAchim Leubner       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1283*4e1bc9a0SAchim Leubner       {
1284*4e1bc9a0SAchim Leubner         SA_DBG1(("saPhyStart: saving pRequest (%p) for later use\n", pRequest));
1285*4e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1286*4e1bc9a0SAchim Leubner       }
1287*4e1bc9a0SAchim Leubner       else
1288*4e1bc9a0SAchim Leubner       {
1289*4e1bc9a0SAchim Leubner         /* return the request to free pool */
1290*4e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1291*4e1bc9a0SAchim Leubner       }
1292*4e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1293*4e1bc9a0SAchim Leubner       SA_DBG1(("saVhistCapture: sending IOMB failed\n" ));
1294*4e1bc9a0SAchim Leubner     }
1295*4e1bc9a0SAchim Leubner   }
1296*4e1bc9a0SAchim Leubner 
1297*4e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "3N");
1298*4e1bc9a0SAchim Leubner 
1299*4e1bc9a0SAchim Leubner   return ret;
1300*4e1bc9a0SAchim Leubner }
1301*4e1bc9a0SAchim Leubner 
1302