mirror of
https://github.com/NVIDIA/open-gpu-kernel-modules.git
synced 2026-03-14 09:37:48 +00:00
633 lines
20 KiB
C
633 lines
20 KiB
C
/*
|
|
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
#include "common_nvswitch.h"
|
|
#include "lr10/lr10.h"
|
|
#include "lr10/smbpbi_lr10.h"
|
|
#include "nvswitch/lr10/dev_nvlsaw_ip.h"
|
|
#include "nvswitch/lr10/dev_nvlsaw_ip_addendum.h"
|
|
|
|
#include "flcn/flcn_nvswitch.h"
|
|
#include "rmflcncmdif_nvswitch.h"
|
|
|
|
#define GET_PFIFO_FROM_DEVICE(dev) (&(dev)->pSmbpbi->sharedSurface->inforomObjects.DEM.object.v1)
|
|
|
|
#define DEM_FIFO_SIZE INFOROM_DEM_OBJECT_V1_00_FIFO_SIZE
|
|
#define DEM_FIFO_PTR(x) ((x) % DEM_FIFO_SIZE)
|
|
#define DEM_PTR_DIFF(cur, next) (((next) > (cur)) ? ((next) - (cur)) : \
|
|
(DEM_FIFO_SIZE - ((cur) - (next))))
|
|
#define DEM_BYTES_OCCUPIED(pf) DEM_PTR_DIFF((pf)->readOffset, (pf)->writeOffset)
|
|
//
|
|
// See how much space is available in the FIFO.
|
|
// Must leave 1 word free so the write pointer does not
|
|
// catch up with the read pointer. That would be indistinguishable
|
|
// from an empty FIFO.
|
|
//
|
|
#define DEM_BYTES_AVAILABLE(pf) (DEM_PTR_DIFF((pf)->writeOffset, (pf)->readOffset) - \
|
|
sizeof(NvU32))
|
|
#define DEM_RECORD_SIZE_MAX (sizeof(NV_MSGBOX_DEM_RECORD) \
|
|
+ NV_MSGBOX_MAX_DRIVER_EVENT_MSG_TXT_SIZE)
|
|
#define DEM_RECORD_SIZE_MIN (sizeof(NV_MSGBOX_DEM_RECORD) + 1)
|
|
|
|
#define FIFO_REC_LOOP_ITERATOR _curPtr
|
|
#define FIFO_REC_LOOP_REC_PTR _recPtr
|
|
#define FIFO_REC_LOOP_REC_SIZE _recSize
|
|
#define FIFO_REC_LOOP_START(pf, cond) \
|
|
{ \
|
|
NvU16 _nextPtr; \
|
|
for (FIFO_REC_LOOP_ITERATOR = (pf)->readOffset; cond; FIFO_REC_LOOP_ITERATOR = _nextPtr) \
|
|
{ \
|
|
NV_MSGBOX_DEM_RECORD *FIFO_REC_LOOP_REC_PTR = (NV_MSGBOX_DEM_RECORD *) \
|
|
((pf)->fifoBuffer + FIFO_REC_LOOP_ITERATOR); \
|
|
NvU16 FIFO_REC_LOOP_REC_SIZE = \
|
|
FIFO_REC_LOOP_REC_PTR->recordSize * sizeof(NvU32);
|
|
|
|
#define FIFO_REC_LOOP_END \
|
|
_nextPtr = DEM_FIFO_PTR(FIFO_REC_LOOP_ITERATOR + FIFO_REC_LOOP_REC_SIZE); \
|
|
} \
|
|
}
|
|
|
|
static void _smbpbiDemInit(nvswitch_device *device, struct smbpbi *pSmbpbi, struct INFOROM_DEM_OBJECT_V1_00 *pFifo);
|
|
|
|
NvlStatus
|
|
nvswitch_smbpbi_alloc_lr10
|
|
(
|
|
nvswitch_device *device
|
|
)
|
|
{
|
|
NV_STATUS status;
|
|
NvU64 dmaHandle;
|
|
void *cpuAddr;
|
|
|
|
// Create DMA mapping for SMBPBI transactions
|
|
status = nvswitch_os_alloc_contig_memory(device->os_handle, &cpuAddr,
|
|
sizeof(SOE_SMBPBI_SHARED_SURFACE),
|
|
(device->dma_addr_width == 32));
|
|
if (status != NVL_SUCCESS)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR, "Failed to allocate contig memory, rc:%d\n",
|
|
status);
|
|
return status;
|
|
}
|
|
|
|
nvswitch_os_memset(cpuAddr, 0, sizeof(SOE_SMBPBI_SHARED_SURFACE));
|
|
|
|
status = nvswitch_os_map_dma_region(device->os_handle, cpuAddr, &dmaHandle,
|
|
sizeof(SOE_SMBPBI_SHARED_SURFACE),
|
|
NVSWITCH_DMA_DIR_BIDIRECTIONAL);
|
|
if (status == NVL_SUCCESS)
|
|
{
|
|
device->pSmbpbi->sharedSurface = cpuAddr;
|
|
device->pSmbpbi->dmaHandle = dmaHandle;
|
|
}
|
|
else
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"Failed to map dma region for SMBPBI shared surface, rc:%d\n",
|
|
status);
|
|
nvswitch_os_free_contig_memory(device->os_handle, cpuAddr, sizeof(SOE_SMBPBI_SHARED_SURFACE));
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NvlStatus
|
|
nvswitch_smbpbi_post_init_hal_lr10
|
|
(
|
|
nvswitch_device *device
|
|
)
|
|
{
|
|
struct smbpbi *pSmbpbi = device->pSmbpbi;
|
|
FLCN *pFlcn;
|
|
NvU64 dmaHandle;
|
|
RM_FLCN_CMD_SOE cmd;
|
|
NVSWITCH_TIMEOUT timeout;
|
|
NvU32 cmdSeqDesc;
|
|
RM_SOE_SMBPBI_CMD_INIT *pInitCmd = &cmd.cmd.smbpbiCmd.init;
|
|
NvlStatus status;
|
|
|
|
if (!device->pInforom || !device->pSmbpbi->sharedSurface)
|
|
{
|
|
return -NVL_ERR_NOT_SUPPORTED;
|
|
}
|
|
|
|
// Populate shared surface with static InfoROM data
|
|
nvswitch_inforom_read_static_data(device, device->pInforom,
|
|
&device->pSmbpbi->sharedSurface->inforomObjects);
|
|
|
|
pFlcn = device->pSoe->pFlcn;
|
|
dmaHandle = pSmbpbi->dmaHandle;
|
|
|
|
nvswitch_os_memset(&cmd, 0, sizeof(cmd));
|
|
cmd.hdr.unitId = RM_SOE_UNIT_SMBPBI;
|
|
cmd.hdr.size = RM_SOE_CMD_SIZE(SMBPBI, INIT);
|
|
cmd.cmd.smbpbiCmd.cmdType = RM_SOE_SMBPBI_CMD_ID_INIT;
|
|
RM_FLCN_U64_PACK(&pInitCmd->dmaHandle, &dmaHandle);
|
|
|
|
//
|
|
// Make the interval twice the heartbeat period to avoid
|
|
// skew between driver and soe threads
|
|
//
|
|
pInitCmd->driverPollingPeriodUs = (NVSWITCH_HEARTBEAT_INTERVAL_NS / 1000) * 2;
|
|
|
|
nvswitch_timeout_create(NVSWITCH_INTERVAL_1SEC_IN_NS, &timeout);
|
|
status = flcnQueueCmdPostBlocking(device, pFlcn,
|
|
(PRM_FLCN_CMD)&cmd,
|
|
NULL, // pMsg - not used for now
|
|
NULL, // pPayload - not used for now
|
|
SOE_RM_CMDQ_LOG_ID,
|
|
&cmdSeqDesc,
|
|
&timeout);
|
|
if (status != NV_OK)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR, "%s: SMBPBI Init command failed. rc:%d\n",
|
|
__FUNCTION__, status);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
void
|
|
nvswitch_smbpbi_destroy_hal_lr10
|
|
(
|
|
nvswitch_device *device
|
|
)
|
|
{
|
|
if (device->pSmbpbi && device->pSmbpbi->sharedSurface)
|
|
{
|
|
nvswitch_os_unmap_dma_region(device->os_handle,
|
|
device->pSmbpbi->sharedSurface,
|
|
device->pSmbpbi->dmaHandle,
|
|
sizeof(SOE_SMBPBI_SHARED_SURFACE),
|
|
NVSWITCH_DMA_DIR_BIDIRECTIONAL);
|
|
nvswitch_os_free_contig_memory(device->os_handle, device->pSmbpbi->sharedSurface,
|
|
sizeof(SOE_SMBPBI_SHARED_SURFACE));
|
|
}
|
|
}
|
|
|
|
NvlStatus
|
|
nvswitch_smbpbi_get_dem_num_messages_lr10
|
|
(
|
|
nvswitch_device *device,
|
|
NvU8 *pMsgCount
|
|
)
|
|
{
|
|
NvU32 reg = NVSWITCH_SAW_RD32_LR10(device, _NVLSAW_SW, _SCRATCH_12);
|
|
|
|
*pMsgCount = DRF_VAL(_NVLSAW_SW, _SCRATCH_12, _EVENT_MESSAGE_COUNT, reg);
|
|
|
|
return NVL_SUCCESS;
|
|
}
|
|
|
|
NvlStatus
|
|
nvswitch_smbpbi_dem_load_lr10
|
|
(
|
|
nvswitch_device *device
|
|
)
|
|
{
|
|
NvlStatus status;
|
|
NvU8 version = 0;
|
|
NvU8 subversion = 0;
|
|
struct inforom *pInforom = device->pInforom;
|
|
NvU8 *pPackedObject = NULL;
|
|
struct INFOROM_DEM_OBJECT_V1_00 *pFifo;
|
|
|
|
if ((pInforom == NULL) || (device->pSmbpbi == NULL) ||
|
|
(device->pSmbpbi->sharedSurface == NULL))
|
|
{
|
|
return -NVL_ERR_NOT_SUPPORTED;
|
|
}
|
|
|
|
pFifo = GET_PFIFO_FROM_DEVICE(device);
|
|
|
|
status = nvswitch_inforom_get_object_version_info(device, "DEM", &version,
|
|
&subversion);
|
|
if (status != NVL_SUCCESS)
|
|
{
|
|
NVSWITCH_PRINT(device, INFO, "no DEM object found, rc:%d\n", status);
|
|
goto nvswitch_inforom_dem_load_fail;
|
|
}
|
|
|
|
if (!INFOROM_OBJECT_SUBVERSION_SUPPORTS_NVSWITCH(subversion))
|
|
{
|
|
NVSWITCH_PRINT(device, WARN, "DEM v%u.%u not supported\n",
|
|
version, subversion);
|
|
status = -NVL_ERR_NOT_SUPPORTED;
|
|
goto nvswitch_inforom_dem_load_fail;
|
|
}
|
|
|
|
NVSWITCH_PRINT(device, INFO, "DEM v%u.%u found\n", version, subversion);
|
|
|
|
if (version != 1)
|
|
{
|
|
NVSWITCH_PRINT(device, WARN, "DEM v%u.%u not supported\n",
|
|
version, subversion);
|
|
status = -NVL_ERR_NOT_SUPPORTED;
|
|
goto nvswitch_inforom_dem_load_fail;
|
|
}
|
|
|
|
pPackedObject = nvswitch_os_malloc(INFOROM_DEM_OBJECT_V1_00_PACKED_SIZE);
|
|
|
|
if (pPackedObject == NULL)
|
|
{
|
|
status = -NVL_NO_MEM;
|
|
goto nvswitch_inforom_dem_load_fail;
|
|
}
|
|
|
|
status = nvswitch_inforom_load_object(device, pInforom, "DEM",
|
|
INFOROM_DEM_OBJECT_V1_00_FMT,
|
|
pPackedObject,
|
|
pFifo);
|
|
if (status != NVL_SUCCESS)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR, "Failed to load DEM object, rc: %d\n",
|
|
status);
|
|
goto nvswitch_inforom_dem_load_fail;
|
|
}
|
|
|
|
nvswitch_inforom_dem_load_fail:
|
|
|
|
if (pPackedObject)
|
|
{
|
|
nvswitch_os_free(pPackedObject);
|
|
}
|
|
|
|
//
|
|
// Mark the cached DEM as usable for Xid logging, even if we were
|
|
// unable to find it in the InfoROM image.
|
|
//
|
|
|
|
device->pSmbpbi->sharedSurface->inforomObjects.DEM.bValid = NV_TRUE;
|
|
|
|
_smbpbiDemInit(device, device->pSmbpbi, pFifo);
|
|
|
|
return status;
|
|
}
|
|
|
|
/*!
|
|
* Validate/Initialize the Driver Event Message (SXid) FIFO buffer
|
|
*
|
|
* @param[in] device device object pointer
|
|
* @param[in] pSmbpbi SMBPBI object pointer
|
|
* @param[in,out] pFifo DEM object pointer
|
|
*
|
|
* @return void
|
|
*/
|
|
static void
|
|
_smbpbiDemInit
|
|
(
|
|
nvswitch_device *device,
|
|
struct smbpbi *pSmbpbi,
|
|
struct INFOROM_DEM_OBJECT_V1_00 *pFifo
|
|
)
|
|
{
|
|
NvU8 msgLeft;
|
|
unsigned recordsHeld = 0;
|
|
NvU16 FIFO_REC_LOOP_ITERATOR;
|
|
NvU16 bytesOccupied;
|
|
NvU16 bytesSeen;
|
|
NvBool status = NV_FALSE;
|
|
|
|
// validate the FIFO buffer
|
|
|
|
if ((DEM_FIFO_PTR(pFifo->writeOffset) != pFifo->writeOffset) ||
|
|
(DEM_FIFO_PTR(pFifo->readOffset) != pFifo->readOffset) ||
|
|
((pFifo->writeOffset % sizeof(NvU32)) != 0) ||
|
|
((pFifo->readOffset % sizeof(NvU32)) != 0))
|
|
{
|
|
goto smbpbiDemInit_exit;
|
|
}
|
|
|
|
if (pFifo->writeOffset == pFifo->readOffset)
|
|
{
|
|
// The FIFO is empty
|
|
status = NV_TRUE;
|
|
goto smbpbiDemInit_exit;
|
|
}
|
|
|
|
//
|
|
// This HAL extracts from a scratch register the count of DEM messages
|
|
// in the FIFO that has not yet been requested by the SMBPBI client.
|
|
// If the FIFO holds more messages than that, it means those in excess
|
|
// of this count have been delivered to the client by PreOS app.
|
|
//
|
|
if (device->hal.nvswitch_smbpbi_get_dem_num_messages(device, &msgLeft) != NVL_SUCCESS)
|
|
{
|
|
// assume the maximum
|
|
msgLeft = ~0;
|
|
}
|
|
|
|
if (msgLeft == 0)
|
|
{
|
|
// Nothing of value in the FIFO. Lets reset it explicitly.
|
|
status = NV_TRUE;
|
|
pFifo->writeOffset = 0;
|
|
pFifo->readOffset = 0;
|
|
goto smbpbiDemInit_exit;
|
|
}
|
|
|
|
//
|
|
// Count the messages in the FIFO, while also checking the structure
|
|
// for integrity. Reset the FIFO in case any corruption is found.
|
|
//
|
|
bytesOccupied = DEM_BYTES_OCCUPIED(pFifo);
|
|
|
|
bytesSeen = 0;
|
|
FIFO_REC_LOOP_START(pFifo, bytesSeen < bytesOccupied)
|
|
if ((_recSize > DEM_RECORD_SIZE_MAX) ||
|
|
(FIFO_REC_LOOP_REC_SIZE < DEM_RECORD_SIZE_MIN))
|
|
{
|
|
goto smbpbiDemInit_exit;
|
|
}
|
|
|
|
bytesSeen += FIFO_REC_LOOP_REC_SIZE;
|
|
++recordsHeld;
|
|
FIFO_REC_LOOP_END
|
|
|
|
if ((bytesSeen != bytesOccupied) || (msgLeft > recordsHeld))
|
|
{
|
|
goto smbpbiDemInit_exit;
|
|
}
|
|
|
|
//
|
|
// Advance the FIFO read ptr in order to remove those messages that
|
|
// have already been delivered to the client.
|
|
//
|
|
FIFO_REC_LOOP_START(pFifo, recordsHeld > msgLeft)
|
|
--recordsHeld;
|
|
FIFO_REC_LOOP_END
|
|
|
|
pFifo->readOffset = FIFO_REC_LOOP_ITERATOR;
|
|
status = NV_TRUE;
|
|
|
|
smbpbiDemInit_exit:
|
|
|
|
if (!status)
|
|
{
|
|
// Reset the FIFO
|
|
pFifo->writeOffset = 0;
|
|
pFifo->readOffset = 0;
|
|
pFifo->seqNumber = 0;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* A helper to create a new DEM FIFO record
|
|
*
|
|
* @param[in,out] pFifo DEM object pointer
|
|
* @param[in] num Xid number
|
|
* @param[in] osErrorString text message to store
|
|
* @param[in] msglen message size
|
|
* @param[out] pRecSize new record size in bytes
|
|
*
|
|
* @return ptr to the new record
|
|
* @return NULL if there's no room in the FIFO
|
|
* or dynamic allocation error
|
|
*/
|
|
static NV_MSGBOX_DEM_RECORD *
|
|
_makeNewRecord
|
|
(
|
|
INFOROM_DEM_OBJECT_V1_00 *pFifo,
|
|
NvU32 num,
|
|
NvU8 *osErrorString,
|
|
NvU32 msglen,
|
|
NvU32 *pRecSize
|
|
)
|
|
{
|
|
NV_MSGBOX_DEM_RECORD *pNewRec;
|
|
|
|
*pRecSize = NV_MIN(sizeof(NV_MSGBOX_DEM_RECORD) + msglen,
|
|
DEM_RECORD_SIZE_MAX);
|
|
|
|
if ((*pRecSize > DEM_BYTES_AVAILABLE(pFifo)) ||
|
|
((pNewRec = nvswitch_os_malloc(*pRecSize)) == NULL))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// Fill the new record.
|
|
nvswitch_os_memset(pNewRec, 0, *pRecSize);
|
|
pNewRec->recordSize = NV_UNSIGNED_DIV_CEIL(*pRecSize, sizeof(NvU32));
|
|
pNewRec->xidId = num;
|
|
pNewRec->seqNumber = pFifo->seqNumber++;
|
|
pNewRec->timeStamp = nvswitch_os_get_platform_time() / NVSWITCH_NSEC_PER_SEC;
|
|
|
|
if (msglen > NV_MSGBOX_MAX_DRIVER_EVENT_MSG_TXT_SIZE)
|
|
{
|
|
// The text string is too long. Truncate and notify the client.
|
|
pNewRec->flags = FLD_SET_DRF(_MSGBOX, _DEM_RECORD_FLAGS,
|
|
_TRUNC, _SET, pNewRec->flags);
|
|
msglen = NV_MSGBOX_MAX_DRIVER_EVENT_MSG_TXT_SIZE - 1;
|
|
}
|
|
|
|
nvswitch_os_memcpy(pNewRec->textMessage, osErrorString, msglen);
|
|
|
|
return pNewRec;
|
|
}
|
|
|
|
/*!
|
|
* A helper to add the new record to the DEM FIFO
|
|
*
|
|
* @param[in,out] pFifo DEM object pointer
|
|
* @param[in] pNewRec the new record
|
|
* @param[in] recSize new record size in bytes
|
|
*
|
|
* @return void
|
|
*/
|
|
static void
|
|
_addNewRecord
|
|
(
|
|
INFOROM_DEM_OBJECT_V1_00 *pFifo,
|
|
NV_MSGBOX_DEM_RECORD *pNewRec,
|
|
NvU32 recSize
|
|
)
|
|
{
|
|
NvU16 rem;
|
|
NvU16 curPtr;
|
|
NvU16 copySz;
|
|
NvU8 *srcPtr;
|
|
|
|
// Copy the new record into the FIFO, handling a possible wrap-around.
|
|
rem = recSize;
|
|
curPtr = pFifo->writeOffset;
|
|
srcPtr = (NvU8 *)pNewRec;
|
|
while (rem > 0)
|
|
{
|
|
copySz = NV_MIN(rem, DEM_FIFO_SIZE - curPtr);
|
|
nvswitch_os_memcpy(pFifo->fifoBuffer + curPtr, srcPtr, copySz);
|
|
rem -= copySz;
|
|
srcPtr += copySz;
|
|
curPtr = DEM_FIFO_PTR(curPtr + copySz);
|
|
}
|
|
|
|
// Advance the FIFO write ptr.
|
|
pFifo->writeOffset = DEM_FIFO_PTR(pFifo->writeOffset +
|
|
(pNewRec->recordSize * sizeof(NvU32)));
|
|
}
|
|
|
|
/*!
|
|
* Add a Driver Event Message (SXid) to the InfoROM DEM FIFO buffer
|
|
*
|
|
* @param[in] device device object pointer
|
|
* @param[in] num Xid number
|
|
* @param[in] msglen message size
|
|
* @param[in] osErrorString text message to store
|
|
*
|
|
* @return void
|
|
*/
|
|
void
|
|
nvswitch_smbpbi_log_message_lr10
|
|
(
|
|
nvswitch_device *device,
|
|
NvU32 num,
|
|
NvU32 msglen,
|
|
NvU8 *osErrorString
|
|
)
|
|
{
|
|
INFOROM_DEM_OBJECT_V1_00 *pFifo;
|
|
NvU32 recSize;
|
|
NvU16 FIFO_REC_LOOP_ITERATOR;
|
|
NV_MSGBOX_DEM_RECORD *pNewRec;
|
|
|
|
if ((device->pSmbpbi == NULL) ||
|
|
(device->pSmbpbi->sharedSurface == NULL))
|
|
{
|
|
return;
|
|
}
|
|
|
|
pFifo = GET_PFIFO_FROM_DEVICE(device);
|
|
|
|
pNewRec = _makeNewRecord(pFifo, num, osErrorString, msglen, &recSize);
|
|
|
|
if (pNewRec != NULL)
|
|
{
|
|
_addNewRecord(pFifo, pNewRec, recSize);
|
|
nvswitch_os_free(pNewRec);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// We are unable to log this message. Mark the latest record
|
|
// with a flag telling the client that message(s) were dropped.
|
|
//
|
|
|
|
NvU16 bytesOccupied = DEM_BYTES_OCCUPIED(pFifo);
|
|
NvU16 bytesSeen;
|
|
NV_MSGBOX_DEM_RECORD *pLastRec = NULL;
|
|
|
|
// Find the newest record
|
|
bytesSeen = 0;
|
|
FIFO_REC_LOOP_START(pFifo, bytesSeen < bytesOccupied)
|
|
pLastRec = FIFO_REC_LOOP_REC_PTR;
|
|
bytesSeen += FIFO_REC_LOOP_REC_SIZE;
|
|
FIFO_REC_LOOP_END
|
|
|
|
if (pLastRec != NULL)
|
|
{
|
|
pLastRec->flags = FLD_SET_DRF(_MSGBOX, _DEM_RECORD_FLAGS,
|
|
_OVFL, _SET, pLastRec->flags);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void
|
|
nvswitch_smbpbi_dem_flush_lr10
|
|
(
|
|
nvswitch_device *device
|
|
)
|
|
{
|
|
NvU8 *pPackedObject = NULL;
|
|
struct INFOROM_DEM_OBJECT_V1_00 *pFifo;
|
|
NvlStatus status = NVL_SUCCESS;
|
|
|
|
pPackedObject = nvswitch_os_malloc(INFOROM_DEM_OBJECT_V1_00_PACKED_SIZE);
|
|
|
|
if (pPackedObject == NULL)
|
|
{
|
|
status = -NVL_NO_MEM;
|
|
goto nvswitch_smbpbi_dem_flush_exit;
|
|
}
|
|
|
|
pFifo = GET_PFIFO_FROM_DEVICE(device);
|
|
|
|
status = nvswitch_inforom_write_object(device, "DEM",
|
|
INFOROM_DEM_OBJECT_V1_00_FMT,
|
|
pFifo,
|
|
pPackedObject);
|
|
|
|
nvswitch_smbpbi_dem_flush_exit:
|
|
nvswitch_os_free(pPackedObject);
|
|
|
|
if (status != NVL_SUCCESS)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR, "DEM object write failed, status=%d\n",
|
|
status);
|
|
}
|
|
}
|
|
|
|
void
|
|
nvswitch_smbpbi_send_unload_lr10
|
|
(
|
|
nvswitch_device *device
|
|
)
|
|
{
|
|
FLCN *pFlcn;
|
|
RM_FLCN_CMD_SOE cmd;
|
|
NVSWITCH_TIMEOUT timeout;
|
|
NvU32 cmdSeqDesc;
|
|
NvlStatus status;
|
|
|
|
pFlcn = device->pSoe->pFlcn;
|
|
|
|
nvswitch_os_memset(&cmd, 0, sizeof(cmd));
|
|
cmd.hdr.unitId = RM_SOE_UNIT_SMBPBI;
|
|
cmd.hdr.size = RM_SOE_CMD_SIZE(SMBPBI, UNLOAD);
|
|
cmd.cmd.smbpbiCmd.cmdType = RM_SOE_SMBPBI_CMD_ID_UNLOAD;
|
|
|
|
nvswitch_timeout_create(NVSWITCH_INTERVAL_1SEC_IN_NS, &timeout);
|
|
status = flcnQueueCmdPostBlocking(device, pFlcn,
|
|
(PRM_FLCN_CMD)&cmd,
|
|
NULL, // pMsg - not used for now
|
|
NULL, // pPayload - not used for now
|
|
SOE_RM_CMDQ_LOG_ID,
|
|
&cmdSeqDesc,
|
|
&timeout);
|
|
if (status != NV_OK)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR, "%s: SMBPBI unload command failed. rc:%d\n",
|
|
__FUNCTION__, status);
|
|
}
|
|
}
|
|
|
|
NvlStatus
|
|
nvswitch_smbpbi_send_init_data_lr10
|
|
(
|
|
nvswitch_device *device
|
|
)
|
|
{
|
|
return NVL_SUCCESS;
|
|
}
|
|
|