1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) Meta Platforms, Inc. and affiliates. */ 3 4 #include <linux/unaligned.h> 5 #include <linux/pci.h> 6 #include <linux/pldmfw.h> 7 #include <linux/types.h> 8 #include <net/devlink.h> 9 10 #include "fbnic.h" 11 #include "fbnic_tlv.h" 12 13 #define FBNIC_SN_STR_LEN 24 14 15 static int fbnic_version_running_put(struct devlink_info_req *req, 16 struct fbnic_fw_ver *fw_ver, 17 char *ver_name) 18 { 19 char running_ver[FBNIC_FW_VER_MAX_SIZE]; 20 int err; 21 22 fbnic_mk_fw_ver_str(fw_ver->version, running_ver); 23 err = devlink_info_version_running_put(req, ver_name, running_ver); 24 if (err) 25 return err; 26 27 if (strlen(fw_ver->commit) > 0) { 28 char commit_name[FBNIC_SN_STR_LEN]; 29 30 snprintf(commit_name, FBNIC_SN_STR_LEN, "%s.commit", ver_name); 31 err = devlink_info_version_running_put(req, commit_name, 32 fw_ver->commit); 33 if (err) 34 return err; 35 } 36 37 return 0; 38 } 39 40 static int fbnic_version_stored_put(struct devlink_info_req *req, 41 struct fbnic_fw_ver *fw_ver, 42 char *ver_name) 43 { 44 char stored_ver[FBNIC_FW_VER_MAX_SIZE]; 45 int err; 46 47 fbnic_mk_fw_ver_str(fw_ver->version, stored_ver); 48 err = devlink_info_version_stored_put(req, ver_name, stored_ver); 49 if (err) 50 return err; 51 52 if (strlen(fw_ver->commit) > 0) { 53 char commit_name[FBNIC_SN_STR_LEN]; 54 55 snprintf(commit_name, FBNIC_SN_STR_LEN, "%s.commit", ver_name); 56 err = devlink_info_version_stored_put(req, commit_name, 57 fw_ver->commit); 58 if (err) 59 return err; 60 } 61 62 return 0; 63 } 64 65 static int fbnic_devlink_info_get(struct devlink *devlink, 66 struct devlink_info_req *req, 67 struct netlink_ext_ack *extack) 68 { 69 struct fbnic_dev *fbd = devlink_priv(devlink); 70 int err; 71 72 err = fbnic_version_running_put(req, &fbd->fw_cap.running.mgmt, 73 DEVLINK_INFO_VERSION_GENERIC_FW); 74 if (err) 75 return err; 76 77 err = fbnic_version_running_put(req, &fbd->fw_cap.running.bootloader, 78 DEVLINK_INFO_VERSION_GENERIC_FW_BOOTLOADER); 79 if (err) 80 return err; 81 82 err = fbnic_version_stored_put(req, &fbd->fw_cap.stored.mgmt, 83 DEVLINK_INFO_VERSION_GENERIC_FW); 84 if (err) 85 return err; 86 87 err = fbnic_version_stored_put(req, &fbd->fw_cap.stored.bootloader, 88 DEVLINK_INFO_VERSION_GENERIC_FW_BOOTLOADER); 89 if (err) 90 return err; 91 92 err = fbnic_version_stored_put(req, &fbd->fw_cap.stored.undi, 93 DEVLINK_INFO_VERSION_GENERIC_FW_UNDI); 94 if (err) 95 return err; 96 97 if (fbd->dsn) { 98 unsigned char serial[FBNIC_SN_STR_LEN]; 99 u8 dsn[8]; 100 101 put_unaligned_be64(fbd->dsn, dsn); 102 err = snprintf(serial, FBNIC_SN_STR_LEN, "%8phD", dsn); 103 if (err < 0) 104 return err; 105 106 err = devlink_info_serial_number_put(req, serial); 107 if (err) 108 return err; 109 } 110 111 return 0; 112 } 113 114 static bool 115 fbnic_pldm_match_record(struct pldmfw *context, struct pldmfw_record *record) 116 { 117 struct pldmfw_desc_tlv *desc; 118 u32 anti_rollback_ver = 0; 119 struct devlink *devlink; 120 struct fbnic_dev *fbd; 121 struct pci_dev *pdev; 122 123 /* First, use the standard PCI matching function */ 124 if (!pldmfw_op_pci_match_record(context, record)) 125 return false; 126 127 pdev = to_pci_dev(context->dev); 128 fbd = pci_get_drvdata(pdev); 129 devlink = priv_to_devlink(fbd); 130 131 /* If PCI match is successful, check for vendor-specific descriptors */ 132 list_for_each_entry(desc, &record->descs, entry) { 133 if (desc->type != PLDM_DESC_ID_VENDOR_DEFINED) 134 continue; 135 136 if (desc->size < 21 || desc->data[0] != 1 || 137 desc->data[1] != 15) 138 continue; 139 140 if (memcmp(desc->data + 2, "AntiRollbackVer", 15) != 0) 141 continue; 142 143 anti_rollback_ver = get_unaligned_le32(desc->data + 17); 144 break; 145 } 146 147 /* Compare versions and return error if they do not match */ 148 if (anti_rollback_ver < fbd->fw_cap.anti_rollback_version) { 149 char buf[128]; 150 151 snprintf(buf, sizeof(buf), 152 "New firmware anti-rollback version (0x%x) is older than device version (0x%x)!", 153 anti_rollback_ver, fbd->fw_cap.anti_rollback_version); 154 devlink_flash_update_status_notify(devlink, buf, 155 "Anti-Rollback", 0, 0); 156 157 return false; 158 } 159 160 return true; 161 } 162 163 static int 164 fbnic_flash_start(struct fbnic_dev *fbd, struct pldmfw_component *component) 165 { 166 struct fbnic_fw_completion *cmpl; 167 int err; 168 169 cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_FW_START_UPGRADE_REQ); 170 if (!cmpl) 171 return -ENOMEM; 172 173 err = fbnic_fw_xmit_fw_start_upgrade(fbd, cmpl, 174 component->identifier, 175 component->component_size); 176 if (err) 177 goto cmpl_free; 178 179 /* Wait for firmware to ack firmware upgrade start */ 180 if (wait_for_completion_timeout(&cmpl->done, 10 * HZ)) 181 err = cmpl->result; 182 else 183 err = -ETIMEDOUT; 184 185 fbnic_mbx_clear_cmpl(fbd, cmpl); 186 cmpl_free: 187 fbnic_fw_put_cmpl(cmpl); 188 189 return err; 190 } 191 192 static int 193 fbnic_flash_component(struct pldmfw *context, 194 struct pldmfw_component *component) 195 { 196 const u8 *data = component->component_data; 197 const u32 size = component->component_size; 198 struct fbnic_fw_completion *cmpl; 199 const char *component_name; 200 struct devlink *devlink; 201 struct fbnic_dev *fbd; 202 struct pci_dev *pdev; 203 u32 offset = 0; 204 u32 length = 0; 205 char buf[32]; 206 int err; 207 208 pdev = to_pci_dev(context->dev); 209 fbd = pci_get_drvdata(pdev); 210 devlink = priv_to_devlink(fbd); 211 212 switch (component->identifier) { 213 case QSPI_SECTION_CMRT: 214 component_name = "boot1"; 215 break; 216 case QSPI_SECTION_CONTROL_FW: 217 component_name = "boot2"; 218 break; 219 case QSPI_SECTION_OPTION_ROM: 220 component_name = "option-rom"; 221 break; 222 default: 223 snprintf(buf, sizeof(buf), "Unknown component ID %u!", 224 component->identifier); 225 devlink_flash_update_status_notify(devlink, buf, NULL, 0, 226 size); 227 return -EINVAL; 228 } 229 230 /* Once firmware receives the request to start upgrading it responds 231 * with two messages: 232 * 1. An ACK that it received the message and possible error code 233 * indicating that an upgrade is not currently possible. 234 * 2. A request for the first chunk of data 235 * 236 * Setup completions for write before issuing the start message so 237 * the driver can catch both messages. 238 */ 239 cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_FW_WRITE_CHUNK_REQ); 240 if (!cmpl) 241 return -ENOMEM; 242 243 err = fbnic_mbx_set_cmpl(fbd, cmpl); 244 if (err) 245 goto cmpl_free; 246 247 devlink_flash_update_timeout_notify(devlink, "Initializing", 248 component_name, 15); 249 err = fbnic_flash_start(fbd, component); 250 if (err) 251 goto err_no_msg; 252 253 while (offset < size) { 254 if (!wait_for_completion_timeout(&cmpl->done, 15 * HZ)) { 255 err = -ETIMEDOUT; 256 break; 257 } 258 259 err = cmpl->result; 260 if (err) 261 break; 262 263 /* Verify firmware is requesting the next chunk in the seq. */ 264 if (cmpl->u.fw_update.offset != offset + length) { 265 err = -EFAULT; 266 break; 267 } 268 269 offset = cmpl->u.fw_update.offset; 270 length = cmpl->u.fw_update.length; 271 272 if (length > TLV_MAX_DATA || offset + length > size) { 273 err = -EFAULT; 274 break; 275 } 276 277 devlink_flash_update_status_notify(devlink, "Flashing", 278 component_name, 279 offset, size); 280 281 /* Mailbox will set length to 0 once it receives the finish 282 * message. 283 */ 284 if (!length) 285 continue; 286 287 reinit_completion(&cmpl->done); 288 err = fbnic_fw_xmit_fw_write_chunk(fbd, data, offset, length, 289 0); 290 if (err) 291 break; 292 } 293 294 if (err) { 295 fbnic_fw_xmit_fw_write_chunk(fbd, NULL, 0, 0, err); 296 err_no_msg: 297 snprintf(buf, sizeof(buf), "Mailbox encountered error %d!", 298 err); 299 devlink_flash_update_status_notify(devlink, buf, 300 component_name, 0, 0); 301 } 302 303 fbnic_mbx_clear_cmpl(fbd, cmpl); 304 cmpl_free: 305 fbnic_fw_put_cmpl(cmpl); 306 307 return err; 308 } 309 310 static const struct pldmfw_ops fbnic_pldmfw_ops = { 311 .match_record = fbnic_pldm_match_record, 312 .flash_component = fbnic_flash_component, 313 }; 314 315 static int 316 fbnic_devlink_flash_update(struct devlink *devlink, 317 struct devlink_flash_update_params *params, 318 struct netlink_ext_ack *extack) 319 { 320 struct fbnic_dev *fbd = devlink_priv(devlink); 321 const struct firmware *fw = params->fw; 322 struct device *dev = fbd->dev; 323 struct pldmfw context; 324 char *err_msg; 325 int err; 326 327 context.ops = &fbnic_pldmfw_ops; 328 context.dev = dev; 329 330 err = pldmfw_flash_image(&context, fw); 331 if (err) { 332 switch (err) { 333 case -EINVAL: 334 err_msg = "Invalid image"; 335 break; 336 case -EOPNOTSUPP: 337 err_msg = "Unsupported image"; 338 break; 339 case -ENOMEM: 340 err_msg = "Out of memory"; 341 break; 342 case -EFAULT: 343 err_msg = "Invalid header"; 344 break; 345 case -ENOENT: 346 err_msg = "No matching record"; 347 break; 348 case -ENODEV: 349 err_msg = "No matching device"; 350 break; 351 case -ETIMEDOUT: 352 err_msg = "Timed out waiting for reply"; 353 break; 354 default: 355 err_msg = "Unknown error"; 356 break; 357 } 358 359 NL_SET_ERR_MSG_FMT_MOD(extack, 360 "Failed to flash PLDM Image: %s (error: %d)", 361 err_msg, err); 362 } 363 364 return err; 365 } 366 367 static const struct devlink_ops fbnic_devlink_ops = { 368 .info_get = fbnic_devlink_info_get, 369 .flash_update = fbnic_devlink_flash_update, 370 }; 371 372 void fbnic_devlink_free(struct fbnic_dev *fbd) 373 { 374 struct devlink *devlink = priv_to_devlink(fbd); 375 376 devlink_free(devlink); 377 } 378 379 struct fbnic_dev *fbnic_devlink_alloc(struct pci_dev *pdev) 380 { 381 void __iomem * const *iomap_table; 382 struct devlink *devlink; 383 struct fbnic_dev *fbd; 384 385 devlink = devlink_alloc(&fbnic_devlink_ops, sizeof(struct fbnic_dev), 386 &pdev->dev); 387 if (!devlink) 388 return NULL; 389 390 fbd = devlink_priv(devlink); 391 pci_set_drvdata(pdev, fbd); 392 fbd->dev = &pdev->dev; 393 394 iomap_table = pcim_iomap_table(pdev); 395 fbd->uc_addr0 = iomap_table[0]; 396 fbd->uc_addr4 = iomap_table[4]; 397 398 fbd->dsn = pci_get_dsn(pdev); 399 fbd->mps = pcie_get_mps(pdev); 400 fbd->readrq = pcie_get_readrq(pdev); 401 402 fbd->mac_addr_boundary = FBNIC_RPC_TCAM_MACDA_DEFAULT_BOUNDARY; 403 404 return fbd; 405 } 406 407 void fbnic_devlink_register(struct fbnic_dev *fbd) 408 { 409 struct devlink *devlink = priv_to_devlink(fbd); 410 411 devlink_register(devlink); 412 } 413 414 void fbnic_devlink_unregister(struct fbnic_dev *fbd) 415 { 416 struct devlink *devlink = priv_to_devlink(fbd); 417 418 devlink_unregister(devlink); 419 } 420