1 /*******************************************************************************
3 Copyright (c) 2013 - 2015, Intel Corporation
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
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.
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.
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.
32 ***************************************************************************/
38 * fm10k_reset_hw_pf - PF hardware reset
39 * @hw: pointer to hardware structure
41 * This function should return the hardware to a state similar to the
42 * one it is in after being powered on.
44 STATIC s32 fm10k_reset_hw_pf(struct fm10k_hw *hw)
50 DEBUGFUNC("fm10k_reset_hw_pf");
52 /* Disable interrupts */
53 FM10K_WRITE_REG(hw, FM10K_EIMR, FM10K_EIMR_DISABLE(ALL));
55 /* Lock ITR2 reg 0 into itself and disable interrupt moderation */
56 FM10K_WRITE_REG(hw, FM10K_ITR2(0), 0);
57 FM10K_WRITE_REG(hw, FM10K_INT_CTRL, 0);
59 /* We assume here Tx and Rx queue 0 are owned by the PF */
61 /* Shut off VF access to their queues forcing them to queue 0 */
62 for (i = 0; i < FM10K_TQMAP_TABLE_SIZE; i++) {
63 FM10K_WRITE_REG(hw, FM10K_TQMAP(i), 0);
64 FM10K_WRITE_REG(hw, FM10K_RQMAP(i), 0);
67 /* shut down all rings */
68 err = fm10k_disable_queues_generic(hw, FM10K_MAX_QUEUES);
72 /* Verify that DMA is no longer active */
73 reg = FM10K_READ_REG(hw, FM10K_DMA_CTRL);
74 if (reg & (FM10K_DMA_CTRL_TX_ACTIVE | FM10K_DMA_CTRL_RX_ACTIVE))
75 return FM10K_ERR_DMA_PENDING;
77 /* verify the switch is ready for reset */
78 reg = FM10K_READ_REG(hw, FM10K_DMA_CTRL2);
79 if (!(reg & FM10K_DMA_CTRL2_SWITCH_READY))
82 /* Inititate data path reset */
83 reg |= FM10K_DMA_CTRL_DATAPATH_RESET;
84 FM10K_WRITE_REG(hw, FM10K_DMA_CTRL, reg);
86 /* Flush write and allow 100us for reset to complete */
87 FM10K_WRITE_FLUSH(hw);
88 usec_delay(FM10K_RESET_TIMEOUT);
90 /* Verify we made it out of reset */
91 reg = FM10K_READ_REG(hw, FM10K_IP);
92 if (!(reg & FM10K_IP_NOTINRESET))
93 err = FM10K_ERR_RESET_FAILED;
100 * fm10k_is_ari_hierarchy_pf - Indicate ARI hierarchy support
101 * @hw: pointer to hardware structure
103 * Looks at the ARI hierarchy bit to determine whether ARI is supported or not.
105 STATIC bool fm10k_is_ari_hierarchy_pf(struct fm10k_hw *hw)
107 u16 sriov_ctrl = FM10K_READ_PCI_WORD(hw, FM10K_PCIE_SRIOV_CTRL);
109 DEBUGFUNC("fm10k_is_ari_hierarchy_pf");
111 return !!(sriov_ctrl & FM10K_PCIE_SRIOV_CTRL_VFARI);
115 * fm10k_init_hw_pf - PF hardware initialization
116 * @hw: pointer to hardware structure
119 STATIC s32 fm10k_init_hw_pf(struct fm10k_hw *hw)
121 u32 dma_ctrl, txqctl;
124 DEBUGFUNC("fm10k_init_hw_pf");
126 /* Establish default VSI as valid */
127 FM10K_WRITE_REG(hw, FM10K_DGLORTDEC(fm10k_dglort_default), 0);
128 FM10K_WRITE_REG(hw, FM10K_DGLORTMAP(fm10k_dglort_default),
129 FM10K_DGLORTMAP_ANY);
131 /* Invalidate all other GLORT entries */
132 for (i = 1; i < FM10K_DGLORT_COUNT; i++)
133 FM10K_WRITE_REG(hw, FM10K_DGLORTMAP(i), FM10K_DGLORTMAP_NONE);
135 /* reset ITR2(0) to point to itself */
136 FM10K_WRITE_REG(hw, FM10K_ITR2(0), 0);
138 /* reset VF ITR2(0) to point to 0 avoid PF registers */
139 FM10K_WRITE_REG(hw, FM10K_ITR2(FM10K_ITR_REG_COUNT_PF), 0);
141 /* loop through all PF ITR2 registers pointing them to the previous */
142 for (i = 1; i < FM10K_ITR_REG_COUNT_PF; i++)
143 FM10K_WRITE_REG(hw, FM10K_ITR2(i), i - 1);
145 /* Enable interrupt moderator if not already enabled */
146 FM10K_WRITE_REG(hw, FM10K_INT_CTRL, FM10K_INT_CTRL_ENABLEMODERATOR);
148 /* compute the default txqctl configuration */
149 txqctl = FM10K_TXQCTL_PF | FM10K_TXQCTL_UNLIMITED_BW |
150 (hw->mac.default_vid << FM10K_TXQCTL_VID_SHIFT);
152 for (i = 0; i < FM10K_MAX_QUEUES; i++) {
153 /* configure rings for 256 Queue / 32 Descriptor cache mode */
154 FM10K_WRITE_REG(hw, FM10K_TQDLOC(i),
155 (i * FM10K_TQDLOC_BASE_32_DESC) |
156 FM10K_TQDLOC_SIZE_32_DESC);
157 FM10K_WRITE_REG(hw, FM10K_TXQCTL(i), txqctl);
159 /* configure rings to provide TPH processing hints */
160 FM10K_WRITE_REG(hw, FM10K_TPH_TXCTRL(i),
161 FM10K_TPH_TXCTRL_DESC_TPHEN |
162 FM10K_TPH_TXCTRL_DESC_RROEN |
163 FM10K_TPH_TXCTRL_DESC_WROEN |
164 FM10K_TPH_TXCTRL_DATA_RROEN);
165 FM10K_WRITE_REG(hw, FM10K_TPH_RXCTRL(i),
166 FM10K_TPH_RXCTRL_DESC_TPHEN |
167 FM10K_TPH_RXCTRL_DESC_RROEN |
168 FM10K_TPH_RXCTRL_DATA_WROEN |
169 FM10K_TPH_RXCTRL_HDR_WROEN);
172 /* set max hold interval to align with 1.024 usec in all modes and
175 switch (hw->bus.speed) {
176 case fm10k_bus_speed_2500:
177 dma_ctrl = FM10K_DMA_CTRL_MAX_HOLD_1US_GEN1;
178 hw->mac.itr_scale = FM10K_TDLEN_ITR_SCALE_GEN1;
180 case fm10k_bus_speed_5000:
181 dma_ctrl = FM10K_DMA_CTRL_MAX_HOLD_1US_GEN2;
182 hw->mac.itr_scale = FM10K_TDLEN_ITR_SCALE_GEN2;
184 case fm10k_bus_speed_8000:
185 dma_ctrl = FM10K_DMA_CTRL_MAX_HOLD_1US_GEN3;
186 hw->mac.itr_scale = FM10K_TDLEN_ITR_SCALE_GEN3;
190 /* just in case, assume Gen3 ITR scale */
191 hw->mac.itr_scale = FM10K_TDLEN_ITR_SCALE_GEN3;
195 /* Configure TSO flags */
196 FM10K_WRITE_REG(hw, FM10K_DTXTCPFLGL, FM10K_TSO_FLAGS_LOW);
197 FM10K_WRITE_REG(hw, FM10K_DTXTCPFLGH, FM10K_TSO_FLAGS_HI);
200 * Set Rx Descriptor size to 32
201 * Set Minimum MSS to 64
202 * Set Maximum number of Rx queues to 256 / 32 Descriptor
204 dma_ctrl |= FM10K_DMA_CTRL_TX_ENABLE | FM10K_DMA_CTRL_RX_ENABLE |
205 FM10K_DMA_CTRL_RX_DESC_SIZE | FM10K_DMA_CTRL_MINMSS_64 |
206 FM10K_DMA_CTRL_32_DESC;
208 FM10K_WRITE_REG(hw, FM10K_DMA_CTRL, dma_ctrl);
210 /* record maximum queue count, we limit ourselves to 128 */
211 hw->mac.max_queues = FM10K_MAX_QUEUES_PF;
213 /* We support either 64 VFs or 7 VFs depending on if we have ARI */
214 hw->iov.total_vfs = fm10k_is_ari_hierarchy_pf(hw) ? 64 : 7;
216 return FM10K_SUCCESS;
220 * fm10k_is_slot_appropriate_pf - Indicate appropriate slot for this SKU
221 * @hw: pointer to hardware structure
223 * Looks at the PCIe bus info to confirm whether or not this slot can support
224 * the necessary bandwidth for this device.
226 STATIC bool fm10k_is_slot_appropriate_pf(struct fm10k_hw *hw)
228 DEBUGFUNC("fm10k_is_slot_appropriate_pf");
230 return (hw->bus.speed == hw->bus_caps.speed) &&
231 (hw->bus.width == hw->bus_caps.width);
235 * fm10k_update_vlan_pf - Update status of VLAN ID in VLAN filter table
236 * @hw: pointer to hardware structure
237 * @vid: VLAN ID to add to table
238 * @vsi: Index indicating VF ID or PF ID in table
239 * @set: Indicates if this is a set or clear operation
241 * This function adds or removes the corresponding VLAN ID from the VLAN
242 * filter table for the corresponding function. In addition to the
243 * standard set/clear that supports one bit a multi-bit write is
244 * supported to set 64 bits at a time.
246 STATIC s32 fm10k_update_vlan_pf(struct fm10k_hw *hw, u32 vid, u8 vsi, bool set)
248 u32 vlan_table, reg, mask, bit, len;
250 /* verify the VSI index is valid */
251 if (vsi > FM10K_VLAN_TABLE_VSI_MAX)
252 return FM10K_ERR_PARAM;
254 /* VLAN multi-bit write:
255 * The multi-bit write has several parts to it.
257 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
258 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
259 * | RSVD0 | Length |C|RSVD0| VLAN ID |
260 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
262 * VLAN ID: Vlan Starting value
263 * RSVD0: Reserved section, must be 0
264 * C: Flag field, 0 is set, 1 is clear (Used in VF VLAN message)
265 * Length: Number of times to repeat the bit being set
268 vid = (vid << 17) >> 17;
270 /* verify the reserved 0 fields are 0 */
271 if (len >= FM10K_VLAN_TABLE_VID_MAX || vid >= FM10K_VLAN_TABLE_VID_MAX)
272 return FM10K_ERR_PARAM;
274 /* Loop through the table updating all required VLANs */
275 for (reg = FM10K_VLAN_TABLE(vsi, vid / 32), bit = vid % 32;
276 len < FM10K_VLAN_TABLE_VID_MAX;
277 len -= 32 - bit, reg++, bit = 0) {
278 /* record the initial state of the register */
279 vlan_table = FM10K_READ_REG(hw, reg);
281 /* truncate mask if we are at the start or end of the run */
282 mask = (~(u32)0 >> ((len < 31) ? 31 - len : 0)) << bit;
284 /* make necessary modifications to the register */
285 mask &= set ? ~vlan_table : vlan_table;
287 FM10K_WRITE_REG(hw, reg, vlan_table ^ mask);
290 return FM10K_SUCCESS;
294 * fm10k_read_mac_addr_pf - Read device MAC address
295 * @hw: pointer to the HW structure
297 * Reads the device MAC address from the SM_AREA and stores the value.
299 STATIC s32 fm10k_read_mac_addr_pf(struct fm10k_hw *hw)
301 u8 perm_addr[ETH_ALEN];
305 DEBUGFUNC("fm10k_read_mac_addr_pf");
307 serial_num = FM10K_READ_REG(hw, FM10K_SM_AREA(1));
309 /* last byte should be all 1's */
310 if ((~serial_num) << 24)
311 return FM10K_ERR_INVALID_MAC_ADDR;
313 perm_addr[0] = (u8)(serial_num >> 24);
314 perm_addr[1] = (u8)(serial_num >> 16);
315 perm_addr[2] = (u8)(serial_num >> 8);
317 serial_num = FM10K_READ_REG(hw, FM10K_SM_AREA(0));
319 /* first byte should be all 1's */
320 if ((~serial_num) >> 24)
321 return FM10K_ERR_INVALID_MAC_ADDR;
323 perm_addr[3] = (u8)(serial_num >> 16);
324 perm_addr[4] = (u8)(serial_num >> 8);
325 perm_addr[5] = (u8)(serial_num);
327 for (i = 0; i < ETH_ALEN; i++) {
328 hw->mac.perm_addr[i] = perm_addr[i];
329 hw->mac.addr[i] = perm_addr[i];
332 return FM10K_SUCCESS;
336 * fm10k_glort_valid_pf - Validate that the provided glort is valid
337 * @hw: pointer to the HW structure
338 * @glort: base glort to be validated
340 * This function will return an error if the provided glort is invalid
342 bool fm10k_glort_valid_pf(struct fm10k_hw *hw, u16 glort)
344 glort &= hw->mac.dglort_map >> FM10K_DGLORTMAP_MASK_SHIFT;
346 return glort == (hw->mac.dglort_map & FM10K_DGLORTMAP_NONE);
350 * fm10k_update_xc_addr_pf - Update device addresses
351 * @hw: pointer to the HW structure
352 * @glort: base resource tag for this request
353 * @mac: MAC address to add/remove from table
354 * @vid: VLAN ID to add/remove from table
355 * @add: Indicates if this is an add or remove operation
356 * @flags: flags field to indicate add and secure
358 * This function generates a message to the Switch API requesting
359 * that the given logical port add/remove the given L2 MAC/VLAN address.
361 STATIC s32 fm10k_update_xc_addr_pf(struct fm10k_hw *hw, u16 glort,
362 const u8 *mac, u16 vid, bool add, u8 flags)
364 struct fm10k_mbx_info *mbx = &hw->mbx;
365 struct fm10k_mac_update mac_update;
368 DEBUGFUNC("fm10k_update_xc_addr_pf");
370 /* if glort or VLAN are not valid return error */
371 if (!fm10k_glort_valid_pf(hw, glort) || vid >= FM10K_VLAN_TABLE_VID_MAX)
372 return FM10K_ERR_PARAM;
375 mac_update.mac_lower = FM10K_CPU_TO_LE32(((u32)mac[2] << 24) |
376 ((u32)mac[3] << 16) |
379 mac_update.mac_upper = FM10K_CPU_TO_LE16(((u32)mac[0] << 8) |
381 mac_update.vlan = FM10K_CPU_TO_LE16(vid);
382 mac_update.glort = FM10K_CPU_TO_LE16(glort);
383 mac_update.action = add ? 0 : 1;
384 mac_update.flags = flags;
386 /* populate mac_update fields */
387 fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_UPDATE_MAC_FWD_RULE);
388 fm10k_tlv_attr_put_le_struct(msg, FM10K_PF_ATTR_ID_MAC_UPDATE,
389 &mac_update, sizeof(mac_update));
391 /* load onto outgoing mailbox */
392 return mbx->ops.enqueue_tx(hw, mbx, msg);
396 * fm10k_update_uc_addr_pf - Update device unicast addresses
397 * @hw: pointer to the HW structure
398 * @glort: base resource tag for this request
399 * @mac: MAC address to add/remove from table
400 * @vid: VLAN ID to add/remove from table
401 * @add: Indicates if this is an add or remove operation
402 * @flags: flags field to indicate add and secure
404 * This function is used to add or remove unicast addresses for
407 STATIC s32 fm10k_update_uc_addr_pf(struct fm10k_hw *hw, u16 glort,
408 const u8 *mac, u16 vid, bool add, u8 flags)
410 DEBUGFUNC("fm10k_update_uc_addr_pf");
412 /* verify MAC address is valid */
413 if (!FM10K_IS_VALID_ETHER_ADDR(mac))
414 return FM10K_ERR_PARAM;
416 return fm10k_update_xc_addr_pf(hw, glort, mac, vid, add, flags);
420 * fm10k_update_mc_addr_pf - Update device multicast addresses
421 * @hw: pointer to the HW structure
422 * @glort: base resource tag for this request
423 * @mac: MAC address to add/remove from table
424 * @vid: VLAN ID to add/remove from table
425 * @add: Indicates if this is an add or remove operation
427 * This function is used to add or remove multicast MAC addresses for
430 STATIC s32 fm10k_update_mc_addr_pf(struct fm10k_hw *hw, u16 glort,
431 const u8 *mac, u16 vid, bool add)
433 DEBUGFUNC("fm10k_update_mc_addr_pf");
435 /* verify multicast address is valid */
436 if (!FM10K_IS_MULTICAST_ETHER_ADDR(mac))
437 return FM10K_ERR_PARAM;
439 return fm10k_update_xc_addr_pf(hw, glort, mac, vid, add, 0);
443 * fm10k_update_xcast_mode_pf - Request update of multicast mode
444 * @hw: pointer to hardware structure
445 * @glort: base resource tag for this request
446 * @mode: integer value indicating mode being requested
448 * This function will attempt to request a higher mode for the port
449 * so that it can enable either multicast, multicast promiscuous, or
450 * promiscuous mode of operation.
452 STATIC s32 fm10k_update_xcast_mode_pf(struct fm10k_hw *hw, u16 glort, u8 mode)
454 struct fm10k_mbx_info *mbx = &hw->mbx;
455 u32 msg[3], xcast_mode;
457 DEBUGFUNC("fm10k_update_xcast_mode_pf");
459 if (mode > FM10K_XCAST_MODE_NONE)
460 return FM10K_ERR_PARAM;
462 /* if glort is not valid return error */
463 if (!fm10k_glort_valid_pf(hw, glort))
464 return FM10K_ERR_PARAM;
466 /* write xcast mode as a single u32 value,
467 * lower 16 bits: glort
468 * upper 16 bits: mode
470 xcast_mode = ((u32)mode << 16) | glort;
472 /* generate message requesting to change xcast mode */
473 fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_XCAST_MODES);
474 fm10k_tlv_attr_put_u32(msg, FM10K_PF_ATTR_ID_XCAST_MODE, xcast_mode);
476 /* load onto outgoing mailbox */
477 return mbx->ops.enqueue_tx(hw, mbx, msg);
481 * fm10k_update_int_moderator_pf - Update interrupt moderator linked list
482 * @hw: pointer to hardware structure
484 * This function walks through the MSI-X vector table to determine the
485 * number of active interrupts and based on that information updates the
486 * interrupt moderator linked list.
488 STATIC void fm10k_update_int_moderator_pf(struct fm10k_hw *hw)
492 /* Disable interrupt moderator */
493 FM10K_WRITE_REG(hw, FM10K_INT_CTRL, 0);
495 /* loop through PF from last to first looking enabled vectors */
496 for (i = FM10K_ITR_REG_COUNT_PF - 1; i; i--) {
497 if (!FM10K_READ_REG(hw, FM10K_MSIX_VECTOR_MASK(i)))
501 /* always reset VFITR2[0] to point to last enabled PF vector */
502 FM10K_WRITE_REG(hw, FM10K_ITR2(FM10K_ITR_REG_COUNT_PF), i);
504 /* reset ITR2[0] to point to last enabled PF vector */
505 if (!hw->iov.num_vfs)
506 FM10K_WRITE_REG(hw, FM10K_ITR2(0), i);
508 /* Enable interrupt moderator */
509 FM10K_WRITE_REG(hw, FM10K_INT_CTRL, FM10K_INT_CTRL_ENABLEMODERATOR);
513 * fm10k_update_lport_state_pf - Notify the switch of a change in port state
514 * @hw: pointer to the HW structure
515 * @glort: base resource tag for this request
516 * @count: number of logical ports being updated
517 * @enable: boolean value indicating enable or disable
519 * This function is used to add/remove a logical port from the switch.
521 STATIC s32 fm10k_update_lport_state_pf(struct fm10k_hw *hw, u16 glort,
522 u16 count, bool enable)
524 struct fm10k_mbx_info *mbx = &hw->mbx;
525 u32 msg[3], lport_msg;
527 DEBUGFUNC("fm10k_lport_state_pf");
529 /* do nothing if we are being asked to create or destroy 0 ports */
531 return FM10K_SUCCESS;
533 /* if glort is not valid return error */
534 if (!fm10k_glort_valid_pf(hw, glort))
535 return FM10K_ERR_PARAM;
537 /* construct the lport message from the 2 pieces of data we have */
538 lport_msg = ((u32)count << 16) | glort;
540 /* generate lport create/delete message */
541 fm10k_tlv_msg_init(msg, enable ? FM10K_PF_MSG_ID_LPORT_CREATE :
542 FM10K_PF_MSG_ID_LPORT_DELETE);
543 fm10k_tlv_attr_put_u32(msg, FM10K_PF_ATTR_ID_PORT, lport_msg);
545 /* load onto outgoing mailbox */
546 return mbx->ops.enqueue_tx(hw, mbx, msg);
550 * fm10k_configure_dglort_map_pf - Configures GLORT entry and queues
551 * @hw: pointer to hardware structure
552 * @dglort: pointer to dglort configuration structure
554 * Reads the configuration structure contained in dglort_cfg and uses
555 * that information to then populate a DGLORTMAP/DEC entry and the queues
556 * to which it has been assigned.
558 STATIC s32 fm10k_configure_dglort_map_pf(struct fm10k_hw *hw,
559 struct fm10k_dglort_cfg *dglort)
561 u16 glort, queue_count, vsi_count, pc_count;
562 u16 vsi, queue, pc, q_idx;
563 u32 txqctl, dglortdec, dglortmap;
565 /* verify the dglort pointer */
567 return FM10K_ERR_PARAM;
569 /* verify the dglort values */
570 if ((dglort->idx > 7) || (dglort->rss_l > 7) || (dglort->pc_l > 3) ||
571 (dglort->vsi_l > 6) || (dglort->vsi_b > 64) ||
572 (dglort->queue_l > 8) || (dglort->queue_b >= 256))
573 return FM10K_ERR_PARAM;
575 /* determine count of VSIs and queues */
576 queue_count = 1 << (dglort->rss_l + dglort->pc_l);
577 vsi_count = 1 << (dglort->vsi_l + dglort->queue_l);
578 glort = dglort->glort;
579 q_idx = dglort->queue_b;
581 /* configure SGLORT for queues */
582 for (vsi = 0; vsi < vsi_count; vsi++, glort++) {
583 for (queue = 0; queue < queue_count; queue++, q_idx++) {
584 if (q_idx >= FM10K_MAX_QUEUES)
587 FM10K_WRITE_REG(hw, FM10K_TX_SGLORT(q_idx), glort);
588 FM10K_WRITE_REG(hw, FM10K_RX_SGLORT(q_idx), glort);
592 /* determine count of PCs and queues */
593 queue_count = 1 << (dglort->queue_l + dglort->rss_l + dglort->vsi_l);
594 pc_count = 1 << dglort->pc_l;
596 /* configure PC for Tx queues */
597 for (pc = 0; pc < pc_count; pc++) {
598 q_idx = pc + dglort->queue_b;
599 for (queue = 0; queue < queue_count; queue++) {
600 if (q_idx >= FM10K_MAX_QUEUES)
603 txqctl = FM10K_READ_REG(hw, FM10K_TXQCTL(q_idx));
604 txqctl &= ~FM10K_TXQCTL_PC_MASK;
605 txqctl |= pc << FM10K_TXQCTL_PC_SHIFT;
606 FM10K_WRITE_REG(hw, FM10K_TXQCTL(q_idx), txqctl);
612 /* configure DGLORTDEC */
613 dglortdec = ((u32)(dglort->rss_l) << FM10K_DGLORTDEC_RSSLENGTH_SHIFT) |
614 ((u32)(dglort->queue_b) << FM10K_DGLORTDEC_QBASE_SHIFT) |
615 ((u32)(dglort->pc_l) << FM10K_DGLORTDEC_PCLENGTH_SHIFT) |
616 ((u32)(dglort->vsi_b) << FM10K_DGLORTDEC_VSIBASE_SHIFT) |
617 ((u32)(dglort->vsi_l) << FM10K_DGLORTDEC_VSILENGTH_SHIFT) |
618 ((u32)(dglort->queue_l));
619 if (dglort->inner_rss)
620 dglortdec |= FM10K_DGLORTDEC_INNERRSS_ENABLE;
622 /* configure DGLORTMAP */
623 dglortmap = (dglort->idx == fm10k_dglort_default) ?
624 FM10K_DGLORTMAP_ANY : FM10K_DGLORTMAP_ZERO;
625 dglortmap <<= dglort->vsi_l + dglort->queue_l + dglort->shared_l;
626 dglortmap |= dglort->glort;
628 /* write values to hardware */
629 FM10K_WRITE_REG(hw, FM10K_DGLORTDEC(dglort->idx), dglortdec);
630 FM10K_WRITE_REG(hw, FM10K_DGLORTMAP(dglort->idx), dglortmap);
632 return FM10K_SUCCESS;
635 u16 fm10k_queues_per_pool(struct fm10k_hw *hw)
637 u16 num_pools = hw->iov.num_pools;
639 return (num_pools > 32) ? 2 : (num_pools > 16) ? 4 : (num_pools > 8) ?
640 8 : FM10K_MAX_QUEUES_POOL;
643 u16 fm10k_vf_queue_index(struct fm10k_hw *hw, u16 vf_idx)
645 u16 num_vfs = hw->iov.num_vfs;
646 u16 vf_q_idx = FM10K_MAX_QUEUES;
648 vf_q_idx -= fm10k_queues_per_pool(hw) * (num_vfs - vf_idx);
653 STATIC u16 fm10k_vectors_per_pool(struct fm10k_hw *hw)
655 u16 num_pools = hw->iov.num_pools;
657 return (num_pools > 32) ? 8 : (num_pools > 16) ? 16 :
658 FM10K_MAX_VECTORS_POOL;
661 STATIC u16 fm10k_vf_vector_index(struct fm10k_hw *hw, u16 vf_idx)
663 u16 vf_v_idx = FM10K_MAX_VECTORS_PF;
665 vf_v_idx += fm10k_vectors_per_pool(hw) * vf_idx;
671 * fm10k_iov_assign_resources_pf - Assign pool resources for virtualization
672 * @hw: pointer to the HW structure
673 * @num_vfs: number of VFs to be allocated
674 * @num_pools: number of virtualization pools to be allocated
676 * Allocates queues and traffic classes to virtualization entities to prepare
677 * the PF for SR-IOV and VMDq
679 STATIC s32 fm10k_iov_assign_resources_pf(struct fm10k_hw *hw, u16 num_vfs,
682 u16 qmap_stride, qpp, vpp, vf_q_idx, vf_q_idx0, qmap_idx;
683 u32 vid = hw->mac.default_vid << FM10K_TXQCTL_VID_SHIFT;
686 /* hardware only supports up to 64 pools */
688 return FM10K_ERR_PARAM;
690 /* the number of VFs cannot exceed the number of pools */
691 if ((num_vfs > num_pools) || (num_vfs > hw->iov.total_vfs))
692 return FM10K_ERR_PARAM;
694 /* record number of virtualization entities */
695 hw->iov.num_vfs = num_vfs;
696 hw->iov.num_pools = num_pools;
698 /* determine qmap offsets and counts */
699 qmap_stride = (num_vfs > 8) ? 32 : 256;
700 qpp = fm10k_queues_per_pool(hw);
701 vpp = fm10k_vectors_per_pool(hw);
703 /* calculate starting index for queues */
704 vf_q_idx = fm10k_vf_queue_index(hw, 0);
707 /* establish TCs with -1 credits and no quanta to prevent transmit */
708 for (i = 0; i < num_vfs; i++) {
709 FM10K_WRITE_REG(hw, FM10K_TC_MAXCREDIT(i), 0);
710 FM10K_WRITE_REG(hw, FM10K_TC_RATE(i), 0);
711 FM10K_WRITE_REG(hw, FM10K_TC_CREDIT(i),
712 FM10K_TC_CREDIT_CREDIT_MASK);
715 /* zero out all mbmem registers */
716 for (i = FM10K_VFMBMEM_LEN * num_vfs; i--;)
717 FM10K_WRITE_REG(hw, FM10K_MBMEM(i), 0);
719 /* clear event notification of VF FLR */
720 FM10K_WRITE_REG(hw, FM10K_PFVFLREC(0), ~0);
721 FM10K_WRITE_REG(hw, FM10K_PFVFLREC(1), ~0);
723 /* loop through unallocated rings assigning them back to PF */
724 for (i = FM10K_MAX_QUEUES_PF; i < vf_q_idx; i++) {
725 FM10K_WRITE_REG(hw, FM10K_TXDCTL(i), 0);
726 FM10K_WRITE_REG(hw, FM10K_TXQCTL(i), FM10K_TXQCTL_PF |
727 FM10K_TXQCTL_UNLIMITED_BW | vid);
728 FM10K_WRITE_REG(hw, FM10K_RXQCTL(i), FM10K_RXQCTL_PF);
731 /* PF should have already updated VFITR2[0] */
733 /* update all ITR registers to flow to VFITR2[0] */
734 for (i = FM10K_ITR_REG_COUNT_PF + 1; i < FM10K_ITR_REG_COUNT; i++) {
735 if (!(i & (vpp - 1)))
736 FM10K_WRITE_REG(hw, FM10K_ITR2(i), i - vpp);
738 FM10K_WRITE_REG(hw, FM10K_ITR2(i), i - 1);
741 /* update PF ITR2[0] to reference the last vector */
742 FM10K_WRITE_REG(hw, FM10K_ITR2(0),
743 fm10k_vf_vector_index(hw, num_vfs - 1));
745 /* loop through rings populating rings and TCs */
746 for (i = 0; i < num_vfs; i++) {
747 /* record index for VF queue 0 for use in end of loop */
748 vf_q_idx0 = vf_q_idx;
750 for (j = 0; j < qpp; j++, qmap_idx++, vf_q_idx++) {
751 /* assign VF and locked TC to queues */
752 FM10K_WRITE_REG(hw, FM10K_TXDCTL(vf_q_idx), 0);
753 FM10K_WRITE_REG(hw, FM10K_TXQCTL(vf_q_idx),
754 (i << FM10K_TXQCTL_TC_SHIFT) | i |
755 FM10K_TXQCTL_VF | vid);
756 FM10K_WRITE_REG(hw, FM10K_RXDCTL(vf_q_idx),
757 FM10K_RXDCTL_WRITE_BACK_MIN_DELAY |
758 FM10K_RXDCTL_DROP_ON_EMPTY);
759 FM10K_WRITE_REG(hw, FM10K_RXQCTL(vf_q_idx),
761 (i << FM10K_RXQCTL_VF_SHIFT));
763 /* map queue pair to VF */
764 FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), vf_q_idx);
765 FM10K_WRITE_REG(hw, FM10K_RQMAP(qmap_idx), vf_q_idx);
768 /* repeat the first ring for all of the remaining VF rings */
769 for (; j < qmap_stride; j++, qmap_idx++) {
770 FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), vf_q_idx0);
771 FM10K_WRITE_REG(hw, FM10K_RQMAP(qmap_idx), vf_q_idx0);
775 /* loop through remaining indexes assigning all to queue 0 */
776 while (qmap_idx < FM10K_TQMAP_TABLE_SIZE) {
777 FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), 0);
778 FM10K_WRITE_REG(hw, FM10K_RQMAP(qmap_idx), 0);
782 return FM10K_SUCCESS;
786 * fm10k_iov_configure_tc_pf - Configure the shaping group for VF
787 * @hw: pointer to the HW structure
788 * @vf_idx: index of VF receiving GLORT
789 * @rate: Rate indicated in Mb/s
791 * Configured the TC for a given VF to allow only up to a given number
792 * of Mb/s of outgoing Tx throughput.
794 STATIC s32 fm10k_iov_configure_tc_pf(struct fm10k_hw *hw, u16 vf_idx, int rate)
796 /* configure defaults */
797 u32 interval = FM10K_TC_RATE_INTERVAL_4US_GEN3;
798 u32 tc_rate = FM10K_TC_RATE_QUANTA_MASK;
800 /* verify vf is in range */
801 if (vf_idx >= hw->iov.num_vfs)
802 return FM10K_ERR_PARAM;
804 /* set interval to align with 4.096 usec in all modes */
805 switch (hw->bus.speed) {
806 case fm10k_bus_speed_2500:
807 interval = FM10K_TC_RATE_INTERVAL_4US_GEN1;
809 case fm10k_bus_speed_5000:
810 interval = FM10K_TC_RATE_INTERVAL_4US_GEN2;
817 if (rate > FM10K_VF_TC_MAX || rate < FM10K_VF_TC_MIN)
818 return FM10K_ERR_PARAM;
820 /* The quanta is measured in Bytes per 4.096 or 8.192 usec
821 * The rate is provided in Mbits per second
822 * To tralslate from rate to quanta we need to multiply the
823 * rate by 8.192 usec and divide by 8 bits/byte. To avoid
824 * dealing with floating point we can round the values up
825 * to the nearest whole number ratio which gives us 128 / 125.
827 tc_rate = (rate * 128) / 125;
829 /* try to keep the rate limiting accurate by increasing
830 * the number of credits and interval for rates less than 4Gb/s
838 /* update rate limiter with new values */
839 FM10K_WRITE_REG(hw, FM10K_TC_RATE(vf_idx), tc_rate | interval);
840 FM10K_WRITE_REG(hw, FM10K_TC_MAXCREDIT(vf_idx), FM10K_TC_MAXCREDIT_64K);
841 FM10K_WRITE_REG(hw, FM10K_TC_CREDIT(vf_idx), FM10K_TC_MAXCREDIT_64K);
843 return FM10K_SUCCESS;
847 * fm10k_iov_assign_int_moderator_pf - Add VF interrupts to moderator list
848 * @hw: pointer to the HW structure
849 * @vf_idx: index of VF receiving GLORT
851 * Update the interrupt moderator linked list to include any MSI-X
852 * interrupts which the VF has enabled in the MSI-X vector table.
854 STATIC s32 fm10k_iov_assign_int_moderator_pf(struct fm10k_hw *hw, u16 vf_idx)
856 u16 vf_v_idx, vf_v_limit, i;
858 /* verify vf is in range */
859 if (vf_idx >= hw->iov.num_vfs)
860 return FM10K_ERR_PARAM;
862 /* determine vector offset and count */
863 vf_v_idx = fm10k_vf_vector_index(hw, vf_idx);
864 vf_v_limit = vf_v_idx + fm10k_vectors_per_pool(hw);
866 /* search for first vector that is not masked */
867 for (i = vf_v_limit - 1; i > vf_v_idx; i--) {
868 if (!FM10K_READ_REG(hw, FM10K_MSIX_VECTOR_MASK(i)))
872 /* reset linked list so it now includes our active vectors */
873 if (vf_idx == (hw->iov.num_vfs - 1))
874 FM10K_WRITE_REG(hw, FM10K_ITR2(0), i);
876 FM10K_WRITE_REG(hw, FM10K_ITR2(vf_v_limit), i);
878 return FM10K_SUCCESS;
882 * fm10k_iov_assign_default_mac_vlan_pf - Assign a MAC and VLAN to VF
883 * @hw: pointer to the HW structure
884 * @vf_info: pointer to VF information structure
886 * Assign a MAC address and default VLAN to a VF and notify it of the update
888 STATIC s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw,
889 struct fm10k_vf_info *vf_info)
891 u16 qmap_stride, queues_per_pool, vf_q_idx, timeout, qmap_idx, i;
892 u32 msg[4], txdctl, txqctl, tdbal = 0, tdbah = 0;
893 s32 err = FM10K_SUCCESS;
896 /* verify vf is in range */
897 if (!vf_info || vf_info->vf_idx >= hw->iov.num_vfs)
898 return FM10K_ERR_PARAM;
900 /* determine qmap offsets and counts */
901 qmap_stride = (hw->iov.num_vfs > 8) ? 32 : 256;
902 queues_per_pool = fm10k_queues_per_pool(hw);
904 /* calculate starting index for queues */
905 vf_idx = vf_info->vf_idx;
906 vf_q_idx = fm10k_vf_queue_index(hw, vf_idx);
907 qmap_idx = qmap_stride * vf_idx;
909 /* MAP Tx queue back to 0 temporarily, and disable it */
910 FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), 0);
911 FM10K_WRITE_REG(hw, FM10K_TXDCTL(vf_q_idx), 0);
913 /* determine correct default VLAN ID */
915 vf_vid = vf_info->pf_vid | FM10K_VLAN_CLEAR;
917 vf_vid = vf_info->sw_vid;
919 /* generate MAC_ADDR request */
920 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
921 fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_DEFAULT_MAC,
922 vf_info->mac, vf_vid);
924 /* load onto outgoing mailbox, ignore any errors on enqueue */
925 if (vf_info->mbx.ops.enqueue_tx)
926 vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);
928 /* verify ring has disabled before modifying base address registers */
929 txdctl = FM10K_READ_REG(hw, FM10K_TXDCTL(vf_q_idx));
930 for (timeout = 0; txdctl & FM10K_TXDCTL_ENABLE; timeout++) {
931 /* limit ourselves to a 1ms timeout */
933 err = FM10K_ERR_DMA_PENDING;
938 txdctl = FM10K_READ_REG(hw, FM10K_TXDCTL(vf_q_idx));
941 /* Update base address registers to contain MAC address */
942 if (FM10K_IS_VALID_ETHER_ADDR(vf_info->mac)) {
943 tdbal = (((u32)vf_info->mac[3]) << 24) |
944 (((u32)vf_info->mac[4]) << 16) |
945 (((u32)vf_info->mac[5]) << 8);
947 tdbah = (((u32)0xFF) << 24) |
948 (((u32)vf_info->mac[0]) << 16) |
949 (((u32)vf_info->mac[1]) << 8) |
950 ((u32)vf_info->mac[2]);
953 /* Record the base address into queue 0 */
954 FM10K_WRITE_REG(hw, FM10K_TDBAL(vf_q_idx), tdbal);
955 FM10K_WRITE_REG(hw, FM10K_TDBAH(vf_q_idx), tdbah);
957 /* Provide the VF the ITR scale, using software-defined fields in TDLEN
958 * to pass the information during VF initialization
960 FM10K_WRITE_REG(hw, FM10K_TDLEN(vf_q_idx), hw->mac.itr_scale <<
961 FM10K_TDLEN_ITR_SCALE_SHIFT);
964 /* configure Queue control register */
965 txqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) &
966 FM10K_TXQCTL_VID_MASK;
967 txqctl |= (vf_idx << FM10K_TXQCTL_TC_SHIFT) |
968 FM10K_TXQCTL_VF | vf_idx;
971 for (i = 0; i < queues_per_pool; i++)
972 FM10K_WRITE_REG(hw, FM10K_TXQCTL(vf_q_idx + i), txqctl);
974 /* restore the queue back to VF ownership */
975 FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), vf_q_idx);
980 * fm10k_iov_reset_resources_pf - Reassign queues and interrupts to a VF
981 * @hw: pointer to the HW structure
982 * @vf_info: pointer to VF information structure
984 * Reassign the interrupts and queues to a VF following an FLR
986 STATIC s32 fm10k_iov_reset_resources_pf(struct fm10k_hw *hw,
987 struct fm10k_vf_info *vf_info)
989 u16 qmap_stride, queues_per_pool, vf_q_idx, qmap_idx;
990 u32 tdbal = 0, tdbah = 0, txqctl, rxqctl;
991 u16 vf_v_idx, vf_v_limit, vf_vid;
992 u8 vf_idx = vf_info->vf_idx;
995 /* verify vf is in range */
996 if (vf_idx >= hw->iov.num_vfs)
997 return FM10K_ERR_PARAM;
999 /* clear event notification of VF FLR */
1000 FM10K_WRITE_REG(hw, FM10K_PFVFLREC(vf_idx / 32), 1 << (vf_idx % 32));
1002 /* force timeout and then disconnect the mailbox */
1003 vf_info->mbx.timeout = 0;
1004 if (vf_info->mbx.ops.disconnect)
1005 vf_info->mbx.ops.disconnect(hw, &vf_info->mbx);
1007 /* determine vector offset and count */
1008 vf_v_idx = fm10k_vf_vector_index(hw, vf_idx);
1009 vf_v_limit = vf_v_idx + fm10k_vectors_per_pool(hw);
1011 /* determine qmap offsets and counts */
1012 qmap_stride = (hw->iov.num_vfs > 8) ? 32 : 256;
1013 queues_per_pool = fm10k_queues_per_pool(hw);
1014 qmap_idx = qmap_stride * vf_idx;
1016 /* make all the queues inaccessible to the VF */
1017 for (i = qmap_idx; i < (qmap_idx + qmap_stride); i++) {
1018 FM10K_WRITE_REG(hw, FM10K_TQMAP(i), 0);
1019 FM10K_WRITE_REG(hw, FM10K_RQMAP(i), 0);
1022 /* calculate starting index for queues */
1023 vf_q_idx = fm10k_vf_queue_index(hw, vf_idx);
1025 /* determine correct default VLAN ID */
1026 if (vf_info->pf_vid)
1027 vf_vid = vf_info->pf_vid;
1029 vf_vid = vf_info->sw_vid;
1031 /* configure Queue control register */
1032 txqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) |
1033 (vf_idx << FM10K_TXQCTL_TC_SHIFT) |
1034 FM10K_TXQCTL_VF | vf_idx;
1035 rxqctl = FM10K_RXQCTL_VF | (vf_idx << FM10K_RXQCTL_VF_SHIFT);
1037 /* stop further DMA and reset queue ownership back to VF */
1038 for (i = vf_q_idx; i < (queues_per_pool + vf_q_idx); i++) {
1039 FM10K_WRITE_REG(hw, FM10K_TXDCTL(i), 0);
1040 FM10K_WRITE_REG(hw, FM10K_TXQCTL(i), txqctl);
1041 FM10K_WRITE_REG(hw, FM10K_RXDCTL(i),
1042 FM10K_RXDCTL_WRITE_BACK_MIN_DELAY |
1043 FM10K_RXDCTL_DROP_ON_EMPTY);
1044 FM10K_WRITE_REG(hw, FM10K_RXQCTL(i), rxqctl);
1047 /* reset TC with -1 credits and no quanta to prevent transmit */
1048 FM10K_WRITE_REG(hw, FM10K_TC_MAXCREDIT(vf_idx), 0);
1049 FM10K_WRITE_REG(hw, FM10K_TC_RATE(vf_idx), 0);
1050 FM10K_WRITE_REG(hw, FM10K_TC_CREDIT(vf_idx),
1051 FM10K_TC_CREDIT_CREDIT_MASK);
1053 /* update our first entry in the table based on previous VF */
1055 hw->mac.ops.update_int_moderator(hw);
1057 hw->iov.ops.assign_int_moderator(hw, vf_idx - 1);
1059 /* reset linked list so it now includes our active vectors */
1060 if (vf_idx == (hw->iov.num_vfs - 1))
1061 FM10K_WRITE_REG(hw, FM10K_ITR2(0), vf_v_idx);
1063 FM10K_WRITE_REG(hw, FM10K_ITR2(vf_v_limit), vf_v_idx);
1065 /* link remaining vectors so that next points to previous */
1066 for (vf_v_idx++; vf_v_idx < vf_v_limit; vf_v_idx++)
1067 FM10K_WRITE_REG(hw, FM10K_ITR2(vf_v_idx), vf_v_idx - 1);
1069 /* zero out MBMEM, VLAN_TABLE, RETA, RSSRK, and MRQC registers */
1070 for (i = FM10K_VFMBMEM_LEN; i--;)
1071 FM10K_WRITE_REG(hw, FM10K_MBMEM_VF(vf_idx, i), 0);
1072 for (i = FM10K_VLAN_TABLE_SIZE; i--;)
1073 FM10K_WRITE_REG(hw, FM10K_VLAN_TABLE(vf_info->vsi, i), 0);
1074 for (i = FM10K_RETA_SIZE; i--;)
1075 FM10K_WRITE_REG(hw, FM10K_RETA(vf_info->vsi, i), 0);
1076 for (i = FM10K_RSSRK_SIZE; i--;)
1077 FM10K_WRITE_REG(hw, FM10K_RSSRK(vf_info->vsi, i), 0);
1078 FM10K_WRITE_REG(hw, FM10K_MRQC(vf_info->vsi), 0);
1080 /* Update base address registers to contain MAC address */
1081 if (FM10K_IS_VALID_ETHER_ADDR(vf_info->mac)) {
1082 tdbal = (((u32)vf_info->mac[3]) << 24) |
1083 (((u32)vf_info->mac[4]) << 16) |
1084 (((u32)vf_info->mac[5]) << 8);
1085 tdbah = (((u32)0xFF) << 24) |
1086 (((u32)vf_info->mac[0]) << 16) |
1087 (((u32)vf_info->mac[1]) << 8) |
1088 ((u32)vf_info->mac[2]);
1091 /* map queue pairs back to VF from last to first */
1092 for (i = queues_per_pool; i--;) {
1093 FM10K_WRITE_REG(hw, FM10K_TDBAL(vf_q_idx + i), tdbal);
1094 FM10K_WRITE_REG(hw, FM10K_TDBAH(vf_q_idx + i), tdbah);
1095 FM10K_WRITE_REG(hw, FM10K_TDLEN(vf_q_idx + i),
1096 hw->mac.itr_scale <<
1097 FM10K_TDLEN_ITR_SCALE_SHIFT);
1098 FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx + i), vf_q_idx + i);
1099 FM10K_WRITE_REG(hw, FM10K_RQMAP(qmap_idx + i), vf_q_idx + i);
1102 return FM10K_SUCCESS;
1106 * fm10k_iov_set_lport_pf - Assign and enable a logical port for a given VF
1107 * @hw: pointer to hardware structure
1108 * @vf_info: pointer to VF information structure
1109 * @lport_idx: Logical port offset from the hardware glort
1110 * @flags: Set of capability flags to extend port beyond basic functionality
1112 * This function allows enabling a VF port by assigning it a GLORT and
1113 * setting the flags so that it can enable an Rx mode.
1115 STATIC s32 fm10k_iov_set_lport_pf(struct fm10k_hw *hw,
1116 struct fm10k_vf_info *vf_info,
1117 u16 lport_idx, u8 flags)
1119 u16 glort = (hw->mac.dglort_map + lport_idx) & FM10K_DGLORTMAP_NONE;
1121 DEBUGFUNC("fm10k_iov_set_lport_state_pf");
1123 /* if glort is not valid return error */
1124 if (!fm10k_glort_valid_pf(hw, glort))
1125 return FM10K_ERR_PARAM;
1127 vf_info->vf_flags = flags | FM10K_VF_FLAG_NONE_CAPABLE;
1128 vf_info->glort = glort;
1130 return FM10K_SUCCESS;
1134 * fm10k_iov_reset_lport_pf - Disable a logical port for a given VF
1135 * @hw: pointer to hardware structure
1136 * @vf_info: pointer to VF information structure
1138 * This function disables a VF port by stripping it of a GLORT and
1139 * setting the flags so that it cannot enable any Rx mode.
1141 STATIC void fm10k_iov_reset_lport_pf(struct fm10k_hw *hw,
1142 struct fm10k_vf_info *vf_info)
1146 DEBUGFUNC("fm10k_iov_reset_lport_state_pf");
1148 /* need to disable the port if it is already enabled */
1149 if (FM10K_VF_FLAG_ENABLED(vf_info)) {
1150 /* notify switch that this port has been disabled */
1151 fm10k_update_lport_state_pf(hw, vf_info->glort, 1, false);
1153 /* generate port state response to notify VF it is not ready */
1154 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
1155 vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);
1158 /* clear flags and glort if it exists */
1159 vf_info->vf_flags = 0;
1164 * fm10k_iov_update_stats_pf - Updates hardware related statistics for VFs
1165 * @hw: pointer to hardware structure
1166 * @q: stats for all queues of a VF
1167 * @vf_idx: index of VF
1169 * This function collects queue stats for VFs.
1171 STATIC void fm10k_iov_update_stats_pf(struct fm10k_hw *hw,
1172 struct fm10k_hw_stats_q *q,
1177 /* get stats for all of the queues */
1178 qpp = fm10k_queues_per_pool(hw);
1179 idx = fm10k_vf_queue_index(hw, vf_idx);
1180 fm10k_update_hw_stats_q(hw, q, idx, qpp);
1183 STATIC s32 fm10k_iov_report_timestamp_pf(struct fm10k_hw *hw,
1184 struct fm10k_vf_info *vf_info,
1189 /* generate port state response to notify VF it is not ready */
1190 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_1588);
1191 fm10k_tlv_attr_put_u64(msg, FM10K_1588_MSG_TIMESTAMP, timestamp);
1193 return vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);
1197 * fm10k_iov_msg_msix_pf - Message handler for MSI-X request from VF
1198 * @hw: Pointer to hardware structure
1199 * @results: Pointer array to message, results[0] is pointer to message
1200 * @mbx: Pointer to mailbox information structure
1202 * This function is a default handler for MSI-X requests from the VF. The
1203 * assumption is that in this case it is acceptable to just directly
1204 * hand off the message from the VF to the underlying shared code.
1206 s32 fm10k_iov_msg_msix_pf(struct fm10k_hw *hw, u32 **results,
1207 struct fm10k_mbx_info *mbx)
1209 struct fm10k_vf_info *vf_info = (struct fm10k_vf_info *)mbx;
1210 u8 vf_idx = vf_info->vf_idx;
1212 UNREFERENCED_1PARAMETER(results);
1213 DEBUGFUNC("fm10k_iov_msg_msix_pf");
1215 return hw->iov.ops.assign_int_moderator(hw, vf_idx);
1219 * fm10k_iov_msg_mac_vlan_pf - Message handler for MAC/VLAN request from VF
1220 * @hw: Pointer to hardware structure
1221 * @results: Pointer array to message, results[0] is pointer to message
1222 * @mbx: Pointer to mailbox information structure
1224 * This function is a default handler for MAC/VLAN requests from the VF.
1225 * The assumption is that in this case it is acceptable to just directly
1226 * hand off the message from the VF to the underlying shared code.
1228 s32 fm10k_iov_msg_mac_vlan_pf(struct fm10k_hw *hw, u32 **results,
1229 struct fm10k_mbx_info *mbx)
1231 struct fm10k_vf_info *vf_info = (struct fm10k_vf_info *)mbx;
1232 int err = FM10K_SUCCESS;
1238 DEBUGFUNC("fm10k_iov_msg_mac_vlan_pf");
1240 /* we shouldn't be updating rules on a disabled interface */
1241 if (!FM10K_VF_FLAG_ENABLED(vf_info))
1242 err = FM10K_ERR_PARAM;
1244 if (!err && !!results[FM10K_MAC_VLAN_MSG_VLAN]) {
1245 result = results[FM10K_MAC_VLAN_MSG_VLAN];
1247 /* record VLAN id requested */
1248 err = fm10k_tlv_attr_get_u32(result, &vid);
1252 /* if VLAN ID is 0, set the default VLAN ID instead of 0 */
1253 if (!vid || (vid == FM10K_VLAN_CLEAR)) {
1254 if (vf_info->pf_vid)
1255 vid |= vf_info->pf_vid;
1257 vid |= vf_info->sw_vid;
1258 } else if (vid != vf_info->pf_vid) {
1259 return FM10K_ERR_PARAM;
1262 /* update VSI info for VF in regards to VLAN table */
1263 err = hw->mac.ops.update_vlan(hw, vid, vf_info->vsi,
1264 !(vid & FM10K_VLAN_CLEAR));
1267 if (!err && !!results[FM10K_MAC_VLAN_MSG_MAC]) {
1268 result = results[FM10K_MAC_VLAN_MSG_MAC];
1270 /* record unicast MAC address requested */
1271 err = fm10k_tlv_attr_get_mac_vlan(result, mac, &vlan);
1275 /* block attempts to set MAC for a locked device */
1276 if (FM10K_IS_VALID_ETHER_ADDR(vf_info->mac) &&
1277 memcmp(mac, vf_info->mac, ETH_ALEN))
1278 return FM10K_ERR_PARAM;
1280 /* if VLAN ID is 0, set the default VLAN ID instead of 0 */
1281 if (!vlan || (vlan == FM10K_VLAN_CLEAR)) {
1282 if (vf_info->pf_vid)
1283 vlan |= vf_info->pf_vid;
1285 vlan |= vf_info->sw_vid;
1286 } else if (vf_info->pf_vid) {
1287 return FM10K_ERR_PARAM;
1290 /* notify switch of request for new unicast address */
1291 err = hw->mac.ops.update_uc_addr(hw, vf_info->glort, mac, vlan,
1292 !(vlan & FM10K_VLAN_CLEAR), 0);
1295 if (!err && !!results[FM10K_MAC_VLAN_MSG_MULTICAST]) {
1296 result = results[FM10K_MAC_VLAN_MSG_MULTICAST];
1298 /* record multicast MAC address requested */
1299 err = fm10k_tlv_attr_get_mac_vlan(result, mac, &vlan);
1303 /* verify that the VF is allowed to request multicast */
1304 if (!(vf_info->vf_flags & FM10K_VF_FLAG_MULTI_ENABLED))
1305 return FM10K_ERR_PARAM;
1307 /* if VLAN ID is 0, set the default VLAN ID instead of 0 */
1308 if (!vlan || (vlan == FM10K_VLAN_CLEAR)) {
1309 if (vf_info->pf_vid)
1310 vlan |= vf_info->pf_vid;
1312 vlan |= vf_info->sw_vid;
1313 } else if (vf_info->pf_vid) {
1314 return FM10K_ERR_PARAM;
1317 /* notify switch of request for new multicast address */
1318 err = hw->mac.ops.update_mc_addr(hw, vf_info->glort, mac,
1319 !(vlan & FM10K_VLAN_CLEAR), 0);
1326 * fm10k_iov_supported_xcast_mode_pf - Determine best match for xcast mode
1327 * @vf_info: VF info structure containing capability flags
1328 * @mode: Requested xcast mode
1330 * This function outputs the mode that most closely matches the requested
1331 * mode. If not modes match it will request we disable the port
1333 STATIC u8 fm10k_iov_supported_xcast_mode_pf(struct fm10k_vf_info *vf_info,
1336 u8 vf_flags = vf_info->vf_flags;
1338 /* match up mode to capabilities as best as possible */
1340 case FM10K_XCAST_MODE_PROMISC:
1341 if (vf_flags & FM10K_VF_FLAG_PROMISC_CAPABLE)
1342 return FM10K_XCAST_MODE_PROMISC;
1344 case FM10K_XCAST_MODE_ALLMULTI:
1345 if (vf_flags & FM10K_VF_FLAG_ALLMULTI_CAPABLE)
1346 return FM10K_XCAST_MODE_ALLMULTI;
1348 case FM10K_XCAST_MODE_MULTI:
1349 if (vf_flags & FM10K_VF_FLAG_MULTI_CAPABLE)
1350 return FM10K_XCAST_MODE_MULTI;
1352 case FM10K_XCAST_MODE_NONE:
1353 if (vf_flags & FM10K_VF_FLAG_NONE_CAPABLE)
1354 return FM10K_XCAST_MODE_NONE;
1360 /* disable interface as it should not be able to request any */
1361 return FM10K_XCAST_MODE_DISABLE;
1365 * fm10k_iov_msg_lport_state_pf - Message handler for port state requests
1366 * @hw: Pointer to hardware structure
1367 * @results: Pointer array to message, results[0] is pointer to message
1368 * @mbx: Pointer to mailbox information structure
1370 * This function is a default handler for port state requests. The port
1371 * state requests for now are basic and consist of enabling or disabling
1374 s32 fm10k_iov_msg_lport_state_pf(struct fm10k_hw *hw, u32 **results,
1375 struct fm10k_mbx_info *mbx)
1377 struct fm10k_vf_info *vf_info = (struct fm10k_vf_info *)mbx;
1379 s32 err = FM10K_SUCCESS;
1383 DEBUGFUNC("fm10k_iov_msg_lport_state_pf");
1385 /* verify VF is allowed to enable even minimal mode */
1386 if (!(vf_info->vf_flags & FM10K_VF_FLAG_NONE_CAPABLE))
1387 return FM10K_ERR_PARAM;
1389 if (!!results[FM10K_LPORT_STATE_MSG_XCAST_MODE]) {
1390 result = results[FM10K_LPORT_STATE_MSG_XCAST_MODE];
1392 /* XCAST mode update requested */
1393 err = fm10k_tlv_attr_get_u8(result, &mode);
1395 return FM10K_ERR_PARAM;
1397 /* prep for possible demotion depending on capabilities */
1398 mode = fm10k_iov_supported_xcast_mode_pf(vf_info, mode);
1400 /* if mode is not currently enabled, enable it */
1401 if (!(FM10K_VF_FLAG_ENABLED(vf_info) & (1 << mode)))
1402 fm10k_update_xcast_mode_pf(hw, vf_info->glort, mode);
1404 /* swap mode back to a bit flag */
1405 mode = FM10K_VF_FLAG_SET_MODE(mode);
1406 } else if (!results[FM10K_LPORT_STATE_MSG_DISABLE]) {
1407 /* need to disable the port if it is already enabled */
1408 if (FM10K_VF_FLAG_ENABLED(vf_info))
1409 err = fm10k_update_lport_state_pf(hw, vf_info->glort,
1412 /* when enabling the port we should reset the rate limiters */
1413 hw->iov.ops.configure_tc(hw, vf_info->vf_idx, vf_info->rate);
1415 /* set mode for minimal functionality */
1416 mode = FM10K_VF_FLAG_SET_MODE_NONE;
1418 /* generate port state response to notify VF it is ready */
1419 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
1420 fm10k_tlv_attr_put_bool(msg, FM10K_LPORT_STATE_MSG_READY);
1421 mbx->ops.enqueue_tx(hw, mbx, msg);
1424 /* if enable state toggled note the update */
1425 if (!err && (!FM10K_VF_FLAG_ENABLED(vf_info) != !mode))
1426 err = fm10k_update_lport_state_pf(hw, vf_info->glort, 1,
1429 /* if state change succeeded, then update our stored state */
1430 mode |= FM10K_VF_FLAG_CAPABLE(vf_info);
1432 vf_info->vf_flags = mode;
1437 const struct fm10k_msg_data fm10k_iov_msg_data_pf[] = {
1438 FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test),
1439 FM10K_VF_MSG_MSIX_HANDLER(fm10k_iov_msg_msix_pf),
1440 FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_iov_msg_mac_vlan_pf),
1441 FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_iov_msg_lport_state_pf),
1442 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
1446 * fm10k_update_stats_hw_pf - Updates hardware related statistics of PF
1447 * @hw: pointer to hardware structure
1448 * @stats: pointer to the stats structure to update
1450 * This function collects and aggregates global and per queue hardware
1453 STATIC void fm10k_update_hw_stats_pf(struct fm10k_hw *hw,
1454 struct fm10k_hw_stats *stats)
1456 u32 timeout, ur, ca, um, xec, vlan_drop, loopback_drop, nodesc_drop;
1459 DEBUGFUNC("fm10k_update_hw_stats_pf");
1461 /* Use Tx queue 0 as a canary to detect a reset */
1462 id = FM10K_READ_REG(hw, FM10K_TXQCTL(0));
1464 /* Read Global Statistics */
1466 timeout = fm10k_read_hw_stats_32b(hw, FM10K_STATS_TIMEOUT,
1468 ur = fm10k_read_hw_stats_32b(hw, FM10K_STATS_UR, &stats->ur);
1469 ca = fm10k_read_hw_stats_32b(hw, FM10K_STATS_CA, &stats->ca);
1470 um = fm10k_read_hw_stats_32b(hw, FM10K_STATS_UM, &stats->um);
1471 xec = fm10k_read_hw_stats_32b(hw, FM10K_STATS_XEC, &stats->xec);
1472 vlan_drop = fm10k_read_hw_stats_32b(hw, FM10K_STATS_VLAN_DROP,
1474 loopback_drop = fm10k_read_hw_stats_32b(hw,
1475 FM10K_STATS_LOOPBACK_DROP,
1476 &stats->loopback_drop);
1477 nodesc_drop = fm10k_read_hw_stats_32b(hw,
1478 FM10K_STATS_NODESC_DROP,
1479 &stats->nodesc_drop);
1481 /* if value has not changed then we have consistent data */
1483 id = FM10K_READ_REG(hw, FM10K_TXQCTL(0));
1484 } while ((id ^ id_prev) & FM10K_TXQCTL_ID_MASK);
1486 /* drop non-ID bits and set VALID ID bit */
1487 id &= FM10K_TXQCTL_ID_MASK;
1488 id |= FM10K_STAT_VALID;
1490 /* Update Global Statistics */
1491 if (stats->stats_idx == id) {
1492 stats->timeout.count += timeout;
1493 stats->ur.count += ur;
1494 stats->ca.count += ca;
1495 stats->um.count += um;
1496 stats->xec.count += xec;
1497 stats->vlan_drop.count += vlan_drop;
1498 stats->loopback_drop.count += loopback_drop;
1499 stats->nodesc_drop.count += nodesc_drop;
1502 /* Update bases and record current PF id */
1503 fm10k_update_hw_base_32b(&stats->timeout, timeout);
1504 fm10k_update_hw_base_32b(&stats->ur, ur);
1505 fm10k_update_hw_base_32b(&stats->ca, ca);
1506 fm10k_update_hw_base_32b(&stats->um, um);
1507 fm10k_update_hw_base_32b(&stats->xec, xec);
1508 fm10k_update_hw_base_32b(&stats->vlan_drop, vlan_drop);
1509 fm10k_update_hw_base_32b(&stats->loopback_drop, loopback_drop);
1510 fm10k_update_hw_base_32b(&stats->nodesc_drop, nodesc_drop);
1511 stats->stats_idx = id;
1513 /* Update Queue Statistics */
1514 fm10k_update_hw_stats_q(hw, stats->q, 0, hw->mac.max_queues);
1518 * fm10k_rebind_hw_stats_pf - Resets base for hardware statistics of PF
1519 * @hw: pointer to hardware structure
1520 * @stats: pointer to the stats structure to update
1522 * This function resets the base for global and per queue hardware
1525 STATIC void fm10k_rebind_hw_stats_pf(struct fm10k_hw *hw,
1526 struct fm10k_hw_stats *stats)
1528 DEBUGFUNC("fm10k_rebind_hw_stats_pf");
1530 /* Unbind Global Statistics */
1531 fm10k_unbind_hw_stats_32b(&stats->timeout);
1532 fm10k_unbind_hw_stats_32b(&stats->ur);
1533 fm10k_unbind_hw_stats_32b(&stats->ca);
1534 fm10k_unbind_hw_stats_32b(&stats->um);
1535 fm10k_unbind_hw_stats_32b(&stats->xec);
1536 fm10k_unbind_hw_stats_32b(&stats->vlan_drop);
1537 fm10k_unbind_hw_stats_32b(&stats->loopback_drop);
1538 fm10k_unbind_hw_stats_32b(&stats->nodesc_drop);
1540 /* Unbind Queue Statistics */
1541 fm10k_unbind_hw_stats_q(stats->q, 0, hw->mac.max_queues);
1543 /* Reinitialize bases for all stats */
1544 fm10k_update_hw_stats_pf(hw, stats);
1548 * fm10k_set_dma_mask_pf - Configures PhyAddrSpace to limit DMA to system
1549 * @hw: pointer to hardware structure
1550 * @dma_mask: 64 bit DMA mask required for platform
1552 * This function sets the PHYADDR.PhyAddrSpace bits for the endpoint in order
1553 * to limit the access to memory beyond what is physically in the system.
1555 STATIC void fm10k_set_dma_mask_pf(struct fm10k_hw *hw, u64 dma_mask)
1557 /* we need to write the upper 32 bits of DMA mask to PhyAddrSpace */
1558 u32 phyaddr = (u32)(dma_mask >> 32);
1560 DEBUGFUNC("fm10k_set_dma_mask_pf");
1562 FM10K_WRITE_REG(hw, FM10K_PHYADDR, phyaddr);
1566 * fm10k_get_fault_pf - Record a fault in one of the interface units
1567 * @hw: pointer to hardware structure
1568 * @type: pointer to fault type register offset
1569 * @fault: pointer to memory location to record the fault
1571 * Record the fault register contents to the fault data structure and
1572 * clear the entry from the register.
1574 * Returns ERR_PARAM if invalid register is specified or no error is present.
1576 STATIC s32 fm10k_get_fault_pf(struct fm10k_hw *hw, int type,
1577 struct fm10k_fault *fault)
1581 DEBUGFUNC("fm10k_get_fault_pf");
1583 /* verify the fault register is in range and is aligned */
1585 case FM10K_PCA_FAULT:
1586 case FM10K_THI_FAULT:
1587 case FM10K_FUM_FAULT:
1590 return FM10K_ERR_PARAM;
1593 /* only service faults that are valid */
1594 func = FM10K_READ_REG(hw, type + FM10K_FAULT_FUNC);
1595 if (!(func & FM10K_FAULT_FUNC_VALID))
1596 return FM10K_ERR_PARAM;
1598 /* read remaining fields */
1599 fault->address = FM10K_READ_REG(hw, type + FM10K_FAULT_ADDR_HI);
1600 fault->address <<= 32;
1601 fault->address = FM10K_READ_REG(hw, type + FM10K_FAULT_ADDR_LO);
1602 fault->specinfo = FM10K_READ_REG(hw, type + FM10K_FAULT_SPECINFO);
1604 /* clear valid bit to allow for next error */
1605 FM10K_WRITE_REG(hw, type + FM10K_FAULT_FUNC, FM10K_FAULT_FUNC_VALID);
1607 /* Record which function triggered the error */
1608 if (func & FM10K_FAULT_FUNC_PF)
1611 fault->func = 1 + ((func & FM10K_FAULT_FUNC_VF_MASK) >>
1612 FM10K_FAULT_FUNC_VF_SHIFT);
1614 /* record fault type */
1615 fault->type = func & FM10K_FAULT_FUNC_TYPE_MASK;
1617 return FM10K_SUCCESS;
1621 * fm10k_request_lport_map_pf - Request LPORT map from the switch API
1622 * @hw: pointer to hardware structure
1625 STATIC s32 fm10k_request_lport_map_pf(struct fm10k_hw *hw)
1627 struct fm10k_mbx_info *mbx = &hw->mbx;
1630 DEBUGFUNC("fm10k_request_lport_pf");
1632 /* issue request asking for LPORT map */
1633 fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_LPORT_MAP);
1635 /* load onto outgoing mailbox */
1636 return mbx->ops.enqueue_tx(hw, mbx, msg);
1640 * fm10k_get_host_state_pf - Returns the state of the switch and mailbox
1641 * @hw: pointer to hardware structure
1642 * @switch_ready: pointer to boolean value that will record switch state
1644 * This funciton will check the DMA_CTRL2 register and mailbox in order
1645 * to determine if the switch is ready for the PF to begin requesting
1646 * addresses and mapping traffic to the local interface.
1648 STATIC s32 fm10k_get_host_state_pf(struct fm10k_hw *hw, bool *switch_ready)
1650 s32 ret_val = FM10K_SUCCESS;
1653 DEBUGFUNC("fm10k_get_host_state_pf");
1655 /* verify the switch is ready for interaction */
1656 dma_ctrl2 = FM10K_READ_REG(hw, FM10K_DMA_CTRL2);
1657 if (!(dma_ctrl2 & FM10K_DMA_CTRL2_SWITCH_READY))
1660 /* retrieve generic host state info */
1661 ret_val = fm10k_get_host_state_generic(hw, switch_ready);
1665 /* interface cannot receive traffic without logical ports */
1666 if (hw->mac.dglort_map == FM10K_DGLORTMAP_NONE)
1667 ret_val = fm10k_request_lport_map_pf(hw);
1673 /* This structure defines the attibutes to be parsed below */
1674 const struct fm10k_tlv_attr fm10k_lport_map_msg_attr[] = {
1675 FM10K_TLV_ATTR_U32(FM10K_PF_ATTR_ID_LPORT_MAP),
1680 * fm10k_msg_lport_map_pf - Message handler for lport_map message from SM
1681 * @hw: Pointer to hardware structure
1682 * @results: pointer array containing parsed data
1683 * @mbx: Pointer to mailbox information structure
1685 * This handler configures the lport mapping based on the reply from the
1688 s32 fm10k_msg_lport_map_pf(struct fm10k_hw *hw, u32 **results,
1689 struct fm10k_mbx_info *mbx)
1695 UNREFERENCED_1PARAMETER(mbx);
1696 DEBUGFUNC("fm10k_msg_lport_map_pf");
1698 err = fm10k_tlv_attr_get_u32(results[FM10K_PF_ATTR_ID_LPORT_MAP],
1703 /* extract values out of the header */
1704 glort = FM10K_MSG_HDR_FIELD_GET(dglort_map, LPORT_MAP_GLORT);
1705 mask = FM10K_MSG_HDR_FIELD_GET(dglort_map, LPORT_MAP_MASK);
1707 /* verify mask is set and none of the masked bits in glort are set */
1708 if (!mask || (glort & ~mask))
1709 return FM10K_ERR_PARAM;
1711 /* verify the mask is contiguous, and that it is 1's followed by 0's */
1712 if (((~(mask - 1) & mask) + mask) & FM10K_DGLORTMAP_NONE)
1713 return FM10K_ERR_PARAM;
1715 /* record the glort, mask, and port count */
1716 hw->mac.dglort_map = dglort_map;
1718 return FM10K_SUCCESS;
1721 const struct fm10k_tlv_attr fm10k_update_pvid_msg_attr[] = {
1722 FM10K_TLV_ATTR_U32(FM10K_PF_ATTR_ID_UPDATE_PVID),
1727 * fm10k_msg_update_pvid_pf - Message handler for port VLAN message from SM
1728 * @hw: Pointer to hardware structure
1729 * @results: pointer array containing parsed data
1730 * @mbx: Pointer to mailbox information structure
1732 * This handler configures the default VLAN for the PF
1734 s32 fm10k_msg_update_pvid_pf(struct fm10k_hw *hw, u32 **results,
1735 struct fm10k_mbx_info *mbx)
1741 UNREFERENCED_1PARAMETER(mbx);
1742 DEBUGFUNC("fm10k_msg_update_pvid_pf");
1744 err = fm10k_tlv_attr_get_u32(results[FM10K_PF_ATTR_ID_UPDATE_PVID],
1749 /* extract values from the pvid update */
1750 glort = FM10K_MSG_HDR_FIELD_GET(pvid_update, UPDATE_PVID_GLORT);
1751 pvid = FM10K_MSG_HDR_FIELD_GET(pvid_update, UPDATE_PVID_PVID);
1753 /* if glort is not valid return error */
1754 if (!fm10k_glort_valid_pf(hw, glort))
1755 return FM10K_ERR_PARAM;
1757 /* verify VID is valid */
1758 if (pvid >= FM10K_VLAN_TABLE_VID_MAX)
1759 return FM10K_ERR_PARAM;
1761 /* record the port VLAN ID value */
1762 hw->mac.default_vid = pvid;
1764 return FM10K_SUCCESS;
1768 * fm10k_record_global_table_data - Move global table data to swapi table info
1769 * @from: pointer to source table data structure
1770 * @to: pointer to destination table info structure
1772 * This function is will copy table_data to the table_info contained in
1775 static void fm10k_record_global_table_data(struct fm10k_global_table_data *from,
1776 struct fm10k_swapi_table_info *to)
1778 /* convert from le32 struct to CPU byte ordered values */
1779 to->used = FM10K_LE32_TO_CPU(from->used);
1780 to->avail = FM10K_LE32_TO_CPU(from->avail);
1783 const struct fm10k_tlv_attr fm10k_err_msg_attr[] = {
1784 FM10K_TLV_ATTR_LE_STRUCT(FM10K_PF_ATTR_ID_ERR,
1785 sizeof(struct fm10k_swapi_error)),
1790 * fm10k_msg_err_pf - Message handler for error reply
1791 * @hw: Pointer to hardware structure
1792 * @results: pointer array containing parsed data
1793 * @mbx: Pointer to mailbox information structure
1795 * This handler will capture the data for any error replies to previous
1796 * messages that the PF has sent.
1798 s32 fm10k_msg_err_pf(struct fm10k_hw *hw, u32 **results,
1799 struct fm10k_mbx_info *mbx)
1801 struct fm10k_swapi_error err_msg;
1804 UNREFERENCED_1PARAMETER(mbx);
1805 DEBUGFUNC("fm10k_msg_err_pf");
1807 /* extract structure from message */
1808 err = fm10k_tlv_attr_get_le_struct(results[FM10K_PF_ATTR_ID_ERR],
1809 &err_msg, sizeof(err_msg));
1813 /* record table status */
1814 fm10k_record_global_table_data(&err_msg.mac, &hw->swapi.mac);
1815 fm10k_record_global_table_data(&err_msg.nexthop, &hw->swapi.nexthop);
1816 fm10k_record_global_table_data(&err_msg.ffu, &hw->swapi.ffu);
1818 /* record SW API status value */
1819 hw->swapi.status = FM10K_LE32_TO_CPU(err_msg.status);
1821 return FM10K_SUCCESS;
1824 const struct fm10k_tlv_attr fm10k_1588_timestamp_msg_attr[] = {
1825 FM10K_TLV_ATTR_LE_STRUCT(FM10K_PF_ATTR_ID_1588_TIMESTAMP,
1826 sizeof(struct fm10k_swapi_1588_timestamp)),
1830 const struct fm10k_tlv_attr fm10k_tx_timestamp_mode_attr[] = {
1831 FM10K_TLV_ATTR_LE_STRUCT(FM10K_PF_ATTR_ID_TIMESTAMP_MODE_RESP,
1832 sizeof(struct fm10k_swapi_tx_timestamp_mode)),
1836 /* currently there is no shared 1588 timestamp handler */
1839 * fm10k_request_tx_timestamp_mode_pf - Request a specific Tx timestamping mode
1840 * @hw: pointer to hardware structure
1841 * @glort: base resource tag for this request
1842 * @mode: integer value indicating the requested mode
1844 * This function will attempt to request a specific timestamp mode for the
1845 * port so that it can receive Tx timestamp messages.
1847 STATIC s32 fm10k_request_tx_timestamp_mode_pf(struct fm10k_hw *hw,
1851 struct fm10k_mbx_info *mbx = &hw->mbx;
1852 u32 msg[3], timestamp_mode;
1854 DEBUGFUNC("fm10k_request_timestamp_mode_pf");
1856 if (mode > FM10K_TIMESTAMP_MODE_PEP_TO_ANY)
1857 return FM10K_ERR_PARAM;
1859 /* if glort is not valid return error */
1860 if (!fm10k_glort_valid_pf(hw, glort))
1861 return FM10K_ERR_PARAM;
1863 /* write timestamp mode as a single u32 value,
1864 * lower 16 bits: glort
1865 * upper 16 bits: mode
1867 timestamp_mode = ((u32)mode << 16) | glort;
1869 /* generate message requesting change to xcast mode */
1870 fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_TX_TIMESTAMP_MODE);
1871 fm10k_tlv_attr_put_u32(msg, FM10K_PF_ATTR_ID_TIMESTAMP_MODE_REQ, timestamp_mode);
1873 /* load onto outgoing mailbox */
1874 return mbx->ops.enqueue_tx(hw, mbx, msg);
1878 * fm10k_adjust_systime_pf - Adjust systime frequency
1879 * @hw: pointer to hardware structure
1880 * @ppb: adjustment rate in parts per billion
1882 * This function will adjust the SYSTIME_CFG register contained in BAR 4
1883 * if this function is supported for BAR 4 access. The adjustment amount
1884 * is based on the parts per billion value provided and adjusted to a
1885 * value based on parts per 2^48 clock cycles.
1887 * If adjustment is not supported or the requested value is too large
1888 * we will return an error.
1890 STATIC s32 fm10k_adjust_systime_pf(struct fm10k_hw *hw, s32 ppb)
1894 DEBUGFUNC("fm10k_adjust_systime_pf");
1896 /* if sw_addr is not set we don't have switch register access */
1898 return ppb ? FM10K_ERR_PARAM : FM10K_SUCCESS;
1900 /* we must convert the value from parts per billion to parts per
1901 * 2^48 cycles. In addition I have opted to only use the 30 most
1902 * significant bits of the adjustment value as the 8 least
1903 * significant bits are located in another register and represent
1904 * a value significantly less than a part per billion, the result
1905 * of dropping the 8 least significant bits is that the adjustment
1906 * value is effectively multiplied by 2^8 when we write it.
1908 * As a result of all this the math for this breaks down as follows:
1909 * ppb / 10^9 == adjust * 2^8 / 2^48
1910 * If we solve this for adjust, and simplify it comes out as:
1911 * ppb * 2^31 / 5^9 == adjust
1913 systime_adjust = (ppb < 0) ? -ppb : ppb;
1914 systime_adjust <<= 31;
1915 do_div(systime_adjust, 1953125);
1917 /* verify the requested adjustment value is in range */
1918 if (systime_adjust > FM10K_SW_SYSTIME_ADJUST_MASK)
1919 return FM10K_ERR_PARAM;
1922 systime_adjust |= FM10K_SW_SYSTIME_ADJUST_DIR_NEGATIVE;
1924 FM10K_WRITE_SW_REG(hw, FM10K_SW_SYSTIME_ADJUST, (u32)systime_adjust);
1926 return FM10K_SUCCESS;
1930 * fm10k_read_systime_pf - Reads value of systime registers
1931 * @hw: pointer to the hardware structure
1933 * Function reads the content of 2 registers, combined to represent a 64 bit
1934 * value measured in nanosecods. In order to guarantee the value is accurate
1935 * we check the 32 most significant bits both before and after reading the
1936 * 32 least significant bits to verify they didn't change as we were reading
1939 static u64 fm10k_read_systime_pf(struct fm10k_hw *hw)
1941 u32 systime_l, systime_h, systime_tmp;
1943 systime_h = fm10k_read_reg(hw, FM10K_SYSTIME + 1);
1946 systime_tmp = systime_h;
1947 systime_l = fm10k_read_reg(hw, FM10K_SYSTIME);
1948 systime_h = fm10k_read_reg(hw, FM10K_SYSTIME + 1);
1949 } while (systime_tmp != systime_h);
1951 return ((u64)systime_h << 32) | systime_l;
1954 static const struct fm10k_msg_data fm10k_msg_data_pf[] = {
1955 FM10K_PF_MSG_ERR_HANDLER(XCAST_MODES, fm10k_msg_err_pf),
1956 FM10K_PF_MSG_ERR_HANDLER(UPDATE_MAC_FWD_RULE, fm10k_msg_err_pf),
1957 FM10K_PF_MSG_LPORT_MAP_HANDLER(fm10k_msg_lport_map_pf),
1958 FM10K_PF_MSG_ERR_HANDLER(LPORT_CREATE, fm10k_msg_err_pf),
1959 FM10K_PF_MSG_ERR_HANDLER(LPORT_DELETE, fm10k_msg_err_pf),
1960 FM10K_PF_MSG_UPDATE_PVID_HANDLER(fm10k_msg_update_pvid_pf),
1961 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
1965 * fm10k_init_ops_pf - Inits func ptrs and MAC type
1966 * @hw: pointer to hardware structure
1968 * Initialize the function pointers and assign the MAC type for PF.
1969 * Does not touch the hardware.
1971 s32 fm10k_init_ops_pf(struct fm10k_hw *hw)
1973 struct fm10k_mac_info *mac = &hw->mac;
1974 struct fm10k_iov_info *iov = &hw->iov;
1976 DEBUGFUNC("fm10k_init_ops_pf");
1978 fm10k_init_ops_generic(hw);
1980 mac->ops.reset_hw = &fm10k_reset_hw_pf;
1981 mac->ops.init_hw = &fm10k_init_hw_pf;
1982 mac->ops.start_hw = &fm10k_start_hw_generic;
1983 mac->ops.stop_hw = &fm10k_stop_hw_generic;
1984 mac->ops.is_slot_appropriate = &fm10k_is_slot_appropriate_pf;
1985 mac->ops.update_vlan = &fm10k_update_vlan_pf;
1986 mac->ops.read_mac_addr = &fm10k_read_mac_addr_pf;
1987 mac->ops.update_uc_addr = &fm10k_update_uc_addr_pf;
1988 mac->ops.update_mc_addr = &fm10k_update_mc_addr_pf;
1989 mac->ops.update_xcast_mode = &fm10k_update_xcast_mode_pf;
1990 mac->ops.update_int_moderator = &fm10k_update_int_moderator_pf;
1991 mac->ops.update_lport_state = &fm10k_update_lport_state_pf;
1992 mac->ops.update_hw_stats = &fm10k_update_hw_stats_pf;
1993 mac->ops.rebind_hw_stats = &fm10k_rebind_hw_stats_pf;
1994 mac->ops.configure_dglort_map = &fm10k_configure_dglort_map_pf;
1995 mac->ops.set_dma_mask = &fm10k_set_dma_mask_pf;
1996 mac->ops.get_fault = &fm10k_get_fault_pf;
1997 mac->ops.get_host_state = &fm10k_get_host_state_pf;
1998 mac->ops.adjust_systime = &fm10k_adjust_systime_pf;
1999 mac->ops.read_systime = &fm10k_read_systime_pf;
2000 mac->ops.request_tx_timestamp_mode = &fm10k_request_tx_timestamp_mode_pf;
2002 mac->max_msix_vectors = fm10k_get_pcie_msix_count_generic(hw);
2004 iov->ops.assign_resources = &fm10k_iov_assign_resources_pf;
2005 iov->ops.configure_tc = &fm10k_iov_configure_tc_pf;
2006 iov->ops.assign_int_moderator = &fm10k_iov_assign_int_moderator_pf;
2007 iov->ops.assign_default_mac_vlan = fm10k_iov_assign_default_mac_vlan_pf;
2008 iov->ops.reset_resources = &fm10k_iov_reset_resources_pf;
2009 iov->ops.set_lport = &fm10k_iov_set_lport_pf;
2010 iov->ops.reset_lport = &fm10k_iov_reset_lport_pf;
2011 iov->ops.update_stats = &fm10k_iov_update_stats_pf;
2012 iov->ops.report_timestamp = &fm10k_iov_report_timestamp_pf;
2014 return fm10k_sm_mbx_init(hw, &hw->mbx, fm10k_msg_data_pf);