xref: /freebsd/sys/dev/pms/RefTisa/sallsdk/spc/saport.c (revision 8ddb146abcdf061be9f2c0db7e391697dafad85c)
1 /*******************************************************************************
2 *Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
3 *
4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided
5 *that the following conditions are met:
6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7 *following disclaimer.
8 *2. Redistributions in binary form must reproduce the above copyright notice,
9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided
10 *with the distribution.
11 *
12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20 
21 ********************************************************************************/
22 /*******************************************************************************/
23 /*! \file saport.c
24  *  \brief The file implements the functions to handle port
25  *
26  */
27 /******************************************************************************/
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30 #include <dev/pms/config.h>
31 
32 #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
33 #ifdef SA_ENABLE_TRACE_FUNCTIONS
34 #ifdef siTraceFileID
35 #undef siTraceFileID
36 #endif
37 #define siTraceFileID 'L'
38 #endif
39 
40 
41 extern bit32 gFPGA_TEST;
42 /******************************************************************************/
43 /*! \brief Add a SAS device to the discovery list of the port
44  *
45  *  Add a SAS device from the discovery list of the port
46  *
47  *  \param agRoot handles for this instance of SAS/SATA LLL
48  *  \param pPort
49  *  \param sasIdentify
50  *  \param sasInitiator
51  *  \param smpTimeout
52  *  \param itNexusTimeout
53  *  \param firstBurstSize
54  *  \param dTypeSRate -- device type and link rate
55  *  \param flag
56  *
57  *  \return -the device descriptor-
58  */
59 /*******************************************************************************/
60 GLOBAL agsaDeviceDesc_t *siPortSASDeviceAdd(
61   agsaRoot_t        *agRoot,
62   agsaPort_t        *pPort,
63   agsaSASIdentify_t sasIdentify,
64   bit32             sasInitiator,
65   bit32             smpTimeout,
66   bit32             itNexusTimeout,
67   bit32             firstBurstSize,
68   bit8              dTypeSRate,
69   bit32             flag
70   )
71 {
72   agsaLLRoot_t          *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
73   agsaDeviceDesc_t      *pDevice;
74 
75   SA_DBG3(("siPortSASDeviceAdd: start\n"));
76 
77   smTraceFuncEnter(hpDBG_VERY_LOUD, "23");
78 
79   /* sanity check */
80   SA_ASSERT((agNULL != agRoot), "");
81   SA_ASSERT((agNULL != pPort), "");
82 
83   /* Acquire Device Lock */
84   ossaSingleThreadedEnter(agRoot, LL_DEVICE_LOCK);
85 
86   /* Try to Allocate from device list */
87   pDevice = (agsaDeviceDesc_t *) saLlistGetHead(&(saRoot->freeDevicesList));
88 
89   /* If device handle available */
90   if ( agNULL != pDevice)
91   {
92     int i;
93 
94     /* Remove from free device list */
95     saLlistRemove(&(saRoot->freeDevicesList), &(pDevice->linkNode));
96 
97     /* Initialize device descriptor */
98     if ( agTRUE == sasInitiator )
99     {
100       pDevice->initiatorDevHandle.sdkData = pDevice;
101       pDevice->targetDevHandle.sdkData = agNULL;
102     }
103     else
104     {
105       pDevice->initiatorDevHandle.sdkData = agNULL;
106       pDevice->targetDevHandle.sdkData = pDevice;
107     }
108 
109     pDevice->initiatorDevHandle.osData = agNULL;
110     pDevice->targetDevHandle.osData = agNULL;
111 
112     /* setup device type */
113     pDevice->deviceType = (bit8)((dTypeSRate & 0x30) >> SHIFT4);
114     SA_DBG3(("siPortSASDeviceAdd: Device Type 0x%x, Port Context %p\n", pDevice->deviceType, pPort));
115     pDevice->pPort = pPort;
116     saLlistInitialize(&(pDevice->pendingIORequests));
117 
118     /* setup sasDeviceInfo */
119     pDevice->devInfo.sasDeviceInfo.commonDevInfo.smpTimeout = (bit16)smpTimeout;
120     pDevice->devInfo.sasDeviceInfo.commonDevInfo.it_NexusTimeout = (bit16)itNexusTimeout;
121     pDevice->devInfo.sasDeviceInfo.commonDevInfo.firstBurstSize = (bit16)firstBurstSize;
122     pDevice->devInfo.sasDeviceInfo.commonDevInfo.devType_S_Rate = dTypeSRate;
123     pDevice->devInfo.sasDeviceInfo.commonDevInfo.flag = flag;
124     for (i = 0; i < 4; i++)
125     {
126       pDevice->devInfo.sasDeviceInfo.commonDevInfo.sasAddressHi[i] = sasIdentify.sasAddressHi[i];
127       pDevice->devInfo.sasDeviceInfo.commonDevInfo.sasAddressLo[i] = sasIdentify.sasAddressLo[i];
128     }
129     pDevice->devInfo.sasDeviceInfo.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp;
130     pDevice->devInfo.sasDeviceInfo.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp;
131     pDevice->devInfo.sasDeviceInfo.phyIdentifier = sasIdentify.phyIdentifier;
132 
133     /* Add to discoverd device for the port */
134     saLlistAdd(&(pPort->listSASATADevices), &(pDevice->linkNode));
135 
136     /* Release Device Lock */
137     ossaSingleThreadedLeave(agRoot, LL_DEVICE_LOCK);
138 
139     /* Log Messages */
140     SA_DBG3(("siPortSASDeviceAdd: sasIdentify addrHI 0x%x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify)));
141     SA_DBG3(("siPortSASDeviceAdd: sasIdentify addrLO 0x%x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify)));
142 
143   }
144   else
145   {
146     /* Release Device Lock */
147     ossaSingleThreadedLeave(agRoot, LL_DEVICE_LOCK);
148     SA_ASSERT((agNULL != pDevice), "");
149     SA_DBG1(("siPortSASDeviceAdd: device allocation failed\n"));
150   }
151   SA_DBG3(("siPortSASDeviceAdd: end\n"));
152 
153   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "23");
154   return pDevice;
155 }
156 
157 /******************************************************************************/
158 /*! \brief The function to remove a device descriptor
159  *
160  *  The function to remove a device descriptor
161  *
162  *  \param agRoot handles for this instance of SAS/SATA hardware
163  *  \param pPort  The pointer to the port
164  *  \param pDevice The pointer to the device
165  *
166  *  \return -void-
167  */
168 /*******************************************************************************/
169 GLOBAL void siPortDeviceRemove(
170   agsaRoot_t        *agRoot,
171   agsaPort_t        *pPort,
172   agsaDeviceDesc_t  *pDevice,
173   bit32             unmap
174   )
175 {
176   agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
177   bit32        deviceIdx;
178 
179   smTraceFuncEnter(hpDBG_VERY_LOUD, "24");
180 
181   /* sanity check */
182   SA_ASSERT((agNULL != agRoot), "");
183   SA_ASSERT((agNULL != pPort), "");
184   SA_ASSERT((agNULL != pDevice), "");
185   SA_ASSERT((SAS_SATA_UNKNOWN_DEVICE != pDevice->deviceType), "");
186 
187   /* remove the device from discovered list */
188   SA_DBG3(("siPortDeviceRemove(SAS/SATA): DeviceIndex %d Device Context %p\n", pDevice->DeviceMapIndex, pDevice));
189 
190   ossaSingleThreadedEnter(agRoot, LL_DEVICE_LOCK);
191   saLlistRemove(&(pPort->listSASATADevices), &(pDevice->linkNode));
192 
193   /* Reset the device data structure */
194   pDevice->pPort = agNULL;
195   pDevice->initiatorDevHandle.osData = agNULL;
196   pDevice->initiatorDevHandle.sdkData = agNULL;
197   pDevice->targetDevHandle.osData = agNULL;
198   pDevice->targetDevHandle.sdkData = agNULL;
199 
200   saLlistAdd(&(saRoot->freeDevicesList), &(pDevice->linkNode));
201 
202   if(unmap)
203   {
204     /* remove the DeviceMap and MapIndex */
205     deviceIdx = pDevice->DeviceMapIndex & DEVICE_ID_BITS;
206     OS_ASSERT(deviceIdx < MAX_IO_DEVICE_ENTRIES, "deviceIdx MAX_IO_DEVICE_ENTRIES");
207 
208     saRoot->DeviceMap[deviceIdx].DeviceIdFromFW = 0;
209     saRoot->DeviceMap[deviceIdx].DeviceHandle = agNULL;
210     pDevice->DeviceMapIndex = 0;
211   }
212   ossaSingleThreadedLeave(agRoot, LL_DEVICE_LOCK);
213 
214   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "24");
215 
216   return;
217 }
218 
219 /******************************************************************************/
220 /*! \brief Add a SATA device to the discovery list of the port
221  *
222  *  Add a SATA device from the discovery list of the port
223  *
224  *  \param agRoot handles for this instance of SAS/SATA hardware
225  *  \param pPort
226  *  \param pSTPBridge
227  *  \param pSignature
228  *  \param pm
229  *  \param pmField
230  *  \param smpReqTimeout
231  *  \param itNexusTimeout
232  *  \param firstBurstSize
233  *  \param dTypeSRate
234  *
235  *  \return -the device descriptor-
236  */
237 /*******************************************************************************/
238 GLOBAL agsaDeviceDesc_t *siPortSATADeviceAdd(
239   agsaRoot_t              *agRoot,
240   agsaPort_t              *pPort,
241   agsaDeviceDesc_t        *pSTPBridge,
242   bit8                    *pSignature,
243   bit8                    pm,
244   bit8                    pmField,
245   bit32                   smpReqTimeout,
246   bit32                   itNexusTimeout,
247   bit32                   firstBurstSize,
248   bit8                    dTypeSRate,
249   bit32                   flag
250   )
251 {
252   agsaLLRoot_t          *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
253   agsaDeviceDesc_t      *pDevice;
254 
255   smTraceFuncEnter(hpDBG_VERY_LOUD, "25");
256 
257   /* sanity check */
258   SA_ASSERT((agNULL != agRoot), "");
259   SA_ASSERT((agNULL != pPort), "");
260 
261   /* Acquire Device Lock */
262   ossaSingleThreadedEnter(agRoot, LL_DEVICE_LOCK);
263 
264   /* Try to Allocate from device list */
265   pDevice = (agsaDeviceDesc_t *) saLlistGetHead(&(saRoot->freeDevicesList));
266 
267   /* If device handle available */
268   if ( agNULL != pDevice)
269   {
270     int i;
271 
272     /* Remove from free device list */
273     saLlistRemove(&(saRoot->freeDevicesList), &(pDevice->linkNode));
274 
275     /* Initialize the device descriptor */
276     pDevice->initiatorDevHandle.sdkData = agNULL;
277     pDevice->targetDevHandle.sdkData = pDevice;
278     pDevice->initiatorDevHandle.osData = agNULL;
279     pDevice->targetDevHandle.osData = agNULL;
280 
281     pDevice->deviceType = (bit8)((dTypeSRate & 0x30) >> SHIFT4);
282     SA_DBG3(("siPortSATADeviceAdd: DeviceType 0x%x Port Context %p\n", pDevice->deviceType, pPort));
283 
284     /* setup device common infomation */
285     pDevice->devInfo.sataDeviceInfo.commonDevInfo.smpTimeout = (bit16)smpReqTimeout;
286     pDevice->devInfo.sataDeviceInfo.commonDevInfo.it_NexusTimeout = (bit16)itNexusTimeout;
287     pDevice->devInfo.sataDeviceInfo.commonDevInfo.firstBurstSize = (bit16)firstBurstSize;
288     pDevice->devInfo.sataDeviceInfo.commonDevInfo.devType_S_Rate = dTypeSRate;
289     pDevice->devInfo.sataDeviceInfo.commonDevInfo.flag = flag;
290     for (i = 0; i < 4; i++)
291     {
292       pDevice->devInfo.sataDeviceInfo.commonDevInfo.sasAddressHi[i] = 0;
293       pDevice->devInfo.sataDeviceInfo.commonDevInfo.sasAddressLo[i] = 0;
294     }
295     /* setup SATA device information */
296     pDevice->devInfo.sataDeviceInfo.connection = pm;
297     pDevice->devInfo.sataDeviceInfo.portMultiplierField = pmField;
298     pDevice->devInfo.sataDeviceInfo.stpPhyIdentifier = 0;
299     pDevice->pPort = pPort;
300 
301     /* Add to discoverd device for the port */
302     saLlistAdd(&(pPort->listSASATADevices), &(pDevice->linkNode));
303 
304     /* Release Device Lock */
305     ossaSingleThreadedLeave(agRoot, LL_DEVICE_LOCK);
306   }
307   else
308   {
309     /* Release Device Lock */
310     ossaSingleThreadedLeave(agRoot, LL_DEVICE_LOCK);
311     SA_ASSERT((agNULL != pDevice), "");
312     SA_DBG1(("siPortSATADeviceAdd: device allocation failed\n"));
313   }
314   SA_DBG3(("siPortSATADeviceAdd: end\n"));
315 
316   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "25");
317   return pDevice;
318 }
319 
320 /******************************************************************************/
321 /*! \brief Invalid a port
322  *
323  *  Invalid a port
324  *
325  *  \param agRoot handles for this instance of SAS/SATA hardware
326  *  \param pPort
327  *
328  *  \return -void-
329  */
330 /*******************************************************************************/
331 GLOBAL void siPortInvalid(
332   agsaRoot_t  *agRoot,
333   agsaPort_t  *pPort
334   )
335 {
336   agsaLLRoot_t    *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
337   smTraceFuncEnter(hpDBG_VERY_LOUD, "26");
338 
339   /* sanity check */
340   SA_ASSERT((agNULL != agRoot), "");
341   SA_ASSERT((agNULL != pPort), "");
342 
343   /* set port's status to invalidating */
344   pPort->status |= PORT_INVALIDATING;
345 
346   /* Remove from validPort and add the port back to the free port link list */
347   ossaSingleThreadedEnter(agRoot, LL_PORT_LOCK);
348   saLlistRemove(&(saRoot->validPorts), &(pPort->linkNode));
349   saLlistAdd(&(saRoot->freePorts), &(pPort->linkNode));
350   pPort->tobedeleted = agFALSE;
351   ossaSingleThreadedLeave(agRoot, LL_PORT_LOCK);
352 
353   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "26");
354 
355   /* return */
356 }
357 
358 /******************************************************************************/
359 /*! \brief The function to remove a device descriptor
360  *
361  *  The function to remove a device descriptor
362  *
363  *  \param agRoot handles for this instance of SAS/SATA hardware
364  *  \param pPort  The pointer to the port
365  *  \param pDevice The pointer to the device
366  *
367  *  \return -void-
368  */
369 /*******************************************************************************/
370 GLOBAL void siPortDeviceListRemove(
371   agsaRoot_t        *agRoot,
372   agsaPort_t        *pPort,
373   agsaDeviceDesc_t  *pDevice
374   )
375 {
376   agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
377 
378   smTraceFuncEnter(hpDBG_VERY_LOUD, "27");
379 
380   /* sanity check */
381   SA_ASSERT((agNULL != agRoot), "");
382   SA_ASSERT((agNULL != pPort), "");
383   SA_ASSERT((agNULL != pDevice), "");
384   SA_ASSERT((SAS_SATA_UNKNOWN_DEVICE != pDevice->deviceType), "");
385 
386   /* remove the device from discovered list */
387   SA_DBG3(("siPortDeviceListRemove(SAS/SATA): PortID %d Device Context %p\n", pPort->portId, pDevice));
388 
389   ossaSingleThreadedEnter(agRoot, LL_DEVICE_LOCK);
390   saLlistRemove(&(pPort->listSASATADevices), &(pDevice->linkNode));
391 
392   /* Reset the device data structure */
393   pDevice->pPort = agNULL;
394   pDevice->initiatorDevHandle.osData = agNULL;
395   pDevice->initiatorDevHandle.sdkData = agNULL;
396   pDevice->targetDevHandle.osData = agNULL;
397   pDevice->targetDevHandle.sdkData = agNULL;
398 
399   saLlistAdd(&(saRoot->freeDevicesList), &(pDevice->linkNode));
400   ossaSingleThreadedLeave(agRoot, LL_DEVICE_LOCK);
401 
402   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "27");
403   return;
404 }
405 
406 /******************************************************************************/
407 /*! \brief Initiate a Port COntrol IOMB command
408  *
409  *  This function is called to initiate a Port COntrol command to the SPC.
410  *  The completion of this function is reported in ossaPortControlCB().
411  *
412  *  \param agRoot        handles for this instance of SAS/SATA hardware
413  *  \param agContext     the context of this API
414  *  \param queueNum      queue number
415  *  \param agPortContext point to the event source structure
416  *  \param param0        parameter 0
417  *  \param param1        parameter 1
418  *
419  *  \return - successful or failure
420  */
421 /*******************************************************************************/
422 GLOBAL bit32 saPortControl(
423   agsaRoot_t            *agRoot,
424   agsaContext_t         *agContext,
425   bit32                 queueNum,
426   agsaPortContext_t     *agPortContext,
427   bit32                 portOperation,
428   bit32                 param0,
429   bit32                 param1
430   )
431 {
432   agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
433   agsaIORequestDesc_t  *pRequest;
434   agsaPort_t           *pPort;
435   bit32                ret = AGSA_RC_SUCCESS;
436   bit32                opportId;
437   agsaPortControlCmd_t payload;
438   bit32               using_reserved = agFALSE;
439 
440 
441   /* sanity check */
442   SA_ASSERT((agNULL !=saRoot ), "");
443   SA_ASSERT((agNULL != agPortContext), "");
444   if(saRoot == agNULL)
445   {
446     SA_DBG1(("saPortControl: saRoot == agNULL\n"));
447     return(AGSA_RC_FAILURE);
448   }
449   smTraceFuncEnter(hpDBG_VERY_LOUD, "28");
450 
451   SA_DBG1(("saPortControl: portContext %p portOperation 0x%x param0 0x%x param1 0x%x\n", agPortContext, portOperation, param0, param1));
452 
453   /* Get request from free IORequests */
454   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
455   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
456   /* If no LL Control request entry available */
457   if ( agNULL == pRequest )
458   {
459     pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
460     /* If no LL Control request entry available */
461     if(agNULL != pRequest)
462     {
463       using_reserved = agTRUE;
464       SA_DBG2(("saPortControl, using saRoot->freeReservedRequests\n"));
465     }
466     else
467     {
468       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
469       SA_DBG1(("saPortControl, No request from free list Not using saRoot->freeReservedRequests\n"));
470       smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "28");
471       return AGSA_RC_BUSY;
472     }
473   }
474 
475   /* If LL Control request entry avaliable */
476   if( using_reserved )
477   {
478     saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
479   }
480   else
481   {
482     /* Remove the request from free list */
483     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
484   }
485   SA_ASSERT((!pRequest->valid), "The pRequest is in use");
486   saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
487   saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
488   saRoot->IOMap[pRequest->HTag].agContext = agContext;
489   pRequest->valid = agTRUE;
490   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
491 
492   /* build IOMB command and send to SPC */
493   /* set payload to zeros */
494   si_memset(&payload, 0, sizeof(agsaPortControlCmd_t));
495 
496   /* find port id */
497   pPort = (agsaPort_t *) (agPortContext->sdkData);
498   opportId = (pPort->portId & PORTID_MASK) | (portOperation << SHIFT8);
499   /* set tag */
500   OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPortControlCmd_t, tag), pRequest->HTag);
501   OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPortControlCmd_t, portOPPortId), opportId);
502   OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPortControlCmd_t, Param0), param0);
503   OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPortControlCmd_t, Param1), param1);
504 
505   SA_DBG1(("saPortControl: portId 0x%x portOperation 0x%x\n", (pPort->portId & PORTID_MASK),portOperation));
506 
507   /* build IOMB command and send to SPC */
508   ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_PORT_CONTROL, IOMB_SIZE64, queueNum);
509   if (AGSA_RC_SUCCESS != ret)
510   {
511     /* remove the request from IOMap */
512     saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
513     saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
514     saRoot->IOMap[pRequest->HTag].agContext = agNULL;
515     pRequest->valid = agFALSE;
516     /* return the request to free pool */
517     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
518     if (saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
519     {
520       SA_DBG1(("saPortControl: saving pRequest (%p) for later use\n", pRequest));
521       saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
522     }
523     else
524     {
525       /* return the request to free pool */
526       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
527     }
528     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
529     SA_DBG1(("saPortControl, sending IOMB failed\n" ));
530   }
531   else
532   {
533     if (portOperation == AGSA_PORT_HARD_RESET)
534     {
535       SA_DBG1(("saPortControl,0x%x AGSA_PORT_HARD_RESET 0x%x param0 0x%x\n",
536                 pPort->portId, param0, param0 & AUTO_HARD_RESET_DEREG_FLAG));
537       saRoot->autoDeregDeviceflag[pPort->portId & PORTID_MASK] = param0 & AUTO_HARD_RESET_DEREG_FLAG;
538     }
539     else if (portOperation == AGSA_PORT_CLEAN_UP)
540     {
541       SA_DBG1(("saPortControl, 0x%x AGSA_PORT_CLEAN_UP param0 0x%x %d\n", pPort->portId, param0,((param0 & AUTO_FW_CLEANUP_DEREG_FLAG) ? 0:1)));
542       saRoot->autoDeregDeviceflag[pPort->portId & PORTID_MASK] = ((param0 & AUTO_FW_CLEANUP_DEREG_FLAG) ? 0:1);
543     }
544     SA_DBG1(("saPortControl, sending IOMB SUCCESS, portId 0x%x autoDeregDeviceflag=0x%x\n", pPort->portId,saRoot->autoDeregDeviceflag[pPort->portId & PORTID_MASK]));
545   }
546 
547   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "28");
548 
549   return ret;
550 }
551 
552 /**
553  * saEncryptGetMode()
554  *
555  *     Returns the status, working state and sector size
556  *     registers of the encryption engine
557  *
558  * @param saRoot
559  * @param encryptInfo
560  *
561  * @return
562  */
563 GLOBAL bit32 saEncryptGetMode(agsaRoot_t        *agRoot,
564                               agsaContext_t     *agContext,
565                               agsaEncryptInfo_t *encryptInfo)
566 {
567     bit32 ret = AGSA_RC_NOT_SUPPORTED;
568 
569     smTraceFuncEnter(hpDBG_VERY_LOUD,"29");
570     agContext = agContext; /* Lint*/
571     SA_DBG4(("saEncryptGetMode, encryptInfo %p\n",encryptInfo ));
572     if(smIS_SPCV(agRoot))
573     {
574       bit32 ScratchPad1 =0;
575       bit32 ScratchPad3 =0;
576 
577       encryptInfo->status = 0;
578       encryptInfo->encryptionCipherMode = 0;
579       encryptInfo->encryptionSecurityMode = 0;
580       encryptInfo->flag = 0;
581 
582       ScratchPad1 = ossaHwRegRead(agRoot,V_Scratchpad_1_Register);
583       ScratchPad3 = ossaHwRegRead(agRoot,V_Scratchpad_3_Register);
584       if((ScratchPad1 & SCRATCH_PAD1_V_RAAE_MASK) ==  SCRATCH_PAD1_V_RAAE_MASK)
585       {
586         if((ScratchPad3 & SCRATCH_PAD3_V_ENC_MASK) == SCRATCH_PAD3_V_ENC_READY ) /* 3 */
587         {
588           if( ScratchPad3 & SCRATCH_PAD3_V_XTS_ENABLED)
589           {
590             encryptInfo->encryptionCipherMode = agsaEncryptCipherModeXTS;
591           }
592           if( (ScratchPad3 & SCRATCH_PAD3_V_SM_MASK ) == SCRATCH_PAD3_V_SMF_ENABLED )
593           {
594             encryptInfo->encryptionSecurityMode = agsaEncryptSMF;
595           }
596           if( (ScratchPad3 & SCRATCH_PAD3_V_SM_MASK ) == SCRATCH_PAD3_V_SMA_ENABLED)
597           {
598             encryptInfo->encryptionSecurityMode = agsaEncryptSMA;
599           }
600           if( (ScratchPad3 & SCRATCH_PAD3_V_SM_MASK ) == SCRATCH_PAD3_V_SMB_ENABLED )
601           {
602             encryptInfo->encryptionSecurityMode = agsaEncryptSMB;
603           }
604           encryptInfo->status = AGSA_RC_SUCCESS;
605           ret = AGSA_RC_SUCCESS;
606         }
607         else if((ScratchPad3 & SCRATCH_PAD3_V_ENC_READY) == SCRATCH_PAD3_V_ENC_DISABLED) /* 0 */
608         {
609           SA_DBG1(("saEncryptGetMode, SCRATCH_PAD3_V_ENC_DISABLED 1 0x%08X 3 0x%08X\n",ScratchPad1,ScratchPad3 ));
610           encryptInfo->status = 0xFFFF;
611           encryptInfo->encryptionCipherMode = 0;
612           encryptInfo->encryptionSecurityMode = 0;
613           ret = AGSA_RC_NOT_SUPPORTED;
614         }
615         else if((ScratchPad3 & SCRATCH_PAD3_V_ENC_MASK ) == SCRATCH_PAD3_V_ENC_DIS_ERR) /* 1 */
616         {
617           SA_DBG1(("saEncryptGetMode, SCRATCH_PAD3_V_ENC_DIS_ERR 1 0x%08X 3 0x%08X\n",ScratchPad1,ScratchPad3 ));
618           encryptInfo->status = (ScratchPad3 & SCRATCH_PAD3_V_ERR_CODE ) >> SHIFT16;
619           if( ScratchPad3 & SCRATCH_PAD3_V_XTS_ENABLED)
620           {
621             encryptInfo->encryptionCipherMode = agsaEncryptCipherModeXTS;
622           }
623           if( (ScratchPad3 & SCRATCH_PAD3_V_SM_MASK ) == SCRATCH_PAD3_V_SMF_ENABLED )
624           {
625             encryptInfo->encryptionSecurityMode = agsaEncryptSMF;
626           }
627           if( (ScratchPad3 & SCRATCH_PAD3_V_SM_MASK ) == SCRATCH_PAD3_V_SMA_ENABLED)
628           {
629             encryptInfo->encryptionSecurityMode = agsaEncryptSMA;
630           }
631           if( (ScratchPad3 & SCRATCH_PAD3_V_SM_MASK ) == SCRATCH_PAD3_V_SMB_ENABLED )
632           {
633             encryptInfo->encryptionSecurityMode = agsaEncryptSMB;
634           }
635           ret = AGSA_RC_FAILURE;
636         }
637         else if((ScratchPad3 & SCRATCH_PAD3_V_ENC_MASK ) == SCRATCH_PAD3_V_ENC_ENA_ERR) /* 2 */
638         {
639 
640           SA_DBG1(("saEncryptGetMode, SCRATCH_PAD3_V_ENC_ENA_ERR 1 0x%08X 3 0x%08X\n",ScratchPad1,ScratchPad3 ));
641           encryptInfo->status = (ScratchPad3 & SCRATCH_PAD3_V_ERR_CODE ) >> SHIFT16;
642           if( ScratchPad3 & SCRATCH_PAD3_V_XTS_ENABLED)
643           {
644             encryptInfo->encryptionCipherMode = agsaEncryptCipherModeXTS;
645             SA_DBG1(("saEncryptGetMode, SCRATCH_PAD3_V_ENC_ENA_ERR 2 0x%08X 3 0x%08X\n",ScratchPad1,ScratchPad3 ));
646           }
647           if( (ScratchPad3 & SCRATCH_PAD3_V_SM_MASK ) == SCRATCH_PAD3_V_SMF_ENABLED )
648           {
649             SA_DBG1(("saEncryptGetMode, SCRATCH_PAD3_V_ENC_ENA_ERR 3 0x%08X 3 0x%08X\n",ScratchPad1,ScratchPad3 ));
650             encryptInfo->encryptionSecurityMode = agsaEncryptSMF;
651           }
652           if( (ScratchPad3 & SCRATCH_PAD3_V_SM_MASK ) == SCRATCH_PAD3_V_SMA_ENABLED)
653           {
654             encryptInfo->encryptionSecurityMode = agsaEncryptSMA;
655           }
656           if( (ScratchPad3 & SCRATCH_PAD3_V_SM_MASK ) == SCRATCH_PAD3_V_SMB_ENABLED )
657           {
658             encryptInfo->encryptionSecurityMode = agsaEncryptSMB;
659           }
660 
661           SA_DBG1(("saEncryptGetMode,encryptInfo status 0x%08X CipherMode 0x%X SecurityMode 0x%X\n" ,
662               encryptInfo->status,
663               encryptInfo->encryptionCipherMode,
664               encryptInfo->encryptionSecurityMode));
665 
666 #ifdef CCFLAGS_SPCV_FPGA_REVB /*The FPGA platform hasn't EEPROM*/
667           ret = AGSA_RC_SUCCESS;
668 #else
669           ret = AGSA_RC_FAILURE;
670 #endif
671         }
672       }
673       else  if((ScratchPad1 & SCRATCH_PAD1_V_RAAE_MASK) ==  SCRATCH_PAD1_V_RAAE_ERR)
674       {
675         SA_DBG1(("saEncryptGetMode, SCRATCH_PAD1_V_RAAE_ERR 1 0x%08X 3 0x%08X\n",ScratchPad1,ScratchPad3 ));
676         ret = AGSA_RC_FAILURE;
677       }
678       else  if((ScratchPad1 & SCRATCH_PAD1_V_RAAE_MASK) == 0x0 )
679       {
680         SA_DBG1(("saEncryptGetMode, RAAE not ready AGSA_RC_BUSY 1 0x%08X 3 0x%08X\n",ScratchPad1,ScratchPad3 ));
681         ret = AGSA_RC_BUSY;
682       }
683       if(ScratchPad3 & SCRATCH_PAD3_V_AUT)
684       {
685         encryptInfo->flag |= OperatorAuthenticationEnable_AUT;
686       }
687       if(ScratchPad3 & SCRATCH_PAD3_V_ARF)
688       {
689         encryptInfo->flag |= ReturnToFactoryMode_ARF;
690       }
691 
692       SA_DBG2(("saEncryptGetMode, encryptionCipherMode 0x%x encryptionSecurityMode 0x%x flag 0x%x status 0x%x\n",
693                 encryptInfo->encryptionCipherMode,
694                 encryptInfo->encryptionSecurityMode,
695                 encryptInfo->flag,
696                 encryptInfo->status));
697       SA_DBG2(("saEncryptGetMode, ScratchPad3 0x%x returns 0x%x\n",ScratchPad3, ret));
698 
699     }
700     else
701     {
702       SA_DBG1(("saEncryptGetMode, SPC AGSA_RC_NOT_SUPPORTED\n"));
703     }
704 
705     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "29");
706     return ret;
707 }
708 
709 /**/
710 GLOBAL bit32 saEncryptSetMode (
711                       agsaRoot_t        *agRoot,
712                       agsaContext_t     *agContext,
713                       bit32             queueNum,
714                       agsaEncryptInfo_t *mode
715                       )
716 
717 {
718   bit32 ret = AGSA_RC_NOT_SUPPORTED;
719   agsaSetControllerConfigCmd_t agControllerConfig;
720   agsaSetControllerConfigCmd_t *pagControllerConfig = &agControllerConfig;
721   bit32 smode = 0;
722 
723   if(smIS_SPCV(agRoot))
724   {
725     bit32 ScratchPad1 =0;
726 
727     ScratchPad1 = ossaHwRegRead(agRoot,V_Scratchpad_1_Register);
728     if((ScratchPad1 & SCRATCH_PAD1_V_RAAE_MASK) ==  SCRATCH_PAD1_V_RAAE_MASK)
729     {
730       si_memset(pagControllerConfig,0,sizeof(agsaSetControllerConfigCmd_t));
731 
732       SA_DBG2(("saEncryptSetMode, encryptionCipherMode 0x%x encryptionSecurityMode 0x%x status 0x%x\n",
733                                           mode->encryptionCipherMode,
734                                           mode->encryptionSecurityMode,
735                                           mode->status
736                                           ));
737 
738       smode = mode->encryptionSecurityMode;
739 
740       if( mode->encryptionCipherMode & agsaEncryptCipherModeXTS)
741       {
742         smode |= 1 << SHIFT22;
743       }
744 
745 
746       pagControllerConfig->pageCode = AGSA_ENCRYPTION_CONTROL_PARM_PAGE | smode;
747       pagControllerConfig->tag =0;
748 
749       SA_DBG2(("saEncryptSetMode,tag 0x%x pageCode 0x%x\n",
750                                           pagControllerConfig->tag,
751                                           pagControllerConfig->pageCode
752                                           ));
753 
754       SA_DBG2(("saEncryptSetMode, 0x%x 0x%x 0x%x 0x%x\n",
755                                           pagControllerConfig->configPage[0],
756                                           pagControllerConfig->configPage[1],
757                                           pagControllerConfig->configPage[2],
758                                           pagControllerConfig->configPage[3]
759                                           ));
760 
761       SA_DBG2(("saEncryptSetMode, 0x%x 0x%x 0x%x 0x%x\n",
762                                           pagControllerConfig->configPage[4],
763                                           pagControllerConfig->configPage[5],
764                                           pagControllerConfig->configPage[6],
765                                           pagControllerConfig->configPage[7]
766                                           ));
767 
768       SA_DBG2(("saEncryptSetMode, 0x%x 0x%x 0x%x 0x%x\n",
769                                           pagControllerConfig->configPage[8],
770                                           pagControllerConfig->configPage[9],
771                                           pagControllerConfig->configPage[10],
772                                           pagControllerConfig->configPage[11]
773                                           ));
774 
775       ret = mpiSetControllerConfigCmd(agRoot,agContext,pagControllerConfig,queueNum,agTRUE);
776 
777       SA_DBG2(("saEncryptSetMode,  pageCode 0x%x tag 0x%x status 0x%x\n",
778                                         pagControllerConfig->pageCode,
779                                         pagControllerConfig->tag,
780                                         ret
781                                         ));
782     }
783     else
784     {
785       SA_DBG2(("saEncryptSetMode,ScratchPad1 not ready %08X\n",ScratchPad1 ));
786       ret = AGSA_RC_BUSY;
787     }
788 
789   }
790   return ret;
791 }
792 
793 
794 
795 /**
796  * saEncryptKekUpdate()
797  *
798  *     Replace a KEK within the controller
799  *
800  * @param saRoot
801  * @param flags
802  * @param newKekIndex
803  * @param wrapperKekIndex
804  * @param encryptKekBlob
805  *
806  * @return
807  */
808 GLOBAL bit32 saEncryptKekUpdate(
809                     agsaRoot_t         *agRoot,
810                     agsaContext_t      *agContext,
811                     bit32              queueNum,
812                     bit32              flags,
813                     bit32              newKekIndex,
814                     bit32              wrapperKekIndex,
815                     bit32              blobFormat,
816                     agsaEncryptKekBlob_t *encryptKekBlob
817                     )
818 {
819   agsaKekManagementCmd_t     payload;
820   bit32 ret, i;
821 
822   smTraceFuncEnter(hpDBG_VERY_LOUD,"30");
823 
824   SA_DBG2(("saEncryptKekUpdate, flags 0x%x newKekIndex 0x%x wrapperKekIndex 0x%x encryptKekBlob %p\n",flags,newKekIndex,wrapperKekIndex,encryptKekBlob));
825   SA_DBG2(("saEncryptKekUpdate, 0x%02X%02X%02X%02X 0x%02X%02X%02X%02X\n",
826                                 encryptKekBlob->kekBlob[0],encryptKekBlob->kekBlob[1],
827                                 encryptKekBlob->kekBlob[2],encryptKekBlob->kekBlob[3],
828                                 encryptKekBlob->kekBlob[4],encryptKekBlob->kekBlob[5],
829                                 encryptKekBlob->kekBlob[6],encryptKekBlob->kekBlob[7]));
830   SA_DBG2(("saEncryptKekUpdate, 0x%02X%02X%02X%02X 0x%02X%02X%02X%02X\n",
831                                 encryptKekBlob->kekBlob[ 8],encryptKekBlob->kekBlob[ 9],
832                                 encryptKekBlob->kekBlob[10],encryptKekBlob->kekBlob[11],
833                                 encryptKekBlob->kekBlob[12],encryptKekBlob->kekBlob[13],
834                                 encryptKekBlob->kekBlob[14],encryptKekBlob->kekBlob[15]));
835   SA_DBG2(("saEncryptKekUpdate, 0x%02X%02X%02X%02X 0x%02X%02X%02X%02X\n",
836                                 encryptKekBlob->kekBlob[16],encryptKekBlob->kekBlob[17],
837                                 encryptKekBlob->kekBlob[18],encryptKekBlob->kekBlob[19],
838                                 encryptKekBlob->kekBlob[20],encryptKekBlob->kekBlob[21],
839                                 encryptKekBlob->kekBlob[22],encryptKekBlob->kekBlob[23]));
840   SA_DBG2(("saEncryptKekUpdate, 0x%02X%02X%02X%02X 0x%02X%02X%02X%02X\n",
841                                 encryptKekBlob->kekBlob[24],encryptKekBlob->kekBlob[25],
842                                 encryptKekBlob->kekBlob[26],encryptKekBlob->kekBlob[27],
843                                 encryptKekBlob->kekBlob[28],encryptKekBlob->kekBlob[29],
844                                 encryptKekBlob->kekBlob[30],encryptKekBlob->kekBlob[31]));
845   SA_DBG2(("saEncryptKekUpdate, 0x%02X%02X%02X%02X 0x%02X%02X%02X%02X\n",
846                                 encryptKekBlob->kekBlob[32],encryptKekBlob->kekBlob[33],
847                                 encryptKekBlob->kekBlob[34],encryptKekBlob->kekBlob[35],
848                                 encryptKekBlob->kekBlob[36],encryptKekBlob->kekBlob[37],
849                                 encryptKekBlob->kekBlob[38],encryptKekBlob->kekBlob[39]));
850   SA_DBG2(("saEncryptKekUpdate, 0x%02X%02X%02X%02X 0x%02X%02X%02X%02X\n",
851                                 encryptKekBlob->kekBlob[40],encryptKekBlob->kekBlob[41],
852                                 encryptKekBlob->kekBlob[42],encryptKekBlob->kekBlob[43],
853                                 encryptKekBlob->kekBlob[44],encryptKekBlob->kekBlob[45],
854                                 encryptKekBlob->kekBlob[46],encryptKekBlob->kekBlob[47]));
855   /* create payload for IOMB */
856   si_memset(&payload, 0, sizeof(agsaKekManagementCmd_t));
857 
858   OSSA_WRITE_LE_32(agRoot,
859                    &payload,
860                    OSSA_OFFSET_OF(agsaKekManagementCmd_t, NEWKIDX_CURKIDX_KBF_Reserved_SKNV_KSOP),
861                    (newKekIndex << SHIFT24) | (wrapperKekIndex << SHIFT16) | blobFormat << SHIFT14 | (flags << SHIFT8) | KEK_MGMT_SUBOP_UPDATE);
862   for (i = 0; i < 12; i++)
863   {
864 
865     OSSA_WRITE_LE_32(agRoot,
866                     &payload,
867                     OSSA_OFFSET_OF(agsaKekManagementCmd_t, kekBlob[i ]),
868                     (bit32)*(bit32*)&encryptKekBlob->kekBlob[i * sizeof(bit32)] );
869 /**/
870     }
871 
872   ret = mpiKekManagementCmd(agRoot, agContext, &payload, queueNum );
873 
874   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "30");
875   return ret;
876 }
877 
878 
879 #ifdef HIALEAH_ENCRYPTION
880 
881 GLOBAL bit32 saEncryptHilUpdate(
882                     agsaRoot_t         *agRoot,
883                     agsaContext_t      *agContext,
884                     bit32              queueNum
885                     )
886 {
887     agsaKekManagementCmd_t     payload;
888 
889     bit32 ScratchPad1 =0;
890     bit32 ScratchPad3 =0;
891     bit32 ret =0;
892 
893     ScratchPad1 = ossaHwRegRead(agRoot,V_Scratchpad_1_Register);
894     ScratchPad3 = ossaHwRegRead(agRoot,V_Scratchpad_3_Register);
895 
896 
897     smTraceFuncEnter(hpDBG_VERY_LOUD,"xxx");
898 
899     SA_DBG2(("saEncryptHilUpdate ScratchPad1 0x08%x ScratchPad3 0x08%x\n",ScratchPad1,ScratchPad3));
900     /* create payload for IOMB */
901     si_memset(&payload, 0, sizeof(agsaKekManagementCmd_t));
902 
903     OSSA_WRITE_LE_32(agRoot,
904                      &payload,
905                      OSSA_OFFSET_OF(agsaKekManagementCmd_t, NEWKIDX_CURKIDX_KBF_Reserved_SKNV_KSOP),
906                      (1 << SHIFT24) | (1 << SHIFT16) | (1 << SHIFT8) | KEK_MGMT_SUBOP_KEYCARDUPDATE);
907 /**/
908 
909     ret = mpiKekManagementCmd(agRoot, agContext, &payload, queueNum );
910 
911     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xxx");
912     return ret;
913 }
914 #endif /* HIALEAH_ENCRYPTION */
915 
916 /**
917  * saEncryptKekInvalidate()
918  *
919  *     Remove a KEK from the controller
920  *
921  * @param saRoot
922  * @param flags
923  * @param newKekIndex
924  * @param wrapperKekIndex
925  * @param encryptKekBlob
926  *
927  * @return
928  */
929 GLOBAL bit32 saEncryptKekInvalidate(
930                      agsaRoot_t        *agRoot,
931                      agsaContext_t     *agContext,
932                      bit32             queueNum,
933                      bit32             kekIndex
934                      )
935 {
936     agsaKekManagementCmd_t     payload;
937     bit32 ret;
938 
939     smTraceFuncEnter(hpDBG_VERY_LOUD,"31");
940 
941     SA_DBG2(("saEncryptKekInvalidate, kekIndex 0x%x \n",kekIndex));
942 
943 
944     /* create payload for IOMB */
945     si_memset(&payload, 0, sizeof(agsaDekManagementCmd_t));
946 
947     OSSA_WRITE_LE_32(agRoot,
948                      &payload,
949                      OSSA_OFFSET_OF(agsaKekManagementCmd_t, NEWKIDX_CURKIDX_KBF_Reserved_SKNV_KSOP),
950                      kekIndex << SHIFT16 | KEK_MGMT_SUBOP_INVALIDATE);
951 
952     ret = mpiKekManagementCmd(agRoot, agContext, &payload,  queueNum );
953 
954     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "31");
955     return ret;
956 }
957 
958 /**
959  * saEncryptDekCacheUpdate()
960  *
961  *     Replace a DEK within the controller cache
962  *
963  * @param saRoot
964  * @param kekIndex
965  * @param dekTableSelect
966  * @param dekAddrHi
967  * @param dekAddrLo
968  * @param dekIndex
969  * @param dekNumberOfEntries
970  *
971  * @return
972  */
973 GLOBAL bit32 saEncryptDekCacheUpdate(
974                      agsaRoot_t        *agRoot,
975                      agsaContext_t     *agContext,
976                      bit32             queueNum,
977                      bit32             kekIndex,
978                      bit32             dekTableSelect,
979                      bit32             dekAddrHi,
980                      bit32             dekAddrLo,
981                      bit32             dekIndex,
982                      bit32             dekNumberOfEntries,
983                      bit32             dekBlobFormat,
984                      bit32             dekTableKeyEntrySize
985                      )
986 {
987     agsaDekManagementCmd_t    payload;
988     bit32 ret;
989 
990     smTraceFuncEnter(hpDBG_VERY_LOUD,"32");
991 
992     SA_DBG2(("saEncryptDekCacheUpdate, kekIndex 0x%x dekTableSelect 0x%x dekAddrHi 0x%x dekAddrLo 0x%x\n",
993                      kekIndex,
994                      dekTableSelect,
995                      dekAddrHi,
996                      dekAddrLo ));
997     SA_DBG2(("saEncryptDekCacheUpdate, dekIndex 0x%x dekNumberOfEntries 0x%x dekBlobFormat 0x%x dekTableKeyEntrySize 0x%x\n",
998                      dekIndex,
999                      dekNumberOfEntries,
1000                      dekBlobFormat,
1001                      dekTableKeyEntrySize));
1002 
1003     /* create payload for IOMB */
1004     si_memset(&payload, 0, sizeof(agsaDekManagementCmd_t));
1005 
1006     OSSA_WRITE_LE_32(agRoot,
1007                      &payload,
1008                      OSSA_OFFSET_OF(agsaDekManagementCmd_t, KEKIDX_Reserved_TBLS_DSOP),
1009                      (kekIndex << SHIFT24) | (dekTableSelect << SHIFT8) | DEK_MGMT_SUBOP_UPDATE);
1010 
1011     OSSA_WRITE_LE_32(agRoot,
1012                      &payload,
1013                      OSSA_OFFSET_OF(agsaDekManagementCmd_t, dekIndex),
1014                      dekIndex);
1015 
1016     OSSA_WRITE_LE_32(agRoot,
1017                      &payload,
1018                      OSSA_OFFSET_OF(agsaDekManagementCmd_t, tableAddrLo),
1019                      dekAddrLo);
1020 
1021     OSSA_WRITE_LE_32(agRoot,
1022                      &payload,
1023                      OSSA_OFFSET_OF(agsaDekManagementCmd_t, tableAddrHi),
1024                      dekAddrHi);
1025 
1026     OSSA_WRITE_LE_32(agRoot,
1027                      &payload,
1028                      OSSA_OFFSET_OF(agsaDekManagementCmd_t, tableEntries),
1029                      dekNumberOfEntries);
1030 
1031     OSSA_WRITE_LE_32(agRoot,
1032                      &payload,
1033                      OSSA_OFFSET_OF(agsaDekManagementCmd_t, Reserved_DBF_TBL_SIZE),
1034                      dekBlobFormat << SHIFT8 | dekTableKeyEntrySize );
1035 
1036     ret = mpiDekManagementCmd(agRoot, agContext, &payload, queueNum);
1037 
1038     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "32");
1039     return ret;
1040 }
1041 
1042 /**
1043  * saEncryptDekCacheInvalidate()
1044  *
1045  *     Remove a DEK from the controller cache
1046  *
1047  * @param saRoot
1048  * @param kekIndex
1049  * @param dekTable
1050  * @param dekAddrHi
1051  * @param dekAddrLo
1052  * @param dekIndex
1053  * @param dekNumberOfEntries
1054  *
1055  * @return
1056  */
1057 GLOBAL bit32 saEncryptDekCacheInvalidate(
1058                     agsaRoot_t         *agRoot,
1059                     agsaContext_t      *agContext,
1060                     bit32              queueNum,
1061                     bit32              dekTable,
1062                     bit32              dekIndex
1063                     )
1064 {
1065     agsaDekManagementCmd_t     payload;
1066     bit32 ret;
1067 
1068     smTraceFuncEnter(hpDBG_VERY_LOUD,"33");
1069 
1070     SA_DBG2(("saEncryptDekCacheInvalidate,dekTable  0x%x dekIndex 0x%x\n",dekTable,dekIndex));
1071 
1072     /* create payload for IOMB */
1073     si_memset(&payload, 0, sizeof(agsaDekManagementCmd_t));
1074 
1075     OSSA_WRITE_LE_32(agRoot,
1076                      &payload,
1077                      OSSA_OFFSET_OF(agsaDekManagementCmd_t, KEKIDX_Reserved_TBLS_DSOP),
1078                      (dekTable << SHIFT8) | DEK_MGMT_SUBOP_INVALIDATE);
1079 
1080     OSSA_WRITE_LE_32(agRoot,
1081                      &payload,
1082                      OSSA_OFFSET_OF(agsaDekManagementCmd_t, dekIndex),
1083                      dekIndex);
1084 
1085     /* Assume all DEKs are 80 bytes*/
1086     OSSA_WRITE_LE_32(agRoot,
1087                      &payload,
1088                      OSSA_OFFSET_OF(agsaDekManagementCmd_t, Reserved_DBF_TBL_SIZE),
1089                      4);
1090 
1091     ret = mpiDekManagementCmd(agRoot, agContext, &payload, queueNum);
1092 
1093     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "33");
1094     return ret;
1095 }
1096 
1097 /**
1098  * saDIFEncryptionOffloadStart()
1099  *
1100  *     initiate the SPCv controller offload function
1101  *
1102  * @param saRoot
1103  * @param agContext
1104  * @param queueNum
1105  * @param op
1106  * @param agsaDifEncPayload
1107  * @param agCB
1108  *
1109  * @return
1110  */
1111 GLOBAL bit32 saDIFEncryptionOffloadStart(
1112                           agsaRoot_t         *agRoot,
1113                           agsaContext_t      *agContext,
1114                           bit32               queueNum,
1115                           bit32               op,
1116                           agsaDifEncPayload_t *agsaDifEncPayload,
1117                           ossaDIFEncryptionOffloadStartCB_t agCB)
1118 {
1119   bit32 ret = AGSA_RC_FAILURE;
1120 
1121   smTraceFuncEnter(hpDBG_VERY_LOUD,"3I");
1122   SA_DBG1(("saDIFEncryptionOffloadStart: start op=%d, agsaDifEncPayload=%p\n", op, agsaDifEncPayload));
1123 
1124   if(smIS_SPCV(agRoot))
1125   {
1126     ret = mpiDIFEncryptionOffloadCmd(agRoot, agContext, queueNum, op, agsaDifEncPayload, agCB);
1127   }
1128   else
1129   {
1130     SA_DBG1(("saDIFEncryptionOffloadStart: spcv only AGSA_RC_FAILURE \n"));
1131   }
1132 
1133   SA_DBG1(("saDIFEncryptionOffloadStart: end status 0x%x\n",ret));
1134   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "3I");
1135   return ret;
1136 }
1137 
1138 /**
1139  * saSetControllerConfig()
1140  *
1141  *     Update a controller mode page
1142  *
1143  * @param saRoot
1144  * @param modePage
1145  * @param length
1146  * @param buffer
1147  * @param agContext
1148  *
1149  * @return
1150  */
1151 GLOBAL bit32 saSetControllerConfig(
1152                       agsaRoot_t        *agRoot,
1153                       bit32             queueNum,
1154                       bit32             modePage,
1155                       bit32             length,
1156                       void              *buffer,
1157                       agsaContext_t     *agContext
1158                       )
1159 {
1160     agsaSetControllerConfigCmd_t agControllerConfig;
1161     bit32 *src;
1162     bit32 i, ret;
1163 
1164     smTraceFuncEnter(hpDBG_VERY_LOUD,"34");
1165 
1166 
1167     if(smIS_SPCV(agRoot))
1168     {
1169 
1170       SA_DBG2(("saSetControllerConfig: queueNum %d modePage 0x%x length %d\n",queueNum,modePage,length ));
1171 
1172       /* If the page is well known, validate the size of the buffer */
1173       if (((modePage == AGSA_INTERRUPT_CONFIGURATION_PAGE)   && (length != sizeof(agsaInterruptConfigPage_t )))    ||
1174            ((modePage == AGSA_ENCRYPTION_DEK_CONFIG_PAGE)    && (length != sizeof(agsaEncryptDekConfigPage_t)))     ||
1175            ((modePage == AGSA_ENCRYPTION_CONTROL_PARM_PAGE)  && (length != sizeof(agsaEncryptControlParamPage_t ))) ||
1176            ((modePage == AGSA_ENCRYPTION_HMAC_CONFIG_PAGE)   && (length != sizeof(agsaEncryptHMACConfigPage_t )))   ||
1177            ((modePage == AGSA_SAS_PROTOCOL_TIMER_CONFIG_PAGE) && (length != sizeof(agsaSASProtocolTimerConfigurationPage_t )))  )
1178       {
1179         SA_DBG1(("saSetControllerConfig: AGSA_RC_FAILURE queueNum %d modePage 0x%x length %d\n",queueNum,modePage,length ));
1180         ret = AGSA_RC_FAILURE;
1181       }
1182       else if(modePage == AGSA_ENCRYPTION_GENERAL_CONFIG_PAGE)
1183       {
1184         SA_DBG1(("saSetControllerConfig: Warning!!!!GENERAL_CONFIG_PAGE cannot be set\n"));
1185         ret = AGSA_RC_FAILURE;
1186       }
1187       else
1188       {
1189         /* Copy the raw mode page data into something that can be wrapped in an IOMB. */
1190         si_memset(&agControllerConfig, 0, sizeof(agsaSetControllerConfigCmd_t));
1191 
1192         agControllerConfig.tag = 0;  /*HTAG */
1193 
1194         src = (bit32 *) buffer;
1195 
1196         for (i = 0; i < (length / 4); i++)
1197         {
1198           OSSA_WRITE_LE_32(agRoot,
1199                            &agControllerConfig,
1200                            OSSA_OFFSET_OF(agsaSetControllerConfigCmd_t, pageCode) + (i * 4),
1201                            *src);
1202 
1203           src++;
1204         }
1205         ret = mpiSetControllerConfigCmd(agRoot, agContext, &agControllerConfig, queueNum,agFALSE);
1206         if(ret)
1207         {
1208           SA_DBG1(("saSetControllerConfig: AGSA_RC_FAILURE (sending) queueNum %d modePage 0x%x length %d\n",queueNum,modePage,length ));
1209         }
1210 
1211       }
1212     }
1213     else
1214     {
1215       SA_DBG1(("saSetControllerConfig: spcv only AGSA_RC_FAILURE queueNum %d modePage 0x%x length %d\n",queueNum,modePage,length ));
1216       ret = AGSA_RC_FAILURE;
1217     }
1218     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "34");
1219     return ret;
1220 }
1221 
1222 
1223 /**
1224  * saGetControllerConfig()
1225  *
1226  *     Retrieve the contents of a controller mode page
1227  *
1228  * @param saRoot
1229  * @param modePage
1230  * @param agContext
1231  *
1232  * @return
1233  */
1234 GLOBAL bit32 saGetControllerConfig(
1235                       agsaRoot_t        *agRoot,
1236                       bit32             queueNum,
1237                       bit32             modePage,
1238                       bit32             flag0,
1239                       bit32             flag1,
1240                       agsaContext_t     *agContext
1241                       )
1242 {
1243     bit32 ret;
1244     agsaGetControllerConfigCmd_t agControllerConfig;
1245 
1246     smTraceFuncEnter(hpDBG_VERY_LOUD,"35");
1247 
1248     SA_DBG2(("saGetControllerConfig, modePage 0x%x  agContext %p flag0 0x%08x flag1 0x%08x\n",modePage,agContext, flag0, flag1 ));
1249     if(smIS_SPCV(agRoot))
1250     {
1251       si_memset(&agControllerConfig, 0, sizeof(agsaGetControllerConfigCmd_t));
1252 
1253       agControllerConfig.pageCode = modePage;
1254       if(modePage == AGSA_INTERRUPT_CONFIGURATION_PAGE)
1255       {
1256         agControllerConfig.INT_VEC_MSK0 = flag0;
1257         agControllerConfig.INT_VEC_MSK1 = flag1;
1258       }
1259       ret = mpiGetControllerConfigCmd(agRoot, agContext, &agControllerConfig, queueNum);
1260     }
1261     else
1262     {
1263       SA_DBG1(("saGetControllerConfig: spcv only AGSA_RC_FAILURE queueNum %d modePage 0x%x flag0 0x%08x flag1 0x%08x\n",queueNum,modePage, flag0, flag1 ));
1264       ret = AGSA_RC_FAILURE;
1265     }
1266 
1267     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "35");
1268     return ret;
1269 }
1270 
1271 GLOBAL bit32 saEncryptSelftestExecute (
1272                         agsaRoot_t    *agRoot,
1273                         agsaContext_t *agContext,
1274                         bit32          queueNum,
1275                         bit32          type,
1276                         bit32          length,
1277                         void          *TestDescriptor)
1278 {
1279   bit32 ret = AGSA_RC_SUCCESS;
1280 
1281   agsaEncryptBist_t bist;
1282   smTraceFuncEnter(hpDBG_VERY_LOUD,"2e");
1283   si_memset(&bist, 0, (sizeof(agsaEncryptBist_t)));
1284 
1285   SA_DBG1(("saEncryptSelftestExecute, enter\n" ));
1286   bist.r_subop = (type & 0xFF);
1287 
1288   si_memcpy(&bist.testDiscption,TestDescriptor,length );
1289 
1290   /* setup IOMB payload */
1291   ret = mpiEncryptBistCmd( agRoot, queueNum, agContext, &bist );
1292 
1293   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2e");
1294 
1295   return (ret);
1296 }
1297 GLOBAL bit32 saOperatorManagement(
1298                         agsaRoot_t           *agRoot,
1299                         agsaContext_t        *agContext,
1300                         bit32                 queueNum,
1301                         bit32                 flag,
1302                         bit8                  role,
1303                         agsaID_t             *id,
1304                         agsaEncryptKekBlob_t *kblob)
1305 {
1306   bit32 ret = AGSA_RC_SUCCESS;
1307   agsaOperatorMangmentCmd_t opmcmd;
1308 
1309   smTraceFuncEnter(hpDBG_VERY_LOUD,"2i");
1310 
1311   SA_DBG1(("saOperatorManagement, enter\n" ));
1312 
1313   si_memset(&opmcmd, 0, sizeof(agsaOperatorMangmentCmd_t));
1314   /*role = ((flag & SA_OPR_MGMNT_FLAG_MASK) >> SA_OPR_MGMNT_FLAG_SHIFT);*/
1315 
1316   flag = (flag & ~SA_OPR_MGMNT_FLAG_MASK);
1317 
1318   opmcmd.OPRIDX_AUTIDX_R_KBF_PKT_OMO = flag;
1319 
1320   opmcmd.IDString_Role[0] = (bit8)role;
1321   SA_DBG1(("saOperatorManagement, role 0x%X flags 0x%08X\n", role, opmcmd.OPRIDX_AUTIDX_R_KBF_PKT_OMO ));
1322 
1323   si_memcpy(&opmcmd.IDString_Role[1], id->ID, AGSA_ID_SIZE);
1324   si_memcpy(&opmcmd.Kblob, kblob, sizeof(agsaEncryptKekBlob_t));
1325 
1326   /* setup IOMB payload */
1327   ret = mpiOperatorManagementCmd(agRoot, queueNum, agContext, &opmcmd);
1328 
1329   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2i");
1330 
1331   return (ret);
1332 }
1333 
1334 /*
1335     The command is for an operator to login to/logout from SPCve.
1336     Only when all IOs are quiesced, can an operator logout.
1337 
1338     flag:
1339       Access type (ACS) [4 bits]
1340         0x1: login
1341         0x2: logout
1342         Others: reserved
1343       KEYopr pinned in the KEK RAM (PIN) [1 bit]
1344         0: not pinned, operator ID table will be searched during authentication.
1345         1: pinned, OPRIDX is referenced to unwrap the certificate.
1346       KEYopr Index in the KEK RAM (OPRIDX) [8 bits]
1347         If KEYopr is pinned in the KEK RAM, OPRIDX is to reference to the KEK for authentication
1348 
1349     cert
1350       Operator Certificate (CERT) [40 bytes]
1351 
1352     response calls ossaSetOperatorCB
1353 */
1354 
1355 GLOBAL bit32
1356 saSetOperator(
1357   agsaRoot_t     *agRoot,
1358   agsaContext_t  *agContext,
1359   bit32           queueNum,
1360   bit32           flag,
1361   void           *cert
1362   )
1363 {
1364   bit32 ret = AGSA_RC_SUCCESS;
1365   agsaSetOperatorCmd_t  SetOperatorCmd;
1366 
1367   smTraceFuncEnter(hpDBG_VERY_LOUD,"3c");
1368   SA_DBG1(("saSetOperator, flag 0x%x cert %p\n",flag, cert));
1369 
1370   /* initialize set operator IOMB */
1371   si_memset(&SetOperatorCmd, 0, sizeof(agsaSetOperatorCmd_t));
1372   SetOperatorCmd.OPRIDX_PIN_ACS = flag;
1373   si_memcpy((bit8*)SetOperatorCmd.cert, (bit8*)cert, 40);
1374 
1375   /* setup IOMB payload */
1376   ret = mpiSetOperatorCmd(agRoot, queueNum, agContext, &SetOperatorCmd);
1377 
1378   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "3c");
1379   return (ret);
1380 }
1381 
1382 /*
1383     The command is to get role and ID of either current or all operators from SPCve.
1384     Option
1385         0x1: current operator
1386         0x2: all operators
1387         Others: reserved
1388 
1389     OprBufAddr
1390         the host buffer address to store the role and ID of all operators. Valid only when option == 0x2.
1391         Buffer size must be 1KB to store max 32 operators's role and ID.
1392     response calls ossaGetOperatorCB
1393 */
1394 GLOBAL bit32
1395 saGetOperator(
1396   agsaRoot_t     *agRoot,
1397   agsaContext_t  *agContext,
1398   bit32           queueNum,
1399   bit32           option,
1400   bit32           AddrHi,
1401   bit32           AddrLo
1402   )
1403 {
1404   bit32 ret = AGSA_RC_SUCCESS;
1405   agsaGetOperatorCmd_t  GetOperatorCmd;
1406 
1407   smTraceFuncEnter(hpDBG_VERY_LOUD,"3d");
1408   SA_DBG1(("saGetOperator, option 0x%x 0x%08x_%08x\n",option,AddrHi,AddrLo ));
1409 
1410   /* initialize get operator IOMB */
1411   si_memset(&GetOperatorCmd, 0, sizeof(agsaGetOperatorCmd_t));
1412   GetOperatorCmd.option = option;
1413   GetOperatorCmd.OprBufAddrLo = AddrLo;
1414   GetOperatorCmd.OprBufAddrHi = AddrHi;
1415 
1416   /* setup IOMB payload */
1417   ret = mpiGetOperatorCmd(agRoot, queueNum, agContext, &GetOperatorCmd);
1418 
1419   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "3d");
1420 
1421   return (ret);
1422 }
1423 
1424