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 17 static 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 31 static 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 47 static 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 60 static 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 98 int 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 dl = priv_to_devlink(pdsc); 111 devlink_flash_update_status_notify(dl, "Preparing to flash", 112 NULL, 0, 0); 113 114 buf_sz = sizeof(pdsc->cmd_regs->data); 115 116 dev_dbg(pdsc->dev, 117 "downloading firmware - size %d part_sz %d nparts %lu\n", 118 (int)fw->size, buf_sz, DIV_ROUND_UP(fw->size, buf_sz)); 119 120 offset = 0; 121 next_interval = 0; 122 data_addr = offsetof(struct pds_core_dev_cmd_regs, data); 123 while (offset < fw->size) { 124 if (offset >= next_interval) { 125 devlink_flash_update_status_notify(dl, "Downloading", 126 NULL, offset, 127 fw->size); 128 next_interval = offset + 129 (fw->size / PDSC_FW_INTERVAL_FRACTION); 130 } 131 132 copy_sz = min_t(unsigned int, buf_sz, fw->size - offset); 133 mutex_lock(&pdsc->devcmd_lock); 134 memcpy_toio(&pdsc->cmd_regs->data, fw->data + offset, copy_sz); 135 err = pdsc_devcmd_fw_download_locked(pdsc, data_addr, 136 offset, copy_sz); 137 mutex_unlock(&pdsc->devcmd_lock); 138 if (err) { 139 dev_err(pdsc->dev, 140 "download failed offset 0x%x addr 0x%llx len 0x%x: %pe\n", 141 offset, data_addr, copy_sz, ERR_PTR(err)); 142 NL_SET_ERR_MSG_MOD(extack, "Segment download failed"); 143 goto err_out; 144 } 145 offset += copy_sz; 146 } 147 devlink_flash_update_status_notify(dl, "Downloading", NULL, 148 fw->size, fw->size); 149 150 devlink_flash_update_timeout_notify(dl, "Installing", NULL, 151 PDSC_FW_INSTALL_TIMEOUT); 152 153 fw_slot = pdsc_devcmd_fw_install(pdsc); 154 if (fw_slot < 0) { 155 err = fw_slot; 156 dev_err(pdsc->dev, "install failed: %pe\n", ERR_PTR(err)); 157 NL_SET_ERR_MSG_MOD(extack, "Failed to start firmware install"); 158 goto err_out; 159 } 160 161 err = pdsc_fw_status_long_wait(pdsc, "Installing", 162 PDSC_FW_INSTALL_TIMEOUT, 163 PDS_CORE_FW_INSTALL_STATUS, 164 extack); 165 if (err) 166 goto err_out; 167 168 devlink_flash_update_timeout_notify(dl, "Selecting", NULL, 169 PDSC_FW_SELECT_TIMEOUT); 170 171 err = pdsc_devcmd_fw_activate(pdsc, fw_slot); 172 if (err) { 173 NL_SET_ERR_MSG_MOD(extack, "Failed to start firmware select"); 174 goto err_out; 175 } 176 177 err = pdsc_fw_status_long_wait(pdsc, "Selecting", 178 PDSC_FW_SELECT_TIMEOUT, 179 PDS_CORE_FW_ACTIVATE_STATUS, 180 extack); 181 if (err) 182 goto err_out; 183 184 dev_info(pdsc->dev, "Firmware update completed, slot %d\n", fw_slot); 185 186 err_out: 187 if (err) 188 devlink_flash_update_status_notify(dl, "Flash failed", 189 NULL, 0, 0); 190 else 191 devlink_flash_update_status_notify(dl, "Flash done", 192 NULL, 0, 0); 193 return err; 194 } 195