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