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 /* clear set bit from VLAN ID */
371 vid &= ~FM10K_VLAN_CLEAR;
373 /* if glort or VLAN are not valid return error */
374 if (!fm10k_glort_valid_pf(hw, glort) || vid >= FM10K_VLAN_TABLE_VID_MAX)
375 return FM10K_ERR_PARAM;
378 mac_update.mac_lower = FM10K_CPU_TO_LE32(((u32)mac[2] << 24) |
379 ((u32)mac[3] << 16) |
382 mac_update.mac_upper = FM10K_CPU_TO_LE16(((u32)mac[0] << 8) |
384 mac_update.vlan = FM10K_CPU_TO_LE16(vid);
385 mac_update.glort = FM10K_CPU_TO_LE16(glort);
386 mac_update.action = add ? 0 : 1;
387 mac_update.flags = flags;
389 /* populate mac_update fields */
390 fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_UPDATE_MAC_FWD_RULE);
391 fm10k_tlv_attr_put_le_struct(msg, FM10K_PF_ATTR_ID_MAC_UPDATE,
392 &mac_update, sizeof(mac_update));
394 /* load onto outgoing mailbox */
395 return mbx->ops.enqueue_tx(hw, mbx, msg);
399 * fm10k_update_uc_addr_pf - Update device unicast addresses
400 * @hw: pointer to the HW structure
401 * @glort: base resource tag for this request
402 * @mac: MAC address to add/remove from table
403 * @vid: VLAN ID to add/remove from table
404 * @add: Indicates if this is an add or remove operation
405 * @flags: flags field to indicate add and secure
407 * This function is used to add or remove unicast addresses for
410 STATIC s32 fm10k_update_uc_addr_pf(struct fm10k_hw *hw, u16 glort,
411 const u8 *mac, u16 vid, bool add, u8 flags)
413 DEBUGFUNC("fm10k_update_uc_addr_pf");
415 /* verify MAC address is valid */
416 if (!FM10K_IS_VALID_ETHER_ADDR(mac))
417 return FM10K_ERR_PARAM;
419 return fm10k_update_xc_addr_pf(hw, glort, mac, vid, add, flags);
423 * fm10k_update_mc_addr_pf - Update device multicast addresses
424 * @hw: pointer to the HW structure
425 * @glort: base resource tag for this request
426 * @mac: MAC address to add/remove from table
427 * @vid: VLAN ID to add/remove from table
428 * @add: Indicates if this is an add or remove operation
430 * This function is used to add or remove multicast MAC addresses for
433 STATIC s32 fm10k_update_mc_addr_pf(struct fm10k_hw *hw, u16 glort,
434 const u8 *mac, u16 vid, bool add)
436 DEBUGFUNC("fm10k_update_mc_addr_pf");
438 /* verify multicast address is valid */
439 if (!FM10K_IS_MULTICAST_ETHER_ADDR(mac))
440 return FM10K_ERR_PARAM;
442 return fm10k_update_xc_addr_pf(hw, glort, mac, vid, add, 0);
446 * fm10k_update_xcast_mode_pf - Request update of multicast mode
447 * @hw: pointer to hardware structure
448 * @glort: base resource tag for this request
449 * @mode: integer value indicating mode being requested
451 * This function will attempt to request a higher mode for the port
452 * so that it can enable either multicast, multicast promiscuous, or
453 * promiscuous mode of operation.
455 STATIC s32 fm10k_update_xcast_mode_pf(struct fm10k_hw *hw, u16 glort, u8 mode)
457 struct fm10k_mbx_info *mbx = &hw->mbx;
458 u32 msg[3], xcast_mode;
460 DEBUGFUNC("fm10k_update_xcast_mode_pf");
462 if (mode > FM10K_XCAST_MODE_NONE)
463 return FM10K_ERR_PARAM;
465 /* if glort is not valid return error */
466 if (!fm10k_glort_valid_pf(hw, glort))
467 return FM10K_ERR_PARAM;
469 /* write xcast mode as a single u32 value,
470 * lower 16 bits: glort
471 * upper 16 bits: mode
473 xcast_mode = ((u32)mode << 16) | glort;
475 /* generate message requesting to change xcast mode */
476 fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_XCAST_MODES);
477 fm10k_tlv_attr_put_u32(msg, FM10K_PF_ATTR_ID_XCAST_MODE, xcast_mode);
479 /* load onto outgoing mailbox */
480 return mbx->ops.enqueue_tx(hw, mbx, msg);
484 * fm10k_update_int_moderator_pf - Update interrupt moderator linked list
485 * @hw: pointer to hardware structure
487 * This function walks through the MSI-X vector table to determine the
488 * number of active interrupts and based on that information updates the
489 * interrupt moderator linked list.
491 STATIC void fm10k_update_int_moderator_pf(struct fm10k_hw *hw)
495 /* Disable interrupt moderator */
496 FM10K_WRITE_REG(hw, FM10K_INT_CTRL, 0);
498 /* loop through PF from last to first looking enabled vectors */
499 for (i = FM10K_ITR_REG_COUNT_PF - 1; i; i--) {
500 if (!FM10K_READ_REG(hw, FM10K_MSIX_VECTOR_MASK(i)))
504 /* always reset VFITR2[0] to point to last enabled PF vector */
505 FM10K_WRITE_REG(hw, FM10K_ITR2(FM10K_ITR_REG_COUNT_PF), i);
507 /* reset ITR2[0] to point to last enabled PF vector */
508 if (!hw->iov.num_vfs)
509 FM10K_WRITE_REG(hw, FM10K_ITR2(0), i);
511 /* Enable interrupt moderator */
512 FM10K_WRITE_REG(hw, FM10K_INT_CTRL, FM10K_INT_CTRL_ENABLEMODERATOR);
516 * fm10k_update_lport_state_pf - Notify the switch of a change in port state
517 * @hw: pointer to the HW structure
518 * @glort: base resource tag for this request
519 * @count: number of logical ports being updated
520 * @enable: boolean value indicating enable or disable
522 * This function is used to add/remove a logical port from the switch.
524 STATIC s32 fm10k_update_lport_state_pf(struct fm10k_hw *hw, u16 glort,
525 u16 count, bool enable)
527 struct fm10k_mbx_info *mbx = &hw->mbx;
528 u32 msg[3], lport_msg;
530 DEBUGFUNC("fm10k_lport_state_pf");
532 /* do nothing if we are being asked to create or destroy 0 ports */
534 return FM10K_SUCCESS;
536 /* if glort is not valid return error */
537 if (!fm10k_glort_valid_pf(hw, glort))
538 return FM10K_ERR_PARAM;
540 /* construct the lport message from the 2 pieces of data we have */
541 lport_msg = ((u32)count << 16) | glort;
543 /* generate lport create/delete message */
544 fm10k_tlv_msg_init(msg, enable ? FM10K_PF_MSG_ID_LPORT_CREATE :
545 FM10K_PF_MSG_ID_LPORT_DELETE);
546 fm10k_tlv_attr_put_u32(msg, FM10K_PF_ATTR_ID_PORT, lport_msg);
548 /* load onto outgoing mailbox */
549 return mbx->ops.enqueue_tx(hw, mbx, msg);
553 * fm10k_configure_dglort_map_pf - Configures GLORT entry and queues
554 * @hw: pointer to hardware structure
555 * @dglort: pointer to dglort configuration structure
557 * Reads the configuration structure contained in dglort_cfg and uses
558 * that information to then populate a DGLORTMAP/DEC entry and the queues
559 * to which it has been assigned.
561 STATIC s32 fm10k_configure_dglort_map_pf(struct fm10k_hw *hw,
562 struct fm10k_dglort_cfg *dglort)
564 u16 glort, queue_count, vsi_count, pc_count;
565 u16 vsi, queue, pc, q_idx;
566 u32 txqctl, dglortdec, dglortmap;
568 /* verify the dglort pointer */
570 return FM10K_ERR_PARAM;
572 /* verify the dglort values */
573 if ((dglort->idx > 7) || (dglort->rss_l > 7) || (dglort->pc_l > 3) ||
574 (dglort->vsi_l > 6) || (dglort->vsi_b > 64) ||
575 (dglort->queue_l > 8) || (dglort->queue_b >= 256))
576 return FM10K_ERR_PARAM;
578 /* determine count of VSIs and queues */
579 queue_count = 1 << (dglort->rss_l + dglort->pc_l);
580 vsi_count = 1 << (dglort->vsi_l + dglort->queue_l);
581 glort = dglort->glort;
582 q_idx = dglort->queue_b;
584 /* configure SGLORT for queues */
585 for (vsi = 0; vsi < vsi_count; vsi++, glort++) {
586 for (queue = 0; queue < queue_count; queue++, q_idx++) {
587 if (q_idx >= FM10K_MAX_QUEUES)
590 FM10K_WRITE_REG(hw, FM10K_TX_SGLORT(q_idx), glort);
591 FM10K_WRITE_REG(hw, FM10K_RX_SGLORT(q_idx), glort);
595 /* determine count of PCs and queues */
596 queue_count = 1 << (dglort->queue_l + dglort->rss_l + dglort->vsi_l);
597 pc_count = 1 << dglort->pc_l;
599 /* configure PC for Tx queues */
600 for (pc = 0; pc < pc_count; pc++) {
601 q_idx = pc + dglort->queue_b;
602 for (queue = 0; queue < queue_count; queue++) {
603 if (q_idx >= FM10K_MAX_QUEUES)
606 txqctl = FM10K_READ_REG(hw, FM10K_TXQCTL(q_idx));
607 txqctl &= ~FM10K_TXQCTL_PC_MASK;
608 txqctl |= pc << FM10K_TXQCTL_PC_SHIFT;
609 FM10K_WRITE_REG(hw, FM10K_TXQCTL(q_idx), txqctl);
615 /* configure DGLORTDEC */
616 dglortdec = ((u32)(dglort->rss_l) << FM10K_DGLORTDEC_RSSLENGTH_SHIFT) |
617 ((u32)(dglort->queue_b) << FM10K_DGLORTDEC_QBASE_SHIFT) |
618 ((u32)(dglort->pc_l) << FM10K_DGLORTDEC_PCLENGTH_SHIFT) |
619 ((u32)(dglort->vsi_b) << FM10K_DGLORTDEC_VSIBASE_SHIFT) |
620 ((u32)(dglort->vsi_l) << FM10K_DGLORTDEC_VSILENGTH_SHIFT) |
621 ((u32)(dglort->queue_l));
622 if (dglort->inner_rss)
623 dglortdec |= FM10K_DGLORTDEC_INNERRSS_ENABLE;
625 /* configure DGLORTMAP */
626 dglortmap = (dglort->idx == fm10k_dglort_default) ?
627 FM10K_DGLORTMAP_ANY : FM10K_DGLORTMAP_ZERO;
628 dglortmap <<= dglort->vsi_l + dglort->queue_l + dglort->shared_l;
629 dglortmap |= dglort->glort;
631 /* write values to hardware */
632 FM10K_WRITE_REG(hw, FM10K_DGLORTDEC(dglort->idx), dglortdec);
633 FM10K_WRITE_REG(hw, FM10K_DGLORTMAP(dglort->idx), dglortmap);
635 return FM10K_SUCCESS;
638 u16 fm10k_queues_per_pool(struct fm10k_hw *hw)
640 u16 num_pools = hw->iov.num_pools;
642 return (num_pools > 32) ? 2 : (num_pools > 16) ? 4 : (num_pools > 8) ?
643 8 : FM10K_MAX_QUEUES_POOL;
646 u16 fm10k_vf_queue_index(struct fm10k_hw *hw, u16 vf_idx)
648 u16 num_vfs = hw->iov.num_vfs;
649 u16 vf_q_idx = FM10K_MAX_QUEUES;
651 vf_q_idx -= fm10k_queues_per_pool(hw) * (num_vfs - vf_idx);
656 STATIC u16 fm10k_vectors_per_pool(struct fm10k_hw *hw)
658 u16 num_pools = hw->iov.num_pools;
660 return (num_pools > 32) ? 8 : (num_pools > 16) ? 16 :
661 FM10K_MAX_VECTORS_POOL;
664 STATIC u16 fm10k_vf_vector_index(struct fm10k_hw *hw, u16 vf_idx)
666 u16 vf_v_idx = FM10K_MAX_VECTORS_PF;
668 vf_v_idx += fm10k_vectors_per_pool(hw) * vf_idx;
674 * fm10k_iov_assign_resources_pf - Assign pool resources for virtualization
675 * @hw: pointer to the HW structure
676 * @num_vfs: number of VFs to be allocated
677 * @num_pools: number of virtualization pools to be allocated
679 * Allocates queues and traffic classes to virtualization entities to prepare
680 * the PF for SR-IOV and VMDq
682 STATIC s32 fm10k_iov_assign_resources_pf(struct fm10k_hw *hw, u16 num_vfs,
685 u16 qmap_stride, qpp, vpp, vf_q_idx, vf_q_idx0, qmap_idx;
686 u32 vid = hw->mac.default_vid << FM10K_TXQCTL_VID_SHIFT;
689 /* hardware only supports up to 64 pools */
691 return FM10K_ERR_PARAM;
693 /* the number of VFs cannot exceed the number of pools */
694 if ((num_vfs > num_pools) || (num_vfs > hw->iov.total_vfs))
695 return FM10K_ERR_PARAM;
697 /* record number of virtualization entities */
698 hw->iov.num_vfs = num_vfs;
699 hw->iov.num_pools = num_pools;
701 /* determine qmap offsets and counts */
702 qmap_stride = (num_vfs > 8) ? 32 : 256;
703 qpp = fm10k_queues_per_pool(hw);
704 vpp = fm10k_vectors_per_pool(hw);
706 /* calculate starting index for queues */
707 vf_q_idx = fm10k_vf_queue_index(hw, 0);
710 /* establish TCs with -1 credits and no quanta to prevent transmit */
711 for (i = 0; i < num_vfs; i++) {
712 FM10K_WRITE_REG(hw, FM10K_TC_MAXCREDIT(i), 0);
713 FM10K_WRITE_REG(hw, FM10K_TC_RATE(i), 0);
714 FM10K_WRITE_REG(hw, FM10K_TC_CREDIT(i),
715 FM10K_TC_CREDIT_CREDIT_MASK);
718 /* zero out all mbmem registers */
719 for (i = FM10K_VFMBMEM_LEN * num_vfs; i--;)
720 FM10K_WRITE_REG(hw, FM10K_MBMEM(i), 0);
722 /* clear event notification of VF FLR */
723 FM10K_WRITE_REG(hw, FM10K_PFVFLREC(0), ~0);
724 FM10K_WRITE_REG(hw, FM10K_PFVFLREC(1), ~0);
726 /* loop through unallocated rings assigning them back to PF */
727 for (i = FM10K_MAX_QUEUES_PF; i < vf_q_idx; i++) {
728 FM10K_WRITE_REG(hw, FM10K_TXDCTL(i), 0);
729 FM10K_WRITE_REG(hw, FM10K_TXQCTL(i), FM10K_TXQCTL_PF |
730 FM10K_TXQCTL_UNLIMITED_BW | vid);
731 FM10K_WRITE_REG(hw, FM10K_RXQCTL(i), FM10K_RXQCTL_PF);
734 /* PF should have already updated VFITR2[0] */
736 /* update all ITR registers to flow to VFITR2[0] */
737 for (i = FM10K_ITR_REG_COUNT_PF + 1; i < FM10K_ITR_REG_COUNT; i++) {
738 if (!(i & (vpp - 1)))
739 FM10K_WRITE_REG(hw, FM10K_ITR2(i), i - vpp);
741 FM10K_WRITE_REG(hw, FM10K_ITR2(i), i - 1);
744 /* update PF ITR2[0] to reference the last vector */
745 FM10K_WRITE_REG(hw, FM10K_ITR2(0),
746 fm10k_vf_vector_index(hw, num_vfs - 1));
748 /* loop through rings populating rings and TCs */
749 for (i = 0; i < num_vfs; i++) {
750 /* record index for VF queue 0 for use in end of loop */
751 vf_q_idx0 = vf_q_idx;
753 for (j = 0; j < qpp; j++, qmap_idx++, vf_q_idx++) {
754 /* assign VF and locked TC to queues */
755 FM10K_WRITE_REG(hw, FM10K_TXDCTL(vf_q_idx), 0);
756 FM10K_WRITE_REG(hw, FM10K_TXQCTL(vf_q_idx),
757 (i << FM10K_TXQCTL_TC_SHIFT) | i |
758 FM10K_TXQCTL_VF | vid);
759 FM10K_WRITE_REG(hw, FM10K_RXDCTL(vf_q_idx),
760 FM10K_RXDCTL_WRITE_BACK_MIN_DELAY |
761 FM10K_RXDCTL_DROP_ON_EMPTY);
762 FM10K_WRITE_REG(hw, FM10K_RXQCTL(vf_q_idx),
764 (i << FM10K_RXQCTL_VF_SHIFT));
766 /* map queue pair to VF */
767 FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), vf_q_idx);
768 FM10K_WRITE_REG(hw, FM10K_RQMAP(qmap_idx), vf_q_idx);
771 /* repeat the first ring for all of the remaining VF rings */
772 for (; j < qmap_stride; j++, qmap_idx++) {
773 FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), vf_q_idx0);
774 FM10K_WRITE_REG(hw, FM10K_RQMAP(qmap_idx), vf_q_idx0);
778 /* loop through remaining indexes assigning all to queue 0 */
779 while (qmap_idx < FM10K_TQMAP_TABLE_SIZE) {
780 FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), 0);
781 FM10K_WRITE_REG(hw, FM10K_RQMAP(qmap_idx), 0);
785 return FM10K_SUCCESS;
789 * fm10k_iov_configure_tc_pf - Configure the shaping group for VF
790 * @hw: pointer to the HW structure
791 * @vf_idx: index of VF receiving GLORT
792 * @rate: Rate indicated in Mb/s
794 * Configured the TC for a given VF to allow only up to a given number
795 * of Mb/s of outgoing Tx throughput.
797 STATIC s32 fm10k_iov_configure_tc_pf(struct fm10k_hw *hw, u16 vf_idx, int rate)
799 /* configure defaults */
800 u32 interval = FM10K_TC_RATE_INTERVAL_4US_GEN3;
801 u32 tc_rate = FM10K_TC_RATE_QUANTA_MASK;
803 /* verify vf is in range */
804 if (vf_idx >= hw->iov.num_vfs)
805 return FM10K_ERR_PARAM;
807 /* set interval to align with 4.096 usec in all modes */
808 switch (hw->bus.speed) {
809 case fm10k_bus_speed_2500:
810 interval = FM10K_TC_RATE_INTERVAL_4US_GEN1;
812 case fm10k_bus_speed_5000:
813 interval = FM10K_TC_RATE_INTERVAL_4US_GEN2;
820 if (rate > FM10K_VF_TC_MAX || rate < FM10K_VF_TC_MIN)
821 return FM10K_ERR_PARAM;
823 /* The quanta is measured in Bytes per 4.096 or 8.192 usec
824 * The rate is provided in Mbits per second
825 * To tralslate from rate to quanta we need to multiply the
826 * rate by 8.192 usec and divide by 8 bits/byte. To avoid
827 * dealing with floating point we can round the values up
828 * to the nearest whole number ratio which gives us 128 / 125.
830 tc_rate = (rate * 128) / 125;
832 /* try to keep the rate limiting accurate by increasing
833 * the number of credits and interval for rates less than 4Gb/s
841 /* update rate limiter with new values */
842 FM10K_WRITE_REG(hw, FM10K_TC_RATE(vf_idx), tc_rate | interval);
843 FM10K_WRITE_REG(hw, FM10K_TC_MAXCREDIT(vf_idx), FM10K_TC_MAXCREDIT_64K);
844 FM10K_WRITE_REG(hw, FM10K_TC_CREDIT(vf_idx), FM10K_TC_MAXCREDIT_64K);
846 return FM10K_SUCCESS;
850 * fm10k_iov_assign_int_moderator_pf - Add VF interrupts to moderator list
851 * @hw: pointer to the HW structure
852 * @vf_idx: index of VF receiving GLORT
854 * Update the interrupt moderator linked list to include any MSI-X
855 * interrupts which the VF has enabled in the MSI-X vector table.
857 STATIC s32 fm10k_iov_assign_int_moderator_pf(struct fm10k_hw *hw, u16 vf_idx)
859 u16 vf_v_idx, vf_v_limit, i;
861 /* verify vf is in range */
862 if (vf_idx >= hw->iov.num_vfs)
863 return FM10K_ERR_PARAM;
865 /* determine vector offset and count */
866 vf_v_idx = fm10k_vf_vector_index(hw, vf_idx);
867 vf_v_limit = vf_v_idx + fm10k_vectors_per_pool(hw);
869 /* search for first vector that is not masked */
870 for (i = vf_v_limit - 1; i > vf_v_idx; i--) {
871 if (!FM10K_READ_REG(hw, FM10K_MSIX_VECTOR_MASK(i)))
875 /* reset linked list so it now includes our active vectors */
876 if (vf_idx == (hw->iov.num_vfs - 1))
877 FM10K_WRITE_REG(hw, FM10K_ITR2(0), i);
879 FM10K_WRITE_REG(hw, FM10K_ITR2(vf_v_limit), i);
881 return FM10K_SUCCESS;
885 * fm10k_iov_assign_default_mac_vlan_pf - Assign a MAC and VLAN to VF
886 * @hw: pointer to the HW structure
887 * @vf_info: pointer to VF information structure
889 * Assign a MAC address and default VLAN to a VF and notify it of the update
891 STATIC s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw,
892 struct fm10k_vf_info *vf_info)
894 u16 qmap_stride, queues_per_pool, vf_q_idx, timeout, qmap_idx, i;
895 u32 msg[4], txdctl, txqctl, tdbal = 0, tdbah = 0;
896 s32 err = FM10K_SUCCESS;
899 /* verify vf is in range */
900 if (!vf_info || vf_info->vf_idx >= hw->iov.num_vfs)
901 return FM10K_ERR_PARAM;
903 /* determine qmap offsets and counts */
904 qmap_stride = (hw->iov.num_vfs > 8) ? 32 : 256;
905 queues_per_pool = fm10k_queues_per_pool(hw);
907 /* calculate starting index for queues */
908 vf_idx = vf_info->vf_idx;
909 vf_q_idx = fm10k_vf_queue_index(hw, vf_idx);
910 qmap_idx = qmap_stride * vf_idx;
912 /* MAP Tx queue back to 0 temporarily, and disable it */
913 FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), 0);
914 FM10K_WRITE_REG(hw, FM10K_TXDCTL(vf_q_idx), 0);
916 /* determine correct default VLAN ID */
918 vf_vid = vf_info->pf_vid | FM10K_VLAN_CLEAR;
920 vf_vid = vf_info->sw_vid;
922 /* generate MAC_ADDR request */
923 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
924 fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_DEFAULT_MAC,
925 vf_info->mac, vf_vid);
927 /* load onto outgoing mailbox, ignore any errors on enqueue */
928 if (vf_info->mbx.ops.enqueue_tx)
929 vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);
931 /* verify ring has disabled before modifying base address registers */
932 txdctl = FM10K_READ_REG(hw, FM10K_TXDCTL(vf_q_idx));
933 for (timeout = 0; txdctl & FM10K_TXDCTL_ENABLE; timeout++) {
934 /* limit ourselves to a 1ms timeout */
936 err = FM10K_ERR_DMA_PENDING;
941 txdctl = FM10K_READ_REG(hw, FM10K_TXDCTL(vf_q_idx));
944 /* Update base address registers to contain MAC address */
945 if (FM10K_IS_VALID_ETHER_ADDR(vf_info->mac)) {
946 tdbal = (((u32)vf_info->mac[3]) << 24) |
947 (((u32)vf_info->mac[4]) << 16) |
948 (((u32)vf_info->mac[5]) << 8);
950 tdbah = (((u32)0xFF) << 24) |
951 (((u32)vf_info->mac[0]) << 16) |
952 (((u32)vf_info->mac[1]) << 8) |
953 ((u32)vf_info->mac[2]);
956 /* Record the base address into queue 0 */
957 FM10K_WRITE_REG(hw, FM10K_TDBAL(vf_q_idx), tdbal);
958 FM10K_WRITE_REG(hw, FM10K_TDBAH(vf_q_idx), tdbah);
960 /* Provide the VF the ITR scale, using software-defined fields in TDLEN
961 * to pass the information during VF initialization
963 FM10K_WRITE_REG(hw, FM10K_TDLEN(vf_q_idx), hw->mac.itr_scale <<
964 FM10K_TDLEN_ITR_SCALE_SHIFT);
967 /* configure Queue control register */
968 txqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) &
969 FM10K_TXQCTL_VID_MASK;
970 txqctl |= (vf_idx << FM10K_TXQCTL_TC_SHIFT) |
971 FM10K_TXQCTL_VF | vf_idx;
974 for (i = 0; i < queues_per_pool; i++)
975 FM10K_WRITE_REG(hw, FM10K_TXQCTL(vf_q_idx + i), txqctl);
977 /* restore the queue back to VF ownership */
978 FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), vf_q_idx);
983 * fm10k_iov_reset_resources_pf - Reassign queues and interrupts to a VF
984 * @hw: pointer to the HW structure
985 * @vf_info: pointer to VF information structure
987 * Reassign the interrupts and queues to a VF following an FLR
989 STATIC s32 fm10k_iov_reset_resources_pf(struct fm10k_hw *hw,
990 struct fm10k_vf_info *vf_info)
992 u16 qmap_stride, queues_per_pool, vf_q_idx, qmap_idx;
993 u32 tdbal = 0, tdbah = 0, txqctl, rxqctl;
994 u16 vf_v_idx, vf_v_limit, vf_vid;
995 u8 vf_idx = vf_info->vf_idx;
998 /* verify vf is in range */
999 if (vf_idx >= hw->iov.num_vfs)
1000 return FM10K_ERR_PARAM;
1002 /* clear event notification of VF FLR */
1003 FM10K_WRITE_REG(hw, FM10K_PFVFLREC(vf_idx / 32), 1 << (vf_idx % 32));
1005 /* force timeout and then disconnect the mailbox */
1006 vf_info->mbx.timeout = 0;
1007 if (vf_info->mbx.ops.disconnect)
1008 vf_info->mbx.ops.disconnect(hw, &vf_info->mbx);
1010 /* determine vector offset and count */
1011 vf_v_idx = fm10k_vf_vector_index(hw, vf_idx);
1012 vf_v_limit = vf_v_idx + fm10k_vectors_per_pool(hw);
1014 /* determine qmap offsets and counts */
1015 qmap_stride = (hw->iov.num_vfs > 8) ? 32 : 256;
1016 queues_per_pool = fm10k_queues_per_pool(hw);
1017 qmap_idx = qmap_stride * vf_idx;
1019 /* make all the queues inaccessible to the VF */
1020 for (i = qmap_idx; i < (qmap_idx + qmap_stride); i++) {
1021 FM10K_WRITE_REG(hw, FM10K_TQMAP(i), 0);
1022 FM10K_WRITE_REG(hw, FM10K_RQMAP(i), 0);
1025 /* calculate starting index for queues */
1026 vf_q_idx = fm10k_vf_queue_index(hw, vf_idx);
1028 /* determine correct default VLAN ID */
1029 if (vf_info->pf_vid)
1030 vf_vid = vf_info->pf_vid;
1032 vf_vid = vf_info->sw_vid;
1034 /* configure Queue control register */
1035 txqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) |
1036 (vf_idx << FM10K_TXQCTL_TC_SHIFT) |
1037 FM10K_TXQCTL_VF | vf_idx;
1038 rxqctl = FM10K_RXQCTL_VF | (vf_idx << FM10K_RXQCTL_VF_SHIFT);
1040 /* stop further DMA and reset queue ownership back to VF */
1041 for (i = vf_q_idx; i < (queues_per_pool + vf_q_idx); i++) {
1042 FM10K_WRITE_REG(hw, FM10K_TXDCTL(i), 0);
1043 FM10K_WRITE_REG(hw, FM10K_TXQCTL(i), txqctl);
1044 FM10K_WRITE_REG(hw, FM10K_RXDCTL(i),
1045 FM10K_RXDCTL_WRITE_BACK_MIN_DELAY |
1046 FM10K_RXDCTL_DROP_ON_EMPTY);
1047 FM10K_WRITE_REG(hw, FM10K_RXQCTL(i), rxqctl);
1050 /* reset TC with -1 credits and no quanta to prevent transmit */
1051 FM10K_WRITE_REG(hw, FM10K_TC_MAXCREDIT(vf_idx), 0);
1052 FM10K_WRITE_REG(hw, FM10K_TC_RATE(vf_idx), 0);
1053 FM10K_WRITE_REG(hw, FM10K_TC_CREDIT(vf_idx),
1054 FM10K_TC_CREDIT_CREDIT_MASK);
1056 /* update our first entry in the table based on previous VF */
1058 hw->mac.ops.update_int_moderator(hw);
1060 hw->iov.ops.assign_int_moderator(hw, vf_idx - 1);
1062 /* reset linked list so it now includes our active vectors */
1063 if (vf_idx == (hw->iov.num_vfs - 1))
1064 FM10K_WRITE_REG(hw, FM10K_ITR2(0), vf_v_idx);
1066 FM10K_WRITE_REG(hw, FM10K_ITR2(vf_v_limit), vf_v_idx);
1068 /* link remaining vectors so that next points to previous */
1069 for (vf_v_idx++; vf_v_idx < vf_v_limit; vf_v_idx++)
1070 FM10K_WRITE_REG(hw, FM10K_ITR2(vf_v_idx), vf_v_idx - 1);
1072 /* zero out MBMEM, VLAN_TABLE, RETA, RSSRK, and MRQC registers */
1073 for (i = FM10K_VFMBMEM_LEN; i--;)
1074 FM10K_WRITE_REG(hw, FM10K_MBMEM_VF(vf_idx, i), 0);
1075 for (i = FM10K_VLAN_TABLE_SIZE; i--;)
1076 FM10K_WRITE_REG(hw, FM10K_VLAN_TABLE(vf_info->vsi, i), 0);
1077 for (i = FM10K_RETA_SIZE; i--;)
1078 FM10K_WRITE_REG(hw, FM10K_RETA(vf_info->vsi, i), 0);
1079 for (i = FM10K_RSSRK_SIZE; i--;)
1080 FM10K_WRITE_REG(hw, FM10K_RSSRK(vf_info->vsi, i), 0);
1081 FM10K_WRITE_REG(hw, FM10K_MRQC(vf_info->vsi), 0);
1083 /* Update base address registers to contain MAC address */
1084 if (FM10K_IS_VALID_ETHER_ADDR(vf_info->mac)) {
1085 tdbal = (((u32)vf_info->mac[3]) << 24) |
1086 (((u32)vf_info->mac[4]) << 16) |
1087 (((u32)vf_info->mac[5]) << 8);
1088 tdbah = (((u32)0xFF) << 24) |
1089 (((u32)vf_info->mac[0]) << 16) |
1090 (((u32)vf_info->mac[1]) << 8) |
1091 ((u32)vf_info->mac[2]);
1094 /* map queue pairs back to VF from last to first */
1095 for (i = queues_per_pool; i--;) {
1096 FM10K_WRITE_REG(hw, FM10K_TDBAL(vf_q_idx + i), tdbal);
1097 FM10K_WRITE_REG(hw, FM10K_TDBAH(vf_q_idx + i), tdbah);
1098 FM10K_WRITE_REG(hw, FM10K_TDLEN(vf_q_idx + i),
1099 hw->mac.itr_scale <<
1100 FM10K_TDLEN_ITR_SCALE_SHIFT);
1101 FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx + i), vf_q_idx + i);
1102 FM10K_WRITE_REG(hw, FM10K_RQMAP(qmap_idx + i), vf_q_idx + i);
1105 /* repeat the first ring for all of the remaining VF rings */
1106 for (i = queues_per_pool; i < qmap_stride; i++) {
1107 FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx + i), vf_q_idx);
1108 FM10K_WRITE_REG(hw, FM10K_RQMAP(qmap_idx + i), vf_q_idx);
1111 return FM10K_SUCCESS;
1115 * fm10k_iov_set_lport_pf - Assign and enable a logical port for a given VF
1116 * @hw: pointer to hardware structure
1117 * @vf_info: pointer to VF information structure
1118 * @lport_idx: Logical port offset from the hardware glort
1119 * @flags: Set of capability flags to extend port beyond basic functionality
1121 * This function allows enabling a VF port by assigning it a GLORT and
1122 * setting the flags so that it can enable an Rx mode.
1124 STATIC s32 fm10k_iov_set_lport_pf(struct fm10k_hw *hw,
1125 struct fm10k_vf_info *vf_info,
1126 u16 lport_idx, u8 flags)
1128 u16 glort = (hw->mac.dglort_map + lport_idx) & FM10K_DGLORTMAP_NONE;
1130 DEBUGFUNC("fm10k_iov_set_lport_state_pf");
1132 /* if glort is not valid return error */
1133 if (!fm10k_glort_valid_pf(hw, glort))
1134 return FM10K_ERR_PARAM;
1136 vf_info->vf_flags = flags | FM10K_VF_FLAG_NONE_CAPABLE;
1137 vf_info->glort = glort;
1139 return FM10K_SUCCESS;
1143 * fm10k_iov_reset_lport_pf - Disable a logical port for a given VF
1144 * @hw: pointer to hardware structure
1145 * @vf_info: pointer to VF information structure
1147 * This function disables a VF port by stripping it of a GLORT and
1148 * setting the flags so that it cannot enable any Rx mode.
1150 STATIC void fm10k_iov_reset_lport_pf(struct fm10k_hw *hw,
1151 struct fm10k_vf_info *vf_info)
1155 DEBUGFUNC("fm10k_iov_reset_lport_state_pf");
1157 /* need to disable the port if it is already enabled */
1158 if (FM10K_VF_FLAG_ENABLED(vf_info)) {
1159 /* notify switch that this port has been disabled */
1160 fm10k_update_lport_state_pf(hw, vf_info->glort, 1, false);
1162 /* generate port state response to notify VF it is not ready */
1163 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
1164 vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);
1167 /* clear flags and glort if it exists */
1168 vf_info->vf_flags = 0;
1173 * fm10k_iov_update_stats_pf - Updates hardware related statistics for VFs
1174 * @hw: pointer to hardware structure
1175 * @q: stats for all queues of a VF
1176 * @vf_idx: index of VF
1178 * This function collects queue stats for VFs.
1180 STATIC void fm10k_iov_update_stats_pf(struct fm10k_hw *hw,
1181 struct fm10k_hw_stats_q *q,
1186 /* get stats for all of the queues */
1187 qpp = fm10k_queues_per_pool(hw);
1188 idx = fm10k_vf_queue_index(hw, vf_idx);
1189 fm10k_update_hw_stats_q(hw, q, idx, qpp);
1192 STATIC s32 fm10k_iov_report_timestamp_pf(struct fm10k_hw *hw,
1193 struct fm10k_vf_info *vf_info,
1198 /* generate port state response to notify VF it is not ready */
1199 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_1588);
1200 fm10k_tlv_attr_put_u64(msg, FM10K_1588_MSG_TIMESTAMP, timestamp);
1202 return vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);
1206 * fm10k_iov_msg_msix_pf - Message handler for MSI-X request from VF
1207 * @hw: Pointer to hardware structure
1208 * @results: Pointer array to message, results[0] is pointer to message
1209 * @mbx: Pointer to mailbox information structure
1211 * This function is a default handler for MSI-X requests from the VF. The
1212 * assumption is that in this case it is acceptable to just directly
1213 * hand off the message from the VF to the underlying shared code.
1215 s32 fm10k_iov_msg_msix_pf(struct fm10k_hw *hw, u32 **results,
1216 struct fm10k_mbx_info *mbx)
1218 struct fm10k_vf_info *vf_info = (struct fm10k_vf_info *)mbx;
1219 u8 vf_idx = vf_info->vf_idx;
1221 UNREFERENCED_1PARAMETER(results);
1222 DEBUGFUNC("fm10k_iov_msg_msix_pf");
1224 return hw->iov.ops.assign_int_moderator(hw, vf_idx);
1228 * fm10k_iov_select_vid - Select correct default vid
1229 * @hw: Pointer to hardware structure
1230 * @vid: vid to correct
1232 * Will report an error if vid is out of range. For vid = 0, it will return
1233 * either the pf_vid or sw_vid depending on which one is set.
1235 STATIC s32 fm10k_iov_select_vid(struct fm10k_vf_info *vf_info, u16 vid)
1238 return vf_info->pf_vid ? vf_info->pf_vid : vf_info->sw_vid;
1239 else if (vf_info->pf_vid && vid != vf_info->pf_vid)
1240 return FM10K_ERR_PARAM;
1246 * fm10k_iov_msg_mac_vlan_pf - Message handler for MAC/VLAN request from VF
1247 * @hw: Pointer to hardware structure
1248 * @results: Pointer array to message, results[0] is pointer to message
1249 * @mbx: Pointer to mailbox information structure
1251 * This function is a default handler for MAC/VLAN requests from the VF.
1252 * The assumption is that in this case it is acceptable to just directly
1253 * hand off the message from the VF to the underlying shared code.
1255 s32 fm10k_iov_msg_mac_vlan_pf(struct fm10k_hw *hw, u32 **results,
1256 struct fm10k_mbx_info *mbx)
1258 struct fm10k_vf_info *vf_info = (struct fm10k_vf_info *)mbx;
1259 int err = FM10K_SUCCESS;
1266 DEBUGFUNC("fm10k_iov_msg_mac_vlan_pf");
1268 /* we shouldn't be updating rules on a disabled interface */
1269 if (!FM10K_VF_FLAG_ENABLED(vf_info))
1270 err = FM10K_ERR_PARAM;
1272 if (!err && !!results[FM10K_MAC_VLAN_MSG_VLAN]) {
1273 result = results[FM10K_MAC_VLAN_MSG_VLAN];
1275 /* record VLAN id requested */
1276 err = fm10k_tlv_attr_get_u32(result, &vid);
1280 /* verify upper 16 bits are zero */
1282 return FM10K_ERR_PARAM;
1284 set = !(vid & FM10K_VLAN_CLEAR);
1285 vid &= ~FM10K_VLAN_CLEAR;
1287 err = fm10k_iov_select_vid(vf_info, (u16)vid);
1293 /* update VSI info for VF in regards to VLAN table */
1294 err = hw->mac.ops.update_vlan(hw, vid, vf_info->vsi, set);
1297 if (!err && !!results[FM10K_MAC_VLAN_MSG_MAC]) {
1298 result = results[FM10K_MAC_VLAN_MSG_MAC];
1300 /* record unicast MAC address requested */
1301 err = fm10k_tlv_attr_get_mac_vlan(result, mac, &vlan);
1305 /* block attempts to set MAC for a locked device */
1306 if (FM10K_IS_VALID_ETHER_ADDR(vf_info->mac) &&
1307 memcmp(mac, vf_info->mac, ETH_ALEN))
1308 return FM10K_ERR_PARAM;
1310 set = !(vlan & FM10K_VLAN_CLEAR);
1311 vlan &= ~FM10K_VLAN_CLEAR;
1313 err = fm10k_iov_select_vid(vf_info, vlan);
1319 /* notify switch of request for new unicast address */
1320 err = hw->mac.ops.update_uc_addr(hw, vf_info->glort,
1324 if (!err && !!results[FM10K_MAC_VLAN_MSG_MULTICAST]) {
1325 result = results[FM10K_MAC_VLAN_MSG_MULTICAST];
1327 /* record multicast MAC address requested */
1328 err = fm10k_tlv_attr_get_mac_vlan(result, mac, &vlan);
1332 /* verify that the VF is allowed to request multicast */
1333 if (!(vf_info->vf_flags & FM10K_VF_FLAG_MULTI_ENABLED))
1334 return FM10K_ERR_PARAM;
1336 set = !(vlan & FM10K_VLAN_CLEAR);
1337 vlan &= ~FM10K_VLAN_CLEAR;
1339 err = fm10k_iov_select_vid(vf_info, vlan);
1345 /* notify switch of request for new multicast address */
1346 err = hw->mac.ops.update_mc_addr(hw, vf_info->glort,
1354 * fm10k_iov_supported_xcast_mode_pf - Determine best match for xcast mode
1355 * @vf_info: VF info structure containing capability flags
1356 * @mode: Requested xcast mode
1358 * This function outputs the mode that most closely matches the requested
1359 * mode. If not modes match it will request we disable the port
1361 STATIC u8 fm10k_iov_supported_xcast_mode_pf(struct fm10k_vf_info *vf_info,
1364 u8 vf_flags = vf_info->vf_flags;
1366 /* match up mode to capabilities as best as possible */
1368 case FM10K_XCAST_MODE_PROMISC:
1369 if (vf_flags & FM10K_VF_FLAG_PROMISC_CAPABLE)
1370 return FM10K_XCAST_MODE_PROMISC;
1372 case FM10K_XCAST_MODE_ALLMULTI:
1373 if (vf_flags & FM10K_VF_FLAG_ALLMULTI_CAPABLE)
1374 return FM10K_XCAST_MODE_ALLMULTI;
1376 case FM10K_XCAST_MODE_MULTI:
1377 if (vf_flags & FM10K_VF_FLAG_MULTI_CAPABLE)
1378 return FM10K_XCAST_MODE_MULTI;
1380 case FM10K_XCAST_MODE_NONE:
1381 if (vf_flags & FM10K_VF_FLAG_NONE_CAPABLE)
1382 return FM10K_XCAST_MODE_NONE;
1388 /* disable interface as it should not be able to request any */
1389 return FM10K_XCAST_MODE_DISABLE;
1393 * fm10k_iov_msg_lport_state_pf - Message handler for port state requests
1394 * @hw: Pointer to hardware structure
1395 * @results: Pointer array to message, results[0] is pointer to message
1396 * @mbx: Pointer to mailbox information structure
1398 * This function is a default handler for port state requests. The port
1399 * state requests for now are basic and consist of enabling or disabling
1402 s32 fm10k_iov_msg_lport_state_pf(struct fm10k_hw *hw, u32 **results,
1403 struct fm10k_mbx_info *mbx)
1405 struct fm10k_vf_info *vf_info = (struct fm10k_vf_info *)mbx;
1407 s32 err = FM10K_SUCCESS;
1411 DEBUGFUNC("fm10k_iov_msg_lport_state_pf");
1413 /* verify VF is allowed to enable even minimal mode */
1414 if (!(vf_info->vf_flags & FM10K_VF_FLAG_NONE_CAPABLE))
1415 return FM10K_ERR_PARAM;
1417 if (!!results[FM10K_LPORT_STATE_MSG_XCAST_MODE]) {
1418 result = results[FM10K_LPORT_STATE_MSG_XCAST_MODE];
1420 /* XCAST mode update requested */
1421 err = fm10k_tlv_attr_get_u8(result, &mode);
1423 return FM10K_ERR_PARAM;
1425 /* prep for possible demotion depending on capabilities */
1426 mode = fm10k_iov_supported_xcast_mode_pf(vf_info, mode);
1428 /* if mode is not currently enabled, enable it */
1429 if (!(FM10K_VF_FLAG_ENABLED(vf_info) & (1 << mode)))
1430 fm10k_update_xcast_mode_pf(hw, vf_info->glort, mode);
1432 /* swap mode back to a bit flag */
1433 mode = FM10K_VF_FLAG_SET_MODE(mode);
1434 } else if (!results[FM10K_LPORT_STATE_MSG_DISABLE]) {
1435 /* need to disable the port if it is already enabled */
1436 if (FM10K_VF_FLAG_ENABLED(vf_info))
1437 err = fm10k_update_lport_state_pf(hw, vf_info->glort,
1440 /* when enabling the port we should reset the rate limiters */
1441 hw->iov.ops.configure_tc(hw, vf_info->vf_idx, vf_info->rate);
1443 /* set mode for minimal functionality */
1444 mode = FM10K_VF_FLAG_SET_MODE_NONE;
1446 /* generate port state response to notify VF it is ready */
1447 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
1448 fm10k_tlv_attr_put_bool(msg, FM10K_LPORT_STATE_MSG_READY);
1449 mbx->ops.enqueue_tx(hw, mbx, msg);
1452 /* if enable state toggled note the update */
1453 if (!err && (!FM10K_VF_FLAG_ENABLED(vf_info) != !mode))
1454 err = fm10k_update_lport_state_pf(hw, vf_info->glort, 1,
1457 /* if state change succeeded, then update our stored state */
1458 mode |= FM10K_VF_FLAG_CAPABLE(vf_info);
1460 vf_info->vf_flags = mode;
1465 const struct fm10k_msg_data fm10k_iov_msg_data_pf[] = {
1466 FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test),
1467 FM10K_VF_MSG_MSIX_HANDLER(fm10k_iov_msg_msix_pf),
1468 FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_iov_msg_mac_vlan_pf),
1469 FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_iov_msg_lport_state_pf),
1470 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
1474 * fm10k_update_stats_hw_pf - Updates hardware related statistics of PF
1475 * @hw: pointer to hardware structure
1476 * @stats: pointer to the stats structure to update
1478 * This function collects and aggregates global and per queue hardware
1481 STATIC void fm10k_update_hw_stats_pf(struct fm10k_hw *hw,
1482 struct fm10k_hw_stats *stats)
1484 u32 timeout, ur, ca, um, xec, vlan_drop, loopback_drop, nodesc_drop;
1487 DEBUGFUNC("fm10k_update_hw_stats_pf");
1489 /* Use Tx queue 0 as a canary to detect a reset */
1490 id = FM10K_READ_REG(hw, FM10K_TXQCTL(0));
1492 /* Read Global Statistics */
1494 timeout = fm10k_read_hw_stats_32b(hw, FM10K_STATS_TIMEOUT,
1496 ur = fm10k_read_hw_stats_32b(hw, FM10K_STATS_UR, &stats->ur);
1497 ca = fm10k_read_hw_stats_32b(hw, FM10K_STATS_CA, &stats->ca);
1498 um = fm10k_read_hw_stats_32b(hw, FM10K_STATS_UM, &stats->um);
1499 xec = fm10k_read_hw_stats_32b(hw, FM10K_STATS_XEC, &stats->xec);
1500 vlan_drop = fm10k_read_hw_stats_32b(hw, FM10K_STATS_VLAN_DROP,
1502 loopback_drop = fm10k_read_hw_stats_32b(hw,
1503 FM10K_STATS_LOOPBACK_DROP,
1504 &stats->loopback_drop);
1505 nodesc_drop = fm10k_read_hw_stats_32b(hw,
1506 FM10K_STATS_NODESC_DROP,
1507 &stats->nodesc_drop);
1509 /* if value has not changed then we have consistent data */
1511 id = FM10K_READ_REG(hw, FM10K_TXQCTL(0));
1512 } while ((id ^ id_prev) & FM10K_TXQCTL_ID_MASK);
1514 /* drop non-ID bits and set VALID ID bit */
1515 id &= FM10K_TXQCTL_ID_MASK;
1516 id |= FM10K_STAT_VALID;
1518 /* Update Global Statistics */
1519 if (stats->stats_idx == id) {
1520 stats->timeout.count += timeout;
1521 stats->ur.count += ur;
1522 stats->ca.count += ca;
1523 stats->um.count += um;
1524 stats->xec.count += xec;
1525 stats->vlan_drop.count += vlan_drop;
1526 stats->loopback_drop.count += loopback_drop;
1527 stats->nodesc_drop.count += nodesc_drop;
1530 /* Update bases and record current PF id */
1531 fm10k_update_hw_base_32b(&stats->timeout, timeout);
1532 fm10k_update_hw_base_32b(&stats->ur, ur);
1533 fm10k_update_hw_base_32b(&stats->ca, ca);
1534 fm10k_update_hw_base_32b(&stats->um, um);
1535 fm10k_update_hw_base_32b(&stats->xec, xec);
1536 fm10k_update_hw_base_32b(&stats->vlan_drop, vlan_drop);
1537 fm10k_update_hw_base_32b(&stats->loopback_drop, loopback_drop);
1538 fm10k_update_hw_base_32b(&stats->nodesc_drop, nodesc_drop);
1539 stats->stats_idx = id;
1541 /* Update Queue Statistics */
1542 fm10k_update_hw_stats_q(hw, stats->q, 0, hw->mac.max_queues);
1546 * fm10k_rebind_hw_stats_pf - Resets base for hardware statistics of PF
1547 * @hw: pointer to hardware structure
1548 * @stats: pointer to the stats structure to update
1550 * This function resets the base for global and per queue hardware
1553 STATIC void fm10k_rebind_hw_stats_pf(struct fm10k_hw *hw,
1554 struct fm10k_hw_stats *stats)
1556 DEBUGFUNC("fm10k_rebind_hw_stats_pf");
1558 /* Unbind Global Statistics */
1559 fm10k_unbind_hw_stats_32b(&stats->timeout);
1560 fm10k_unbind_hw_stats_32b(&stats->ur);
1561 fm10k_unbind_hw_stats_32b(&stats->ca);
1562 fm10k_unbind_hw_stats_32b(&stats->um);
1563 fm10k_unbind_hw_stats_32b(&stats->xec);
1564 fm10k_unbind_hw_stats_32b(&stats->vlan_drop);
1565 fm10k_unbind_hw_stats_32b(&stats->loopback_drop);
1566 fm10k_unbind_hw_stats_32b(&stats->nodesc_drop);
1568 /* Unbind Queue Statistics */
1569 fm10k_unbind_hw_stats_q(stats->q, 0, hw->mac.max_queues);
1571 /* Reinitialize bases for all stats */
1572 fm10k_update_hw_stats_pf(hw, stats);
1576 * fm10k_set_dma_mask_pf - Configures PhyAddrSpace to limit DMA to system
1577 * @hw: pointer to hardware structure
1578 * @dma_mask: 64 bit DMA mask required for platform
1580 * This function sets the PHYADDR.PhyAddrSpace bits for the endpoint in order
1581 * to limit the access to memory beyond what is physically in the system.
1583 STATIC void fm10k_set_dma_mask_pf(struct fm10k_hw *hw, u64 dma_mask)
1585 /* we need to write the upper 32 bits of DMA mask to PhyAddrSpace */
1586 u32 phyaddr = (u32)(dma_mask >> 32);
1588 DEBUGFUNC("fm10k_set_dma_mask_pf");
1590 FM10K_WRITE_REG(hw, FM10K_PHYADDR, phyaddr);
1594 * fm10k_get_fault_pf - Record a fault in one of the interface units
1595 * @hw: pointer to hardware structure
1596 * @type: pointer to fault type register offset
1597 * @fault: pointer to memory location to record the fault
1599 * Record the fault register contents to the fault data structure and
1600 * clear the entry from the register.
1602 * Returns ERR_PARAM if invalid register is specified or no error is present.
1604 STATIC s32 fm10k_get_fault_pf(struct fm10k_hw *hw, int type,
1605 struct fm10k_fault *fault)
1609 DEBUGFUNC("fm10k_get_fault_pf");
1611 /* verify the fault register is in range and is aligned */
1613 case FM10K_PCA_FAULT:
1614 case FM10K_THI_FAULT:
1615 case FM10K_FUM_FAULT:
1618 return FM10K_ERR_PARAM;
1621 /* only service faults that are valid */
1622 func = FM10K_READ_REG(hw, type + FM10K_FAULT_FUNC);
1623 if (!(func & FM10K_FAULT_FUNC_VALID))
1624 return FM10K_ERR_PARAM;
1626 /* read remaining fields */
1627 fault->address = FM10K_READ_REG(hw, type + FM10K_FAULT_ADDR_HI);
1628 fault->address <<= 32;
1629 fault->address = FM10K_READ_REG(hw, type + FM10K_FAULT_ADDR_LO);
1630 fault->specinfo = FM10K_READ_REG(hw, type + FM10K_FAULT_SPECINFO);
1632 /* clear valid bit to allow for next error */
1633 FM10K_WRITE_REG(hw, type + FM10K_FAULT_FUNC, FM10K_FAULT_FUNC_VALID);
1635 /* Record which function triggered the error */
1636 if (func & FM10K_FAULT_FUNC_PF)
1639 fault->func = 1 + ((func & FM10K_FAULT_FUNC_VF_MASK) >>
1640 FM10K_FAULT_FUNC_VF_SHIFT);
1642 /* record fault type */
1643 fault->type = func & FM10K_FAULT_FUNC_TYPE_MASK;
1645 return FM10K_SUCCESS;
1649 * fm10k_request_lport_map_pf - Request LPORT map from the switch API
1650 * @hw: pointer to hardware structure
1653 STATIC s32 fm10k_request_lport_map_pf(struct fm10k_hw *hw)
1655 struct fm10k_mbx_info *mbx = &hw->mbx;
1658 DEBUGFUNC("fm10k_request_lport_pf");
1660 /* issue request asking for LPORT map */
1661 fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_LPORT_MAP);
1663 /* load onto outgoing mailbox */
1664 return mbx->ops.enqueue_tx(hw, mbx, msg);
1668 * fm10k_get_host_state_pf - Returns the state of the switch and mailbox
1669 * @hw: pointer to hardware structure
1670 * @switch_ready: pointer to boolean value that will record switch state
1672 * This funciton will check the DMA_CTRL2 register and mailbox in order
1673 * to determine if the switch is ready for the PF to begin requesting
1674 * addresses and mapping traffic to the local interface.
1676 STATIC s32 fm10k_get_host_state_pf(struct fm10k_hw *hw, bool *switch_ready)
1678 s32 ret_val = FM10K_SUCCESS;
1681 DEBUGFUNC("fm10k_get_host_state_pf");
1683 /* verify the switch is ready for interaction */
1684 dma_ctrl2 = FM10K_READ_REG(hw, FM10K_DMA_CTRL2);
1685 if (!(dma_ctrl2 & FM10K_DMA_CTRL2_SWITCH_READY))
1688 /* retrieve generic host state info */
1689 ret_val = fm10k_get_host_state_generic(hw, switch_ready);
1693 /* interface cannot receive traffic without logical ports */
1694 if (hw->mac.dglort_map == FM10K_DGLORTMAP_NONE)
1695 ret_val = fm10k_request_lport_map_pf(hw);
1701 /* This structure defines the attibutes to be parsed below */
1702 const struct fm10k_tlv_attr fm10k_lport_map_msg_attr[] = {
1703 FM10K_TLV_ATTR_U32(FM10K_PF_ATTR_ID_LPORT_MAP),
1708 * fm10k_msg_lport_map_pf - Message handler for lport_map message from SM
1709 * @hw: Pointer to hardware structure
1710 * @results: pointer array containing parsed data
1711 * @mbx: Pointer to mailbox information structure
1713 * This handler configures the lport mapping based on the reply from the
1716 s32 fm10k_msg_lport_map_pf(struct fm10k_hw *hw, u32 **results,
1717 struct fm10k_mbx_info *mbx)
1723 UNREFERENCED_1PARAMETER(mbx);
1724 DEBUGFUNC("fm10k_msg_lport_map_pf");
1726 err = fm10k_tlv_attr_get_u32(results[FM10K_PF_ATTR_ID_LPORT_MAP],
1731 /* extract values out of the header */
1732 glort = FM10K_MSG_HDR_FIELD_GET(dglort_map, LPORT_MAP_GLORT);
1733 mask = FM10K_MSG_HDR_FIELD_GET(dglort_map, LPORT_MAP_MASK);
1735 /* verify mask is set and none of the masked bits in glort are set */
1736 if (!mask || (glort & ~mask))
1737 return FM10K_ERR_PARAM;
1739 /* verify the mask is contiguous, and that it is 1's followed by 0's */
1740 if (((~(mask - 1) & mask) + mask) & FM10K_DGLORTMAP_NONE)
1741 return FM10K_ERR_PARAM;
1743 /* record the glort, mask, and port count */
1744 hw->mac.dglort_map = dglort_map;
1746 return FM10K_SUCCESS;
1749 const struct fm10k_tlv_attr fm10k_update_pvid_msg_attr[] = {
1750 FM10K_TLV_ATTR_U32(FM10K_PF_ATTR_ID_UPDATE_PVID),
1755 * fm10k_msg_update_pvid_pf - Message handler for port VLAN message from SM
1756 * @hw: Pointer to hardware structure
1757 * @results: pointer array containing parsed data
1758 * @mbx: Pointer to mailbox information structure
1760 * This handler configures the default VLAN for the PF
1762 s32 fm10k_msg_update_pvid_pf(struct fm10k_hw *hw, u32 **results,
1763 struct fm10k_mbx_info *mbx)
1769 UNREFERENCED_1PARAMETER(mbx);
1770 DEBUGFUNC("fm10k_msg_update_pvid_pf");
1772 err = fm10k_tlv_attr_get_u32(results[FM10K_PF_ATTR_ID_UPDATE_PVID],
1777 /* extract values from the pvid update */
1778 glort = FM10K_MSG_HDR_FIELD_GET(pvid_update, UPDATE_PVID_GLORT);
1779 pvid = FM10K_MSG_HDR_FIELD_GET(pvid_update, UPDATE_PVID_PVID);
1781 /* if glort is not valid return error */
1782 if (!fm10k_glort_valid_pf(hw, glort))
1783 return FM10K_ERR_PARAM;
1785 /* verify VID is valid */
1786 if (pvid >= FM10K_VLAN_TABLE_VID_MAX)
1787 return FM10K_ERR_PARAM;
1789 /* record the port VLAN ID value */
1790 hw->mac.default_vid = pvid;
1792 return FM10K_SUCCESS;
1796 * fm10k_record_global_table_data - Move global table data to swapi table info
1797 * @from: pointer to source table data structure
1798 * @to: pointer to destination table info structure
1800 * This function is will copy table_data to the table_info contained in
1803 static void fm10k_record_global_table_data(struct fm10k_global_table_data *from,
1804 struct fm10k_swapi_table_info *to)
1806 /* convert from le32 struct to CPU byte ordered values */
1807 to->used = FM10K_LE32_TO_CPU(from->used);
1808 to->avail = FM10K_LE32_TO_CPU(from->avail);
1811 const struct fm10k_tlv_attr fm10k_err_msg_attr[] = {
1812 FM10K_TLV_ATTR_LE_STRUCT(FM10K_PF_ATTR_ID_ERR,
1813 sizeof(struct fm10k_swapi_error)),
1818 * fm10k_msg_err_pf - Message handler for error reply
1819 * @hw: Pointer to hardware structure
1820 * @results: pointer array containing parsed data
1821 * @mbx: Pointer to mailbox information structure
1823 * This handler will capture the data for any error replies to previous
1824 * messages that the PF has sent.
1826 s32 fm10k_msg_err_pf(struct fm10k_hw *hw, u32 **results,
1827 struct fm10k_mbx_info *mbx)
1829 struct fm10k_swapi_error err_msg;
1832 UNREFERENCED_1PARAMETER(mbx);
1833 DEBUGFUNC("fm10k_msg_err_pf");
1835 /* extract structure from message */
1836 err = fm10k_tlv_attr_get_le_struct(results[FM10K_PF_ATTR_ID_ERR],
1837 &err_msg, sizeof(err_msg));
1841 /* record table status */
1842 fm10k_record_global_table_data(&err_msg.mac, &hw->swapi.mac);
1843 fm10k_record_global_table_data(&err_msg.nexthop, &hw->swapi.nexthop);
1844 fm10k_record_global_table_data(&err_msg.ffu, &hw->swapi.ffu);
1846 /* record SW API status value */
1847 hw->swapi.status = FM10K_LE32_TO_CPU(err_msg.status);
1849 return FM10K_SUCCESS;
1852 const struct fm10k_tlv_attr fm10k_1588_timestamp_msg_attr[] = {
1853 FM10K_TLV_ATTR_LE_STRUCT(FM10K_PF_ATTR_ID_1588_TIMESTAMP,
1854 sizeof(struct fm10k_swapi_1588_timestamp)),
1858 const struct fm10k_tlv_attr fm10k_tx_timestamp_mode_attr[] = {
1859 FM10K_TLV_ATTR_LE_STRUCT(FM10K_PF_ATTR_ID_TIMESTAMP_MODE_RESP,
1860 sizeof(struct fm10k_swapi_tx_timestamp_mode)),
1864 /* currently there is no shared 1588 timestamp handler */
1867 * fm10k_request_tx_timestamp_mode_pf - Request a specific Tx timestamping mode
1868 * @hw: pointer to hardware structure
1869 * @glort: base resource tag for this request
1870 * @mode: integer value indicating the requested mode
1872 * This function will attempt to request a specific timestamp mode for the
1873 * port so that it can receive Tx timestamp messages.
1875 STATIC s32 fm10k_request_tx_timestamp_mode_pf(struct fm10k_hw *hw,
1879 struct fm10k_mbx_info *mbx = &hw->mbx;
1880 u32 msg[3], timestamp_mode;
1882 DEBUGFUNC("fm10k_request_timestamp_mode_pf");
1884 if (mode > FM10K_TIMESTAMP_MODE_PEP_TO_ANY)
1885 return FM10K_ERR_PARAM;
1887 /* if glort is not valid return error */
1888 if (!fm10k_glort_valid_pf(hw, glort))
1889 return FM10K_ERR_PARAM;
1891 /* write timestamp mode as a single u32 value,
1892 * lower 16 bits: glort
1893 * upper 16 bits: mode
1895 timestamp_mode = ((u32)mode << 16) | glort;
1897 /* generate message requesting change to xcast mode */
1898 fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_TX_TIMESTAMP_MODE);
1899 fm10k_tlv_attr_put_u32(msg, FM10K_PF_ATTR_ID_TIMESTAMP_MODE_REQ, timestamp_mode);
1901 /* load onto outgoing mailbox */
1902 return mbx->ops.enqueue_tx(hw, mbx, msg);
1906 * fm10k_adjust_systime_pf - Adjust systime frequency
1907 * @hw: pointer to hardware structure
1908 * @ppb: adjustment rate in parts per billion
1910 * This function will adjust the SYSTIME_CFG register contained in BAR 4
1911 * if this function is supported for BAR 4 access. The adjustment amount
1912 * is based on the parts per billion value provided and adjusted to a
1913 * value based on parts per 2^48 clock cycles.
1915 * If adjustment is not supported or the requested value is too large
1916 * we will return an error.
1918 STATIC s32 fm10k_adjust_systime_pf(struct fm10k_hw *hw, s32 ppb)
1922 DEBUGFUNC("fm10k_adjust_systime_pf");
1924 /* if sw_addr is not set we don't have switch register access */
1926 return ppb ? FM10K_ERR_PARAM : FM10K_SUCCESS;
1928 /* we must convert the value from parts per billion to parts per
1929 * 2^48 cycles. In addition I have opted to only use the 30 most
1930 * significant bits of the adjustment value as the 8 least
1931 * significant bits are located in another register and represent
1932 * a value significantly less than a part per billion, the result
1933 * of dropping the 8 least significant bits is that the adjustment
1934 * value is effectively multiplied by 2^8 when we write it.
1936 * As a result of all this the math for this breaks down as follows:
1937 * ppb / 10^9 == adjust * 2^8 / 2^48
1938 * If we solve this for adjust, and simplify it comes out as:
1939 * ppb * 2^31 / 5^9 == adjust
1941 systime_adjust = (ppb < 0) ? -ppb : ppb;
1942 systime_adjust <<= 31;
1943 do_div(systime_adjust, 1953125);
1945 /* verify the requested adjustment value is in range */
1946 if (systime_adjust > FM10K_SW_SYSTIME_ADJUST_MASK)
1947 return FM10K_ERR_PARAM;
1950 systime_adjust |= FM10K_SW_SYSTIME_ADJUST_DIR_NEGATIVE;
1952 FM10K_WRITE_SW_REG(hw, FM10K_SW_SYSTIME_ADJUST, (u32)systime_adjust);
1954 return FM10K_SUCCESS;
1958 * fm10k_read_systime_pf - Reads value of systime registers
1959 * @hw: pointer to the hardware structure
1961 * Function reads the content of 2 registers, combined to represent a 64 bit
1962 * value measured in nanosecods. In order to guarantee the value is accurate
1963 * we check the 32 most significant bits both before and after reading the
1964 * 32 least significant bits to verify they didn't change as we were reading
1967 static u64 fm10k_read_systime_pf(struct fm10k_hw *hw)
1969 u32 systime_l, systime_h, systime_tmp;
1971 systime_h = fm10k_read_reg(hw, FM10K_SYSTIME + 1);
1974 systime_tmp = systime_h;
1975 systime_l = fm10k_read_reg(hw, FM10K_SYSTIME);
1976 systime_h = fm10k_read_reg(hw, FM10K_SYSTIME + 1);
1977 } while (systime_tmp != systime_h);
1979 return ((u64)systime_h << 32) | systime_l;
1982 static const struct fm10k_msg_data fm10k_msg_data_pf[] = {
1983 FM10K_PF_MSG_ERR_HANDLER(XCAST_MODES, fm10k_msg_err_pf),
1984 FM10K_PF_MSG_ERR_HANDLER(UPDATE_MAC_FWD_RULE, fm10k_msg_err_pf),
1985 FM10K_PF_MSG_LPORT_MAP_HANDLER(fm10k_msg_lport_map_pf),
1986 FM10K_PF_MSG_ERR_HANDLER(LPORT_CREATE, fm10k_msg_err_pf),
1987 FM10K_PF_MSG_ERR_HANDLER(LPORT_DELETE, fm10k_msg_err_pf),
1988 FM10K_PF_MSG_UPDATE_PVID_HANDLER(fm10k_msg_update_pvid_pf),
1989 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
1993 * fm10k_init_ops_pf - Inits func ptrs and MAC type
1994 * @hw: pointer to hardware structure
1996 * Initialize the function pointers and assign the MAC type for PF.
1997 * Does not touch the hardware.
1999 s32 fm10k_init_ops_pf(struct fm10k_hw *hw)
2001 struct fm10k_mac_info *mac = &hw->mac;
2002 struct fm10k_iov_info *iov = &hw->iov;
2004 DEBUGFUNC("fm10k_init_ops_pf");
2006 fm10k_init_ops_generic(hw);
2008 mac->ops.reset_hw = &fm10k_reset_hw_pf;
2009 mac->ops.init_hw = &fm10k_init_hw_pf;
2010 mac->ops.start_hw = &fm10k_start_hw_generic;
2011 mac->ops.stop_hw = &fm10k_stop_hw_generic;
2012 mac->ops.is_slot_appropriate = &fm10k_is_slot_appropriate_pf;
2013 mac->ops.update_vlan = &fm10k_update_vlan_pf;
2014 mac->ops.read_mac_addr = &fm10k_read_mac_addr_pf;
2015 mac->ops.update_uc_addr = &fm10k_update_uc_addr_pf;
2016 mac->ops.update_mc_addr = &fm10k_update_mc_addr_pf;
2017 mac->ops.update_xcast_mode = &fm10k_update_xcast_mode_pf;
2018 mac->ops.update_int_moderator = &fm10k_update_int_moderator_pf;
2019 mac->ops.update_lport_state = &fm10k_update_lport_state_pf;
2020 mac->ops.update_hw_stats = &fm10k_update_hw_stats_pf;
2021 mac->ops.rebind_hw_stats = &fm10k_rebind_hw_stats_pf;
2022 mac->ops.configure_dglort_map = &fm10k_configure_dglort_map_pf;
2023 mac->ops.set_dma_mask = &fm10k_set_dma_mask_pf;
2024 mac->ops.get_fault = &fm10k_get_fault_pf;
2025 mac->ops.get_host_state = &fm10k_get_host_state_pf;
2026 mac->ops.adjust_systime = &fm10k_adjust_systime_pf;
2027 mac->ops.read_systime = &fm10k_read_systime_pf;
2028 mac->ops.request_tx_timestamp_mode = &fm10k_request_tx_timestamp_mode_pf;
2030 mac->max_msix_vectors = fm10k_get_pcie_msix_count_generic(hw);
2032 iov->ops.assign_resources = &fm10k_iov_assign_resources_pf;
2033 iov->ops.configure_tc = &fm10k_iov_configure_tc_pf;
2034 iov->ops.assign_int_moderator = &fm10k_iov_assign_int_moderator_pf;
2035 iov->ops.assign_default_mac_vlan = fm10k_iov_assign_default_mac_vlan_pf;
2036 iov->ops.reset_resources = &fm10k_iov_reset_resources_pf;
2037 iov->ops.set_lport = &fm10k_iov_set_lport_pf;
2038 iov->ops.reset_lport = &fm10k_iov_reset_lport_pf;
2039 iov->ops.update_stats = &fm10k_iov_update_stats_pf;
2040 iov->ops.report_timestamp = &fm10k_iov_report_timestamp_pf;
2042 return fm10k_sm_mbx_init(hw, &hw->mbx, fm10k_msg_data_pf);