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
40extern 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/*******************************************************************************/
59GLOBAL 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/*******************************************************************************/
168GLOBAL 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/*******************************************************************************/
237GLOBAL 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/*******************************************************************************/
330GLOBAL 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/*******************************************************************************/
369GLOBAL 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/*******************************************************************************/
421GLOBAL 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 */
562GLOBAL 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/**/
709GLOBAL 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 */
807GLOBAL 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
880GLOBAL 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 */
928GLOBAL 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 */
972GLOBAL 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 */
1056GLOBAL 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 */
1110GLOBAL 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 */
1150GLOBAL 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 */
1233GLOBAL 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
1270GLOBAL 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}
1296GLOBAL 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
1354GLOBAL bit32
1355saSetOperator(
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*/
1393GLOBAL bit32
1394saGetOperator(
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