Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/qat/qat_common/adf_heartbeat.c
Show First 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
adf_get_hb_timer(struct adf_accel_dev *accel_dev, unsigned int *value) | adf_get_hb_timer(struct adf_accel_dev *accel_dev, unsigned int *value) | ||||
{ | { | ||||
struct adf_hw_device_data *hw_data = accel_dev->hw_device; | struct adf_hw_device_data *hw_data = accel_dev->hw_device; | ||||
char timer_str[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 }; | char timer_str[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 }; | ||||
unsigned int timer_val = ADF_CFG_HB_DEFAULT_VALUE; | unsigned int timer_val = ADF_CFG_HB_DEFAULT_VALUE; | ||||
u32 clk_per_sec = 0; | u32 clk_per_sec = 0; | ||||
if (!hw_data->get_ae_clock) | /* HB clock may be different than AE clock */ | ||||
if (hw_data->get_hb_clock) { | |||||
clk_per_sec = (u32)hw_data->get_hb_clock(hw_data); | |||||
} else if (hw_data->get_ae_clock) { | |||||
clk_per_sec = (u32)hw_data->get_ae_clock(hw_data); | |||||
} else { | |||||
return EINVAL; | return EINVAL; | ||||
} | |||||
clk_per_sec = (u32)hw_data->get_ae_clock(hw_data); | |||||
/* Get Heartbeat Timer value from the configuration */ | /* Get Heartbeat Timer value from the configuration */ | ||||
if (!adf_cfg_get_param_value(accel_dev, | if (!adf_cfg_get_param_value(accel_dev, | ||||
ADF_GENERAL_SEC, | ADF_GENERAL_SEC, | ||||
ADF_HEARTBEAT_TIMER, | ADF_HEARTBEAT_TIMER, | ||||
(char *)timer_str)) { | (char *)timer_str)) { | ||||
if (compat_strtouint((char *)timer_str, | if (compat_strtouint((char *)timer_str, | ||||
ADF_CFG_BASE_DEC, | ADF_CFG_BASE_DEC, | ||||
&timer_val)) | &timer_val)) | ||||
Show All 10 Lines | adf_get_hb_timer(struct adf_accel_dev *accel_dev, unsigned int *value) | ||||
/* Convert msec to clocks */ | /* Convert msec to clocks */ | ||||
clk_per_sec = clk_per_sec / 1000; | clk_per_sec = clk_per_sec / 1000; | ||||
*value = timer_val * clk_per_sec; | *value = timer_val * clk_per_sec; | ||||
return 0; | return 0; | ||||
} | } | ||||
struct adf_hb_count { | |||||
u16 ae_thread[ADF_NUM_HB_CNT_PER_AE]; | |||||
}; | |||||
int | int | ||||
adf_get_heartbeat_status(struct adf_accel_dev *accel_dev) | adf_get_heartbeat_status(struct adf_accel_dev *accel_dev) | ||||
{ | { | ||||
struct icp_qat_fw_init_admin_hb_cnt *live_s, *last_s, *curr_s; | |||||
struct adf_hw_device_data *hw_device = accel_dev->hw_device; | struct adf_hw_device_data *hw_device = accel_dev->hw_device; | ||||
struct icp_qat_fw_init_admin_hb_stats *live_s = | |||||
(struct icp_qat_fw_init_admin_hb_stats *) | |||||
accel_dev->admin->virt_hb_addr; | |||||
const size_t max_aes = hw_device->get_num_aes(hw_device); | const size_t max_aes = hw_device->get_num_aes(hw_device); | ||||
const size_t hb_ctrs = hw_device->heartbeat_ctr_num; | |||||
const size_t stats_size = | const size_t stats_size = | ||||
max_aes * sizeof(struct icp_qat_fw_init_admin_hb_stats); | max_aes * hb_ctrs * sizeof(struct icp_qat_fw_init_admin_hb_cnt); | ||||
int ret = 0; | int ret = 0; | ||||
size_t ae, thr; | size_t ae, thr; | ||||
u16 *count_s; | |||||
unsigned long ae_mask = 0; | unsigned long ae_mask = 0; | ||||
int num_threads_per_ae = ADF_NUM_HB_CNT_PER_AE; | |||||
/* | /* | ||||
* Memory layout of Heartbeat | * Memory layout of Heartbeat | ||||
* | * | ||||
* +----------------+----------------+---------+ | * +----------------+----------------+---------+ | ||||
* | Live value | Last value | Count | | * | Live value | Last value | Count | | ||||
* +----------------+----------------+---------+ | * +----------------+----------------+---------+ | ||||
* \_______________/\_______________/\________/ | * \_______________/\_______________/\________/ | ||||
* ^ ^ ^ | * ^ ^ ^ | ||||
* | | | | * | | | | ||||
* | | max_aes * sizeof(adf_hb_count) | * | | max_aes * hb_ctrs * | ||||
* | max_aes * sizeof(icp_qat_fw_init_admin_hb_stats) | * | | sizeof(u16) | ||||
* max_aes * sizeof(icp_qat_fw_init_admin_hb_stats) | * | | | ||||
* | max_aes * hb_ctrs * | |||||
* | sizeof(icp_qat_fw_init_admin_hb_cnt) | |||||
* | | |||||
* max_aes * hb_ctrs * | |||||
* sizeof(icp_qat_fw_init_admin_hb_cnt) | |||||
*/ | */ | ||||
struct icp_qat_fw_init_admin_hb_stats *curr_s; | live_s = (struct icp_qat_fw_init_admin_hb_cnt *) | ||||
struct icp_qat_fw_init_admin_hb_stats *last_s = live_s + max_aes; | accel_dev->admin->virt_hb_addr; | ||||
struct adf_hb_count *count = (struct adf_hb_count *)(last_s + max_aes); | last_s = live_s + (max_aes * hb_ctrs); | ||||
count_s = (u16 *)(last_s + (max_aes * hb_ctrs)); | |||||
curr_s = malloc(stats_size, M_QAT, M_WAITOK | M_ZERO); | curr_s = malloc(stats_size, M_QAT, M_WAITOK | M_ZERO); | ||||
memcpy(curr_s, live_s, stats_size); | memcpy(curr_s, live_s, stats_size); | ||||
ae_mask = hw_device->ae_mask; | ae_mask = hw_device->ae_mask; | ||||
for_each_set_bit(ae, &ae_mask, max_aes) | for_each_set_bit(ae, &ae_mask, max_aes) | ||||
{ | { | ||||
for (thr = 0; thr < num_threads_per_ae; ++thr) { | |||||
struct icp_qat_fw_init_admin_hb_cnt *curr = | struct icp_qat_fw_init_admin_hb_cnt *curr = | ||||
&curr_s[ae].stats[thr]; | curr_s + ae * hb_ctrs; | ||||
struct icp_qat_fw_init_admin_hb_cnt *prev = | struct icp_qat_fw_init_admin_hb_cnt *prev = | ||||
&last_s[ae].stats[thr]; | last_s + ae * hb_ctrs; | ||||
u16 req = curr->req_heartbeat_cnt; | u16 *count = count_s + ae * hb_ctrs; | ||||
u16 resp = curr->resp_heartbeat_cnt; | |||||
u16 last = prev->resp_heartbeat_cnt; | |||||
for (thr = 0; thr < hb_ctrs; ++thr) { | |||||
u16 req = curr[thr].req_heartbeat_cnt; | |||||
u16 resp = curr[thr].resp_heartbeat_cnt; | |||||
u16 last = prev[thr].resp_heartbeat_cnt; | |||||
if ((thr == ADF_AE_ADMIN_THREAD || req != resp) && | if ((thr == ADF_AE_ADMIN_THREAD || req != resp) && | ||||
resp == last) { | resp == last) { | ||||
u16 retry = ++count[ae].ae_thread[thr]; | u16 retry = ++count[thr]; | ||||
if (retry >= ADF_CFG_HB_COUNT_THRESHOLD) | if (retry >= ADF_CFG_HB_COUNT_THRESHOLD) | ||||
ret = EIO; | ret = EIO; | ||||
} else { | } else { | ||||
count[ae].ae_thread[thr] = 0; | count[thr] = 0; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/* Copy current stats for the next iteration */ | /* Copy current stats for the next iteration */ | ||||
memcpy(last_s, curr_s, stats_size); | memcpy(last_s, curr_s, stats_size); | ||||
free(curr_s, M_QAT); | free(curr_s, M_QAT); | ||||
▲ Show 20 Lines • Show All 44 Lines • Show Last 20 Lines |