1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include <linux/ethtool.h> 4 #include <linux/firmware.h> 5 6 #include "common.h" 7 #include "module_fw.h" 8 #include "cmis.h" 9 10 struct cmis_fw_update_fw_mng_features { 11 u8 start_cmd_payload_size; 12 u8 write_mechanism; 13 u16 max_duration_start; 14 u16 max_duration_write; 15 u16 max_duration_complete; 16 }; 17 18 /* See section 9.4.2 "CMD 0041h: Firmware Management Features" in CMIS standard 19 * revision 5.2. 20 * struct cmis_cdb_fw_mng_features_rpl is a structured layout of the flat 21 * array, ethtool_cmis_cdb_rpl::payload. 22 */ 23 struct cmis_cdb_fw_mng_features_rpl { 24 u8 resv1; 25 u8 resv2; 26 u8 start_cmd_payload_size; 27 u8 resv3; 28 u8 read_write_len_ext; 29 u8 write_mechanism; 30 u8 resv4; 31 u8 resv5; 32 __be16 max_duration_start; 33 __be16 resv6; 34 __be16 max_duration_write; 35 __be16 max_duration_complete; 36 __be16 resv7; 37 }; 38 39 enum cmis_cdb_fw_write_mechanism { 40 CMIS_CDB_FW_WRITE_MECHANISM_NONE = 0x00, 41 CMIS_CDB_FW_WRITE_MECHANISM_LPL = 0x01, 42 CMIS_CDB_FW_WRITE_MECHANISM_EPL = 0x10, 43 CMIS_CDB_FW_WRITE_MECHANISM_BOTH = 0x11, 44 }; 45 46 static int 47 cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb, 48 struct net_device *dev, 49 struct cmis_fw_update_fw_mng_features *fw_mng, 50 struct ethnl_module_fw_flash_ntf_params *ntf_params) 51 { 52 struct ethtool_cmis_cdb_cmd_args args = {}; 53 struct cmis_cdb_fw_mng_features_rpl *rpl; 54 u8 flags = CDB_F_STATUS_VALID; 55 int err; 56 57 ethtool_cmis_cdb_check_completion_flag(cdb->cmis_rev, &flags); 58 ethtool_cmis_cdb_compose_args(&args, 59 ETHTOOL_CMIS_CDB_CMD_FW_MANAGMENT_FEATURES, 60 NULL, 0, NULL, 0, 61 cdb->max_completion_time, 62 cdb->read_write_len_ext, 1000, 63 sizeof(*rpl), flags); 64 65 err = ethtool_cmis_cdb_execute_cmd(dev, &args); 66 if (err < 0) { 67 ethnl_module_fw_flash_ntf_err(dev, ntf_params, 68 "FW Management Features command failed", 69 args.err_msg); 70 return err; 71 } 72 73 rpl = (struct cmis_cdb_fw_mng_features_rpl *)args.req.payload; 74 if (rpl->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_NONE) { 75 ethnl_module_fw_flash_ntf_err(dev, ntf_params, 76 "CDB write mechanism is not supported", 77 NULL); 78 return -EOPNOTSUPP; 79 } 80 81 /* Above, we used read_write_len_ext that we got from CDB 82 * advertisement. Update it with the value that we got from module 83 * features query, which is specific for Firmware Management Commands 84 * (IDs 0100h-01FFh). 85 */ 86 cdb->read_write_len_ext = rpl->read_write_len_ext; 87 fw_mng->start_cmd_payload_size = rpl->start_cmd_payload_size; 88 fw_mng->write_mechanism = 89 rpl->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_LPL ? 90 CMIS_CDB_FW_WRITE_MECHANISM_LPL : 91 CMIS_CDB_FW_WRITE_MECHANISM_EPL; 92 fw_mng->max_duration_start = be16_to_cpu(rpl->max_duration_start); 93 fw_mng->max_duration_write = be16_to_cpu(rpl->max_duration_write); 94 fw_mng->max_duration_complete = be16_to_cpu(rpl->max_duration_complete); 95 96 return 0; 97 } 98 99 /* See section 9.7.2 "CMD 0101h: Start Firmware Download" in CMIS standard 100 * revision 5.2. 101 * struct cmis_cdb_start_fw_download_pl is a structured layout of the 102 * flat array, ethtool_cmis_cdb_request::payload. 103 */ 104 struct cmis_cdb_start_fw_download_pl { 105 __struct_group(cmis_cdb_start_fw_download_pl_h, head, /* no attrs */, 106 __be32 image_size; 107 __be32 resv1; 108 ); 109 u8 vendor_data[ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH - 110 sizeof(struct cmis_cdb_start_fw_download_pl_h)]; 111 }; 112 113 static int 114 cmis_fw_update_start_download(struct ethtool_cmis_cdb *cdb, 115 struct ethtool_cmis_fw_update_params *fw_update, 116 struct cmis_fw_update_fw_mng_features *fw_mng) 117 { 118 u8 vendor_data_size = fw_mng->start_cmd_payload_size; 119 struct cmis_cdb_start_fw_download_pl pl = {}; 120 struct ethtool_cmis_cdb_cmd_args args = {}; 121 u8 lpl_len; 122 int err; 123 124 pl.image_size = cpu_to_be32(fw_update->fw->size); 125 memcpy(pl.vendor_data, fw_update->fw->data, vendor_data_size); 126 127 lpl_len = offsetof(struct cmis_cdb_start_fw_download_pl, 128 vendor_data[vendor_data_size]); 129 130 ethtool_cmis_cdb_compose_args(&args, 131 ETHTOOL_CMIS_CDB_CMD_START_FW_DOWNLOAD, 132 (u8 *)&pl, lpl_len, NULL, 0, 133 fw_mng->max_duration_start, 134 cdb->read_write_len_ext, 1000, 0, 135 CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID); 136 137 err = ethtool_cmis_cdb_execute_cmd(fw_update->dev, &args); 138 if (err < 0) 139 ethnl_module_fw_flash_ntf_err(fw_update->dev, 140 &fw_update->ntf_params, 141 "Start FW download command failed", 142 args.err_msg); 143 144 return err; 145 } 146 147 /* See section 9.7.4 "CMD 0103h: Write Firmware Block LPL" in CMIS standard 148 * revision 5.2. 149 * struct cmis_cdb_write_fw_block_lpl_pl is a structured layout of the 150 * flat array, ethtool_cmis_cdb_request::payload. 151 */ 152 struct cmis_cdb_write_fw_block_lpl_pl { 153 __be32 block_address; 154 u8 fw_block[ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH - sizeof(__be32)]; 155 }; 156 157 static int 158 cmis_fw_update_write_image_lpl(struct ethtool_cmis_cdb *cdb, 159 struct ethtool_cmis_fw_update_params *fw_update, 160 struct cmis_fw_update_fw_mng_features *fw_mng) 161 { 162 u8 start = fw_mng->start_cmd_payload_size; 163 u32 offset, max_block_size, max_lpl_len; 164 u32 image_size = fw_update->fw->size; 165 int err; 166 167 max_lpl_len = min_t(u32, 168 ethtool_cmis_get_max_lpl_size(cdb->read_write_len_ext), 169 ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH); 170 max_block_size = 171 max_lpl_len - sizeof_field(struct cmis_cdb_write_fw_block_lpl_pl, 172 block_address); 173 174 for (offset = start; offset < image_size; offset += max_block_size) { 175 struct cmis_cdb_write_fw_block_lpl_pl pl = { 176 .block_address = cpu_to_be32(offset - start), 177 }; 178 struct ethtool_cmis_cdb_cmd_args args = {}; 179 u32 block_size, lpl_len; 180 181 ethnl_module_fw_flash_ntf_in_progress(fw_update->dev, 182 &fw_update->ntf_params, 183 offset - start, 184 image_size); 185 block_size = min_t(u32, max_block_size, image_size - offset); 186 memcpy(pl.fw_block, &fw_update->fw->data[offset], block_size); 187 lpl_len = block_size + 188 sizeof_field(struct cmis_cdb_write_fw_block_lpl_pl, 189 block_address); 190 191 ethtool_cmis_cdb_compose_args(&args, 192 ETHTOOL_CMIS_CDB_CMD_WRITE_FW_BLOCK_LPL, 193 (u8 *)&pl, lpl_len, NULL, 0, 194 fw_mng->max_duration_write, 195 cdb->read_write_len_ext, 1, 0, 196 CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID); 197 198 err = ethtool_cmis_cdb_execute_cmd(fw_update->dev, &args); 199 if (err < 0) { 200 ethnl_module_fw_flash_ntf_err(fw_update->dev, 201 &fw_update->ntf_params, 202 "Write FW block LPL command failed", 203 args.err_msg); 204 return err; 205 } 206 } 207 208 return 0; 209 } 210 211 struct cmis_cdb_write_fw_block_epl_pl { 212 u8 fw_block[ETHTOOL_CMIS_CDB_EPL_MAX_PL_LENGTH]; 213 }; 214 215 static int 216 cmis_fw_update_write_image_epl(struct ethtool_cmis_cdb *cdb, 217 struct ethtool_cmis_fw_update_params *fw_update, 218 struct cmis_fw_update_fw_mng_features *fw_mng) 219 { 220 u8 start = fw_mng->start_cmd_payload_size; 221 u32 image_size = fw_update->fw->size; 222 u32 offset, lpl_len; 223 int err; 224 225 lpl_len = sizeof_field(struct cmis_cdb_write_fw_block_lpl_pl, 226 block_address); 227 228 for (offset = start; offset < image_size; 229 offset += ETHTOOL_CMIS_CDB_EPL_MAX_PL_LENGTH) { 230 struct cmis_cdb_write_fw_block_lpl_pl lpl = { 231 .block_address = cpu_to_be32(offset - start), 232 }; 233 struct cmis_cdb_write_fw_block_epl_pl *epl; 234 struct ethtool_cmis_cdb_cmd_args args = {}; 235 u32 epl_len; 236 237 ethnl_module_fw_flash_ntf_in_progress(fw_update->dev, 238 &fw_update->ntf_params, 239 offset - start, 240 image_size); 241 242 epl_len = min_t(u32, ETHTOOL_CMIS_CDB_EPL_MAX_PL_LENGTH, 243 image_size - offset); 244 epl = kmalloc_array(epl_len, sizeof(u8), GFP_KERNEL); 245 if (!epl) 246 return -ENOMEM; 247 248 memcpy(epl->fw_block, &fw_update->fw->data[offset], epl_len); 249 250 ethtool_cmis_cdb_compose_args(&args, 251 ETHTOOL_CMIS_CDB_CMD_WRITE_FW_BLOCK_EPL, 252 (u8 *)&lpl, lpl_len, (u8 *)epl, 253 epl_len, 254 fw_mng->max_duration_write, 255 cdb->read_write_len_ext, 1, 0, 256 CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID); 257 258 err = ethtool_cmis_cdb_execute_cmd(fw_update->dev, &args); 259 kfree(epl); 260 if (err < 0) { 261 ethnl_module_fw_flash_ntf_err(fw_update->dev, 262 &fw_update->ntf_params, 263 "Write FW block EPL command failed", 264 args.err_msg); 265 return err; 266 } 267 } 268 269 return 0; 270 } 271 272 static int 273 cmis_fw_update_complete_download(struct ethtool_cmis_cdb *cdb, 274 struct net_device *dev, 275 struct cmis_fw_update_fw_mng_features *fw_mng, 276 struct ethnl_module_fw_flash_ntf_params *ntf_params) 277 { 278 struct ethtool_cmis_cdb_cmd_args args = {}; 279 int err; 280 281 ethtool_cmis_cdb_compose_args(&args, 282 ETHTOOL_CMIS_CDB_CMD_COMPLETE_FW_DOWNLOAD, 283 NULL, 0, NULL, 0, 284 fw_mng->max_duration_complete, 285 cdb->read_write_len_ext, 1000, 0, 286 CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID); 287 288 err = ethtool_cmis_cdb_execute_cmd(dev, &args); 289 if (err < 0) 290 ethnl_module_fw_flash_ntf_err(dev, ntf_params, 291 "Complete FW download command failed", 292 args.err_msg); 293 294 return err; 295 } 296 297 static int 298 cmis_fw_update_download_image(struct ethtool_cmis_cdb *cdb, 299 struct ethtool_cmis_fw_update_params *fw_update, 300 struct cmis_fw_update_fw_mng_features *fw_mng) 301 { 302 int err; 303 304 err = cmis_fw_update_start_download(cdb, fw_update, fw_mng); 305 if (err < 0) 306 return err; 307 308 if (fw_mng->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_LPL) { 309 err = cmis_fw_update_write_image_lpl(cdb, fw_update, fw_mng); 310 if (err < 0) 311 return err; 312 } else { 313 err = cmis_fw_update_write_image_epl(cdb, fw_update, fw_mng); 314 if (err < 0) 315 return err; 316 } 317 318 err = cmis_fw_update_complete_download(cdb, fw_update->dev, fw_mng, 319 &fw_update->ntf_params); 320 if (err < 0) 321 return err; 322 323 return 0; 324 } 325 326 enum { 327 CMIS_MODULE_LOW_PWR = 1, 328 CMIS_MODULE_READY = 3, 329 }; 330 331 static bool module_is_ready(u8 data) 332 { 333 u8 state = (data >> 1) & 7; 334 335 return state == CMIS_MODULE_READY || state == CMIS_MODULE_LOW_PWR; 336 } 337 338 #define CMIS_MODULE_READY_MAX_DURATION_MSEC 1000 339 #define CMIS_MODULE_STATE_OFFSET 3 340 341 static int 342 cmis_fw_update_wait_for_module_state(struct net_device *dev, u8 flags) 343 { 344 u8 state; 345 346 return ethtool_cmis_wait_for_cond(dev, flags, CDB_F_MODULE_STATE_VALID, 347 CMIS_MODULE_READY_MAX_DURATION_MSEC, 348 CMIS_MODULE_STATE_OFFSET, 349 module_is_ready, NULL, &state); 350 } 351 352 /* See section 9.7.10 "CMD 0109h: Run Firmware Image" in CMIS standard 353 * revision 5.2. 354 * struct cmis_cdb_run_fw_image_pl is a structured layout of the flat 355 * array, ethtool_cmis_cdb_request::payload. 356 */ 357 struct cmis_cdb_run_fw_image_pl { 358 u8 resv1; 359 u8 image_to_run; 360 u16 delay_to_reset; 361 }; 362 363 static int 364 cmis_fw_update_run_image(struct ethtool_cmis_cdb *cdb, struct net_device *dev, 365 struct ethnl_module_fw_flash_ntf_params *ntf_params) 366 { 367 struct ethtool_cmis_cdb_cmd_args args = {}; 368 struct cmis_cdb_run_fw_image_pl pl = {0}; 369 int err; 370 371 ethtool_cmis_cdb_compose_args(&args, ETHTOOL_CMIS_CDB_CMD_RUN_FW_IMAGE, 372 (u8 *)&pl, sizeof(pl), NULL, 0, 373 cdb->max_completion_time, 374 cdb->read_write_len_ext, 1000, 0, 375 CDB_F_MODULE_STATE_VALID); 376 377 err = ethtool_cmis_cdb_execute_cmd(dev, &args); 378 if (err < 0) { 379 ethnl_module_fw_flash_ntf_err(dev, ntf_params, 380 "Run image command failed", 381 args.err_msg); 382 return err; 383 } 384 385 err = cmis_fw_update_wait_for_module_state(dev, args.flags); 386 if (err < 0) 387 ethnl_module_fw_flash_ntf_err(dev, ntf_params, 388 "Module is not ready on time after reset", 389 NULL); 390 391 return err; 392 } 393 394 static int 395 cmis_fw_update_commit_image(struct ethtool_cmis_cdb *cdb, 396 struct net_device *dev, 397 struct ethnl_module_fw_flash_ntf_params *ntf_params) 398 { 399 struct ethtool_cmis_cdb_cmd_args args = {}; 400 int err; 401 402 ethtool_cmis_cdb_compose_args(&args, 403 ETHTOOL_CMIS_CDB_CMD_COMMIT_FW_IMAGE, 404 NULL, 0, NULL, 0, 405 cdb->max_completion_time, 406 cdb->read_write_len_ext, 1000, 0, 407 CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID); 408 409 err = ethtool_cmis_cdb_execute_cmd(dev, &args); 410 if (err < 0) 411 ethnl_module_fw_flash_ntf_err(dev, ntf_params, 412 "Commit image command failed", 413 args.err_msg); 414 415 return err; 416 } 417 418 static int cmis_fw_update_reset(struct net_device *dev) 419 { 420 __u32 reset_data = ETH_RESET_PHY; 421 422 return dev->ethtool_ops->reset(dev, &reset_data); 423 } 424 425 void 426 ethtool_cmis_fw_update(struct ethtool_cmis_fw_update_params *fw_update) 427 { 428 struct ethnl_module_fw_flash_ntf_params *ntf_params = 429 &fw_update->ntf_params; 430 struct cmis_fw_update_fw_mng_features fw_mng = {0}; 431 struct net_device *dev = fw_update->dev; 432 struct ethtool_cmis_cdb *cdb; 433 int err; 434 435 cdb = ethtool_cmis_cdb_init(dev, &fw_update->params, ntf_params); 436 if (IS_ERR(cdb)) 437 goto err_send_ntf; 438 439 ethnl_module_fw_flash_ntf_start(dev, ntf_params); 440 441 err = cmis_fw_update_fw_mng_features_get(cdb, dev, &fw_mng, ntf_params); 442 if (err < 0) 443 goto err_cdb_fini; 444 445 err = cmis_fw_update_download_image(cdb, fw_update, &fw_mng); 446 if (err < 0) 447 goto err_cdb_fini; 448 449 err = cmis_fw_update_run_image(cdb, dev, ntf_params); 450 if (err < 0) 451 goto err_cdb_fini; 452 453 /* The CDB command "Run Firmware Image" resets the firmware, so the new 454 * one might have different settings. 455 * Free the old CDB instance, and init a new one. 456 */ 457 ethtool_cmis_cdb_fini(cdb); 458 459 cdb = ethtool_cmis_cdb_init(dev, &fw_update->params, ntf_params); 460 if (IS_ERR(cdb)) 461 goto err_send_ntf; 462 463 err = cmis_fw_update_commit_image(cdb, dev, ntf_params); 464 if (err < 0) 465 goto err_cdb_fini; 466 467 err = cmis_fw_update_reset(dev); 468 if (err < 0) 469 goto err_cdb_fini; 470 471 ethnl_module_fw_flash_ntf_complete(dev, ntf_params); 472 ethtool_cmis_cdb_fini(cdb); 473 return; 474 475 err_cdb_fini: 476 ethtool_cmis_cdb_fini(cdb); 477 err_send_ntf: 478 ethnl_module_fw_flash_ntf_err(dev, ntf_params, NULL, NULL); 479 } 480