1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include <linux/ethtool.h> 4 #include <linux/firmware.h> 5 #include <linux/sfp.h> 6 #include <net/devlink.h> 7 8 #include "netlink.h" 9 #include "common.h" 10 #include "bitset.h" 11 #include "module_fw.h" 12 13 struct module_req_info { 14 struct ethnl_req_info base; 15 }; 16 17 struct module_reply_data { 18 struct ethnl_reply_data base; 19 struct ethtool_module_power_mode_params power; 20 }; 21 22 #define MODULE_REPDATA(__reply_base) \ 23 container_of(__reply_base, struct module_reply_data, base) 24 25 /* MODULE_GET */ 26 27 const struct nla_policy ethnl_module_get_policy[ETHTOOL_A_MODULE_HEADER + 1] = { 28 [ETHTOOL_A_MODULE_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy), 29 }; 30 31 static int module_get_power_mode(struct net_device *dev, 32 struct module_reply_data *data, 33 struct netlink_ext_ack *extack) 34 { 35 const struct ethtool_ops *ops = dev->ethtool_ops; 36 37 if (!ops->get_module_power_mode) 38 return 0; 39 40 if (dev->ethtool->module_fw_flash_in_progress) { 41 NL_SET_ERR_MSG(extack, 42 "Module firmware flashing is in progress"); 43 return -EBUSY; 44 } 45 46 return ops->get_module_power_mode(dev, &data->power, extack); 47 } 48 49 static int module_prepare_data(const struct ethnl_req_info *req_base, 50 struct ethnl_reply_data *reply_base, 51 const struct genl_info *info) 52 { 53 struct module_reply_data *data = MODULE_REPDATA(reply_base); 54 struct net_device *dev = reply_base->dev; 55 int ret; 56 57 ret = ethnl_ops_begin(dev); 58 if (ret < 0) 59 return ret; 60 61 ret = module_get_power_mode(dev, data, info->extack); 62 if (ret < 0) 63 goto out_complete; 64 65 out_complete: 66 ethnl_ops_complete(dev); 67 return ret; 68 } 69 70 static int module_reply_size(const struct ethnl_req_info *req_base, 71 const struct ethnl_reply_data *reply_base) 72 { 73 struct module_reply_data *data = MODULE_REPDATA(reply_base); 74 int len = 0; 75 76 if (data->power.policy) 77 len += nla_total_size(sizeof(u8)); /* _MODULE_POWER_MODE_POLICY */ 78 79 if (data->power.mode) 80 len += nla_total_size(sizeof(u8)); /* _MODULE_POWER_MODE */ 81 82 return len; 83 } 84 85 static int module_fill_reply(struct sk_buff *skb, 86 const struct ethnl_req_info *req_base, 87 const struct ethnl_reply_data *reply_base) 88 { 89 const struct module_reply_data *data = MODULE_REPDATA(reply_base); 90 91 if (data->power.policy && 92 nla_put_u8(skb, ETHTOOL_A_MODULE_POWER_MODE_POLICY, 93 data->power.policy)) 94 return -EMSGSIZE; 95 96 if (data->power.mode && 97 nla_put_u8(skb, ETHTOOL_A_MODULE_POWER_MODE, data->power.mode)) 98 return -EMSGSIZE; 99 100 return 0; 101 } 102 103 /* MODULE_SET */ 104 105 const struct nla_policy ethnl_module_set_policy[ETHTOOL_A_MODULE_POWER_MODE_POLICY + 1] = { 106 [ETHTOOL_A_MODULE_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy), 107 [ETHTOOL_A_MODULE_POWER_MODE_POLICY] = 108 NLA_POLICY_RANGE(NLA_U8, ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH, 109 ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO), 110 }; 111 112 static int 113 ethnl_set_module_validate(struct ethnl_req_info *req_info, 114 struct genl_info *info) 115 { 116 const struct ethtool_ops *ops = req_info->dev->ethtool_ops; 117 struct nlattr **tb = info->attrs; 118 119 if (!tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY]) 120 return 0; 121 122 if (req_info->dev->ethtool->module_fw_flash_in_progress) { 123 NL_SET_ERR_MSG(info->extack, 124 "Module firmware flashing is in progress"); 125 return -EBUSY; 126 } 127 128 if (!ops->get_module_power_mode || !ops->set_module_power_mode) { 129 NL_SET_ERR_MSG_ATTR(info->extack, 130 tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY], 131 "Setting power mode policy is not supported by this device"); 132 return -EOPNOTSUPP; 133 } 134 135 return 1; 136 } 137 138 static int 139 ethnl_set_module(struct ethnl_req_info *req_info, struct genl_info *info) 140 { 141 struct ethtool_module_power_mode_params power = {}; 142 struct ethtool_module_power_mode_params power_new; 143 const struct ethtool_ops *ops; 144 struct net_device *dev = req_info->dev; 145 struct nlattr **tb = info->attrs; 146 int ret; 147 148 ops = dev->ethtool_ops; 149 150 power_new.policy = nla_get_u8(tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY]); 151 ret = ops->get_module_power_mode(dev, &power, info->extack); 152 if (ret < 0) 153 return ret; 154 155 if (power_new.policy == power.policy) 156 return 0; 157 158 ret = ops->set_module_power_mode(dev, &power_new, info->extack); 159 return ret < 0 ? ret : 1; 160 } 161 162 const struct ethnl_request_ops ethnl_module_request_ops = { 163 .request_cmd = ETHTOOL_MSG_MODULE_GET, 164 .reply_cmd = ETHTOOL_MSG_MODULE_GET_REPLY, 165 .hdr_attr = ETHTOOL_A_MODULE_HEADER, 166 .req_info_size = sizeof(struct module_req_info), 167 .reply_data_size = sizeof(struct module_reply_data), 168 169 .prepare_data = module_prepare_data, 170 .reply_size = module_reply_size, 171 .fill_reply = module_fill_reply, 172 173 .set_validate = ethnl_set_module_validate, 174 .set = ethnl_set_module, 175 .set_ntf_cmd = ETHTOOL_MSG_MODULE_NTF, 176 }; 177 178 /* MODULE_FW_FLASH_ACT */ 179 180 const struct nla_policy 181 ethnl_module_fw_flash_act_policy[ETHTOOL_A_MODULE_FW_FLASH_PASSWORD + 1] = { 182 [ETHTOOL_A_MODULE_FW_FLASH_HEADER] = 183 NLA_POLICY_NESTED(ethnl_header_policy), 184 [ETHTOOL_A_MODULE_FW_FLASH_FILE_NAME] = { .type = NLA_NUL_STRING }, 185 [ETHTOOL_A_MODULE_FW_FLASH_PASSWORD] = { .type = NLA_U32 }, 186 }; 187 188 static LIST_HEAD(module_fw_flash_work_list); 189 static DEFINE_SPINLOCK(module_fw_flash_work_list_lock); 190 191 static int 192 module_flash_fw_work_list_add(struct ethtool_module_fw_flash *module_fw, 193 struct genl_info *info) 194 { 195 struct ethtool_module_fw_flash *work; 196 197 /* First, check if already registered. */ 198 spin_lock(&module_fw_flash_work_list_lock); 199 list_for_each_entry(work, &module_fw_flash_work_list, list) { 200 if (work->fw_update.ntf_params.portid == info->snd_portid && 201 work->fw_update.dev == module_fw->fw_update.dev) { 202 spin_unlock(&module_fw_flash_work_list_lock); 203 return -EALREADY; 204 } 205 } 206 207 list_add_tail(&module_fw->list, &module_fw_flash_work_list); 208 spin_unlock(&module_fw_flash_work_list_lock); 209 210 return 0; 211 } 212 213 static void module_flash_fw_work_list_del(struct list_head *list) 214 { 215 spin_lock(&module_fw_flash_work_list_lock); 216 list_del(list); 217 spin_unlock(&module_fw_flash_work_list_lock); 218 } 219 220 static void module_flash_fw_work(struct work_struct *work) 221 { 222 struct ethtool_module_fw_flash *module_fw; 223 224 module_fw = container_of(work, struct ethtool_module_fw_flash, work); 225 226 ethtool_cmis_fw_update(&module_fw->fw_update); 227 228 module_flash_fw_work_list_del(&module_fw->list); 229 module_fw->fw_update.dev->ethtool->module_fw_flash_in_progress = false; 230 netdev_put(module_fw->fw_update.dev, &module_fw->dev_tracker); 231 release_firmware(module_fw->fw_update.fw); 232 kfree(module_fw); 233 } 234 235 #define MODULE_EEPROM_PHYS_ID_PAGE 0 236 #define MODULE_EEPROM_PHYS_ID_I2C_ADDR 0x50 237 238 static int module_flash_fw_work_init(struct ethtool_module_fw_flash *module_fw, 239 struct net_device *dev, 240 struct netlink_ext_ack *extack) 241 { 242 const struct ethtool_ops *ops = dev->ethtool_ops; 243 struct ethtool_module_eeprom page_data = {}; 244 u8 phys_id; 245 int err; 246 247 /* Fetch the SFF-8024 Identifier Value. For all supported standards, it 248 * is located at I2C address 0x50, byte 0. See section 4.1 in SFF-8024, 249 * revision 4.9. 250 */ 251 page_data.page = MODULE_EEPROM_PHYS_ID_PAGE; 252 page_data.offset = SFP_PHYS_ID; 253 page_data.length = sizeof(phys_id); 254 page_data.i2c_address = MODULE_EEPROM_PHYS_ID_I2C_ADDR; 255 page_data.data = &phys_id; 256 257 err = ops->get_module_eeprom_by_page(dev, &page_data, extack); 258 if (err < 0) 259 return err; 260 261 switch (phys_id) { 262 case SFF8024_ID_QSFP_DD: 263 case SFF8024_ID_OSFP: 264 case SFF8024_ID_DSFP: 265 case SFF8024_ID_QSFP_PLUS_CMIS: 266 case SFF8024_ID_SFP_DD_CMIS: 267 case SFF8024_ID_SFP_PLUS_CMIS: 268 INIT_WORK(&module_fw->work, module_flash_fw_work); 269 break; 270 default: 271 NL_SET_ERR_MSG(extack, 272 "Module type does not support firmware flashing"); 273 return -EOPNOTSUPP; 274 } 275 276 return 0; 277 } 278 279 void ethnl_module_fw_flash_sock_destroy(struct ethnl_sock_priv *sk_priv) 280 { 281 struct ethtool_module_fw_flash *work; 282 283 spin_lock(&module_fw_flash_work_list_lock); 284 list_for_each_entry(work, &module_fw_flash_work_list, list) { 285 if (work->fw_update.dev == sk_priv->dev && 286 work->fw_update.ntf_params.portid == sk_priv->portid) { 287 work->fw_update.ntf_params.closed_sock = true; 288 break; 289 } 290 } 291 spin_unlock(&module_fw_flash_work_list_lock); 292 } 293 294 static int 295 module_flash_fw_schedule(struct net_device *dev, const char *file_name, 296 struct ethtool_module_fw_flash_params *params, 297 struct sk_buff *skb, struct genl_info *info) 298 { 299 struct ethtool_cmis_fw_update_params *fw_update; 300 struct ethtool_module_fw_flash *module_fw; 301 int err; 302 303 module_fw = kzalloc(sizeof(*module_fw), GFP_KERNEL); 304 if (!module_fw) 305 return -ENOMEM; 306 307 fw_update = &module_fw->fw_update; 308 fw_update->params = *params; 309 err = request_firmware_direct(&fw_update->fw, 310 file_name, &dev->dev); 311 if (err) { 312 NL_SET_ERR_MSG(info->extack, 313 "Failed to request module firmware image"); 314 goto err_free; 315 } 316 317 err = module_flash_fw_work_init(module_fw, dev, info->extack); 318 if (err < 0) 319 goto err_release_firmware; 320 321 dev->ethtool->module_fw_flash_in_progress = true; 322 netdev_hold(dev, &module_fw->dev_tracker, GFP_KERNEL); 323 fw_update->dev = dev; 324 fw_update->ntf_params.portid = info->snd_portid; 325 fw_update->ntf_params.seq = info->snd_seq; 326 fw_update->ntf_params.closed_sock = false; 327 328 err = ethnl_sock_priv_set(skb, dev, fw_update->ntf_params.portid, 329 ETHTOOL_SOCK_TYPE_MODULE_FW_FLASH); 330 if (err < 0) 331 goto err_release_firmware; 332 333 err = module_flash_fw_work_list_add(module_fw, info); 334 if (err < 0) 335 goto err_release_firmware; 336 337 schedule_work(&module_fw->work); 338 339 return 0; 340 341 err_release_firmware: 342 release_firmware(fw_update->fw); 343 err_free: 344 kfree(module_fw); 345 return err; 346 } 347 348 static int module_flash_fw(struct net_device *dev, struct nlattr **tb, 349 struct sk_buff *skb, struct genl_info *info) 350 { 351 struct ethtool_module_fw_flash_params params = {}; 352 const char *file_name; 353 struct nlattr *attr; 354 355 if (GENL_REQ_ATTR_CHECK(info, ETHTOOL_A_MODULE_FW_FLASH_FILE_NAME)) 356 return -EINVAL; 357 358 file_name = nla_data(tb[ETHTOOL_A_MODULE_FW_FLASH_FILE_NAME]); 359 360 attr = tb[ETHTOOL_A_MODULE_FW_FLASH_PASSWORD]; 361 if (attr) { 362 params.password = cpu_to_be32(nla_get_u32(attr)); 363 params.password_valid = true; 364 } 365 366 return module_flash_fw_schedule(dev, file_name, ¶ms, skb, info); 367 } 368 369 static int ethnl_module_fw_flash_validate(struct net_device *dev, 370 struct netlink_ext_ack *extack) 371 { 372 struct devlink_port *devlink_port = dev->devlink_port; 373 const struct ethtool_ops *ops = dev->ethtool_ops; 374 375 if (!ops->set_module_eeprom_by_page || 376 !ops->get_module_eeprom_by_page) { 377 NL_SET_ERR_MSG(extack, 378 "Flashing module firmware is not supported by this device"); 379 return -EOPNOTSUPP; 380 } 381 382 if (!ops->reset) { 383 NL_SET_ERR_MSG(extack, 384 "Reset module is not supported by this device, so flashing is not permitted"); 385 return -EOPNOTSUPP; 386 } 387 388 if (dev->ethtool->module_fw_flash_in_progress) { 389 NL_SET_ERR_MSG(extack, "Module firmware flashing already in progress"); 390 return -EBUSY; 391 } 392 393 if (dev->flags & IFF_UP) { 394 NL_SET_ERR_MSG(extack, "Netdevice is up, so flashing is not permitted"); 395 return -EBUSY; 396 } 397 398 if (devlink_port && devlink_port->attrs.split) { 399 NL_SET_ERR_MSG(extack, "Can't perform firmware flashing on a split port"); 400 return -EOPNOTSUPP; 401 } 402 403 return 0; 404 } 405 406 int ethnl_act_module_fw_flash(struct sk_buff *skb, struct genl_info *info) 407 { 408 struct ethnl_req_info req_info = {}; 409 struct nlattr **tb = info->attrs; 410 struct net_device *dev; 411 int ret; 412 413 ret = ethnl_parse_header_dev_get(&req_info, 414 tb[ETHTOOL_A_MODULE_FW_FLASH_HEADER], 415 genl_info_net(info), info->extack, 416 true); 417 if (ret < 0) 418 return ret; 419 dev = req_info.dev; 420 421 rtnl_lock(); 422 ret = ethnl_ops_begin(dev); 423 if (ret < 0) 424 goto out_rtnl; 425 426 ret = ethnl_module_fw_flash_validate(dev, info->extack); 427 if (ret < 0) 428 goto out_rtnl; 429 430 ret = module_flash_fw(dev, tb, skb, info); 431 432 ethnl_ops_complete(dev); 433 434 out_rtnl: 435 rtnl_unlock(); 436 ethnl_parse_header_dev_put(&req_info); 437 return ret; 438 } 439 440 /* MODULE_FW_FLASH_NTF */ 441 442 static int 443 ethnl_module_fw_flash_ntf_put_err(struct sk_buff *skb, char *err_msg, 444 char *sub_err_msg) 445 { 446 int err_msg_len, sub_err_msg_len, total_len; 447 struct nlattr *attr; 448 449 if (!err_msg) 450 return 0; 451 452 err_msg_len = strlen(err_msg); 453 total_len = err_msg_len + 2; /* For period and NUL. */ 454 455 if (sub_err_msg) { 456 sub_err_msg_len = strlen(sub_err_msg); 457 total_len += sub_err_msg_len + 2; /* For ", ". */ 458 } 459 460 attr = nla_reserve(skb, ETHTOOL_A_MODULE_FW_FLASH_STATUS_MSG, 461 total_len); 462 if (!attr) 463 return -ENOMEM; 464 465 if (sub_err_msg) 466 sprintf(nla_data(attr), "%s, %s.", err_msg, sub_err_msg); 467 else 468 sprintf(nla_data(attr), "%s.", err_msg); 469 470 return 0; 471 } 472 473 static void 474 ethnl_module_fw_flash_ntf(struct net_device *dev, 475 enum ethtool_module_fw_flash_status status, 476 struct ethnl_module_fw_flash_ntf_params *ntf_params, 477 char *err_msg, char *sub_err_msg, 478 u64 done, u64 total) 479 { 480 struct sk_buff *skb; 481 void *hdr; 482 int ret; 483 484 if (ntf_params->closed_sock) 485 return; 486 487 skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 488 if (!skb) 489 return; 490 491 hdr = ethnl_unicast_put(skb, ntf_params->portid, ++ntf_params->seq, 492 ETHTOOL_MSG_MODULE_FW_FLASH_NTF); 493 if (!hdr) 494 goto err_skb; 495 496 ret = ethnl_fill_reply_header(skb, dev, 497 ETHTOOL_A_MODULE_FW_FLASH_HEADER); 498 if (ret < 0) 499 goto err_skb; 500 501 if (nla_put_u32(skb, ETHTOOL_A_MODULE_FW_FLASH_STATUS, status)) 502 goto err_skb; 503 504 ret = ethnl_module_fw_flash_ntf_put_err(skb, err_msg, sub_err_msg); 505 if (ret < 0) 506 goto err_skb; 507 508 if (nla_put_uint(skb, ETHTOOL_A_MODULE_FW_FLASH_DONE, done)) 509 goto err_skb; 510 511 if (nla_put_uint(skb, ETHTOOL_A_MODULE_FW_FLASH_TOTAL, total)) 512 goto err_skb; 513 514 genlmsg_end(skb, hdr); 515 genlmsg_unicast(dev_net(dev), skb, ntf_params->portid); 516 return; 517 518 err_skb: 519 nlmsg_free(skb); 520 } 521 522 void ethnl_module_fw_flash_ntf_err(struct net_device *dev, 523 struct ethnl_module_fw_flash_ntf_params *params, 524 char *err_msg, char *sub_err_msg) 525 { 526 ethnl_module_fw_flash_ntf(dev, ETHTOOL_MODULE_FW_FLASH_STATUS_ERROR, 527 params, err_msg, sub_err_msg, 0, 0); 528 } 529 530 void 531 ethnl_module_fw_flash_ntf_start(struct net_device *dev, 532 struct ethnl_module_fw_flash_ntf_params *params) 533 { 534 ethnl_module_fw_flash_ntf(dev, ETHTOOL_MODULE_FW_FLASH_STATUS_STARTED, 535 params, NULL, NULL, 0, 0); 536 } 537 538 void 539 ethnl_module_fw_flash_ntf_complete(struct net_device *dev, 540 struct ethnl_module_fw_flash_ntf_params *params) 541 { 542 ethnl_module_fw_flash_ntf(dev, ETHTOOL_MODULE_FW_FLASH_STATUS_COMPLETED, 543 params, NULL, NULL, 0, 0); 544 } 545 546 void 547 ethnl_module_fw_flash_ntf_in_progress(struct net_device *dev, 548 struct ethnl_module_fw_flash_ntf_params *params, 549 u64 done, u64 total) 550 { 551 ethnl_module_fw_flash_ntf(dev, 552 ETHTOOL_MODULE_FW_FLASH_STATUS_IN_PROGRESS, 553 params, NULL, NULL, done, total); 554 } 555
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.