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