bnxt_vfr.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. /* Broadcom NetXtreme-C/E network driver.
  2. *
  3. * Copyright (c) 2016-2017 Broadcom Limited
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation.
  8. */
  9. #include <linux/pci.h>
  10. #include <linux/netdevice.h>
  11. #include <linux/etherdevice.h>
  12. #include <linux/rtnetlink.h>
  13. #include <linux/jhash.h>
  14. #include <net/pkt_cls.h>
  15. #include "bnxt_hsi.h"
  16. #include "bnxt.h"
  17. #include "bnxt_hwrm.h"
  18. #include "bnxt_vfr.h"
  19. #include "bnxt_devlink.h"
  20. #include "bnxt_tc.h"
  21. #ifdef CONFIG_BNXT_SRIOV
  22. #define CFA_HANDLE_INVALID 0xffff
  23. #define VF_IDX_INVALID 0xffff
  24. static int hwrm_cfa_vfr_alloc(struct bnxt *bp, u16 vf_idx,
  25. u16 *tx_cfa_action, u16 *rx_cfa_code)
  26. {
  27. struct hwrm_cfa_vfr_alloc_output *resp;
  28. struct hwrm_cfa_vfr_alloc_input *req;
  29. int rc;
  30. rc = hwrm_req_init(bp, req, HWRM_CFA_VFR_ALLOC);
  31. if (!rc) {
  32. req->vf_id = cpu_to_le16(vf_idx);
  33. sprintf(req->vfr_name, "vfr%d", vf_idx);
  34. resp = hwrm_req_hold(bp, req);
  35. rc = hwrm_req_send(bp, req);
  36. if (!rc) {
  37. *tx_cfa_action = le16_to_cpu(resp->tx_cfa_action);
  38. *rx_cfa_code = le16_to_cpu(resp->rx_cfa_code);
  39. netdev_dbg(bp->dev, "tx_cfa_action=0x%x, rx_cfa_code=0x%x",
  40. *tx_cfa_action, *rx_cfa_code);
  41. }
  42. hwrm_req_drop(bp, req);
  43. }
  44. if (rc)
  45. netdev_info(bp->dev, "%s error rc=%d\n", __func__, rc);
  46. return rc;
  47. }
  48. static int hwrm_cfa_vfr_free(struct bnxt *bp, u16 vf_idx)
  49. {
  50. struct hwrm_cfa_vfr_free_input *req;
  51. int rc;
  52. rc = hwrm_req_init(bp, req, HWRM_CFA_VFR_FREE);
  53. if (!rc) {
  54. sprintf(req->vfr_name, "vfr%d", vf_idx);
  55. rc = hwrm_req_send(bp, req);
  56. }
  57. if (rc)
  58. netdev_info(bp->dev, "%s error rc=%d\n", __func__, rc);
  59. return rc;
  60. }
  61. static int bnxt_hwrm_vfr_qcfg(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
  62. u16 *max_mtu)
  63. {
  64. struct hwrm_func_qcfg_output *resp;
  65. struct hwrm_func_qcfg_input *req;
  66. u16 mtu;
  67. int rc;
  68. rc = hwrm_req_init(bp, req, HWRM_FUNC_QCFG);
  69. if (rc)
  70. return rc;
  71. req->fid = cpu_to_le16(bp->pf.vf[vf_rep->vf_idx].fw_fid);
  72. resp = hwrm_req_hold(bp, req);
  73. rc = hwrm_req_send(bp, req);
  74. if (!rc) {
  75. mtu = le16_to_cpu(resp->max_mtu_configured);
  76. if (!mtu)
  77. *max_mtu = BNXT_MAX_MTU;
  78. else
  79. *max_mtu = mtu;
  80. }
  81. hwrm_req_drop(bp, req);
  82. return rc;
  83. }
  84. static int bnxt_vf_rep_open(struct net_device *dev)
  85. {
  86. struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
  87. struct bnxt *bp = vf_rep->bp;
  88. /* Enable link and TX only if the parent PF is open. */
  89. if (netif_running(bp->dev)) {
  90. netif_carrier_on(dev);
  91. netif_tx_start_all_queues(dev);
  92. }
  93. return 0;
  94. }
  95. static int bnxt_vf_rep_close(struct net_device *dev)
  96. {
  97. netif_carrier_off(dev);
  98. netif_tx_disable(dev);
  99. return 0;
  100. }
  101. static netdev_tx_t bnxt_vf_rep_xmit(struct sk_buff *skb,
  102. struct net_device *dev)
  103. {
  104. struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
  105. int rc, len = skb->len;
  106. skb_dst_drop(skb);
  107. dst_hold((struct dst_entry *)vf_rep->dst);
  108. skb_dst_set(skb, (struct dst_entry *)vf_rep->dst);
  109. skb->dev = vf_rep->dst->u.port_info.lower_dev;
  110. rc = dev_queue_xmit(skb);
  111. if (!rc) {
  112. vf_rep->tx_stats.packets++;
  113. vf_rep->tx_stats.bytes += len;
  114. }
  115. return rc;
  116. }
  117. static void
  118. bnxt_vf_rep_get_stats64(struct net_device *dev,
  119. struct rtnl_link_stats64 *stats)
  120. {
  121. struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
  122. stats->rx_packets = vf_rep->rx_stats.packets;
  123. stats->rx_bytes = vf_rep->rx_stats.bytes;
  124. stats->tx_packets = vf_rep->tx_stats.packets;
  125. stats->tx_bytes = vf_rep->tx_stats.bytes;
  126. }
  127. static int bnxt_vf_rep_setup_tc_block_cb(enum tc_setup_type type,
  128. void *type_data,
  129. void *cb_priv)
  130. {
  131. struct bnxt_vf_rep *vf_rep = cb_priv;
  132. struct bnxt *bp = vf_rep->bp;
  133. int vf_fid = bp->pf.vf[vf_rep->vf_idx].fw_fid;
  134. if (!bnxt_tc_flower_enabled(vf_rep->bp) ||
  135. !tc_cls_can_offload_and_chain0(bp->dev, type_data))
  136. return -EOPNOTSUPP;
  137. switch (type) {
  138. case TC_SETUP_CLSFLOWER:
  139. return bnxt_tc_setup_flower(bp, vf_fid, type_data);
  140. default:
  141. return -EOPNOTSUPP;
  142. }
  143. }
  144. static LIST_HEAD(bnxt_vf_block_cb_list);
  145. static int bnxt_vf_rep_setup_tc(struct net_device *dev, enum tc_setup_type type,
  146. void *type_data)
  147. {
  148. struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
  149. switch (type) {
  150. case TC_SETUP_BLOCK:
  151. return flow_block_cb_setup_simple(type_data,
  152. &bnxt_vf_block_cb_list,
  153. bnxt_vf_rep_setup_tc_block_cb,
  154. vf_rep, vf_rep, true);
  155. default:
  156. return -EOPNOTSUPP;
  157. }
  158. }
  159. struct net_device *bnxt_get_vf_rep(struct bnxt *bp, u16 cfa_code)
  160. {
  161. u16 vf_idx;
  162. if (cfa_code && bp->cfa_code_map && BNXT_PF(bp)) {
  163. vf_idx = bp->cfa_code_map[cfa_code];
  164. if (vf_idx != VF_IDX_INVALID)
  165. return bp->vf_reps[vf_idx]->dev;
  166. }
  167. return NULL;
  168. }
  169. void bnxt_vf_rep_rx(struct bnxt *bp, struct sk_buff *skb)
  170. {
  171. struct bnxt_vf_rep *vf_rep = netdev_priv(skb->dev);
  172. vf_rep->rx_stats.bytes += skb->len;
  173. vf_rep->rx_stats.packets++;
  174. netif_receive_skb(skb);
  175. }
  176. static int bnxt_vf_rep_get_phys_port_name(struct net_device *dev, char *buf,
  177. size_t len)
  178. {
  179. struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
  180. struct pci_dev *pf_pdev = vf_rep->bp->pdev;
  181. int rc;
  182. rc = snprintf(buf, len, "pf%dvf%d", PCI_FUNC(pf_pdev->devfn),
  183. vf_rep->vf_idx);
  184. if (rc >= len)
  185. return -EOPNOTSUPP;
  186. return 0;
  187. }
  188. static void bnxt_vf_rep_get_drvinfo(struct net_device *dev,
  189. struct ethtool_drvinfo *info)
  190. {
  191. strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
  192. }
  193. static int bnxt_vf_rep_get_port_parent_id(struct net_device *dev,
  194. struct netdev_phys_item_id *ppid)
  195. {
  196. struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
  197. /* as only PORT_PARENT_ID is supported currently use common code
  198. * between PF and VF-rep for now.
  199. */
  200. return bnxt_get_port_parent_id(vf_rep->bp->dev, ppid);
  201. }
  202. static const struct ethtool_ops bnxt_vf_rep_ethtool_ops = {
  203. .get_drvinfo = bnxt_vf_rep_get_drvinfo
  204. };
  205. static const struct net_device_ops bnxt_vf_rep_netdev_ops = {
  206. .ndo_open = bnxt_vf_rep_open,
  207. .ndo_stop = bnxt_vf_rep_close,
  208. .ndo_start_xmit = bnxt_vf_rep_xmit,
  209. .ndo_get_stats64 = bnxt_vf_rep_get_stats64,
  210. .ndo_setup_tc = bnxt_vf_rep_setup_tc,
  211. .ndo_get_port_parent_id = bnxt_vf_rep_get_port_parent_id,
  212. .ndo_get_phys_port_name = bnxt_vf_rep_get_phys_port_name
  213. };
  214. bool bnxt_dev_is_vf_rep(struct net_device *dev)
  215. {
  216. return dev->netdev_ops == &bnxt_vf_rep_netdev_ops;
  217. }
  218. /* Called when the parent PF interface is closed:
  219. * As the mode transition from SWITCHDEV to LEGACY
  220. * happens under the rtnl_lock() this routine is safe
  221. * under the rtnl_lock()
  222. */
  223. void bnxt_vf_reps_close(struct bnxt *bp)
  224. {
  225. struct bnxt_vf_rep *vf_rep;
  226. u16 num_vfs, i;
  227. if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
  228. return;
  229. num_vfs = pci_num_vf(bp->pdev);
  230. for (i = 0; i < num_vfs; i++) {
  231. vf_rep = bp->vf_reps[i];
  232. if (netif_running(vf_rep->dev))
  233. bnxt_vf_rep_close(vf_rep->dev);
  234. }
  235. }
  236. /* Called when the parent PF interface is opened (re-opened):
  237. * As the mode transition from SWITCHDEV to LEGACY
  238. * happen under the rtnl_lock() this routine is safe
  239. * under the rtnl_lock()
  240. */
  241. void bnxt_vf_reps_open(struct bnxt *bp)
  242. {
  243. int i;
  244. if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
  245. return;
  246. for (i = 0; i < pci_num_vf(bp->pdev); i++) {
  247. /* Open the VF-Rep only if it is allocated in the FW */
  248. if (bp->vf_reps[i]->tx_cfa_action != CFA_HANDLE_INVALID)
  249. bnxt_vf_rep_open(bp->vf_reps[i]->dev);
  250. }
  251. }
  252. static void __bnxt_free_one_vf_rep(struct bnxt *bp, struct bnxt_vf_rep *vf_rep)
  253. {
  254. if (!vf_rep)
  255. return;
  256. if (vf_rep->dst) {
  257. dst_release((struct dst_entry *)vf_rep->dst);
  258. vf_rep->dst = NULL;
  259. }
  260. if (vf_rep->tx_cfa_action != CFA_HANDLE_INVALID) {
  261. hwrm_cfa_vfr_free(bp, vf_rep->vf_idx);
  262. vf_rep->tx_cfa_action = CFA_HANDLE_INVALID;
  263. }
  264. }
  265. static void __bnxt_vf_reps_destroy(struct bnxt *bp)
  266. {
  267. u16 num_vfs = pci_num_vf(bp->pdev);
  268. struct bnxt_vf_rep *vf_rep;
  269. int i;
  270. for (i = 0; i < num_vfs; i++) {
  271. vf_rep = bp->vf_reps[i];
  272. if (vf_rep) {
  273. __bnxt_free_one_vf_rep(bp, vf_rep);
  274. if (vf_rep->dev) {
  275. /* if register_netdev failed, then netdev_ops
  276. * would have been set to NULL
  277. */
  278. if (vf_rep->dev->netdev_ops)
  279. unregister_netdev(vf_rep->dev);
  280. free_netdev(vf_rep->dev);
  281. }
  282. }
  283. }
  284. kfree(bp->vf_reps);
  285. bp->vf_reps = NULL;
  286. }
  287. void bnxt_vf_reps_destroy(struct bnxt *bp)
  288. {
  289. bool closed = false;
  290. if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
  291. return;
  292. if (!bp->vf_reps)
  293. return;
  294. /* Ensure that parent PF's and VF-reps' RX/TX has been quiesced
  295. * before proceeding with VF-rep cleanup.
  296. */
  297. rtnl_lock();
  298. if (netif_running(bp->dev)) {
  299. bnxt_close_nic(bp, false, false);
  300. closed = true;
  301. }
  302. /* un-publish cfa_code_map so that RX path can't see it anymore */
  303. kfree(bp->cfa_code_map);
  304. bp->cfa_code_map = NULL;
  305. if (closed) {
  306. /* Temporarily set legacy mode to avoid re-opening
  307. * representors and restore switchdev mode after that.
  308. */
  309. bp->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY;
  310. bnxt_open_nic(bp, false, false);
  311. bp->eswitch_mode = DEVLINK_ESWITCH_MODE_SWITCHDEV;
  312. }
  313. rtnl_unlock();
  314. /* Need to call vf_reps_destroy() outside of rntl_lock
  315. * as unregister_netdev takes rtnl_lock
  316. */
  317. __bnxt_vf_reps_destroy(bp);
  318. }
  319. /* Free the VF-Reps in firmware, during firmware hot-reset processing.
  320. * Note that the VF-Rep netdevs are still active (not unregistered) during
  321. * this process. As the mode transition from SWITCHDEV to LEGACY happens
  322. * under the rtnl_lock() this routine is safe under the rtnl_lock().
  323. */
  324. void bnxt_vf_reps_free(struct bnxt *bp)
  325. {
  326. u16 num_vfs = pci_num_vf(bp->pdev);
  327. int i;
  328. if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
  329. return;
  330. for (i = 0; i < num_vfs; i++)
  331. __bnxt_free_one_vf_rep(bp, bp->vf_reps[i]);
  332. }
  333. static int bnxt_alloc_vf_rep(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
  334. u16 *cfa_code_map)
  335. {
  336. /* get cfa handles from FW */
  337. if (hwrm_cfa_vfr_alloc(bp, vf_rep->vf_idx, &vf_rep->tx_cfa_action,
  338. &vf_rep->rx_cfa_code))
  339. return -ENOLINK;
  340. cfa_code_map[vf_rep->rx_cfa_code] = vf_rep->vf_idx;
  341. vf_rep->dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, GFP_KERNEL);
  342. if (!vf_rep->dst)
  343. return -ENOMEM;
  344. /* only cfa_action is needed to mux a packet while TXing */
  345. vf_rep->dst->u.port_info.port_id = vf_rep->tx_cfa_action;
  346. vf_rep->dst->u.port_info.lower_dev = bp->dev;
  347. return 0;
  348. }
  349. /* Allocate the VF-Reps in firmware, during firmware hot-reset processing.
  350. * Note that the VF-Rep netdevs are still active (not unregistered) during
  351. * this process. As the mode transition from SWITCHDEV to LEGACY happens
  352. * under the rtnl_lock() this routine is safe under the rtnl_lock().
  353. */
  354. int bnxt_vf_reps_alloc(struct bnxt *bp)
  355. {
  356. u16 *cfa_code_map = bp->cfa_code_map, num_vfs = pci_num_vf(bp->pdev);
  357. struct bnxt_vf_rep *vf_rep;
  358. int rc, i;
  359. if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
  360. return 0;
  361. if (!cfa_code_map)
  362. return -EINVAL;
  363. for (i = 0; i < MAX_CFA_CODE; i++)
  364. cfa_code_map[i] = VF_IDX_INVALID;
  365. for (i = 0; i < num_vfs; i++) {
  366. vf_rep = bp->vf_reps[i];
  367. vf_rep->vf_idx = i;
  368. rc = bnxt_alloc_vf_rep(bp, vf_rep, cfa_code_map);
  369. if (rc)
  370. goto err;
  371. }
  372. return 0;
  373. err:
  374. netdev_info(bp->dev, "%s error=%d\n", __func__, rc);
  375. bnxt_vf_reps_free(bp);
  376. return rc;
  377. }
  378. /* Use the OUI of the PF's perm addr and report the same mac addr
  379. * for the same VF-rep each time
  380. */
  381. static void bnxt_vf_rep_eth_addr_gen(u8 *src_mac, u16 vf_idx, u8 *mac)
  382. {
  383. u32 addr;
  384. ether_addr_copy(mac, src_mac);
  385. addr = jhash(src_mac, ETH_ALEN, 0) + vf_idx;
  386. mac[3] = (u8)(addr & 0xFF);
  387. mac[4] = (u8)((addr >> 8) & 0xFF);
  388. mac[5] = (u8)((addr >> 16) & 0xFF);
  389. }
  390. static void bnxt_vf_rep_netdev_init(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
  391. struct net_device *dev)
  392. {
  393. struct net_device *pf_dev = bp->dev;
  394. u16 max_mtu;
  395. SET_NETDEV_DEV(dev, &bp->pdev->dev);
  396. dev->netdev_ops = &bnxt_vf_rep_netdev_ops;
  397. dev->ethtool_ops = &bnxt_vf_rep_ethtool_ops;
  398. /* Just inherit all the featues of the parent PF as the VF-R
  399. * uses the RX/TX rings of the parent PF
  400. */
  401. dev->hw_features = pf_dev->hw_features;
  402. dev->gso_partial_features = pf_dev->gso_partial_features;
  403. dev->vlan_features = pf_dev->vlan_features;
  404. dev->hw_enc_features = pf_dev->hw_enc_features;
  405. dev->features |= pf_dev->features;
  406. bnxt_vf_rep_eth_addr_gen(bp->pf.mac_addr, vf_rep->vf_idx,
  407. dev->perm_addr);
  408. eth_hw_addr_set(dev, dev->perm_addr);
  409. /* Set VF-Rep's max-mtu to the corresponding VF's max-mtu */
  410. if (!bnxt_hwrm_vfr_qcfg(bp, vf_rep, &max_mtu))
  411. dev->max_mtu = max_mtu;
  412. dev->min_mtu = ETH_ZLEN;
  413. }
  414. int bnxt_vf_reps_create(struct bnxt *bp)
  415. {
  416. u16 *cfa_code_map = NULL, num_vfs = pci_num_vf(bp->pdev);
  417. struct bnxt_vf_rep *vf_rep;
  418. struct net_device *dev;
  419. int rc, i;
  420. if (!(bp->flags & BNXT_FLAG_DSN_VALID))
  421. return -ENODEV;
  422. bp->vf_reps = kcalloc(num_vfs, sizeof(vf_rep), GFP_KERNEL);
  423. if (!bp->vf_reps)
  424. return -ENOMEM;
  425. /* storage for cfa_code to vf-idx mapping */
  426. cfa_code_map = kmalloc_array(MAX_CFA_CODE, sizeof(*bp->cfa_code_map),
  427. GFP_KERNEL);
  428. if (!cfa_code_map) {
  429. rc = -ENOMEM;
  430. goto err;
  431. }
  432. for (i = 0; i < MAX_CFA_CODE; i++)
  433. cfa_code_map[i] = VF_IDX_INVALID;
  434. for (i = 0; i < num_vfs; i++) {
  435. dev = alloc_etherdev(sizeof(*vf_rep));
  436. if (!dev) {
  437. rc = -ENOMEM;
  438. goto err;
  439. }
  440. vf_rep = netdev_priv(dev);
  441. bp->vf_reps[i] = vf_rep;
  442. vf_rep->dev = dev;
  443. vf_rep->bp = bp;
  444. vf_rep->vf_idx = i;
  445. vf_rep->tx_cfa_action = CFA_HANDLE_INVALID;
  446. rc = bnxt_alloc_vf_rep(bp, vf_rep, cfa_code_map);
  447. if (rc)
  448. goto err;
  449. bnxt_vf_rep_netdev_init(bp, vf_rep, dev);
  450. rc = register_netdev(dev);
  451. if (rc) {
  452. /* no need for unregister_netdev in cleanup */
  453. dev->netdev_ops = NULL;
  454. goto err;
  455. }
  456. }
  457. /* publish cfa_code_map only after all VF-reps have been initialized */
  458. bp->cfa_code_map = cfa_code_map;
  459. netif_keep_dst(bp->dev);
  460. return 0;
  461. err:
  462. netdev_info(bp->dev, "%s error=%d\n", __func__, rc);
  463. kfree(cfa_code_map);
  464. __bnxt_vf_reps_destroy(bp);
  465. return rc;
  466. }
  467. /* Devlink related routines */
  468. int bnxt_dl_eswitch_mode_get(struct devlink *devlink, u16 *mode)
  469. {
  470. struct bnxt *bp = bnxt_get_bp_from_dl(devlink);
  471. *mode = bp->eswitch_mode;
  472. return 0;
  473. }
  474. int bnxt_dl_eswitch_mode_set(struct devlink *devlink, u16 mode,
  475. struct netlink_ext_ack *extack)
  476. {
  477. struct bnxt *bp = bnxt_get_bp_from_dl(devlink);
  478. int ret = 0;
  479. if (bp->eswitch_mode == mode) {
  480. netdev_info(bp->dev, "already in %s eswitch mode\n",
  481. mode == DEVLINK_ESWITCH_MODE_LEGACY ?
  482. "legacy" : "switchdev");
  483. return -EINVAL;
  484. }
  485. switch (mode) {
  486. case DEVLINK_ESWITCH_MODE_LEGACY:
  487. bnxt_vf_reps_destroy(bp);
  488. break;
  489. case DEVLINK_ESWITCH_MODE_SWITCHDEV:
  490. if (bp->hwrm_spec_code < 0x10803) {
  491. netdev_warn(bp->dev, "FW does not support SRIOV E-Switch SWITCHDEV mode\n");
  492. return -ENOTSUPP;
  493. }
  494. /* Create representors for existing VFs */
  495. if (pci_num_vf(bp->pdev) > 0)
  496. ret = bnxt_vf_reps_create(bp);
  497. break;
  498. default:
  499. return -EINVAL;
  500. }
  501. if (!ret)
  502. bp->eswitch_mode = mode;
  503. return ret;
  504. }
  505. #endif