39bc92705ec65f7e51a007d5a65bb28fa66605e1
[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         /* verify we have at least 1 queue */
130         if (!~FM10K_READ_REG(hw, FM10K_TXQCTL(0)) ||
131             !~FM10K_READ_REG(hw, FM10K_RXQCTL(0)))
132                 return FM10K_ERR_NO_RESOURCES;
133
134         /* determine how many queues we have */
135         for (i = 1; tqdloc0 && (i < FM10K_MAX_QUEUES_POOL); i++) {
136                 /* verify the Descriptor cache offsets are increasing */
137                 tqdloc = ~FM10K_READ_REG(hw, FM10K_TQDLOC(i));
138                 if (!tqdloc || (tqdloc == tqdloc0))
139                         break;
140
141                 /* check to verify the PF doesn't own any of our queues */
142                 if (!~FM10K_READ_REG(hw, FM10K_TXQCTL(i)) ||
143                     !~FM10K_READ_REG(hw, FM10K_RXQCTL(i)))
144                         break;
145         }
146
147         /* shut down queues we own and reset DMA configuration */
148         err = fm10k_disable_queues_generic(hw, i);
149         if (err)
150                 return err;
151
152         /* record maximum queue count */
153         hw->mac.max_queues = i;
154
155         /* fetch default VLAN and ITR scale */
156         hw->mac.default_vid = (FM10K_READ_REG(hw, FM10K_TXQCTL(0)) &
157                                FM10K_TXQCTL_VID_MASK) >> FM10K_TXQCTL_VID_SHIFT;
158         hw->mac.itr_scale = (FM10K_READ_REG(hw, FM10K_TDLEN(0)) &
159                              FM10K_TDLEN_ITR_SCALE_MASK) >>
160                             FM10K_TDLEN_ITR_SCALE_SHIFT;
161
162         return FM10K_SUCCESS;
163 }
164
165 /**
166  *  fm10k_is_slot_appropriate_vf - Indicate appropriate slot for this SKU
167  *  @hw: pointer to hardware structure
168  *
169  *  Looks at the PCIe bus info to confirm whether or not this slot can support
170  *  the necessary bandwidth for this device. Since the VF has no control over
171  *  the "slot" it is in, always indicate that the slot is appropriate.
172  **/
173 STATIC bool fm10k_is_slot_appropriate_vf(struct fm10k_hw *hw)
174 {
175         UNREFERENCED_1PARAMETER(hw);
176         DEBUGFUNC("fm10k_is_slot_appropriate_vf");
177
178         return TRUE;
179 }
180
181 /* This structure defines the attibutes to be parsed below */
182 const struct fm10k_tlv_attr fm10k_mac_vlan_msg_attr[] = {
183         FM10K_TLV_ATTR_U32(FM10K_MAC_VLAN_MSG_VLAN),
184         FM10K_TLV_ATTR_BOOL(FM10K_MAC_VLAN_MSG_SET),
185         FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_MAC),
186         FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_DEFAULT_MAC),
187         FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_MULTICAST),
188         FM10K_TLV_ATTR_LAST
189 };
190
191 /**
192  *  fm10k_update_vlan_vf - Update status of VLAN ID in VLAN filter table
193  *  @hw: pointer to hardware structure
194  *  @vid: VLAN ID to add to table
195  *  @vsi: Reserved, should always be 0
196  *  @set: Indicates if this is a set or clear operation
197  *
198  *  This function adds or removes the corresponding VLAN ID from the VLAN
199  *  filter table for this VF.
200  **/
201 STATIC s32 fm10k_update_vlan_vf(struct fm10k_hw *hw, u32 vid, u8 vsi, bool set)
202 {
203         struct fm10k_mbx_info *mbx = &hw->mbx;
204         u32 msg[4];
205
206         /* verify the index is not set */
207         if (vsi)
208                 return FM10K_ERR_PARAM;
209
210         /* verify upper 4 bits of vid and length are 0 */
211         if ((vid << 16 | vid) >> 28)
212                 return FM10K_ERR_PARAM;
213
214         /* encode set bit into the VLAN ID */
215         if (!set)
216                 vid |= FM10K_VLAN_CLEAR;
217
218         /* generate VLAN request */
219         fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
220         fm10k_tlv_attr_put_u32(msg, FM10K_MAC_VLAN_MSG_VLAN, vid);
221
222         /* load onto outgoing mailbox */
223         return mbx->ops.enqueue_tx(hw, mbx, msg);
224 }
225
226 /**
227  *  fm10k_msg_mac_vlan_vf - Read device MAC address from mailbox message
228  *  @hw: pointer to the HW structure
229  *  @results: Attributes for message
230  *  @mbx: unused mailbox data
231  *
232  *  This function should determine the MAC address for the VF
233  **/
234 s32 fm10k_msg_mac_vlan_vf(struct fm10k_hw *hw, u32 **results,
235                           struct fm10k_mbx_info *mbx)
236 {
237         u8 perm_addr[ETH_ALEN];
238         u16 vid;
239         s32 err;
240
241         UNREFERENCED_1PARAMETER(mbx);
242         DEBUGFUNC("fm10k_msg_mac_vlan_vf");
243
244         /* record MAC address requested */
245         err = fm10k_tlv_attr_get_mac_vlan(
246                                         results[FM10K_MAC_VLAN_MSG_DEFAULT_MAC],
247                                         perm_addr, &vid);
248         if (err)
249                 return err;
250
251         memcpy(hw->mac.perm_addr, perm_addr, ETH_ALEN);
252         hw->mac.default_vid = vid & (FM10K_VLAN_TABLE_VID_MAX - 1);
253         hw->mac.vlan_override = !!(vid & FM10K_VLAN_CLEAR);
254
255         return FM10K_SUCCESS;
256 }
257
258 /**
259  *  fm10k_read_mac_addr_vf - Read device MAC address
260  *  @hw: pointer to the HW structure
261  *
262  *  This function should determine the MAC address for the VF
263  **/
264 STATIC s32 fm10k_read_mac_addr_vf(struct fm10k_hw *hw)
265 {
266         u8 perm_addr[ETH_ALEN];
267         u32 base_addr;
268
269         DEBUGFUNC("fm10k_read_mac_addr_vf");
270
271         base_addr = FM10K_READ_REG(hw, FM10K_TDBAL(0));
272
273         /* last byte should be 0 */
274         if (base_addr << 24)
275                 return  FM10K_ERR_INVALID_MAC_ADDR;
276
277         perm_addr[3] = (u8)(base_addr >> 24);
278         perm_addr[4] = (u8)(base_addr >> 16);
279         perm_addr[5] = (u8)(base_addr >> 8);
280
281         base_addr = FM10K_READ_REG(hw, FM10K_TDBAH(0));
282
283         /* first byte should be all 1's */
284         if ((~base_addr) >> 24)
285                 return  FM10K_ERR_INVALID_MAC_ADDR;
286
287         perm_addr[0] = (u8)(base_addr >> 16);
288         perm_addr[1] = (u8)(base_addr >> 8);
289         perm_addr[2] = (u8)(base_addr);
290
291         memcpy(hw->mac.perm_addr, perm_addr, ETH_ALEN);
292         memcpy(hw->mac.addr, perm_addr, ETH_ALEN);
293
294         return FM10K_SUCCESS;
295 }
296
297 /**
298  *  fm10k_update_uc_addr_vf - Update device unicast addresses
299  *  @hw: pointer to the HW structure
300  *  @glort: unused
301  *  @mac: MAC address to add/remove from table
302  *  @vid: VLAN ID to add/remove from table
303  *  @add: Indicates if this is an add or remove operation
304  *  @flags: flags field to indicate add and secure - unused
305  *
306  *  This function is used to add or remove unicast MAC addresses for
307  *  the VF.
308  **/
309 STATIC s32 fm10k_update_uc_addr_vf(struct fm10k_hw *hw, u16 glort,
310                                    const u8 *mac, u16 vid, bool add, u8 flags)
311 {
312         struct fm10k_mbx_info *mbx = &hw->mbx;
313         u32 msg[7];
314
315         DEBUGFUNC("fm10k_update_uc_addr_vf");
316
317         UNREFERENCED_2PARAMETER(glort, flags);
318
319         /* verify VLAN ID is valid */
320         if (vid >= FM10K_VLAN_TABLE_VID_MAX)
321                 return FM10K_ERR_PARAM;
322
323         /* verify MAC address is valid */
324         if (!FM10K_IS_VALID_ETHER_ADDR(mac))
325                 return FM10K_ERR_PARAM;
326
327         /* verify we are not locked down on the MAC address */
328         if (FM10K_IS_VALID_ETHER_ADDR(hw->mac.perm_addr) &&
329             memcmp(hw->mac.perm_addr, mac, ETH_ALEN))
330                 return FM10K_ERR_PARAM;
331
332         /* add bit to notify us if this is a set or clear operation */
333         if (!add)
334                 vid |= FM10K_VLAN_CLEAR;
335
336         /* generate VLAN request */
337         fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
338         fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_MAC, mac, vid);
339
340         /* load onto outgoing mailbox */
341         return mbx->ops.enqueue_tx(hw, mbx, msg);
342 }
343
344 /**
345  *  fm10k_update_mc_addr_vf - Update device multicast addresses
346  *  @hw: pointer to the HW structure
347  *  @glort: unused
348  *  @mac: MAC address to add/remove from table
349  *  @vid: VLAN ID to add/remove from table
350  *  @add: Indicates if this is an add or remove operation
351  *
352  *  This function is used to add or remove multicast MAC addresses for
353  *  the VF.
354  **/
355 STATIC s32 fm10k_update_mc_addr_vf(struct fm10k_hw *hw, u16 glort,
356                                    const u8 *mac, u16 vid, bool add)
357 {
358         struct fm10k_mbx_info *mbx = &hw->mbx;
359         u32 msg[7];
360
361         DEBUGFUNC("fm10k_update_uc_addr_vf");
362
363         UNREFERENCED_1PARAMETER(glort);
364
365         /* verify VLAN ID is valid */
366         if (vid >= FM10K_VLAN_TABLE_VID_MAX)
367                 return FM10K_ERR_PARAM;
368
369         /* verify multicast address is valid */
370         if (!FM10K_IS_MULTICAST_ETHER_ADDR(mac))
371                 return FM10K_ERR_PARAM;
372
373         /* add bit to notify us if this is a set or clear operation */
374         if (!add)
375                 vid |= FM10K_VLAN_CLEAR;
376
377         /* generate VLAN request */
378         fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
379         fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_MULTICAST,
380                                     mac, vid);
381
382         /* load onto outgoing mailbox */
383         return mbx->ops.enqueue_tx(hw, mbx, msg);
384 }
385
386 /**
387  *  fm10k_update_int_moderator_vf - Request update of interrupt moderator list
388  *  @hw: pointer to hardware structure
389  *
390  *  This function will issue a request to the PF to rescan our MSI-X table
391  *  and to update the interrupt moderator linked list.
392  **/
393 STATIC void fm10k_update_int_moderator_vf(struct fm10k_hw *hw)
394 {
395         struct fm10k_mbx_info *mbx = &hw->mbx;
396         u32 msg[1];
397
398         /* generate MSI-X request */
399         fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MSIX);
400
401         /* load onto outgoing mailbox */
402         mbx->ops.enqueue_tx(hw, mbx, msg);
403 }
404
405 /* This structure defines the attibutes to be parsed below */
406 const struct fm10k_tlv_attr fm10k_lport_state_msg_attr[] = {
407         FM10K_TLV_ATTR_BOOL(FM10K_LPORT_STATE_MSG_DISABLE),
408         FM10K_TLV_ATTR_U8(FM10K_LPORT_STATE_MSG_XCAST_MODE),
409         FM10K_TLV_ATTR_BOOL(FM10K_LPORT_STATE_MSG_READY),
410         FM10K_TLV_ATTR_LAST
411 };
412
413 /**
414  *  fm10k_msg_lport_state_vf - Message handler for lport_state message from PF
415  *  @hw: Pointer to hardware structure
416  *  @results: pointer array containing parsed data
417  *  @mbx: Pointer to mailbox information structure
418  *
419  *  This handler is meant to capture the indication from the PF that we
420  *  are ready to bring up the interface.
421  **/
422 s32 fm10k_msg_lport_state_vf(struct fm10k_hw *hw, u32 **results,
423                              struct fm10k_mbx_info *mbx)
424 {
425         UNREFERENCED_1PARAMETER(mbx);
426         DEBUGFUNC("fm10k_msg_lport_state_vf");
427
428         hw->mac.dglort_map = !results[FM10K_LPORT_STATE_MSG_READY] ?
429                              FM10K_DGLORTMAP_NONE : FM10K_DGLORTMAP_ZERO;
430
431         return FM10K_SUCCESS;
432 }
433
434 /**
435  *  fm10k_update_lport_state_vf - Update device state in lower device
436  *  @hw: pointer to the HW structure
437  *  @glort: unused
438  *  @count: number of logical ports to enable - unused (always 1)
439  *  @enable: boolean value indicating if this is an enable or disable request
440  *
441  *  Notify the lower device of a state change.  If the lower device is
442  *  enabled we can add filters, if it is disabled all filters for this
443  *  logical port are flushed.
444  **/
445 STATIC s32 fm10k_update_lport_state_vf(struct fm10k_hw *hw, u16 glort,
446                                        u16 count, bool enable)
447 {
448         struct fm10k_mbx_info *mbx = &hw->mbx;
449         u32 msg[2];
450
451         UNREFERENCED_2PARAMETER(glort, count);
452         DEBUGFUNC("fm10k_update_lport_state_vf");
453
454         /* reset glort mask 0 as we have to wait to be enabled */
455         hw->mac.dglort_map = FM10K_DGLORTMAP_NONE;
456
457         /* generate port state request */
458         fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
459         if (!enable)
460                 fm10k_tlv_attr_put_bool(msg, FM10K_LPORT_STATE_MSG_DISABLE);
461
462         /* load onto outgoing mailbox */
463         return mbx->ops.enqueue_tx(hw, mbx, msg);
464 }
465
466 /**
467  *  fm10k_update_xcast_mode_vf - Request update of multicast mode
468  *  @hw: pointer to hardware structure
469  *  @glort: unused
470  *  @mode: integer value indicating mode being requested
471  *
472  *  This function will attempt to request a higher mode for the port
473  *  so that it can enable either multicast, multicast promiscuous, or
474  *  promiscuous mode of operation.
475  **/
476 STATIC s32 fm10k_update_xcast_mode_vf(struct fm10k_hw *hw, u16 glort, u8 mode)
477 {
478         struct fm10k_mbx_info *mbx = &hw->mbx;
479         u32 msg[3];
480
481         UNREFERENCED_1PARAMETER(glort);
482         DEBUGFUNC("fm10k_update_xcast_mode_vf");
483
484         if (mode > FM10K_XCAST_MODE_NONE)
485                 return FM10K_ERR_PARAM;
486
487         /* generate message requesting to change xcast mode */
488         fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
489         fm10k_tlv_attr_put_u8(msg, FM10K_LPORT_STATE_MSG_XCAST_MODE, mode);
490
491         /* load onto outgoing mailbox */
492         return mbx->ops.enqueue_tx(hw, mbx, msg);
493 }
494
495 const struct fm10k_tlv_attr fm10k_1588_msg_attr[] = {
496         FM10K_TLV_ATTR_U64(FM10K_1588_MSG_CLK_OFFSET),
497         FM10K_TLV_ATTR_LAST
498 };
499
500 /* currently there is no shared 1588 message handler */
501
502 /**
503  *  fm10k_update_hw_stats_vf - Updates hardware related statistics of VF
504  *  @hw: pointer to hardware structure
505  *  @stats: pointer to statistics structure
506  *
507  *  This function collects and aggregates per queue hardware statistics.
508  **/
509 STATIC void fm10k_update_hw_stats_vf(struct fm10k_hw *hw,
510                                      struct fm10k_hw_stats *stats)
511 {
512         DEBUGFUNC("fm10k_update_hw_stats_vf");
513
514         fm10k_update_hw_stats_q(hw, stats->q, 0, hw->mac.max_queues);
515 }
516
517 /**
518  *  fm10k_rebind_hw_stats_vf - Resets base for hardware statistics of VF
519  *  @hw: pointer to hardware structure
520  *  @stats: pointer to the stats structure to update
521  *
522  *  This function resets the base for queue hardware statistics.
523  **/
524 STATIC void fm10k_rebind_hw_stats_vf(struct fm10k_hw *hw,
525                                      struct fm10k_hw_stats *stats)
526 {
527         DEBUGFUNC("fm10k_rebind_hw_stats_vf");
528
529         /* Unbind Queue Statistics */
530         fm10k_unbind_hw_stats_q(stats->q, 0, hw->mac.max_queues);
531
532         /* Reinitialize bases for all stats */
533         fm10k_update_hw_stats_vf(hw, stats);
534 }
535
536 /**
537  *  fm10k_configure_dglort_map_vf - Configures GLORT entry and queues
538  *  @hw: pointer to hardware structure
539  *  @dglort: pointer to dglort configuration structure
540  *
541  *  Reads the configuration structure contained in dglort_cfg and uses
542  *  that information to then populate a DGLORTMAP/DEC entry and the queues
543  *  to which it has been assigned.
544  **/
545 STATIC s32 fm10k_configure_dglort_map_vf(struct fm10k_hw *hw,
546                                          struct fm10k_dglort_cfg *dglort)
547 {
548         UNREFERENCED_1PARAMETER(hw);
549         DEBUGFUNC("fm10k_configure_dglort_map_vf");
550
551         /* verify the dglort pointer */
552         if (!dglort)
553                 return FM10K_ERR_PARAM;
554
555         /* stub for now until we determine correct message for this */
556
557         return FM10K_SUCCESS;
558 }
559
560 /**
561  *  fm10k_adjust_systime_vf - Adjust systime frequency
562  *  @hw: pointer to hardware structure
563  *  @ppb: adjustment rate in parts per billion
564  *
565  *  This function takes an adjustment rate in parts per billion and will
566  *  verify that this value is 0 as the VF cannot support adjusting the
567  *  systime clock.
568  *
569  *  If the ppb value is non-zero the return is ERR_PARAM else success
570  **/
571 STATIC s32 fm10k_adjust_systime_vf(struct fm10k_hw *hw, s32 ppb)
572 {
573         UNREFERENCED_1PARAMETER(hw);
574         DEBUGFUNC("fm10k_adjust_systime_vf");
575
576         /* The VF cannot adjust the clock frequency, however it should
577          * already have a syntonic clock with whichever host interface is
578          * running as the master for the host interface clock domain so
579          * there should be not frequency adjustment necessary.
580          */
581         return ppb ? FM10K_ERR_PARAM : FM10K_SUCCESS;
582 }
583
584 /**
585  *  fm10k_read_systime_vf - Reads value of systime registers
586  *  @hw: pointer to the hardware structure
587  *
588  *  Function reads the content of 2 registers, combined to represent a 64 bit
589  *  value measured in nanoseconds.  In order to guarantee the value is accurate
590  *  we check the 32 most significant bits both before and after reading the
591  *  32 least significant bits to verify they didn't change as we were reading
592  *  the registers.
593  **/
594 static u64 fm10k_read_systime_vf(struct fm10k_hw *hw)
595 {
596         u32 systime_l, systime_h, systime_tmp;
597
598         systime_h = fm10k_read_reg(hw, FM10K_VFSYSTIME + 1);
599
600         do {
601                 systime_tmp = systime_h;
602                 systime_l = fm10k_read_reg(hw, FM10K_VFSYSTIME);
603                 systime_h = fm10k_read_reg(hw, FM10K_VFSYSTIME + 1);
604         } while (systime_tmp != systime_h);
605
606         return ((u64)systime_h << 32) | systime_l;
607 }
608
609 static const struct fm10k_msg_data fm10k_msg_data_vf[] = {
610         FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test),
611         FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_msg_mac_vlan_vf),
612         FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_msg_lport_state_vf),
613         FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
614 };
615
616 /**
617  *  fm10k_init_ops_vf - Inits func ptrs and MAC type
618  *  @hw: pointer to hardware structure
619  *
620  *  Initialize the function pointers and assign the MAC type for VF.
621  *  Does not touch the hardware.
622  **/
623 s32 fm10k_init_ops_vf(struct fm10k_hw *hw)
624 {
625         struct fm10k_mac_info *mac = &hw->mac;
626
627         DEBUGFUNC("fm10k_init_ops_vf");
628
629         fm10k_init_ops_generic(hw);
630
631         mac->ops.reset_hw = &fm10k_reset_hw_vf;
632         mac->ops.init_hw = &fm10k_init_hw_vf;
633         mac->ops.start_hw = &fm10k_start_hw_generic;
634         mac->ops.stop_hw = &fm10k_stop_hw_vf;
635         mac->ops.is_slot_appropriate = &fm10k_is_slot_appropriate_vf;
636         mac->ops.update_vlan = &fm10k_update_vlan_vf;
637         mac->ops.read_mac_addr = &fm10k_read_mac_addr_vf;
638         mac->ops.update_uc_addr = &fm10k_update_uc_addr_vf;
639         mac->ops.update_mc_addr = &fm10k_update_mc_addr_vf;
640         mac->ops.update_xcast_mode = &fm10k_update_xcast_mode_vf;
641         mac->ops.update_int_moderator = &fm10k_update_int_moderator_vf;
642         mac->ops.update_lport_state = &fm10k_update_lport_state_vf;
643         mac->ops.update_hw_stats = &fm10k_update_hw_stats_vf;
644         mac->ops.rebind_hw_stats = &fm10k_rebind_hw_stats_vf;
645         mac->ops.configure_dglort_map = &fm10k_configure_dglort_map_vf;
646         mac->ops.get_host_state = &fm10k_get_host_state_generic;
647         mac->ops.adjust_systime = &fm10k_adjust_systime_vf;
648         mac->ops.read_systime = &fm10k_read_systime_vf;
649
650         mac->max_msix_vectors = fm10k_get_pcie_msix_count_generic(hw);
651
652         return fm10k_pfvf_mbx_init(hw, &hw->mbx, fm10k_msg_data_vf, 0);
653 }