module.c 14 KB

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