1// SPDX-License-Identifier: GPL-2.0 2/* Copyright(c) 2023 Advanced Micro Devices, Inc */ 3 4#include "core.h" 5 6/* The worst case wait for the install activity is about 25 minutes when 7 * installing a new CPLD, which is very seldom. Normal is about 30-35 8 * seconds. Since the driver can't tell if a CPLD update will happen we 9 * set the timeout for the ugly case. 10 */ 11#define PDSC_FW_INSTALL_TIMEOUT (25 * 60) 12#define PDSC_FW_SELECT_TIMEOUT 30 13 14/* Number of periodic log updates during fw file download */ 15#define PDSC_FW_INTERVAL_FRACTION 32 16 17static int pdsc_devcmd_fw_download_locked(struct pdsc *pdsc, u64 addr, 18 u32 offset, u32 length) 19{ 20 union pds_core_dev_cmd cmd = { 21 .fw_download.opcode = PDS_CORE_CMD_FW_DOWNLOAD, 22 .fw_download.offset = cpu_to_le32(offset), 23 .fw_download.addr = cpu_to_le64(addr), 24 .fw_download.length = cpu_to_le32(length), 25 }; 26 union pds_core_dev_comp comp; 27 28 return pdsc_devcmd_locked(pdsc, &cmd, &comp, pdsc->devcmd_timeout); 29} 30 31static int pdsc_devcmd_fw_install(struct pdsc *pdsc) 32{ 33 union pds_core_dev_cmd cmd = { 34 .fw_control.opcode = PDS_CORE_CMD_FW_CONTROL, 35 .fw_control.oper = PDS_CORE_FW_INSTALL_ASYNC 36 }; 37 union pds_core_dev_comp comp; 38 int err; 39 40 err = pdsc_devcmd(pdsc, &cmd, &comp, pdsc->devcmd_timeout); 41 if (err < 0) 42 return err; 43 44 return comp.fw_control.slot; 45} 46 47static int pdsc_devcmd_fw_activate(struct pdsc *pdsc, 48 enum pds_core_fw_slot slot) 49{ 50 union pds_core_dev_cmd cmd = { 51 .fw_control.opcode = PDS_CORE_CMD_FW_CONTROL, 52 .fw_control.oper = PDS_CORE_FW_ACTIVATE_ASYNC, 53 .fw_control.slot = slot 54 }; 55 union pds_core_dev_comp comp; 56 57 return pdsc_devcmd(pdsc, &cmd, &comp, pdsc->devcmd_timeout); 58} 59 60static int pdsc_fw_status_long_wait(struct pdsc *pdsc, 61 const char *label, 62 unsigned long timeout, 63 u8 fw_cmd, 64 struct netlink_ext_ack *extack) 65{ 66 union pds_core_dev_cmd cmd = { 67 .fw_control.opcode = PDS_CORE_CMD_FW_CONTROL, 68 .fw_control.oper = fw_cmd, 69 }; 70 union pds_core_dev_comp comp; 71 unsigned long start_time; 72 unsigned long end_time; 73 int err; 74 75 /* Ping on the status of the long running async install 76 * command. We get EAGAIN while the command is still 77 * running, else we get the final command status. 78 */ 79 start_time = jiffies; 80 end_time = start_time + (timeout * HZ); 81 do { 82 err = pdsc_devcmd(pdsc, &cmd, &comp, pdsc->devcmd_timeout); 83 msleep(20); 84 } while (time_before(jiffies, end_time) && 85 (err == -EAGAIN || err == -ETIMEDOUT)); 86 87 if (err == -EAGAIN || err == -ETIMEDOUT) { 88 NL_SET_ERR_MSG_MOD(extack, "Firmware wait timed out"); 89 dev_err(pdsc->dev, "DEV_CMD firmware wait %s timed out\n", 90 label); 91 } else if (err) { 92 NL_SET_ERR_MSG_MOD(extack, "Firmware wait failed"); 93 } 94 95 return err; 96} 97 98int pdsc_firmware_update(struct pdsc *pdsc, const struct firmware *fw, 99 struct netlink_ext_ack *extack) 100{ 101 u32 buf_sz, copy_sz, offset; 102 struct devlink *dl; 103 int next_interval; 104 u64 data_addr; 105 int err = 0; 106 int fw_slot; 107 108 dev_info(pdsc->dev, "Installing firmware\n"); 109 110 if (!pdsc->cmd_regs) 111 return -ENXIO; 112 113 dl = priv_to_devlink(pdsc); 114 devlink_flash_update_status_notify(dl, "Preparing to flash", 115 NULL, 0, 0); 116 117 buf_sz = sizeof(pdsc->cmd_regs->data); 118 119 dev_dbg(pdsc->dev, 120 "downloading firmware - size %d part_sz %d nparts %lu\n", 121 (int)fw->size, buf_sz, DIV_ROUND_UP(fw->size, buf_sz)); 122 123 offset = 0; 124 next_interval = 0; 125 data_addr = offsetof(struct pds_core_dev_cmd_regs, data); 126 while (offset < fw->size) { 127 if (offset >= next_interval) { 128 devlink_flash_update_status_notify(dl, "Downloading", 129 NULL, offset, 130 fw->size); 131 next_interval = offset + 132 (fw->size / PDSC_FW_INTERVAL_FRACTION); 133 } 134 135 copy_sz = min_t(unsigned int, buf_sz, fw->size - offset); 136 mutex_lock(&pdsc->devcmd_lock); 137 memcpy_toio(&pdsc->cmd_regs->data, fw->data + offset, copy_sz); 138 err = pdsc_devcmd_fw_download_locked(pdsc, data_addr, 139 offset, copy_sz); 140 mutex_unlock(&pdsc->devcmd_lock); 141 if (err) { 142 dev_err(pdsc->dev, 143 "download failed offset 0x%x addr 0x%llx len 0x%x: %pe\n", 144 offset, data_addr, copy_sz, ERR_PTR(err)); 145 NL_SET_ERR_MSG_MOD(extack, "Segment download failed"); 146 goto err_out; 147 } 148 offset += copy_sz; 149 } 150 devlink_flash_update_status_notify(dl, "Downloading", NULL, 151 fw->size, fw->size); 152 153 devlink_flash_update_timeout_notify(dl, "Installing", NULL, 154 PDSC_FW_INSTALL_TIMEOUT); 155 156 fw_slot = pdsc_devcmd_fw_install(pdsc); 157 if (fw_slot < 0) { 158 err = fw_slot; 159 dev_err(pdsc->dev, "install failed: %pe\n", ERR_PTR(err)); 160 NL_SET_ERR_MSG_MOD(extack, "Failed to start firmware install"); 161 goto err_out; 162 } 163 164 err = pdsc_fw_status_long_wait(pdsc, "Installing", 165 PDSC_FW_INSTALL_TIMEOUT, 166 PDS_CORE_FW_INSTALL_STATUS, 167 extack); 168 if (err) 169 goto err_out; 170 171 devlink_flash_update_timeout_notify(dl, "Selecting", NULL, 172 PDSC_FW_SELECT_TIMEOUT); 173 174 err = pdsc_devcmd_fw_activate(pdsc, fw_slot); 175 if (err) { 176 NL_SET_ERR_MSG_MOD(extack, "Failed to start firmware select"); 177 goto err_out; 178 } 179 180 err = pdsc_fw_status_long_wait(pdsc, "Selecting", 181 PDSC_FW_SELECT_TIMEOUT, 182 PDS_CORE_FW_ACTIVATE_STATUS, 183 extack); 184 if (err) 185 goto err_out; 186 187 dev_info(pdsc->dev, "Firmware update completed, slot %d\n", fw_slot); 188 189err_out: 190 if (err) 191 devlink_flash_update_status_notify(dl, "Flash failed", 192 NULL, 0, 0); 193 else 194 devlink_flash_update_status_notify(dl, "Flash done", 195 NULL, 0, 0); 196 return err; 197} 198