This commit is contained in:
Andy Ritger
2022-11-10 08:39:33 -08:00
parent 7c345b838b
commit 758b4ee818
1323 changed files with 262135 additions and 60754 deletions

View File

@@ -31,6 +31,9 @@
#include "flcn/flcn_nvswitch.h"
#include "soe/soe_nvswitch.h"
#include "nvVer.h"
#include "nvlink_inband_msg.h"
static NvlStatus _nvswitch_ctrl_inband_flush_data(nvswitch_device *device, NVSWITCH_INBAND_FLUSH_DATA_PARAMS *p);
#define NVSWITCH_DEV_CMD_CHECK_ADMIN NVBIT64(0)
#define NVSWITCH_DEV_CMD_CHECK_FM NVBIT64(1)
@@ -297,6 +300,14 @@ _nvswitch_corelib_write_discovery_token
NvU64 token
)
{
nvswitch_device *device = link->dev->pDevInfo;
if (link->version >= NVLINK_DEVICE_VERSION_40)
{
nvswitch_store_topology_information(device, link);
return NVL_SUCCESS;
}
return NVL_SUCCESS;
}
@@ -307,7 +318,7 @@ _nvswitch_corelib_ali_training
)
{
nvswitch_device *device = link->dev->pDevInfo;
return device->hal.nvswitch_launch_ALI_link_training(device, link);
return device->hal.nvswitch_launch_ALI_link_training(device, link, NV_FALSE);
}
void
@@ -379,11 +390,15 @@ _nvswitch_init_device_regkeys
NVSWITCH_INIT_REGKEY(_PUBLIC, crc_bit_error_rate_short,
NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT,
NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_OFF);
NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_DEFAULT);
NVSWITCH_INIT_REGKEY(_PUBLIC, crc_bit_error_rate_long,
NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG,
NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_OFF);
NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_DEFAULT);
NVSWITCH_INIT_REGKEY(_PUBLIC, surpress_link_errors_for_gpu_reset,
NV_SWITCH_REGKEY_SURPRESS_LINK_ERRORS_FOR_GPU_RESET,
NV_SWITCH_REGKEY_SURPRESS_LINK_ERRORS_FOR_GPU_RESET_DISABLE);
//
// Debug use regkeys
@@ -505,9 +520,21 @@ _nvswitch_init_device_regkeys
NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL,
NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL_DEFAULT);
NVSWITCH_INIT_REGKEY(_PRIVATE, force_kernel_i2c,
NV_SWITCH_REGKEY_FORCE_KERNEL_I2C,
NV_SWITCH_REGKEY_FORCE_KERNEL_I2C_DEFAULT);
NVSWITCH_INIT_REGKEY(_PRIVATE, link_recal_settings,
NV_SWITCH_REGKEY_LINK_RECAL_SETTINGS,
NV_SWITCH_REGKEY_LINK_RECAL_SETTINGS_NOP);
NVSWITCH_INIT_REGKEY(_PRIVATE, lp_threshold,
NV_SWITCH_REGKEY_SET_LP_THRESHOLD,
NV_SWITCH_REGKEY_SET_LP_THRESHOLD_DEFAULT);
NVSWITCH_INIT_REGKEY(_PUBLIC, minion_intr,
NV_SWITCH_REGKEY_MINION_INTERRUPTS,
NV_SWITCH_REGKEY_MINION_INTERRUPTS_DEFAULT);
}
NvU64
nvswitch_lib_deferred_task_dispatcher
@@ -518,12 +545,14 @@ nvswitch_lib_deferred_task_dispatcher
NvU64 time_nsec;
NvU64 time_next_nsec = nvswitch_os_get_platform_time() + 100*NVSWITCH_INTERVAL_1MSEC_IN_NS;
NVSWITCH_TASK_TYPE *task;
NVSWITCH_TASK_TYPE *prev_task;
if (!NVSWITCH_IS_DEVICE_VALID(device))
{
return NV_U64_MAX;
}
prev_task = NULL;
task = device->tasks;
// Walk the task list, executing those whose next execution interval is at hand
@@ -541,13 +570,50 @@ nvswitch_lib_deferred_task_dispatcher
task->last_run_nsec = time_nsec;
// Run the task
if (NVSWITCH_IS_DEVICE_INITIALIZED(device) ||
(task->flags & NVSWITCH_TASK_TYPE_FLAGS_ALWAYS_RUN))
(*task->task_fn)(device);
(task->flags & NVSWITCH_TASK_TYPE_FLAGS_RUN_EVEN_IF_DEVICE_NOT_INITIALIZED))
{
if(task->flags & NVSWITCH_TASK_TYPE_FLAGS_VOID_PTR_ARGS)
(*task->task_fn_vdptr)(device, task->task_args); // run task with provided args
else
(*task->task_fn_devptr)(device);
}
}
// Determine its next run time
time_next_nsec = NV_MIN(task->last_run_nsec + task->period_nsec, time_next_nsec);
task = task->next;
// Advance pointer. If run once flag is set and task ran, remove task from list.
if((task->flags & NVSWITCH_TASK_TYPE_FLAGS_RUN_ONCE) &&
(task->last_run_nsec == time_nsec))
{
prev_task = task->prev;
// Removing from list head
if (prev_task == NULL)
{
device->tasks = task->next;
if (device->tasks != NULL)
{
device->tasks->prev = NULL;
}
nvswitch_os_free(task);
task = device->tasks;
}
else
{
prev_task->next = task->next;
if (prev_task->next != NULL)
{
prev_task->next->prev = prev_task;
}
nvswitch_os_free(task);
task = prev_task->next;
}
}
else
{
task = task->next;
}
}
time_nsec = nvswitch_os_get_platform_time();
@@ -568,6 +634,11 @@ _nvswitch_setup_hal
nvswitch_setup_hal_lr10(device);
return NVL_SUCCESS;
}
if (nvswitch_is_ls10_device_id(pci_device_id))
{
nvswitch_setup_hal_ls10(device);
return NVL_SUCCESS;
}
NVSWITCH_PRINT(device, ERROR,
"NVSwitch HAL setup failed - Unrecognized PCI Device ID\n");
return -NVL_ERR_NOT_SUPPORTED;
@@ -648,6 +719,7 @@ nvswitch_is_soe_supported
return device->hal.nvswitch_is_soe_supported(device);
}
NvlStatus
nvswitch_init_soe
(
@@ -744,12 +816,12 @@ _nvswitch_post_init_device_setup
}
static NvlStatus
_nvswitch_setup_link_system_registers
_nvswitch_setup_system_registers
(
nvswitch_device *device
)
{
return device->hal.nvswitch_setup_link_system_registers(device);
return device->hal.nvswitch_setup_system_registers(device);
}
static void
@@ -932,14 +1004,27 @@ nvswitch_ctrl_set_fm_driver_state(
NVSWITCH_SET_FM_DRIVER_STATE_PARAMS *p
)
{
NvU32 prev_fm_status;
if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
{
return -NVL_BAD_ARGS;
}
prev_fm_status = device->driver_fabric_state;
device->driver_fabric_state = p->driverState;
device->fabric_state_timestamp = nvswitch_os_get_platform_time();
if (prev_fm_status != p->driverState)
{
if (nvswitch_lib_notify_client_events(device,
NVSWITCH_DEVICE_EVENT_FABRIC_STATE) != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "%s: Failed to notify event\n",
__FUNCTION__);
}
}
return NVL_SUCCESS;
}
@@ -1069,12 +1154,100 @@ _nvswitch_ctrl_unregister_events(
return NVL_SUCCESS;
}
/*
* @Brief : Sends NACK or drops given inband msg based on message type
*
* @Description :
*
* @param[in] device NvSwitch device to contain this link
* @param[in] linkId Link ID
* @param[in] msghdr Header to the message
*
*/
static void
nvswitch_send_nack_or_drop
(
nvswitch_device *device,
NvU32 linkId,
nvlink_inband_msg_header_t *msghdr
)
{
switch(msghdr->type)
{
case NVLINK_INBAND_MSG_TYPE_MC_TEAM_SETUP_REQ:
device->hal.nvswitch_send_inband_nack(device, (NvU32 *)msghdr, linkId);
NVSWITCH_PRINT(device, ERROR,
"Sending NACK for message (type 0x%x)\n", msghdr->type);
return;
default:
// TODO: Add SXid in future if needed.
NVSWITCH_PRINT(device, ERROR,
"Dropping message (type 0x%x)\n", msghdr->type);
return;
}
}
/*
* @Brief : Deletes all the entries in persistent or non-persistent lists.
* Send nacks if requested.
*
* @Description :
*
* @param[in] device NVSwitch device to contain this link
* @param[in] linkId Link number
* @param[in] bSendNack Send nacks if true
* @param[in] bNonPersistentOnly Clear only non-persistent list
*/
static void
_nvswitch_inband_clear_lists
(
nvswitch_device *device,
NvU32 linkId,
NvBool bSendNack,
NvBool bNonPersistentOnly
)
{
nvswitch_inband_data_list *curr = NULL;
nvswitch_inband_data_list *next = NULL;
nvlink_inband_msg_header_t *msghdr = NULL;
nvListForEachEntry_safe(curr, next,
&device->link[linkId].inbandData.nonpersistent_list, entry)
{
if (bSendNack)
{
msghdr = (nvlink_inband_msg_header_t *)curr->data;
nvswitch_send_nack_or_drop(device, linkId, msghdr);
}
nvListDel(&curr->entry);
nvswitch_os_free(curr);
}
if (bNonPersistentOnly)
return;
nvListForEachEntry_safe(curr, next,
&device->link[linkId].inbandData.persistent_list, entry)
{
if (bSendNack)
{
msghdr = (nvlink_inband_msg_header_t *)curr->data;
nvswitch_send_nack_or_drop(device, linkId, msghdr);
}
nvListDel(&curr->entry);
nvswitch_os_free(curr);
}
}
static void
nvswitch_fabric_state_heartbeat(
nvswitch_device *device
)
{
NvU64 age;
NvU32 linkId;
if (!NVSWITCH_IS_DEVICE_VALID(device))
return;
@@ -1086,6 +1259,18 @@ nvswitch_fabric_state_heartbeat(
age > (NvU64)device->fm_timeout * 1000ULL * 1000ULL)
device->driver_fabric_state = NVSWITCH_DRIVER_FABRIC_STATE_MANAGER_TIMEOUT;
//
// If FM is not running, clear pending non-persistent messages. Persistent
// messages can be processed by the FM when it restarts.
//
if (device->driver_fabric_state != NVSWITCH_DRIVER_FABRIC_STATE_CONFIGURED)
{
for (linkId = 0; linkId < nvswitch_get_num_links(device); linkId++)
_nvswitch_inband_clear_lists(device, linkId,
NV_TRUE /* Nack */,
NV_TRUE /* Non-persistent only */);
}
(void)device->hal.nvswitch_write_fabric_state(device);
}
@@ -1240,8 +1425,12 @@ nvswitch_lib_initialize_device
nvswitch_task_create(device, &nvswitch_fabric_state_heartbeat,
NVSWITCH_HEARTBEAT_INTERVAL_NS,
NVSWITCH_TASK_TYPE_FLAGS_ALWAYS_RUN);
NVSWITCH_TASK_TYPE_FLAGS_RUN_EVEN_IF_DEVICE_NOT_INITIALIZED);
//
// Blacklisted devices return successfully in order to preserve the fabric state heartbeat
// and ensure OOB utilities don't think the driver has died
//
if (device->device_blacklist_reason == NVSWITCH_DEVICE_BLACKLIST_REASON_MANUAL_OUT_OF_BAND)
{
NVSWITCH_PRINT(device, SETUP,
@@ -1250,13 +1439,13 @@ nvswitch_lib_initialize_device
device->nvlink_device->pciInfo.bus,
device->nvlink_device->pciInfo.device,
device->nvlink_device->pciInfo.function);
return retval;
return NVL_SUCCESS;
}
if (is_blacklisted_by_os)
{
(void)nvswitch_lib_blacklist_device(device, NVSWITCH_DEVICE_BLACKLIST_REASON_MANUAL_IN_BAND);
return retval;
return NVL_SUCCESS;
}
for (link_num=0; link_num < nvswitch_get_num_links(device); link_num++)
@@ -1365,6 +1554,7 @@ nvswitch_initialize_inforom_fail:
nvswitch_initialize_device_state_fail:
_nvswitch_destruct_soe(device);
nvswitch_tasks_destroy(device);
return retval;
}
@@ -1426,7 +1616,7 @@ nvswitch_lib_post_init_device
__FUNCTION__);
}
retval = _nvswitch_setup_link_system_registers(device);
retval = _nvswitch_setup_system_registers(device);
if (retval != NVL_SUCCESS)
{
return retval;
@@ -1448,9 +1638,44 @@ nvswitch_lib_post_init_blacklist_device
_nvswitch_post_init_blacklist_device_setup(device);
}
void
_nvswitch_check_pending_data_and_notify
(
nvswitch_device *device,
NVSWITCH_CLIENT_EVENT *event
)
{
switch (event->eventId)
{
case NVSWITCH_DEVICE_EVENT_INBAND_DATA:
{
NvU32 i;
for (i = 0; i < nvswitch_get_num_links(device); i++)
{
if (!nvListIsEmpty(&device->link[i].inbandData.persistent_list) ||
!nvListIsEmpty(&device->link[i].inbandData.nonpersistent_list))
{
(void)nvswitch_os_notify_client_event(device->os_handle,
event->private_driver_data,
event->eventId);
}
}
break;
}
default:
return;
}
}
/*!
* @brief: Gets the client event associated with the file descriptor
* if it already exists in the Device's client event list.
*
* If found, and if there is pending data for the event,
* the event is triggered before returning to unblock the
* client right away.
*/
NvlStatus
nvswitch_lib_get_client_event
@@ -1474,6 +1699,7 @@ nvswitch_lib_get_client_event
if (curr->private_driver_data == osPrivate)
{
*ppClientEvent = curr;
_nvswitch_check_pending_data_and_notify(device, curr);
return NVL_SUCCESS;
}
}
@@ -1654,6 +1880,7 @@ nvswitch_lib_shutdown_device
nvswitch_device *device
)
{
NVSWITCH_INBAND_FLUSH_DATA_PARAMS p;
if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
{
@@ -1670,6 +1897,10 @@ nvswitch_lib_shutdown_device
nvswitch_hw_counter_shutdown(device);
// FLUSH any pending messages to avoid memory leaks
p.linkMask = nvswitch_get_enabled_link_mask(device);
_nvswitch_ctrl_inband_flush_data(device, &p);
_nvswitch_unregister_links(device);
nvswitch_destroy_error_log(device, &device->log_FATAL_ERRORS);
@@ -1760,7 +1991,11 @@ nvswitch_lib_get_bios_version
return -NVL_BAD_ARGS;
ret = device->hal.nvswitch_ctrl_get_bios_info(device, &p);
if (version != NULL)
{
*version = p.version;
}
return ret;
}
@@ -2250,7 +2485,7 @@ nvswitch_timeout_check
return (time->timeout_ns <= time_current);
}
void
NvlStatus
nvswitch_task_create
(
nvswitch_device *device,
@@ -2259,23 +2494,74 @@ nvswitch_task_create
NvU32 flags
)
{
NVSWITCH_TASK_TYPE *task = nvswitch_os_malloc(sizeof(*task));
NVSWITCH_TASK_TYPE *task;
task = nvswitch_os_malloc(sizeof(NVSWITCH_TASK_TYPE));
if (task == NULL)
{
NVSWITCH_PRINT(device, ERROR,
"%s: Unable to allocate task.\n",
__FUNCTION__);
return -NVL_NO_MEM;
}
else
{
task->task_fn = task_fn;
task->task_fn_devptr = task_fn;
task->task_args = NULL;
task->period_nsec = period_nsec;
task->last_run_nsec = 0;
task->last_run_nsec = nvswitch_os_get_platform_time(); // Prevent deferred tasks from being run immediately
task->flags = flags;
task->prev = NULL;
task->next = device->tasks;
if (device->tasks != NULL)
{
device->tasks->prev = task;
}
device->tasks = task;
}
return NVL_SUCCESS;
}
NvlStatus
nvswitch_task_create_args
(
nvswitch_device *device,
void *fn_args,
void (*task_fn)(nvswitch_device* device, void *fn_args),
NvU64 period_nsec,
NvU32 flags
)
{
NVSWITCH_TASK_TYPE *task;
task = nvswitch_os_malloc(sizeof(NVSWITCH_TASK_TYPE));
flags = flags | NVSWITCH_TASK_TYPE_FLAGS_VOID_PTR_ARGS; // ensure dispatcher always executes tasks passed through this function with args
if (task == NULL)
{
NVSWITCH_PRINT(device, ERROR,
"%s: Unable to allocate task.\n",
__FUNCTION__);
return -NVL_NO_MEM;
}
else
{
task->task_fn_vdptr = task_fn;
task->task_args = fn_args;
task->period_nsec = period_nsec;
task->last_run_nsec = nvswitch_os_get_platform_time(); // Prevent deferred tasks from being run immediately
task->flags = flags;
task->prev = NULL;
task->next = device->tasks;
if (device->tasks != NULL)
{
device->tasks->prev = task;
}
device->tasks = task;
}
return NVL_SUCCESS;
}
void
@@ -2544,7 +2830,7 @@ _nvswitch_ctrl_get_nvlipt_counters
//
// This control call is now deprecated.
// New control call to fetch throughput counters is:
// _nvswitch_ctrl_get_throughput_counters
// nvswitch_ctrl_get_throughput_counters
//
return -NVL_ERR_NOT_SUPPORTED;
}
@@ -2559,7 +2845,7 @@ _nvswitch_ctrl_set_nvlipt_counter_config
//
// This control call is now deprecated.
// New control call to fetch throughput counters is:
// _nvswitch_ctrl_get_throughput_counters_lr10
// nvswitch_ctrl_get_throughput_counters_lr10
//
// Setting counter config is not allowed on these
// non-configurable counters. These counters are
@@ -2578,7 +2864,7 @@ _nvswitch_ctrl_get_nvlipt_counter_config
//
// This control call is now deprecated.
// New control call to fetch throughput counters is:
// _nvswitch_ctrl_get_throughput_counters_lr10
// nvswitch_ctrl_get_throughput_counters_lr10
//
// Getting counter config is useful if counters are
// configurable. These counters are not configurable
@@ -2587,6 +2873,26 @@ _nvswitch_ctrl_get_nvlipt_counter_config
return -NVL_ERR_NOT_SUPPORTED;
}
static NvlStatus
_nvswitch_ctrl_register_read
(
nvswitch_device *device,
NVSWITCH_REGISTER_READ *p
)
{
return device->hal.nvswitch_ctrl_register_read(device, p);
}
static NvlStatus
_nvswitch_ctrl_register_write
(
nvswitch_device *device,
NVSWITCH_REGISTER_WRITE *p
)
{
return device->hal.nvswitch_ctrl_register_write(device, p);
}
NvU32
nvswitch_i2c_get_port_info
(
@@ -2627,6 +2933,16 @@ _nvswitch_ctrl_get_bios_info
return device->hal.nvswitch_ctrl_get_bios_info(device, p);
}
static NvlStatus
_nvswitch_ctrl_get_inforom_version
(
nvswitch_device *device,
NVSWITCH_GET_INFOROM_VERSION_PARAMS *p
)
{
return device->hal.nvswitch_ctrl_get_inforom_version(device, p);
}
NvlStatus
nvswitch_ctrl_set_latency_bins
(
@@ -2647,8 +2963,8 @@ _nvswitch_ctrl_get_ingress_reqlinkid
return device->hal.nvswitch_ctrl_get_ingress_reqlinkid(device, params);
}
static NvlStatus
_nvswitch_ctrl_get_throughput_counters
NvlStatus
nvswitch_ctrl_get_throughput_counters
(
nvswitch_device *device,
NVSWITCH_GET_THROUGHPUT_COUNTERS_PARAMS *p
@@ -2724,6 +3040,26 @@ _nvswitch_ctrl_get_nvlink_ecc_errors
return device->hal.nvswitch_get_nvlink_ecc_errors(device, params);
}
static NvlStatus
_nvswitch_ctrl_set_mc_rid_table
(
nvswitch_device *device,
NVSWITCH_SET_MC_RID_TABLE_PARAMS *p
)
{
return device->hal.nvswitch_ctrl_set_mc_rid_table(device, p);
}
static NvlStatus
_nvswitch_ctrl_get_mc_rid_table
(
nvswitch_device *device,
NVSWITCH_GET_MC_RID_TABLE_PARAMS *p
)
{
return device->hal.nvswitch_ctrl_get_mc_rid_table(device, p);
}
static NvlStatus
_nvswitch_ctrl_set_residency_bins
(
@@ -2794,38 +3130,6 @@ _nvswitch_ctrl_inband_read_data
return device->hal.nvswitch_ctrl_inband_read_data(device, p);
}
/*
* @Brief : Deletes all the entires in persistant or nonpersistant list
*
* @Description :
*
* @param[in] device NvSwitch device to contain this link
* @param[in] linkId link number of the link
*
*/
static void
_nvswitch_inband_clear_list
(
nvswitch_device *device,
NvU32 linkId
)
{
nvswitch_inband_data_list *curr = NULL;
nvswitch_inband_data_list *next = NULL;
nvListForEachEntry_safe(curr, next, &device->link[linkId].inbandData.persistent_list, entry)
{
nvListDel(&curr->entry);
nvswitch_os_free(curr);
}
nvListForEachEntry_safe(curr, next, &device->link[linkId].inbandData.nonpersistent_list, entry)
{
nvListDel(&curr->entry);
nvswitch_os_free(curr);
}
}
static NvlStatus
_nvswitch_ctrl_inband_flush_data
(
@@ -2847,9 +3151,16 @@ _nvswitch_ctrl_inband_flush_data
FOR_EACH_INDEX_IN_MASK(64, i, p->linkMask)
{
if (nvswitch_is_link_valid(device, i) &&
(enabledLinkMask & NVBIT(i)))
(enabledLinkMask & NVBIT64(i)))
{
_nvswitch_inband_clear_list(device, i);
//
// Flush is expected to clear both persistent and non-persistent
// list. FM does flush when it wants to drop (ignore) all pending
// messages w/o any NACKs.
//
_nvswitch_inband_clear_lists(device, i,
NV_FALSE /* Nack */,
NV_FALSE /* Non-persistent only */);
}
}
FOR_EACH_INDEX_IN_MASK_END;
@@ -2872,16 +3183,16 @@ _nvswitch_ctrl_inband_pending_data_stats
for (link_num = 0; link_num < nvswitch_get_num_links(device); link_num++)
{
if (nvswitch_is_link_valid(device, link_num) &&
(enabledLinkMask & NVBIT(link_num)))
(enabledLinkMask & NVBIT64(link_num)))
{
if (!nvListIsEmpty(&device->link[link_num].inbandData.persistent_list))
{
persistent_mask |= NVBIT(link_num);
persistent_mask |= NVBIT64(link_num);
}
if (!nvListIsEmpty(&device->link[link_num].inbandData.nonpersistent_list))
{
nonpersistent_mask |= NVBIT(link_num);
nonpersistent_mask |= NVBIT64(link_num);
}
}
}
@@ -3100,6 +3411,8 @@ nvswitch_inband_read_data
if (nvListIsEmpty(&device->link[linkId].inbandData.persistent_list) &&
nvListIsEmpty(&device->link[linkId].inbandData.nonpersistent_list))
{
NVSWITCH_PRINT(device, ERROR, "%s: LinkId %d doesnt have any data to send\n",
__FUNCTION__, linkId);
*dataSize = 0;
return -NVL_NOT_FOUND;
}
@@ -3120,6 +3433,34 @@ nvswitch_inband_read_data
return NVL_SUCCESS;
}
/*
* @Brief : Returns NV_TRUE if the given inband msg
* needs to go to persistant list
*
* @Description :
*
* @param[in] device NvSwitch device to contain this link
* @param[in] msghdr Header to the message
*
*/
static NvBool
nvswitch_is_message_persistent
(
nvswitch_device *device,
nvlink_inband_msg_header_t *msghdr
)
{
// We expect only one message per received data
switch(msghdr->type)
{
case NVLINK_INBAND_MSG_TYPE_MC_TEAM_RELEASE_REQ:
return NV_TRUE;
default:
return NV_FALSE;
}
}
/*
* @Brief : Moves the data into persistant or nonpersistant list
*
@@ -3136,6 +3477,60 @@ nvswitch_filter_messages
NvU32 linkId
)
{
NvlStatus status;
nvlink_inband_msg_header_t *msghdr = NULL;
nvswitch_inband_data_list *msg = device->link[linkId].inbandData.message;
NvU8 *buffer = device->link[linkId].inbandData.message->data;
NVSWITCH_DRIVER_FABRIC_STATE driver_fabric_state = 0;
NvBool bSendNackOrDrop = NV_FALSE;
NVSWITCH_ASSERT(nvswitch_lib_read_fabric_state(device, NULL, NULL,
&driver_fabric_state) == NVL_SUCCESS);
msghdr = (nvlink_inband_msg_header_t*)buffer;
if (nvswitch_is_message_persistent(device, msghdr))
{
if (nvListCount(&device->link[linkId].inbandData.persistent_list) <
device->hal.nvswitch_get_max_persistent_message_count(device))
{
nvListAdd(&msg->entry, &device->link[linkId].inbandData.persistent_list);
}
else
{
bSendNackOrDrop = NV_TRUE;
}
}
else
{
if (driver_fabric_state == NVSWITCH_DRIVER_FABRIC_STATE_CONFIGURED)
{
nvListAdd(&msg->entry,
&device->link[linkId].inbandData.nonpersistent_list);
}
else
{
bSendNackOrDrop = NV_TRUE;
}
}
if (bSendNackOrDrop)
{
nvswitch_send_nack_or_drop(device, linkId, msghdr);
nvswitch_os_free(msg);
}
else
{
status = nvswitch_lib_notify_client_events(device,
NVSWITCH_DEVICE_EVENT_INBAND_DATA);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "%s: Failed to notify INBAND_DATA event\n",
__FUNCTION__);
}
}
device->link[linkId].inbandData.message = NULL;
}
/*
@@ -3769,7 +4164,7 @@ nvswitch_lib_smbpbi_log_sxid
{
va_list arglist;
int msglen;
char string[80];
char string[RM_SOE_SMBPBI_CMD_LOG_MESSAGE_MAX_STRING];
va_start(arglist, pFormat);
msglen = nvswitch_os_vsnprintf(string, sizeof(string), pFormat, arglist);
@@ -3778,7 +4173,7 @@ nvswitch_lib_smbpbi_log_sxid
if (!(msglen < 0))
{
msglen = NV_MIN(msglen + 1, (int) sizeof(string));
nvswitch_smbpbi_log_message(device, sxid, msglen, (NvU8 *) string);
device->hal.nvswitch_smbpbi_log_message(device, sxid, msglen, (NvU8 *) string);
}
}
@@ -4191,10 +4586,51 @@ NvlStatus
nvswitch_launch_ALI_link_training
(
nvswitch_device *device,
nvlink_link *link,
NvBool bSync
)
{
return device->hal.nvswitch_launch_ALI_link_training(device, link, bSync);
}
static NvlStatus
_nvswitch_ctrl_get_err_info
(
nvswitch_device *device,
NVSWITCH_NVLINK_GET_ERR_INFO_PARAMS *ret
)
{
return device->hal.nvswitch_ctrl_get_err_info(device, ret);
}
static NvlStatus
_nvswitch_ctrl_clear_counters
(
nvswitch_device *device,
NVSWITCH_NVLINK_CLEAR_COUNTERS_PARAMS *ret
)
{
return device->hal.nvswitch_ctrl_clear_counters(device, ret);
}
void
nvswitch_setup_link_system_registers
(
nvswitch_device *device,
nvlink_link *link
)
{
return device->hal.nvswitch_launch_ALI_link_training(device, link);
device->hal.nvswitch_setup_link_system_registers(device, link);
}
void
nvswitch_load_link_disable_settings
(
nvswitch_device *device,
nvlink_link *link
)
{
device->hal.nvswitch_load_link_disable_settings(device, link);
}
NvlStatus
@@ -4242,7 +4678,7 @@ nvswitch_lib_ctrl
_nvswitch_ctrl_therm_read_temperature,
NVSWITCH_CTRL_GET_TEMPERATURE_PARAMS);
NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_THROUGHPUT_COUNTERS,
_nvswitch_ctrl_get_throughput_counters,
nvswitch_ctrl_get_throughput_counters,
NVSWITCH_GET_THROUGHPUT_COUNTERS_PARAMS);
NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_FATAL_ERROR_SCOPE,
_nvswitch_ctrl_get_fatal_error_scope,
@@ -4351,6 +4787,9 @@ nvswitch_lib_ctrl
NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_BIOS_INFO,
_nvswitch_ctrl_get_bios_info,
NVSWITCH_GET_BIOS_INFO_PARAMS);
NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_INFOROM_VERSION,
_nvswitch_ctrl_get_inforom_version,
NVSWITCH_GET_INFOROM_VERSION_PARAMS);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
CTRL_NVSWITCH_BLACKLIST_DEVICE,
nvswitch_ctrl_blacklist_device,
@@ -4386,6 +4825,16 @@ nvswitch_lib_ctrl
_nvswitch_ctrl_set_training_error_info,
NVSWITCH_SET_TRAINING_ERROR_INFO_PARAMS,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
CTRL_NVSWITCH_SET_MC_RID_TABLE,
_nvswitch_ctrl_set_mc_rid_table,
NVSWITCH_SET_MC_RID_TABLE_PARAMS,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
CTRL_NVSWITCH_GET_MC_RID_TABLE,
_nvswitch_ctrl_get_mc_rid_table,
NVSWITCH_GET_MC_RID_TABLE_PARAMS,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
CTRL_NVSWITCH_GET_COUNTERS,
_nvswitch_ctrl_get_counters,
@@ -4413,6 +4862,12 @@ nvswitch_lib_ctrl
CTRL_NVSWITCH_RESERVED_4);
NVSWITCH_DEV_CMD_DISPATCH_RESERVED(
CTRL_NVSWITCH_RESERVED_5);
NVSWITCH_DEV_CMD_DISPATCH_RESERVED(
CTRL_NVSWITCH_RESERVED_8);
NVSWITCH_DEV_CMD_DISPATCH_RESERVED(
CTRL_NVSWITCH_RESERVED_9);
NVSWITCH_DEV_CMD_DISPATCH_RESERVED(
CTRL_NVSWITCH_RESERVED_10);
NVSWITCH_DEV_CMD_DISPATCH(
CTRL_NVSWITCH_GET_TEMPERATURE_LIMIT,
_nvswitch_ctrl_therm_get_temperature_limit,
@@ -4488,6 +4943,23 @@ nvswitch_lib_ctrl
_nvswitch_ctrl_get_sw_info,
NVSWITCH_GET_SW_INFO_PARAMS,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_REGISTER_READ,
_nvswitch_ctrl_register_read,
NVSWITCH_REGISTER_READ,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_REGISTER_WRITE,
_nvswitch_ctrl_register_write,
NVSWITCH_REGISTER_WRITE,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_GET_ERR_INFO,
_nvswitch_ctrl_get_err_info,
NVSWITCH_NVLINK_GET_ERR_INFO_PARAMS,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_CLEAR_COUNTERS,
_nvswitch_ctrl_clear_counters,
NVSWITCH_NVLINK_CLEAR_COUNTERS_PARAMS,
osPrivate, flags);
default:
nvswitch_os_print(NVSWITCH_DBG_LEVEL_INFO, "unknown ioctl %x\n", cmd);
retval = -NVL_BAD_ARGS;