fm10k_vf.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Intel(R) Ethernet Switch Host Interface Driver
  3. * Copyright(c) 2013 - 2016 Intel Corporation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms and conditions of the GNU General Public License,
  7. * version 2, as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * The full GNU General Public License is included in this distribution in
  15. * the file called "COPYING".
  16. *
  17. * Contact Information:
  18. * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
  19. * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  20. */
  21. #include "fm10k_vf.h"
  22. /**
  23. * fm10k_stop_hw_vf - Stop Tx/Rx units
  24. * @hw: pointer to hardware structure
  25. *
  26. **/
  27. static s32 fm10k_stop_hw_vf(struct fm10k_hw *hw)
  28. {
  29. u8 *perm_addr = hw->mac.perm_addr;
  30. u32 bal = 0, bah = 0, tdlen;
  31. s32 err;
  32. u16 i;
  33. /* we need to disable the queues before taking further steps */
  34. err = fm10k_stop_hw_generic(hw);
  35. if (err && err != FM10K_ERR_REQUESTS_PENDING)
  36. return err;
  37. /* If permanent address is set then we need to restore it */
  38. if (is_valid_ether_addr(perm_addr)) {
  39. bal = (((u32)perm_addr[3]) << 24) |
  40. (((u32)perm_addr[4]) << 16) |
  41. (((u32)perm_addr[5]) << 8);
  42. bah = (((u32)0xFF) << 24) |
  43. (((u32)perm_addr[0]) << 16) |
  44. (((u32)perm_addr[1]) << 8) |
  45. ((u32)perm_addr[2]);
  46. }
  47. /* restore default itr_scale for next VF initialization */
  48. tdlen = hw->mac.itr_scale << FM10K_TDLEN_ITR_SCALE_SHIFT;
  49. /* The queues have already been disabled so we just need to
  50. * update their base address registers
  51. */
  52. for (i = 0; i < hw->mac.max_queues; i++) {
  53. fm10k_write_reg(hw, FM10K_TDBAL(i), bal);
  54. fm10k_write_reg(hw, FM10K_TDBAH(i), bah);
  55. fm10k_write_reg(hw, FM10K_RDBAL(i), bal);
  56. fm10k_write_reg(hw, FM10K_RDBAH(i), bah);
  57. /* Restore ITR scale in software-defined mechanism in TDLEN
  58. * for next VF initialization. See definition of
  59. * FM10K_TDLEN_ITR_SCALE_SHIFT for more details on the use of
  60. * TDLEN here.
  61. */
  62. fm10k_write_reg(hw, FM10K_TDLEN(i), tdlen);
  63. }
  64. return err;
  65. }
  66. /**
  67. * fm10k_reset_hw_vf - VF hardware reset
  68. * @hw: pointer to hardware structure
  69. *
  70. * This function should return the hardware to a state similar to the
  71. * one it is in after just being initialized.
  72. **/
  73. static s32 fm10k_reset_hw_vf(struct fm10k_hw *hw)
  74. {
  75. s32 err;
  76. /* shut down queues we own and reset DMA configuration */
  77. err = fm10k_stop_hw_vf(hw);
  78. if (err == FM10K_ERR_REQUESTS_PENDING)
  79. hw->mac.reset_while_pending++;
  80. else if (err)
  81. return err;
  82. /* Inititate VF reset */
  83. fm10k_write_reg(hw, FM10K_VFCTRL, FM10K_VFCTRL_RST);
  84. /* Flush write and allow 100us for reset to complete */
  85. fm10k_write_flush(hw);
  86. udelay(FM10K_RESET_TIMEOUT);
  87. /* Clear reset bit and verify it was cleared */
  88. fm10k_write_reg(hw, FM10K_VFCTRL, 0);
  89. if (fm10k_read_reg(hw, FM10K_VFCTRL) & FM10K_VFCTRL_RST)
  90. return FM10K_ERR_RESET_FAILED;
  91. return 0;
  92. }
  93. /**
  94. * fm10k_init_hw_vf - VF hardware initialization
  95. * @hw: pointer to hardware structure
  96. *
  97. **/
  98. static s32 fm10k_init_hw_vf(struct fm10k_hw *hw)
  99. {
  100. u32 tqdloc, tqdloc0 = ~fm10k_read_reg(hw, FM10K_TQDLOC(0));
  101. s32 err;
  102. u16 i;
  103. /* verify we have at least 1 queue */
  104. if (!~fm10k_read_reg(hw, FM10K_TXQCTL(0)) ||
  105. !~fm10k_read_reg(hw, FM10K_RXQCTL(0))) {
  106. err = FM10K_ERR_NO_RESOURCES;
  107. goto reset_max_queues;
  108. }
  109. /* determine how many queues we have */
  110. for (i = 1; tqdloc0 && (i < FM10K_MAX_QUEUES_POOL); i++) {
  111. /* verify the Descriptor cache offsets are increasing */
  112. tqdloc = ~fm10k_read_reg(hw, FM10K_TQDLOC(i));
  113. if (!tqdloc || (tqdloc == tqdloc0))
  114. break;
  115. /* check to verify the PF doesn't own any of our queues */
  116. if (!~fm10k_read_reg(hw, FM10K_TXQCTL(i)) ||
  117. !~fm10k_read_reg(hw, FM10K_RXQCTL(i)))
  118. break;
  119. }
  120. /* shut down queues we own and reset DMA configuration */
  121. err = fm10k_disable_queues_generic(hw, i);
  122. if (err)
  123. goto reset_max_queues;
  124. /* record maximum queue count */
  125. hw->mac.max_queues = i;
  126. /* fetch default VLAN and ITR scale */
  127. hw->mac.default_vid = (fm10k_read_reg(hw, FM10K_TXQCTL(0)) &
  128. FM10K_TXQCTL_VID_MASK) >> FM10K_TXQCTL_VID_SHIFT;
  129. /* Read the ITR scale from TDLEN. See the definition of
  130. * FM10K_TDLEN_ITR_SCALE_SHIFT for more information about how TDLEN is
  131. * used here.
  132. */
  133. hw->mac.itr_scale = (fm10k_read_reg(hw, FM10K_TDLEN(0)) &
  134. FM10K_TDLEN_ITR_SCALE_MASK) >>
  135. FM10K_TDLEN_ITR_SCALE_SHIFT;
  136. return 0;
  137. reset_max_queues:
  138. hw->mac.max_queues = 0;
  139. return err;
  140. }
  141. /* This structure defines the attibutes to be parsed below */
  142. const struct fm10k_tlv_attr fm10k_mac_vlan_msg_attr[] = {
  143. FM10K_TLV_ATTR_U32(FM10K_MAC_VLAN_MSG_VLAN),
  144. FM10K_TLV_ATTR_BOOL(FM10K_MAC_VLAN_MSG_SET),
  145. FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_MAC),
  146. FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_DEFAULT_MAC),
  147. FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_MULTICAST),
  148. FM10K_TLV_ATTR_LAST
  149. };
  150. /**
  151. * fm10k_update_vlan_vf - Update status of VLAN ID in VLAN filter table
  152. * @hw: pointer to hardware structure
  153. * @vid: VLAN ID to add to table
  154. * @vsi: Reserved, should always be 0
  155. * @set: Indicates if this is a set or clear operation
  156. *
  157. * This function adds or removes the corresponding VLAN ID from the VLAN
  158. * filter table for this VF.
  159. **/
  160. static s32 fm10k_update_vlan_vf(struct fm10k_hw *hw, u32 vid, u8 vsi, bool set)
  161. {
  162. struct fm10k_mbx_info *mbx = &hw->mbx;
  163. u32 msg[4];
  164. /* verify the index is not set */
  165. if (vsi)
  166. return FM10K_ERR_PARAM;
  167. /* clever trick to verify reserved bits in both vid and length */
  168. if ((vid << 16 | vid) >> 28)
  169. return FM10K_ERR_PARAM;
  170. /* encode set bit into the VLAN ID */
  171. if (!set)
  172. vid |= FM10K_VLAN_CLEAR;
  173. /* generate VLAN request */
  174. fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
  175. fm10k_tlv_attr_put_u32(msg, FM10K_MAC_VLAN_MSG_VLAN, vid);
  176. /* load onto outgoing mailbox */
  177. return mbx->ops.enqueue_tx(hw, mbx, msg);
  178. }
  179. /**
  180. * fm10k_msg_mac_vlan_vf - Read device MAC address from mailbox message
  181. * @hw: pointer to the HW structure
  182. * @results: Attributes for message
  183. * @mbx: unused mailbox data
  184. *
  185. * This function should determine the MAC address for the VF
  186. **/
  187. s32 fm10k_msg_mac_vlan_vf(struct fm10k_hw *hw, u32 **results,
  188. struct fm10k_mbx_info *mbx)
  189. {
  190. u8 perm_addr[ETH_ALEN];
  191. u16 vid;
  192. s32 err;
  193. /* record MAC address requested */
  194. err = fm10k_tlv_attr_get_mac_vlan(
  195. results[FM10K_MAC_VLAN_MSG_DEFAULT_MAC],
  196. perm_addr, &vid);
  197. if (err)
  198. return err;
  199. ether_addr_copy(hw->mac.perm_addr, perm_addr);
  200. hw->mac.default_vid = vid & (FM10K_VLAN_TABLE_VID_MAX - 1);
  201. hw->mac.vlan_override = !!(vid & FM10K_VLAN_OVERRIDE);
  202. return 0;
  203. }
  204. /**
  205. * fm10k_read_mac_addr_vf - Read device MAC address
  206. * @hw: pointer to the HW structure
  207. *
  208. * This function should determine the MAC address for the VF
  209. **/
  210. static s32 fm10k_read_mac_addr_vf(struct fm10k_hw *hw)
  211. {
  212. u8 perm_addr[ETH_ALEN];
  213. u32 base_addr;
  214. base_addr = fm10k_read_reg(hw, FM10K_TDBAL(0));
  215. /* last byte should be 0 */
  216. if (base_addr << 24)
  217. return FM10K_ERR_INVALID_MAC_ADDR;
  218. perm_addr[3] = (u8)(base_addr >> 24);
  219. perm_addr[4] = (u8)(base_addr >> 16);
  220. perm_addr[5] = (u8)(base_addr >> 8);
  221. base_addr = fm10k_read_reg(hw, FM10K_TDBAH(0));
  222. /* first byte should be all 1's */
  223. if ((~base_addr) >> 24)
  224. return FM10K_ERR_INVALID_MAC_ADDR;
  225. perm_addr[0] = (u8)(base_addr >> 16);
  226. perm_addr[1] = (u8)(base_addr >> 8);
  227. perm_addr[2] = (u8)(base_addr);
  228. ether_addr_copy(hw->mac.perm_addr, perm_addr);
  229. ether_addr_copy(hw->mac.addr, perm_addr);
  230. return 0;
  231. }
  232. /**
  233. * fm10k_update_uc_addr_vf - Update device unicast addresses
  234. * @hw: pointer to the HW structure
  235. * @glort: unused
  236. * @mac: MAC address to add/remove from table
  237. * @vid: VLAN ID to add/remove from table
  238. * @add: Indicates if this is an add or remove operation
  239. * @flags: flags field to indicate add and secure - unused
  240. *
  241. * This function is used to add or remove unicast MAC addresses for
  242. * the VF.
  243. **/
  244. static s32 fm10k_update_uc_addr_vf(struct fm10k_hw *hw, u16 glort,
  245. const u8 *mac, u16 vid, bool add, u8 flags)
  246. {
  247. struct fm10k_mbx_info *mbx = &hw->mbx;
  248. u32 msg[7];
  249. /* verify VLAN ID is valid */
  250. if (vid >= FM10K_VLAN_TABLE_VID_MAX)
  251. return FM10K_ERR_PARAM;
  252. /* verify MAC address is valid */
  253. if (!is_valid_ether_addr(mac))
  254. return FM10K_ERR_PARAM;
  255. /* verify we are not locked down on the MAC address */
  256. if (is_valid_ether_addr(hw->mac.perm_addr) &&
  257. !ether_addr_equal(hw->mac.perm_addr, mac))
  258. return FM10K_ERR_PARAM;
  259. /* add bit to notify us if this is a set or clear operation */
  260. if (!add)
  261. vid |= FM10K_VLAN_CLEAR;
  262. /* generate VLAN request */
  263. fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
  264. fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_MAC, mac, vid);
  265. /* load onto outgoing mailbox */
  266. return mbx->ops.enqueue_tx(hw, mbx, msg);
  267. }
  268. /**
  269. * fm10k_update_mc_addr_vf - Update device multicast addresses
  270. * @hw: pointer to the HW structure
  271. * @glort: unused
  272. * @mac: MAC address to add/remove from table
  273. * @vid: VLAN ID to add/remove from table
  274. * @add: Indicates if this is an add or remove operation
  275. *
  276. * This function is used to add or remove multicast MAC addresses for
  277. * the VF.
  278. **/
  279. static s32 fm10k_update_mc_addr_vf(struct fm10k_hw *hw, u16 glort,
  280. const u8 *mac, u16 vid, bool add)
  281. {
  282. struct fm10k_mbx_info *mbx = &hw->mbx;
  283. u32 msg[7];
  284. /* verify VLAN ID is valid */
  285. if (vid >= FM10K_VLAN_TABLE_VID_MAX)
  286. return FM10K_ERR_PARAM;
  287. /* verify multicast address is valid */
  288. if (!is_multicast_ether_addr(mac))
  289. return FM10K_ERR_PARAM;
  290. /* add bit to notify us if this is a set or clear operation */
  291. if (!add)
  292. vid |= FM10K_VLAN_CLEAR;
  293. /* generate VLAN request */
  294. fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
  295. fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_MULTICAST,
  296. mac, vid);
  297. /* load onto outgoing mailbox */
  298. return mbx->ops.enqueue_tx(hw, mbx, msg);
  299. }
  300. /**
  301. * fm10k_update_int_moderator_vf - Request update of interrupt moderator list
  302. * @hw: pointer to hardware structure
  303. *
  304. * This function will issue a request to the PF to rescan our MSI-X table
  305. * and to update the interrupt moderator linked list.
  306. **/
  307. static void fm10k_update_int_moderator_vf(struct fm10k_hw *hw)
  308. {
  309. struct fm10k_mbx_info *mbx = &hw->mbx;
  310. u32 msg[1];
  311. /* generate MSI-X request */
  312. fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MSIX);
  313. /* load onto outgoing mailbox */
  314. mbx->ops.enqueue_tx(hw, mbx, msg);
  315. }
  316. /* This structure defines the attibutes to be parsed below */
  317. const struct fm10k_tlv_attr fm10k_lport_state_msg_attr[] = {
  318. FM10K_TLV_ATTR_BOOL(FM10K_LPORT_STATE_MSG_DISABLE),
  319. FM10K_TLV_ATTR_U8(FM10K_LPORT_STATE_MSG_XCAST_MODE),
  320. FM10K_TLV_ATTR_BOOL(FM10K_LPORT_STATE_MSG_READY),
  321. FM10K_TLV_ATTR_LAST
  322. };
  323. /**
  324. * fm10k_msg_lport_state_vf - Message handler for lport_state message from PF
  325. * @hw: Pointer to hardware structure
  326. * @results: pointer array containing parsed data
  327. * @mbx: Pointer to mailbox information structure
  328. *
  329. * This handler is meant to capture the indication from the PF that we
  330. * are ready to bring up the interface.
  331. **/
  332. s32 fm10k_msg_lport_state_vf(struct fm10k_hw *hw, u32 **results,
  333. struct fm10k_mbx_info *mbx)
  334. {
  335. hw->mac.dglort_map = !results[FM10K_LPORT_STATE_MSG_READY] ?
  336. FM10K_DGLORTMAP_NONE : FM10K_DGLORTMAP_ZERO;
  337. return 0;
  338. }
  339. /**
  340. * fm10k_update_lport_state_vf - Update device state in lower device
  341. * @hw: pointer to the HW structure
  342. * @glort: unused
  343. * @count: number of logical ports to enable - unused (always 1)
  344. * @enable: boolean value indicating if this is an enable or disable request
  345. *
  346. * Notify the lower device of a state change. If the lower device is
  347. * enabled we can add filters, if it is disabled all filters for this
  348. * logical port are flushed.
  349. **/
  350. static s32 fm10k_update_lport_state_vf(struct fm10k_hw *hw, u16 glort,
  351. u16 count, bool enable)
  352. {
  353. struct fm10k_mbx_info *mbx = &hw->mbx;
  354. u32 msg[2];
  355. /* reset glort mask 0 as we have to wait to be enabled */
  356. hw->mac.dglort_map = FM10K_DGLORTMAP_NONE;
  357. /* generate port state request */
  358. fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
  359. if (!enable)
  360. fm10k_tlv_attr_put_bool(msg, FM10K_LPORT_STATE_MSG_DISABLE);
  361. /* load onto outgoing mailbox */
  362. return mbx->ops.enqueue_tx(hw, mbx, msg);
  363. }
  364. /**
  365. * fm10k_update_xcast_mode_vf - Request update of multicast mode
  366. * @hw: pointer to hardware structure
  367. * @glort: unused
  368. * @mode: integer value indicating mode being requested
  369. *
  370. * This function will attempt to request a higher mode for the port
  371. * so that it can enable either multicast, multicast promiscuous, or
  372. * promiscuous mode of operation.
  373. **/
  374. static s32 fm10k_update_xcast_mode_vf(struct fm10k_hw *hw, u16 glort, u8 mode)
  375. {
  376. struct fm10k_mbx_info *mbx = &hw->mbx;
  377. u32 msg[3];
  378. if (mode > FM10K_XCAST_MODE_NONE)
  379. return FM10K_ERR_PARAM;
  380. /* generate message requesting to change xcast mode */
  381. fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
  382. fm10k_tlv_attr_put_u8(msg, FM10K_LPORT_STATE_MSG_XCAST_MODE, mode);
  383. /* load onto outgoing mailbox */
  384. return mbx->ops.enqueue_tx(hw, mbx, msg);
  385. }
  386. /**
  387. * fm10k_update_hw_stats_vf - Updates hardware related statistics of VF
  388. * @hw: pointer to hardware structure
  389. * @stats: pointer to statistics structure
  390. *
  391. * This function collects and aggregates per queue hardware statistics.
  392. **/
  393. static void fm10k_update_hw_stats_vf(struct fm10k_hw *hw,
  394. struct fm10k_hw_stats *stats)
  395. {
  396. fm10k_update_hw_stats_q(hw, stats->q, 0, hw->mac.max_queues);
  397. }
  398. /**
  399. * fm10k_rebind_hw_stats_vf - Resets base for hardware statistics of VF
  400. * @hw: pointer to hardware structure
  401. * @stats: pointer to the stats structure to update
  402. *
  403. * This function resets the base for queue hardware statistics.
  404. **/
  405. static void fm10k_rebind_hw_stats_vf(struct fm10k_hw *hw,
  406. struct fm10k_hw_stats *stats)
  407. {
  408. /* Unbind Queue Statistics */
  409. fm10k_unbind_hw_stats_q(stats->q, 0, hw->mac.max_queues);
  410. /* Reinitialize bases for all stats */
  411. fm10k_update_hw_stats_vf(hw, stats);
  412. }
  413. /**
  414. * fm10k_configure_dglort_map_vf - Configures GLORT entry and queues
  415. * @hw: pointer to hardware structure
  416. * @dglort: pointer to dglort configuration structure
  417. *
  418. * Reads the configuration structure contained in dglort_cfg and uses
  419. * that information to then populate a DGLORTMAP/DEC entry and the queues
  420. * to which it has been assigned.
  421. **/
  422. static s32 fm10k_configure_dglort_map_vf(struct fm10k_hw *hw,
  423. struct fm10k_dglort_cfg *dglort)
  424. {
  425. /* verify the dglort pointer */
  426. if (!dglort)
  427. return FM10K_ERR_PARAM;
  428. /* stub for now until we determine correct message for this */
  429. return 0;
  430. }
  431. static const struct fm10k_msg_data fm10k_msg_data_vf[] = {
  432. FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test),
  433. FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_msg_mac_vlan_vf),
  434. FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_msg_lport_state_vf),
  435. FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
  436. };
  437. static const struct fm10k_mac_ops mac_ops_vf = {
  438. .get_bus_info = fm10k_get_bus_info_generic,
  439. .reset_hw = fm10k_reset_hw_vf,
  440. .init_hw = fm10k_init_hw_vf,
  441. .start_hw = fm10k_start_hw_generic,
  442. .stop_hw = fm10k_stop_hw_vf,
  443. .update_vlan = fm10k_update_vlan_vf,
  444. .read_mac_addr = fm10k_read_mac_addr_vf,
  445. .update_uc_addr = fm10k_update_uc_addr_vf,
  446. .update_mc_addr = fm10k_update_mc_addr_vf,
  447. .update_xcast_mode = fm10k_update_xcast_mode_vf,
  448. .update_int_moderator = fm10k_update_int_moderator_vf,
  449. .update_lport_state = fm10k_update_lport_state_vf,
  450. .update_hw_stats = fm10k_update_hw_stats_vf,
  451. .rebind_hw_stats = fm10k_rebind_hw_stats_vf,
  452. .configure_dglort_map = fm10k_configure_dglort_map_vf,
  453. .get_host_state = fm10k_get_host_state_generic,
  454. };
  455. static s32 fm10k_get_invariants_vf(struct fm10k_hw *hw)
  456. {
  457. fm10k_get_invariants_generic(hw);
  458. return fm10k_pfvf_mbx_init(hw, &hw->mbx, fm10k_msg_data_vf, 0);
  459. }
  460. const struct fm10k_info fm10k_vf_info = {
  461. .mac = fm10k_mac_vf,
  462. .get_invariants = fm10k_get_invariants_vf,
  463. .mac_ops = &mac_ops_vf,
  464. };