fm10k/base: scale interrupt on PCIe link speed
[dpdk.git] / drivers / net / fm10k / base / fm10k_vf.c
1 /*******************************************************************************
2
3 Copyright (c) 2013 - 2015, Intel Corporation
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8
9  1. Redistributions of source code must retain the above copyright notice,
10     this list of conditions and the following disclaimer.
11
12  2. Redistributions in binary form must reproduce the above copyright
13     notice, this list of conditions and the following disclaimer in the
14     documentation and/or other materials provided with the distribution.
15
16  3. Neither the name of the Intel Corporation nor the names of its
17     contributors may be used to endorse or promote products derived from
18     this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
31
32 ***************************************************************************/
33
34 #include "fm10k_vf.h"
35
36 /**
37  *  fm10k_stop_hw_vf - Stop Tx/Rx units
38  *  @hw: pointer to hardware structure
39  *
40  **/
41 STATIC s32 fm10k_stop_hw_vf(struct fm10k_hw *hw)
42 {
43         u8 *perm_addr = hw->mac.perm_addr;
44         u32 bal = 0, bah = 0, tdlen;
45         s32 err;
46         u16 i;
47
48         DEBUGFUNC("fm10k_stop_hw_vf");
49
50         /* we need to disable the queues before taking further steps */
51         err = fm10k_stop_hw_generic(hw);
52         if (err)
53                 return err;
54
55         /* If permanent address is set then we need to restore it */
56         if (FM10K_IS_VALID_ETHER_ADDR(perm_addr)) {
57                 bal = (((u32)perm_addr[3]) << 24) |
58                       (((u32)perm_addr[4]) << 16) |
59                       (((u32)perm_addr[5]) << 8);
60                 bah = (((u32)0xFF)         << 24) |
61                       (((u32)perm_addr[0]) << 16) |
62                       (((u32)perm_addr[1]) << 8) |
63                        ((u32)perm_addr[2]);
64         }
65
66         /* restore default itr_scale for next VF initialization */
67         tdlen = hw->mac.itr_scale << FM10K_TDLEN_ITR_SCALE_SHIFT;
68
69         /* The queues have already been disabled so we just need to
70          * update their base address registers
71          */
72         for (i = 0; i < hw->mac.max_queues; i++) {
73                 FM10K_WRITE_REG(hw, FM10K_TDBAL(i), bal);
74                 FM10K_WRITE_REG(hw, FM10K_TDBAH(i), bah);
75                 FM10K_WRITE_REG(hw, FM10K_RDBAL(i), bal);
76                 FM10K_WRITE_REG(hw, FM10K_RDBAH(i), bah);
77                 FM10K_WRITE_REG(hw, FM10K_TDLEN(i), tdlen);
78         }
79
80         return FM10K_SUCCESS;
81 }
82
83 /**
84  *  fm10k_reset_hw_vf - VF hardware reset
85  *  @hw: pointer to hardware structure
86  *
87  *  This function should return the hardware to a state similar to the
88  *  one it is in after just being initialized.
89  **/
90 STATIC s32 fm10k_reset_hw_vf(struct fm10k_hw *hw)
91 {
92         s32 err;
93
94         DEBUGFUNC("fm10k_reset_hw_vf");
95
96         /* shut down queues we own and reset DMA configuration */
97         err = fm10k_stop_hw_vf(hw);
98         if (err)
99                 return err;
100
101         /* Inititate VF reset */
102         FM10K_WRITE_REG(hw, FM10K_VFCTRL, FM10K_VFCTRL_RST);
103
104         /* Flush write and allow 100us for reset to complete */
105         FM10K_WRITE_FLUSH(hw);
106         usec_delay(FM10K_RESET_TIMEOUT);
107
108         /* Clear reset bit and verify it was cleared */
109         FM10K_WRITE_REG(hw, FM10K_VFCTRL, 0);
110         if (FM10K_READ_REG(hw, FM10K_VFCTRL) & FM10K_VFCTRL_RST)
111                 err = FM10K_ERR_RESET_FAILED;
112
113         return err;
114 }
115
116 /**
117  *  fm10k_init_hw_vf - VF hardware initialization
118  *  @hw: pointer to hardware structure
119  *
120  **/
121 STATIC s32 fm10k_init_hw_vf(struct fm10k_hw *hw)
122 {
123         u32 tqdloc, tqdloc0 = ~FM10K_READ_REG(hw, FM10K_TQDLOC(0));
124         s32 err;
125         u16 i;
126
127         DEBUGFUNC("fm10k_init_hw_vf");
128
129         /* assume we always have at least 1 queue */
130         for (i = 1; tqdloc0 && (i < FM10K_MAX_QUEUES_POOL); i++) {
131                 /* verify the Descriptor cache offsets are increasing */
132                 tqdloc = ~FM10K_READ_REG(hw, FM10K_TQDLOC(i));
133                 if (!tqdloc || (tqdloc == tqdloc0))
134                         break;
135
136                 /* check to verify the PF doesn't own any of our queues */
137                 if (!~FM10K_READ_REG(hw, FM10K_TXQCTL(i)) ||
138                     !~FM10K_READ_REG(hw, FM10K_RXQCTL(i)))
139                         break;
140         }
141
142         /* shut down queues we own and reset DMA configuration */
143         err = fm10k_disable_queues_generic(hw, i);
144         if (err)
145                 return err;
146
147         /* record maximum queue count */
148         hw->mac.max_queues = i;
149
150         /* fetch default VLAN and ITR scale */
151         hw->mac.default_vid = (FM10K_READ_REG(hw, FM10K_TXQCTL(0)) &
152                                FM10K_TXQCTL_VID_MASK) >> FM10K_TXQCTL_VID_SHIFT;
153         hw->mac.itr_scale = (FM10K_READ_REG(hw, FM10K_TDLEN(0)) &
154                              FM10K_TDLEN_ITR_SCALE_MASK) >>
155                             FM10K_TDLEN_ITR_SCALE_SHIFT;
156
157         /* ensure a non-zero itr scale */
158         if (!hw->mac.itr_scale)
159                 hw->mac.itr_scale = FM10K_TDLEN_ITR_SCALE_GEN3;
160
161         return FM10K_SUCCESS;
162 }
163
164 /**
165  *  fm10k_is_slot_appropriate_vf - Indicate appropriate slot for this SKU
166  *  @hw: pointer to hardware structure
167  *
168  *  Looks at the PCIe bus info to confirm whether or not this slot can support
169  *  the necessary bandwidth for this device. Since the VF has no control over
170  *  the "slot" it is in, always indicate that the slot is appropriate.
171  **/
172 STATIC bool fm10k_is_slot_appropriate_vf(struct fm10k_hw *hw)
173 {
174         UNREFERENCED_1PARAMETER(hw);
175         DEBUGFUNC("fm10k_is_slot_appropriate_vf");
176
177         return TRUE;
178 }
179
180 /* This structure defines the attibutes to be parsed below */
181 const struct fm10k_tlv_attr fm10k_mac_vlan_msg_attr[] = {
182         FM10K_TLV_ATTR_U32(FM10K_MAC_VLAN_MSG_VLAN),
183         FM10K_TLV_ATTR_BOOL(FM10K_MAC_VLAN_MSG_SET),
184         FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_MAC),
185         FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_DEFAULT_MAC),
186         FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_MULTICAST),
187         FM10K_TLV_ATTR_LAST
188 };
189
190 /**
191  *  fm10k_update_vlan_vf - Update status of VLAN ID in VLAN filter table
192  *  @hw: pointer to hardware structure
193  *  @vid: VLAN ID to add to table
194  *  @vsi: Reserved, should always be 0
195  *  @set: Indicates if this is a set or clear operation
196  *
197  *  This function adds or removes the corresponding VLAN ID from the VLAN
198  *  filter table for this VF.
199  **/
200 STATIC s32 fm10k_update_vlan_vf(struct fm10k_hw *hw, u32 vid, u8 vsi, bool set)
201 {
202         struct fm10k_mbx_info *mbx = &hw->mbx;
203         u32 msg[4];
204
205         /* verify the index is not set */
206         if (vsi)
207                 return FM10K_ERR_PARAM;
208
209         /* verify upper 4 bits of vid and length are 0 */
210         if ((vid << 16 | vid) >> 28)
211                 return FM10K_ERR_PARAM;
212
213         /* encode set bit into the VLAN ID */
214         if (!set)
215                 vid |= FM10K_VLAN_CLEAR;
216
217         /* generate VLAN request */
218         fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
219         fm10k_tlv_attr_put_u32(msg, FM10K_MAC_VLAN_MSG_VLAN, vid);
220
221         /* load onto outgoing mailbox */
222         return mbx->ops.enqueue_tx(hw, mbx, msg);
223 }
224
225 /**
226  *  fm10k_msg_mac_vlan_vf - Read device MAC address from mailbox message
227  *  @hw: pointer to the HW structure
228  *  @results: Attributes for message
229  *  @mbx: unused mailbox data
230  *
231  *  This function should determine the MAC address for the VF
232  **/
233 s32 fm10k_msg_mac_vlan_vf(struct fm10k_hw *hw, u32 **results,
234                           struct fm10k_mbx_info *mbx)
235 {
236         u8 perm_addr[ETH_ALEN];
237         u16 vid;
238         s32 err;
239
240         UNREFERENCED_1PARAMETER(mbx);
241         DEBUGFUNC("fm10k_msg_mac_vlan_vf");
242
243         /* record MAC address requested */
244         err = fm10k_tlv_attr_get_mac_vlan(
245                                         results[FM10K_MAC_VLAN_MSG_DEFAULT_MAC],
246                                         perm_addr, &vid);
247         if (err)
248                 return err;
249
250         memcpy(hw->mac.perm_addr, perm_addr, ETH_ALEN);
251         hw->mac.default_vid = vid & (FM10K_VLAN_TABLE_VID_MAX - 1);
252         hw->mac.vlan_override = !!(vid & FM10K_VLAN_CLEAR);
253
254         return FM10K_SUCCESS;
255 }
256
257 /**
258  *  fm10k_read_mac_addr_vf - Read device MAC address
259  *  @hw: pointer to the HW structure
260  *
261  *  This function should determine the MAC address for the VF
262  **/
263 STATIC s32 fm10k_read_mac_addr_vf(struct fm10k_hw *hw)
264 {
265         u8 perm_addr[ETH_ALEN];
266         u32 base_addr;
267
268         DEBUGFUNC("fm10k_read_mac_addr_vf");
269
270         base_addr = FM10K_READ_REG(hw, FM10K_TDBAL(0));
271
272         /* last byte should be 0 */
273         if (base_addr << 24)
274                 return  FM10K_ERR_INVALID_MAC_ADDR;
275
276         perm_addr[3] = (u8)(base_addr >> 24);
277         perm_addr[4] = (u8)(base_addr >> 16);
278         perm_addr[5] = (u8)(base_addr >> 8);
279
280         base_addr = FM10K_READ_REG(hw, FM10K_TDBAH(0));
281
282         /* first byte should be all 1's */
283         if ((~base_addr) >> 24)
284                 return  FM10K_ERR_INVALID_MAC_ADDR;
285
286         perm_addr[0] = (u8)(base_addr >> 16);
287         perm_addr[1] = (u8)(base_addr >> 8);
288         perm_addr[2] = (u8)(base_addr);
289
290         memcpy(hw->mac.perm_addr, perm_addr, ETH_ALEN);
291         memcpy(hw->mac.addr, perm_addr, ETH_ALEN);
292
293         return FM10K_SUCCESS;
294 }
295
296 /**
297  *  fm10k_update_uc_addr_vf - Update device unicast addresses
298  *  @hw: pointer to the HW structure
299  *  @glort: unused
300  *  @mac: MAC address to add/remove from table
301  *  @vid: VLAN ID to add/remove from table
302  *  @add: Indicates if this is an add or remove operation
303  *  @flags: flags field to indicate add and secure - unused
304  *
305  *  This function is used to add or remove unicast MAC addresses for
306  *  the VF.
307  **/
308 STATIC s32 fm10k_update_uc_addr_vf(struct fm10k_hw *hw, u16 glort,
309                                    const u8 *mac, u16 vid, bool add, u8 flags)
310 {
311         struct fm10k_mbx_info *mbx = &hw->mbx;
312         u32 msg[7];
313
314         DEBUGFUNC("fm10k_update_uc_addr_vf");
315
316         UNREFERENCED_2PARAMETER(glort, flags);
317
318         /* verify VLAN ID is valid */
319         if (vid >= FM10K_VLAN_TABLE_VID_MAX)
320                 return FM10K_ERR_PARAM;
321
322         /* verify MAC address is valid */
323         if (!FM10K_IS_VALID_ETHER_ADDR(mac))
324                 return FM10K_ERR_PARAM;
325
326         /* verify we are not locked down on the MAC address */
327         if (FM10K_IS_VALID_ETHER_ADDR(hw->mac.perm_addr) &&
328             memcmp(hw->mac.perm_addr, mac, ETH_ALEN))
329                 return FM10K_ERR_PARAM;
330
331         /* add bit to notify us if this is a set or clear operation */
332         if (!add)
333                 vid |= FM10K_VLAN_CLEAR;
334
335         /* generate VLAN request */
336         fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
337         fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_MAC, mac, vid);
338
339         /* load onto outgoing mailbox */
340         return mbx->ops.enqueue_tx(hw, mbx, msg);
341 }
342
343 /**
344  *  fm10k_update_mc_addr_vf - Update device multicast addresses
345  *  @hw: pointer to the HW structure
346  *  @glort: unused
347  *  @mac: MAC address to add/remove from table
348  *  @vid: VLAN ID to add/remove from table
349  *  @add: Indicates if this is an add or remove operation
350  *
351  *  This function is used to add or remove multicast MAC addresses for
352  *  the VF.
353  **/
354 STATIC s32 fm10k_update_mc_addr_vf(struct fm10k_hw *hw, u16 glort,
355                                    const u8 *mac, u16 vid, bool add)
356 {
357         struct fm10k_mbx_info *mbx = &hw->mbx;
358         u32 msg[7];
359
360         DEBUGFUNC("fm10k_update_uc_addr_vf");
361
362         UNREFERENCED_1PARAMETER(glort);
363
364         /* verify VLAN ID is valid */
365         if (vid >= FM10K_VLAN_TABLE_VID_MAX)
366                 return FM10K_ERR_PARAM;
367
368         /* verify multicast address is valid */
369         if (!FM10K_IS_MULTICAST_ETHER_ADDR(mac))
370                 return FM10K_ERR_PARAM;
371
372         /* add bit to notify us if this is a set or clear operation */
373         if (!add)
374                 vid |= FM10K_VLAN_CLEAR;
375
376         /* generate VLAN request */
377         fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
378         fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_MULTICAST,
379                                     mac, vid);
380
381         /* load onto outgoing mailbox */
382         return mbx->ops.enqueue_tx(hw, mbx, msg);
383 }
384
385 /**
386  *  fm10k_update_int_moderator_vf - Request update of interrupt moderator list
387  *  @hw: pointer to hardware structure
388  *
389  *  This function will issue a request to the PF to rescan our MSI-X table
390  *  and to update the interrupt moderator linked list.
391  **/
392 STATIC void fm10k_update_int_moderator_vf(struct fm10k_hw *hw)
393 {
394         struct fm10k_mbx_info *mbx = &hw->mbx;
395         u32 msg[1];
396
397         /* generate MSI-X request */
398         fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MSIX);
399
400         /* load onto outgoing mailbox */
401         mbx->ops.enqueue_tx(hw, mbx, msg);
402 }
403
404 /* This structure defines the attibutes to be parsed below */
405 const struct fm10k_tlv_attr fm10k_lport_state_msg_attr[] = {
406         FM10K_TLV_ATTR_BOOL(FM10K_LPORT_STATE_MSG_DISABLE),
407         FM10K_TLV_ATTR_U8(FM10K_LPORT_STATE_MSG_XCAST_MODE),
408         FM10K_TLV_ATTR_BOOL(FM10K_LPORT_STATE_MSG_READY),
409         FM10K_TLV_ATTR_LAST
410 };
411
412 /**
413  *  fm10k_msg_lport_state_vf - Message handler for lport_state message from PF
414  *  @hw: Pointer to hardware structure
415  *  @results: pointer array containing parsed data
416  *  @mbx: Pointer to mailbox information structure
417  *
418  *  This handler is meant to capture the indication from the PF that we
419  *  are ready to bring up the interface.
420  **/
421 s32 fm10k_msg_lport_state_vf(struct fm10k_hw *hw, u32 **results,
422                              struct fm10k_mbx_info *mbx)
423 {
424         UNREFERENCED_1PARAMETER(mbx);
425         DEBUGFUNC("fm10k_msg_lport_state_vf");
426
427         hw->mac.dglort_map = !results[FM10K_LPORT_STATE_MSG_READY] ?
428                              FM10K_DGLORTMAP_NONE : FM10K_DGLORTMAP_ZERO;
429
430         return FM10K_SUCCESS;
431 }
432
433 /**
434  *  fm10k_update_lport_state_vf - Update device state in lower device
435  *  @hw: pointer to the HW structure
436  *  @glort: unused
437  *  @count: number of logical ports to enable - unused (always 1)
438  *  @enable: boolean value indicating if this is an enable or disable request
439  *
440  *  Notify the lower device of a state change.  If the lower device is
441  *  enabled we can add filters, if it is disabled all filters for this
442  *  logical port are flushed.
443  **/
444 STATIC s32 fm10k_update_lport_state_vf(struct fm10k_hw *hw, u16 glort,
445                                        u16 count, bool enable)
446 {
447         struct fm10k_mbx_info *mbx = &hw->mbx;
448         u32 msg[2];
449
450         UNREFERENCED_2PARAMETER(glort, count);
451         DEBUGFUNC("fm10k_update_lport_state_vf");
452
453         /* reset glort mask 0 as we have to wait to be enabled */
454         hw->mac.dglort_map = FM10K_DGLORTMAP_NONE;
455
456         /* generate port state request */
457         fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
458         if (!enable)
459                 fm10k_tlv_attr_put_bool(msg, FM10K_LPORT_STATE_MSG_DISABLE);
460
461         /* load onto outgoing mailbox */
462         return mbx->ops.enqueue_tx(hw, mbx, msg);
463 }
464
465 /**
466  *  fm10k_update_xcast_mode_vf - Request update of multicast mode
467  *  @hw: pointer to hardware structure
468  *  @glort: unused
469  *  @mode: integer value indicating mode being requested
470  *
471  *  This function will attempt to request a higher mode for the port
472  *  so that it can enable either multicast, multicast promiscuous, or
473  *  promiscuous mode of operation.
474  **/
475 STATIC s32 fm10k_update_xcast_mode_vf(struct fm10k_hw *hw, u16 glort, u8 mode)
476 {
477         struct fm10k_mbx_info *mbx = &hw->mbx;
478         u32 msg[3];
479
480         UNREFERENCED_1PARAMETER(glort);
481         DEBUGFUNC("fm10k_update_xcast_mode_vf");
482
483         if (mode > FM10K_XCAST_MODE_NONE)
484                 return FM10K_ERR_PARAM;
485
486         /* generate message requesting to change xcast mode */
487         fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
488         fm10k_tlv_attr_put_u8(msg, FM10K_LPORT_STATE_MSG_XCAST_MODE, mode);
489
490         /* load onto outgoing mailbox */
491         return mbx->ops.enqueue_tx(hw, mbx, msg);
492 }
493
494 const struct fm10k_tlv_attr fm10k_1588_msg_attr[] = {
495         FM10K_TLV_ATTR_U64(FM10K_1588_MSG_TIMESTAMP),
496         FM10K_TLV_ATTR_LAST
497 };
498
499 /* currently there is no shared 1588 timestamp handler */
500
501 /**
502  *  fm10k_update_hw_stats_vf - Updates hardware related statistics of VF
503  *  @hw: pointer to hardware structure
504  *  @stats: pointer to statistics structure
505  *
506  *  This function collects and aggregates per queue hardware statistics.
507  **/
508 STATIC void fm10k_update_hw_stats_vf(struct fm10k_hw *hw,
509                                      struct fm10k_hw_stats *stats)
510 {
511         DEBUGFUNC("fm10k_update_hw_stats_vf");
512
513         fm10k_update_hw_stats_q(hw, stats->q, 0, hw->mac.max_queues);
514 }
515
516 /**
517  *  fm10k_rebind_hw_stats_vf - Resets base for hardware statistics of VF
518  *  @hw: pointer to hardware structure
519  *  @stats: pointer to the stats structure to update
520  *
521  *  This function resets the base for queue hardware statistics.
522  **/
523 STATIC void fm10k_rebind_hw_stats_vf(struct fm10k_hw *hw,
524                                      struct fm10k_hw_stats *stats)
525 {
526         DEBUGFUNC("fm10k_rebind_hw_stats_vf");
527
528         /* Unbind Queue Statistics */
529         fm10k_unbind_hw_stats_q(stats->q, 0, hw->mac.max_queues);
530
531         /* Reinitialize bases for all stats */
532         fm10k_update_hw_stats_vf(hw, stats);
533 }
534
535 /**
536  *  fm10k_configure_dglort_map_vf - Configures GLORT entry and queues
537  *  @hw: pointer to hardware structure
538  *  @dglort: pointer to dglort configuration structure
539  *
540  *  Reads the configuration structure contained in dglort_cfg and uses
541  *  that information to then populate a DGLORTMAP/DEC entry and the queues
542  *  to which it has been assigned.
543  **/
544 STATIC s32 fm10k_configure_dglort_map_vf(struct fm10k_hw *hw,
545                                          struct fm10k_dglort_cfg *dglort)
546 {
547         UNREFERENCED_1PARAMETER(hw);
548         DEBUGFUNC("fm10k_configure_dglort_map_vf");
549
550         /* verify the dglort pointer */
551         if (!dglort)
552                 return FM10K_ERR_PARAM;
553
554         /* stub for now until we determine correct message for this */
555
556         return FM10K_SUCCESS;
557 }
558
559 /**
560  * fm10k_request_tx_timestamp_mode_vf - Request Tx timestamp mode
561  * @hw: pointer to hardware structure
562  * @glort: glort to request Tx timestamps for
563  * @mode: timestamp mode to request
564  *
565  * This function takes the requested timestamp mode and verifies that it was
566  * requested as none since the VF cannot support receipt of Tx timestamps.
567  *
568  * If the mode is non-zero ERR_PARAM, else success
569  **/
570 STATIC s32 fm10k_request_tx_timestamp_mode_vf(struct fm10k_hw *hw,
571                                               u16 glort,
572                                               u8 mode)
573 {
574         UNREFERENCED_2PARAMETER(hw, glort);
575
576         return mode ? FM10K_ERR_PARAM : FM10K_SUCCESS;
577 }
578
579 /**
580  *  fm10k_adjust_systime_vf - Adjust systime frequency
581  *  @hw: pointer to hardware structure
582  *  @ppb: adjustment rate in parts per billion
583  *
584  *  This function takes an adjustment rate in parts per billion and will
585  *  verify that this value is 0 as the VF cannot support adjusting the
586  *  systime clock.
587  *
588  *  If the ppb value is non-zero the return is ERR_PARAM else success
589  **/
590 STATIC s32 fm10k_adjust_systime_vf(struct fm10k_hw *hw, s32 ppb)
591 {
592         UNREFERENCED_1PARAMETER(hw);
593         DEBUGFUNC("fm10k_adjust_systime_vf");
594
595         /* The VF cannot adjust the clock frequency, however it should
596          * already have a syntonic clock with whichever host interface is
597          * running as the master for the host interface clock domain so
598          * there should be not frequency adjustment necessary.
599          */
600         return ppb ? FM10K_ERR_PARAM : FM10K_SUCCESS;
601 }
602
603 /**
604  *  fm10k_read_systime_vf - Reads value of systime registers
605  *  @hw: pointer to the hardware structure
606  *
607  *  Function reads the content of 2 registers, combined to represent a 64 bit
608  *  value measured in nanoseconds.  In order to guarantee the value is accurate
609  *  we check the 32 most significant bits both before and after reading the
610  *  32 least significant bits to verify they didn't change as we were reading
611  *  the registers.
612  **/
613 static u64 fm10k_read_systime_vf(struct fm10k_hw *hw)
614 {
615         u32 systime_l, systime_h, systime_tmp;
616
617         systime_h = fm10k_read_reg(hw, FM10K_VFSYSTIME + 1);
618
619         do {
620                 systime_tmp = systime_h;
621                 systime_l = fm10k_read_reg(hw, FM10K_VFSYSTIME);
622                 systime_h = fm10k_read_reg(hw, FM10K_VFSYSTIME + 1);
623         } while (systime_tmp != systime_h);
624
625         return ((u64)systime_h << 32) | systime_l;
626 }
627
628 static const struct fm10k_msg_data fm10k_msg_data_vf[] = {
629         FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test),
630         FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_msg_mac_vlan_vf),
631         FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_msg_lport_state_vf),
632         FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
633 };
634
635 /**
636  *  fm10k_init_ops_vf - Inits func ptrs and MAC type
637  *  @hw: pointer to hardware structure
638  *
639  *  Initialize the function pointers and assign the MAC type for VF.
640  *  Does not touch the hardware.
641  **/
642 s32 fm10k_init_ops_vf(struct fm10k_hw *hw)
643 {
644         struct fm10k_mac_info *mac = &hw->mac;
645
646         DEBUGFUNC("fm10k_init_ops_vf");
647
648         fm10k_init_ops_generic(hw);
649
650         mac->ops.reset_hw = &fm10k_reset_hw_vf;
651         mac->ops.init_hw = &fm10k_init_hw_vf;
652         mac->ops.start_hw = &fm10k_start_hw_generic;
653         mac->ops.stop_hw = &fm10k_stop_hw_vf;
654         mac->ops.is_slot_appropriate = &fm10k_is_slot_appropriate_vf;
655         mac->ops.update_vlan = &fm10k_update_vlan_vf;
656         mac->ops.read_mac_addr = &fm10k_read_mac_addr_vf;
657         mac->ops.update_uc_addr = &fm10k_update_uc_addr_vf;
658         mac->ops.update_mc_addr = &fm10k_update_mc_addr_vf;
659         mac->ops.update_xcast_mode = &fm10k_update_xcast_mode_vf;
660         mac->ops.update_int_moderator = &fm10k_update_int_moderator_vf;
661         mac->ops.update_lport_state = &fm10k_update_lport_state_vf;
662         mac->ops.update_hw_stats = &fm10k_update_hw_stats_vf;
663         mac->ops.rebind_hw_stats = &fm10k_rebind_hw_stats_vf;
664         mac->ops.configure_dglort_map = &fm10k_configure_dglort_map_vf;
665         mac->ops.get_host_state = &fm10k_get_host_state_generic;
666         mac->ops.adjust_systime = &fm10k_adjust_systime_vf;
667         mac->ops.read_systime = &fm10k_read_systime_vf;
668         mac->ops.request_tx_timestamp_mode = &fm10k_request_tx_timestamp_mode_vf;
669
670         mac->max_msix_vectors = fm10k_get_pcie_msix_count_generic(hw);
671
672         return fm10k_pfvf_mbx_init(hw, &hw->mbx, fm10k_msg_data_vf, 0);
673 }