fm10k_iov.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. /* Intel(R) Ethernet Switch Host Interface Driver
  2. * Copyright(c) 2013 - 2017 Intel Corporation.
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms and conditions of the GNU General Public License,
  6. * version 2, as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope it will be useful, but WITHOUT
  9. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  11. * more details.
  12. *
  13. * The full GNU General Public License is included in this distribution in
  14. * the file called "COPYING".
  15. *
  16. * Contact Information:
  17. * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
  18. * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  19. */
  20. #include "fm10k.h"
  21. #include "fm10k_vf.h"
  22. #include "fm10k_pf.h"
  23. static s32 fm10k_iov_msg_error(struct fm10k_hw *hw, u32 **results,
  24. struct fm10k_mbx_info *mbx)
  25. {
  26. struct fm10k_vf_info *vf_info = (struct fm10k_vf_info *)mbx;
  27. struct fm10k_intfc *interface = hw->back;
  28. struct pci_dev *pdev = interface->pdev;
  29. dev_err(&pdev->dev, "Unknown message ID %u on VF %d\n",
  30. **results & FM10K_TLV_ID_MASK, vf_info->vf_idx);
  31. return fm10k_tlv_msg_error(hw, results, mbx);
  32. }
  33. /**
  34. * fm10k_iov_msg_queue_mac_vlan - Message handler for MAC/VLAN request from VF
  35. * @hw: Pointer to hardware structure
  36. * @results: Pointer array to message, results[0] is pointer to message
  37. * @mbx: Pointer to mailbox information structure
  38. *
  39. * This function is a custom handler for MAC/VLAN requests from the VF. The
  40. * assumption is that it is acceptable to directly hand off the message from
  41. * the VF to the PF's switch manager. However, we use a MAC/VLAN message
  42. * queue to avoid overloading the mailbox when a large number of requests
  43. * come in.
  44. **/
  45. static s32 fm10k_iov_msg_queue_mac_vlan(struct fm10k_hw *hw, u32 **results,
  46. struct fm10k_mbx_info *mbx)
  47. {
  48. struct fm10k_vf_info *vf_info = (struct fm10k_vf_info *)mbx;
  49. struct fm10k_intfc *interface = hw->back;
  50. u8 mac[ETH_ALEN];
  51. u32 *result;
  52. int err = 0;
  53. bool set;
  54. u16 vlan;
  55. u32 vid;
  56. /* we shouldn't be updating rules on a disabled interface */
  57. if (!FM10K_VF_FLAG_ENABLED(vf_info))
  58. err = FM10K_ERR_PARAM;
  59. if (!err && !!results[FM10K_MAC_VLAN_MSG_VLAN]) {
  60. result = results[FM10K_MAC_VLAN_MSG_VLAN];
  61. /* record VLAN id requested */
  62. err = fm10k_tlv_attr_get_u32(result, &vid);
  63. if (err)
  64. return err;
  65. set = !(vid & FM10K_VLAN_CLEAR);
  66. vid &= ~FM10K_VLAN_CLEAR;
  67. /* if the length field has been set, this is a multi-bit
  68. * update request. For multi-bit requests, simply disallow
  69. * them when the pf_vid has been set. In this case, the PF
  70. * should have already cleared the VLAN_TABLE, and if we
  71. * allowed them, it could allow a rogue VF to receive traffic
  72. * on a VLAN it was not assigned. In the single-bit case, we
  73. * need to modify requests for VLAN 0 to use the default PF or
  74. * SW vid when assigned.
  75. */
  76. if (vid >> 16) {
  77. /* prevent multi-bit requests when PF has
  78. * administratively set the VLAN for this VF
  79. */
  80. if (vf_info->pf_vid)
  81. return FM10K_ERR_PARAM;
  82. } else {
  83. err = fm10k_iov_select_vid(vf_info, (u16)vid);
  84. if (err < 0)
  85. return err;
  86. vid = err;
  87. }
  88. /* update VSI info for VF in regards to VLAN table */
  89. err = hw->mac.ops.update_vlan(hw, vid, vf_info->vsi, set);
  90. }
  91. if (!err && !!results[FM10K_MAC_VLAN_MSG_MAC]) {
  92. result = results[FM10K_MAC_VLAN_MSG_MAC];
  93. /* record unicast MAC address requested */
  94. err = fm10k_tlv_attr_get_mac_vlan(result, mac, &vlan);
  95. if (err)
  96. return err;
  97. /* block attempts to set MAC for a locked device */
  98. if (is_valid_ether_addr(vf_info->mac) &&
  99. !ether_addr_equal(mac, vf_info->mac))
  100. return FM10K_ERR_PARAM;
  101. set = !(vlan & FM10K_VLAN_CLEAR);
  102. vlan &= ~FM10K_VLAN_CLEAR;
  103. err = fm10k_iov_select_vid(vf_info, vlan);
  104. if (err < 0)
  105. return err;
  106. vlan = (u16)err;
  107. /* Add this request to the MAC/VLAN queue */
  108. err = fm10k_queue_mac_request(interface, vf_info->glort,
  109. mac, vlan, set);
  110. }
  111. if (!err && !!results[FM10K_MAC_VLAN_MSG_MULTICAST]) {
  112. result = results[FM10K_MAC_VLAN_MSG_MULTICAST];
  113. /* record multicast MAC address requested */
  114. err = fm10k_tlv_attr_get_mac_vlan(result, mac, &vlan);
  115. if (err)
  116. return err;
  117. /* verify that the VF is allowed to request multicast */
  118. if (!(vf_info->vf_flags & FM10K_VF_FLAG_MULTI_ENABLED))
  119. return FM10K_ERR_PARAM;
  120. set = !(vlan & FM10K_VLAN_CLEAR);
  121. vlan &= ~FM10K_VLAN_CLEAR;
  122. err = fm10k_iov_select_vid(vf_info, vlan);
  123. if (err < 0)
  124. return err;
  125. vlan = (u16)err;
  126. /* Add this request to the MAC/VLAN queue */
  127. err = fm10k_queue_mac_request(interface, vf_info->glort,
  128. mac, vlan, set);
  129. }
  130. return err;
  131. }
  132. static const struct fm10k_msg_data iov_mbx_data[] = {
  133. FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test),
  134. FM10K_VF_MSG_MSIX_HANDLER(fm10k_iov_msg_msix_pf),
  135. FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_iov_msg_queue_mac_vlan),
  136. FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_iov_msg_lport_state_pf),
  137. FM10K_TLV_MSG_ERROR_HANDLER(fm10k_iov_msg_error),
  138. };
  139. s32 fm10k_iov_event(struct fm10k_intfc *interface)
  140. {
  141. struct fm10k_hw *hw = &interface->hw;
  142. struct fm10k_iov_data *iov_data;
  143. s64 vflre;
  144. int i;
  145. /* if there is no iov_data then there is no mailbox to process */
  146. if (!READ_ONCE(interface->iov_data))
  147. return 0;
  148. rcu_read_lock();
  149. iov_data = interface->iov_data;
  150. /* check again now that we are in the RCU block */
  151. if (!iov_data)
  152. goto read_unlock;
  153. if (!(fm10k_read_reg(hw, FM10K_EICR) & FM10K_EICR_VFLR))
  154. goto read_unlock;
  155. /* read VFLRE to determine if any VFs have been reset */
  156. vflre = fm10k_read_reg(hw, FM10K_PFVFLRE(1));
  157. vflre <<= 32;
  158. vflre |= fm10k_read_reg(hw, FM10K_PFVFLRE(0));
  159. i = iov_data->num_vfs;
  160. for (vflre <<= 64 - i; vflre && i--; vflre += vflre) {
  161. struct fm10k_vf_info *vf_info = &iov_data->vf_info[i];
  162. if (vflre >= 0)
  163. continue;
  164. hw->iov.ops.reset_resources(hw, vf_info);
  165. vf_info->mbx.ops.connect(hw, &vf_info->mbx);
  166. }
  167. read_unlock:
  168. rcu_read_unlock();
  169. return 0;
  170. }
  171. s32 fm10k_iov_mbx(struct fm10k_intfc *interface)
  172. {
  173. struct fm10k_hw *hw = &interface->hw;
  174. struct fm10k_iov_data *iov_data;
  175. int i;
  176. /* if there is no iov_data then there is no mailbox to process */
  177. if (!READ_ONCE(interface->iov_data))
  178. return 0;
  179. rcu_read_lock();
  180. iov_data = interface->iov_data;
  181. /* check again now that we are in the RCU block */
  182. if (!iov_data)
  183. goto read_unlock;
  184. /* lock the mailbox for transmit and receive */
  185. fm10k_mbx_lock(interface);
  186. /* Most VF messages sent to the PF cause the PF to respond by
  187. * requesting from the SM mailbox. This means that too many VF
  188. * messages processed at once could cause a mailbox timeout on the PF.
  189. * To prevent this, store a pointer to the next VF mbx to process. Use
  190. * that as the start of the loop so that we don't starve whichever VF
  191. * got ignored on the previous run.
  192. */
  193. process_mbx:
  194. for (i = iov_data->next_vf_mbx ? : iov_data->num_vfs; i--;) {
  195. struct fm10k_vf_info *vf_info = &iov_data->vf_info[i];
  196. struct fm10k_mbx_info *mbx = &vf_info->mbx;
  197. u16 glort = vf_info->glort;
  198. /* process the SM mailbox first to drain outgoing messages */
  199. hw->mbx.ops.process(hw, &hw->mbx);
  200. /* verify port mapping is valid, if not reset port */
  201. if (vf_info->vf_flags && !fm10k_glort_valid_pf(hw, glort)) {
  202. hw->iov.ops.reset_lport(hw, vf_info);
  203. fm10k_clear_macvlan_queue(interface, glort, false);
  204. }
  205. /* reset VFs that have mailbox timed out */
  206. if (!mbx->timeout) {
  207. hw->iov.ops.reset_resources(hw, vf_info);
  208. mbx->ops.connect(hw, mbx);
  209. }
  210. /* guarantee we have free space in the SM mailbox */
  211. if (!hw->mbx.ops.tx_ready(&hw->mbx, FM10K_VFMBX_MSG_MTU)) {
  212. /* keep track of how many times this occurs */
  213. interface->hw_sm_mbx_full++;
  214. /* make sure we try again momentarily */
  215. fm10k_service_event_schedule(interface);
  216. break;
  217. }
  218. /* cleanup mailbox and process received messages */
  219. mbx->ops.process(hw, mbx);
  220. }
  221. /* if we stopped processing mailboxes early, update next_vf_mbx.
  222. * Otherwise, reset next_vf_mbx, and restart loop so that we process
  223. * the remaining mailboxes we skipped at the start.
  224. */
  225. if (i >= 0) {
  226. iov_data->next_vf_mbx = i + 1;
  227. } else if (iov_data->next_vf_mbx) {
  228. iov_data->next_vf_mbx = 0;
  229. goto process_mbx;
  230. }
  231. /* free the lock */
  232. fm10k_mbx_unlock(interface);
  233. read_unlock:
  234. rcu_read_unlock();
  235. return 0;
  236. }
  237. void fm10k_iov_suspend(struct pci_dev *pdev)
  238. {
  239. struct fm10k_intfc *interface = pci_get_drvdata(pdev);
  240. struct fm10k_iov_data *iov_data = interface->iov_data;
  241. struct fm10k_hw *hw = &interface->hw;
  242. int num_vfs, i;
  243. /* pull out num_vfs from iov_data */
  244. num_vfs = iov_data ? iov_data->num_vfs : 0;
  245. /* shut down queue mapping for VFs */
  246. fm10k_write_reg(hw, FM10K_DGLORTMAP(fm10k_dglort_vf_rss),
  247. FM10K_DGLORTMAP_NONE);
  248. /* Stop any active VFs and reset their resources */
  249. for (i = 0; i < num_vfs; i++) {
  250. struct fm10k_vf_info *vf_info = &iov_data->vf_info[i];
  251. hw->iov.ops.reset_resources(hw, vf_info);
  252. hw->iov.ops.reset_lport(hw, vf_info);
  253. fm10k_clear_macvlan_queue(interface, vf_info->glort, false);
  254. }
  255. }
  256. int fm10k_iov_resume(struct pci_dev *pdev)
  257. {
  258. struct fm10k_intfc *interface = pci_get_drvdata(pdev);
  259. struct fm10k_iov_data *iov_data = interface->iov_data;
  260. struct fm10k_dglort_cfg dglort = { 0 };
  261. struct fm10k_hw *hw = &interface->hw;
  262. int num_vfs, i;
  263. /* pull out num_vfs from iov_data */
  264. num_vfs = iov_data ? iov_data->num_vfs : 0;
  265. /* return error if iov_data is not already populated */
  266. if (!iov_data)
  267. return -ENOMEM;
  268. /* allocate hardware resources for the VFs */
  269. hw->iov.ops.assign_resources(hw, num_vfs, num_vfs);
  270. /* configure DGLORT mapping for RSS */
  271. dglort.glort = hw->mac.dglort_map & FM10K_DGLORTMAP_NONE;
  272. dglort.idx = fm10k_dglort_vf_rss;
  273. dglort.inner_rss = 1;
  274. dglort.rss_l = fls(fm10k_queues_per_pool(hw) - 1);
  275. dglort.queue_b = fm10k_vf_queue_index(hw, 0);
  276. dglort.vsi_l = fls(hw->iov.total_vfs - 1);
  277. dglort.vsi_b = 1;
  278. hw->mac.ops.configure_dglort_map(hw, &dglort);
  279. /* assign resources to the device */
  280. for (i = 0; i < num_vfs; i++) {
  281. struct fm10k_vf_info *vf_info = &iov_data->vf_info[i];
  282. /* allocate all but the last GLORT to the VFs */
  283. if (i == ((~hw->mac.dglort_map) >> FM10K_DGLORTMAP_MASK_SHIFT))
  284. break;
  285. /* assign GLORT to VF, and restrict it to multicast */
  286. hw->iov.ops.set_lport(hw, vf_info, i,
  287. FM10K_VF_FLAG_MULTI_CAPABLE);
  288. /* mailbox is disconnected so we don't send a message */
  289. hw->iov.ops.assign_default_mac_vlan(hw, vf_info);
  290. /* now we are ready so we can connect */
  291. vf_info->mbx.ops.connect(hw, &vf_info->mbx);
  292. }
  293. return 0;
  294. }
  295. s32 fm10k_iov_update_pvid(struct fm10k_intfc *interface, u16 glort, u16 pvid)
  296. {
  297. struct fm10k_iov_data *iov_data = interface->iov_data;
  298. struct fm10k_hw *hw = &interface->hw;
  299. struct fm10k_vf_info *vf_info;
  300. u16 vf_idx = (glort - hw->mac.dglort_map) & FM10K_DGLORTMAP_NONE;
  301. /* no IOV support, not our message to process */
  302. if (!iov_data)
  303. return FM10K_ERR_PARAM;
  304. /* glort outside our range, not our message to process */
  305. if (vf_idx >= iov_data->num_vfs)
  306. return FM10K_ERR_PARAM;
  307. /* determine if an update has occurred and if so notify the VF */
  308. vf_info = &iov_data->vf_info[vf_idx];
  309. if (vf_info->sw_vid != pvid) {
  310. vf_info->sw_vid = pvid;
  311. hw->iov.ops.assign_default_mac_vlan(hw, vf_info);
  312. }
  313. return 0;
  314. }
  315. static void fm10k_iov_free_data(struct pci_dev *pdev)
  316. {
  317. struct fm10k_intfc *interface = pci_get_drvdata(pdev);
  318. if (!interface->iov_data)
  319. return;
  320. /* reclaim hardware resources */
  321. fm10k_iov_suspend(pdev);
  322. /* drop iov_data from interface */
  323. kfree_rcu(interface->iov_data, rcu);
  324. interface->iov_data = NULL;
  325. }
  326. static s32 fm10k_iov_alloc_data(struct pci_dev *pdev, int num_vfs)
  327. {
  328. struct fm10k_intfc *interface = pci_get_drvdata(pdev);
  329. struct fm10k_iov_data *iov_data = interface->iov_data;
  330. struct fm10k_hw *hw = &interface->hw;
  331. size_t size;
  332. int i, err;
  333. /* return error if iov_data is already populated */
  334. if (iov_data)
  335. return -EBUSY;
  336. /* The PF should always be able to assign resources */
  337. if (!hw->iov.ops.assign_resources)
  338. return -ENODEV;
  339. /* nothing to do if no VFs are requested */
  340. if (!num_vfs)
  341. return 0;
  342. /* allocate memory for VF storage */
  343. size = offsetof(struct fm10k_iov_data, vf_info[num_vfs]);
  344. iov_data = kzalloc(size, GFP_KERNEL);
  345. if (!iov_data)
  346. return -ENOMEM;
  347. /* record number of VFs */
  348. iov_data->num_vfs = num_vfs;
  349. /* loop through vf_info structures initializing each entry */
  350. for (i = 0; i < num_vfs; i++) {
  351. struct fm10k_vf_info *vf_info = &iov_data->vf_info[i];
  352. /* Record VF VSI value */
  353. vf_info->vsi = i + 1;
  354. vf_info->vf_idx = i;
  355. /* initialize mailbox memory */
  356. err = fm10k_pfvf_mbx_init(hw, &vf_info->mbx, iov_mbx_data, i);
  357. if (err) {
  358. dev_err(&pdev->dev,
  359. "Unable to initialize SR-IOV mailbox\n");
  360. kfree(iov_data);
  361. return err;
  362. }
  363. }
  364. /* assign iov_data to interface */
  365. interface->iov_data = iov_data;
  366. /* allocate hardware resources for the VFs */
  367. fm10k_iov_resume(pdev);
  368. return 0;
  369. }
  370. void fm10k_iov_disable(struct pci_dev *pdev)
  371. {
  372. if (pci_num_vf(pdev) && pci_vfs_assigned(pdev))
  373. dev_err(&pdev->dev,
  374. "Cannot disable SR-IOV while VFs are assigned\n");
  375. else
  376. pci_disable_sriov(pdev);
  377. fm10k_iov_free_data(pdev);
  378. }
  379. static void fm10k_disable_aer_comp_abort(struct pci_dev *pdev)
  380. {
  381. u32 err_sev;
  382. int pos;
  383. pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
  384. if (!pos)
  385. return;
  386. pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_SEVER, &err_sev);
  387. err_sev &= ~PCI_ERR_UNC_COMP_ABORT;
  388. pci_write_config_dword(pdev, pos + PCI_ERR_UNCOR_SEVER, err_sev);
  389. }
  390. int fm10k_iov_configure(struct pci_dev *pdev, int num_vfs)
  391. {
  392. int current_vfs = pci_num_vf(pdev);
  393. int err = 0;
  394. if (current_vfs && pci_vfs_assigned(pdev)) {
  395. dev_err(&pdev->dev,
  396. "Cannot modify SR-IOV while VFs are assigned\n");
  397. num_vfs = current_vfs;
  398. } else {
  399. pci_disable_sriov(pdev);
  400. fm10k_iov_free_data(pdev);
  401. }
  402. /* allocate resources for the VFs */
  403. err = fm10k_iov_alloc_data(pdev, num_vfs);
  404. if (err)
  405. return err;
  406. /* allocate VFs if not already allocated */
  407. if (num_vfs && (num_vfs != current_vfs)) {
  408. /* Disable completer abort error reporting as
  409. * the VFs can trigger this any time they read a queue
  410. * that they don't own.
  411. */
  412. fm10k_disable_aer_comp_abort(pdev);
  413. err = pci_enable_sriov(pdev, num_vfs);
  414. if (err) {
  415. dev_err(&pdev->dev,
  416. "Enable PCI SR-IOV failed: %d\n", err);
  417. return err;
  418. }
  419. }
  420. return num_vfs;
  421. }
  422. static inline void fm10k_reset_vf_info(struct fm10k_intfc *interface,
  423. struct fm10k_vf_info *vf_info)
  424. {
  425. struct fm10k_hw *hw = &interface->hw;
  426. /* assigning the MAC address will send a mailbox message */
  427. fm10k_mbx_lock(interface);
  428. /* disable LPORT for this VF which clears switch rules */
  429. hw->iov.ops.reset_lport(hw, vf_info);
  430. fm10k_clear_macvlan_queue(interface, vf_info->glort, false);
  431. /* assign new MAC+VLAN for this VF */
  432. hw->iov.ops.assign_default_mac_vlan(hw, vf_info);
  433. /* re-enable the LPORT for this VF */
  434. hw->iov.ops.set_lport(hw, vf_info, vf_info->vf_idx,
  435. FM10K_VF_FLAG_MULTI_CAPABLE);
  436. fm10k_mbx_unlock(interface);
  437. }
  438. int fm10k_ndo_set_vf_mac(struct net_device *netdev, int vf_idx, u8 *mac)
  439. {
  440. struct fm10k_intfc *interface = netdev_priv(netdev);
  441. struct fm10k_iov_data *iov_data = interface->iov_data;
  442. struct fm10k_vf_info *vf_info;
  443. /* verify SR-IOV is active and that vf idx is valid */
  444. if (!iov_data || vf_idx >= iov_data->num_vfs)
  445. return -EINVAL;
  446. /* verify MAC addr is valid */
  447. if (!is_zero_ether_addr(mac) && !is_valid_ether_addr(mac))
  448. return -EINVAL;
  449. /* record new MAC address */
  450. vf_info = &iov_data->vf_info[vf_idx];
  451. ether_addr_copy(vf_info->mac, mac);
  452. fm10k_reset_vf_info(interface, vf_info);
  453. return 0;
  454. }
  455. int fm10k_ndo_set_vf_vlan(struct net_device *netdev, int vf_idx, u16 vid,
  456. u8 qos, __be16 vlan_proto)
  457. {
  458. struct fm10k_intfc *interface = netdev_priv(netdev);
  459. struct fm10k_iov_data *iov_data = interface->iov_data;
  460. struct fm10k_hw *hw = &interface->hw;
  461. struct fm10k_vf_info *vf_info;
  462. /* verify SR-IOV is active and that vf idx is valid */
  463. if (!iov_data || vf_idx >= iov_data->num_vfs)
  464. return -EINVAL;
  465. /* QOS is unsupported and VLAN IDs accepted range 0-4094 */
  466. if (qos || (vid > (VLAN_VID_MASK - 1)))
  467. return -EINVAL;
  468. /* VF VLAN Protocol part to default is unsupported */
  469. if (vlan_proto != htons(ETH_P_8021Q))
  470. return -EPROTONOSUPPORT;
  471. vf_info = &iov_data->vf_info[vf_idx];
  472. /* exit if there is nothing to do */
  473. if (vf_info->pf_vid == vid)
  474. return 0;
  475. /* record default VLAN ID for VF */
  476. vf_info->pf_vid = vid;
  477. /* Clear the VLAN table for the VF */
  478. hw->mac.ops.update_vlan(hw, FM10K_VLAN_ALL, vf_info->vsi, false);
  479. fm10k_reset_vf_info(interface, vf_info);
  480. return 0;
  481. }
  482. int fm10k_ndo_set_vf_bw(struct net_device *netdev, int vf_idx,
  483. int __always_unused min_rate, int max_rate)
  484. {
  485. struct fm10k_intfc *interface = netdev_priv(netdev);
  486. struct fm10k_iov_data *iov_data = interface->iov_data;
  487. struct fm10k_hw *hw = &interface->hw;
  488. /* verify SR-IOV is active and that vf idx is valid */
  489. if (!iov_data || vf_idx >= iov_data->num_vfs)
  490. return -EINVAL;
  491. /* rate limit cannot be less than 10Mbs or greater than link speed */
  492. if (max_rate &&
  493. (max_rate < FM10K_VF_TC_MIN || max_rate > FM10K_VF_TC_MAX))
  494. return -EINVAL;
  495. /* store values */
  496. iov_data->vf_info[vf_idx].rate = max_rate;
  497. /* update hardware configuration */
  498. hw->iov.ops.configure_tc(hw, vf_idx, max_rate);
  499. return 0;
  500. }
  501. int fm10k_ndo_get_vf_config(struct net_device *netdev,
  502. int vf_idx, struct ifla_vf_info *ivi)
  503. {
  504. struct fm10k_intfc *interface = netdev_priv(netdev);
  505. struct fm10k_iov_data *iov_data = interface->iov_data;
  506. struct fm10k_vf_info *vf_info;
  507. /* verify SR-IOV is active and that vf idx is valid */
  508. if (!iov_data || vf_idx >= iov_data->num_vfs)
  509. return -EINVAL;
  510. vf_info = &iov_data->vf_info[vf_idx];
  511. ivi->vf = vf_idx;
  512. ivi->max_tx_rate = vf_info->rate;
  513. ivi->min_tx_rate = 0;
  514. ether_addr_copy(ivi->mac, vf_info->mac);
  515. ivi->vlan = vf_info->pf_vid;
  516. ivi->qos = 0;
  517. return 0;
  518. }