module.c 14 KB

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