1b6fec18fSAlexander Duyck /* Intel Ethernet Switch Host Interface Driver
2b6fec18fSAlexander Duyck  * Copyright(c) 2013 - 2014 Intel Corporation.
3b6fec18fSAlexander Duyck  *
4b6fec18fSAlexander Duyck  * This program is free software; you can redistribute it and/or modify it
5b6fec18fSAlexander Duyck  * under the terms and conditions of the GNU General Public License,
6b6fec18fSAlexander Duyck  * version 2, as published by the Free Software Foundation.
7b6fec18fSAlexander Duyck  *
8b6fec18fSAlexander Duyck  * This program is distributed in the hope it will be useful, but WITHOUT
9b6fec18fSAlexander Duyck  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10b6fec18fSAlexander Duyck  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11b6fec18fSAlexander Duyck  * more details.
12b6fec18fSAlexander Duyck  *
13b6fec18fSAlexander Duyck  * The full GNU General Public License is included in this distribution in
14b6fec18fSAlexander Duyck  * the file called "COPYING".
15b6fec18fSAlexander Duyck  *
16b6fec18fSAlexander Duyck  * Contact Information:
17b6fec18fSAlexander Duyck  * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
18b6fec18fSAlexander Duyck  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
19b6fec18fSAlexander Duyck  */
20b6fec18fSAlexander Duyck 
21b6fec18fSAlexander Duyck #include "fm10k_pf.h"
22b6fec18fSAlexander Duyck 
23b6fec18fSAlexander Duyck /**
24b6fec18fSAlexander Duyck  *  fm10k_reset_hw_pf - PF hardware reset
25b6fec18fSAlexander Duyck  *  @hw: pointer to hardware structure
26b6fec18fSAlexander Duyck  *
27b6fec18fSAlexander Duyck  *  This function should return the hardware to a state similar to the
28b6fec18fSAlexander Duyck  *  one it is in after being powered on.
29b6fec18fSAlexander Duyck  **/
30b6fec18fSAlexander Duyck static s32 fm10k_reset_hw_pf(struct fm10k_hw *hw)
31b6fec18fSAlexander Duyck {
32b6fec18fSAlexander Duyck 	s32 err;
33b6fec18fSAlexander Duyck 	u32 reg;
34b6fec18fSAlexander Duyck 	u16 i;
35b6fec18fSAlexander Duyck 
36b6fec18fSAlexander Duyck 	/* Disable interrupts */
37b6fec18fSAlexander Duyck 	fm10k_write_reg(hw, FM10K_EIMR, FM10K_EIMR_DISABLE(ALL));
38b6fec18fSAlexander Duyck 
39b6fec18fSAlexander Duyck 	/* Lock ITR2 reg 0 into itself and disable interrupt moderation */
40b6fec18fSAlexander Duyck 	fm10k_write_reg(hw, FM10K_ITR2(0), 0);
41b6fec18fSAlexander Duyck 	fm10k_write_reg(hw, FM10K_INT_CTRL, 0);
42b6fec18fSAlexander Duyck 
43b6fec18fSAlexander Duyck 	/* We assume here Tx and Rx queue 0 are owned by the PF */
44b6fec18fSAlexander Duyck 
45b6fec18fSAlexander Duyck 	/* Shut off VF access to their queues forcing them to queue 0 */
46b6fec18fSAlexander Duyck 	for (i = 0; i < FM10K_TQMAP_TABLE_SIZE; i++) {
47b6fec18fSAlexander Duyck 		fm10k_write_reg(hw, FM10K_TQMAP(i), 0);
48b6fec18fSAlexander Duyck 		fm10k_write_reg(hw, FM10K_RQMAP(i), 0);
49b6fec18fSAlexander Duyck 	}
50b6fec18fSAlexander Duyck 
51b6fec18fSAlexander Duyck 	/* shut down all rings */
52b6fec18fSAlexander Duyck 	err = fm10k_disable_queues_generic(hw, FM10K_MAX_QUEUES);
53b6fec18fSAlexander Duyck 	if (err)
54b6fec18fSAlexander Duyck 		return err;
55b6fec18fSAlexander Duyck 
56b6fec18fSAlexander Duyck 	/* Verify that DMA is no longer active */
57b6fec18fSAlexander Duyck 	reg = fm10k_read_reg(hw, FM10K_DMA_CTRL);
58b6fec18fSAlexander Duyck 	if (reg & (FM10K_DMA_CTRL_TX_ACTIVE | FM10K_DMA_CTRL_RX_ACTIVE))
59b6fec18fSAlexander Duyck 		return FM10K_ERR_DMA_PENDING;
60b6fec18fSAlexander Duyck 
61b6fec18fSAlexander Duyck 	/* Inititate data path reset */
62b6fec18fSAlexander Duyck 	reg |= FM10K_DMA_CTRL_DATAPATH_RESET;
63b6fec18fSAlexander Duyck 	fm10k_write_reg(hw, FM10K_DMA_CTRL, reg);
64b6fec18fSAlexander Duyck 
65b6fec18fSAlexander Duyck 	/* Flush write and allow 100us for reset to complete */
66b6fec18fSAlexander Duyck 	fm10k_write_flush(hw);
67b6fec18fSAlexander Duyck 	udelay(FM10K_RESET_TIMEOUT);
68b6fec18fSAlexander Duyck 
69b6fec18fSAlexander Duyck 	/* Verify we made it out of reset */
70b6fec18fSAlexander Duyck 	reg = fm10k_read_reg(hw, FM10K_IP);
71b6fec18fSAlexander Duyck 	if (!(reg & FM10K_IP_NOTINRESET))
72b6fec18fSAlexander Duyck 		err = FM10K_ERR_RESET_FAILED;
73b6fec18fSAlexander Duyck 
74b6fec18fSAlexander Duyck 	return err;
75b6fec18fSAlexander Duyck }
76b6fec18fSAlexander Duyck 
77b6fec18fSAlexander Duyck /**
78b6fec18fSAlexander Duyck  *  fm10k_init_hw_pf - PF hardware initialization
79b6fec18fSAlexander Duyck  *  @hw: pointer to hardware structure
80b6fec18fSAlexander Duyck  *
81b6fec18fSAlexander Duyck  **/
82b6fec18fSAlexander Duyck static s32 fm10k_init_hw_pf(struct fm10k_hw *hw)
83b6fec18fSAlexander Duyck {
84b6fec18fSAlexander Duyck 	u32 dma_ctrl, txqctl;
85b6fec18fSAlexander Duyck 	u16 i;
86b6fec18fSAlexander Duyck 
87b6fec18fSAlexander Duyck 	/* Establish default VSI as valid */
88b6fec18fSAlexander Duyck 	fm10k_write_reg(hw, FM10K_DGLORTDEC(fm10k_dglort_default), 0);
89b6fec18fSAlexander Duyck 	fm10k_write_reg(hw, FM10K_DGLORTMAP(fm10k_dglort_default),
90b6fec18fSAlexander Duyck 			FM10K_DGLORTMAP_ANY);
91b6fec18fSAlexander Duyck 
92b6fec18fSAlexander Duyck 	/* Invalidate all other GLORT entries */
93b6fec18fSAlexander Duyck 	for (i = 1; i < FM10K_DGLORT_COUNT; i++)
94b6fec18fSAlexander Duyck 		fm10k_write_reg(hw, FM10K_DGLORTMAP(i), FM10K_DGLORTMAP_NONE);
95b6fec18fSAlexander Duyck 
96b6fec18fSAlexander Duyck 	/* reset ITR2(0) to point to itself */
97b6fec18fSAlexander Duyck 	fm10k_write_reg(hw, FM10K_ITR2(0), 0);
98b6fec18fSAlexander Duyck 
99b6fec18fSAlexander Duyck 	/* reset VF ITR2(0) to point to 0 avoid PF registers */
100b6fec18fSAlexander Duyck 	fm10k_write_reg(hw, FM10K_ITR2(FM10K_ITR_REG_COUNT_PF), 0);
101b6fec18fSAlexander Duyck 
102b6fec18fSAlexander Duyck 	/* loop through all PF ITR2 registers pointing them to the previous */
103b6fec18fSAlexander Duyck 	for (i = 1; i < FM10K_ITR_REG_COUNT_PF; i++)
104b6fec18fSAlexander Duyck 		fm10k_write_reg(hw, FM10K_ITR2(i), i - 1);
105b6fec18fSAlexander Duyck 
106b6fec18fSAlexander Duyck 	/* Enable interrupt moderator if not already enabled */
107b6fec18fSAlexander Duyck 	fm10k_write_reg(hw, FM10K_INT_CTRL, FM10K_INT_CTRL_ENABLEMODERATOR);
108b6fec18fSAlexander Duyck 
109b6fec18fSAlexander Duyck 	/* compute the default txqctl configuration */
110b6fec18fSAlexander Duyck 	txqctl = FM10K_TXQCTL_PF | FM10K_TXQCTL_UNLIMITED_BW |
111b6fec18fSAlexander Duyck 		 (hw->mac.default_vid << FM10K_TXQCTL_VID_SHIFT);
112b6fec18fSAlexander Duyck 
113b6fec18fSAlexander Duyck 	for (i = 0; i < FM10K_MAX_QUEUES; i++) {
114b6fec18fSAlexander Duyck 		/* configure rings for 256 Queue / 32 Descriptor cache mode */
115b6fec18fSAlexander Duyck 		fm10k_write_reg(hw, FM10K_TQDLOC(i),
116b6fec18fSAlexander Duyck 				(i * FM10K_TQDLOC_BASE_32_DESC) |
117b6fec18fSAlexander Duyck 				FM10K_TQDLOC_SIZE_32_DESC);
118b6fec18fSAlexander Duyck 		fm10k_write_reg(hw, FM10K_TXQCTL(i), txqctl);
119b6fec18fSAlexander Duyck 
120b6fec18fSAlexander Duyck 		/* configure rings to provide TPH processing hints */
121b6fec18fSAlexander Duyck 		fm10k_write_reg(hw, FM10K_TPH_TXCTRL(i),
122b6fec18fSAlexander Duyck 				FM10K_TPH_TXCTRL_DESC_TPHEN |
123b6fec18fSAlexander Duyck 				FM10K_TPH_TXCTRL_DESC_RROEN |
124b6fec18fSAlexander Duyck 				FM10K_TPH_TXCTRL_DESC_WROEN |
125b6fec18fSAlexander Duyck 				FM10K_TPH_TXCTRL_DATA_RROEN);
126b6fec18fSAlexander Duyck 		fm10k_write_reg(hw, FM10K_TPH_RXCTRL(i),
127b6fec18fSAlexander Duyck 				FM10K_TPH_RXCTRL_DESC_TPHEN |
128b6fec18fSAlexander Duyck 				FM10K_TPH_RXCTRL_DESC_RROEN |
129b6fec18fSAlexander Duyck 				FM10K_TPH_RXCTRL_DATA_WROEN |
130b6fec18fSAlexander Duyck 				FM10K_TPH_RXCTRL_HDR_WROEN);
131b6fec18fSAlexander Duyck 	}
132b6fec18fSAlexander Duyck 
133b6fec18fSAlexander Duyck 	/* set max hold interval to align with 1.024 usec in all modes */
134b6fec18fSAlexander Duyck 	switch (hw->bus.speed) {
135b6fec18fSAlexander Duyck 	case fm10k_bus_speed_2500:
136b6fec18fSAlexander Duyck 		dma_ctrl = FM10K_DMA_CTRL_MAX_HOLD_1US_GEN1;
137b6fec18fSAlexander Duyck 		break;
138b6fec18fSAlexander Duyck 	case fm10k_bus_speed_5000:
139b6fec18fSAlexander Duyck 		dma_ctrl = FM10K_DMA_CTRL_MAX_HOLD_1US_GEN2;
140b6fec18fSAlexander Duyck 		break;
141b6fec18fSAlexander Duyck 	case fm10k_bus_speed_8000:
142b6fec18fSAlexander Duyck 		dma_ctrl = FM10K_DMA_CTRL_MAX_HOLD_1US_GEN3;
143b6fec18fSAlexander Duyck 		break;
144b6fec18fSAlexander Duyck 	default:
145b6fec18fSAlexander Duyck 		dma_ctrl = 0;
146b6fec18fSAlexander Duyck 		break;
147b6fec18fSAlexander Duyck 	}
148b6fec18fSAlexander Duyck 
149b6fec18fSAlexander Duyck 	/* Configure TSO flags */
150b6fec18fSAlexander Duyck 	fm10k_write_reg(hw, FM10K_DTXTCPFLGL, FM10K_TSO_FLAGS_LOW);
151b6fec18fSAlexander Duyck 	fm10k_write_reg(hw, FM10K_DTXTCPFLGH, FM10K_TSO_FLAGS_HI);
152b6fec18fSAlexander Duyck 
153b6fec18fSAlexander Duyck 	/* Enable DMA engine
154b6fec18fSAlexander Duyck 	 * Set Rx Descriptor size to 32
155b6fec18fSAlexander Duyck 	 * Set Minimum MSS to 64
156b6fec18fSAlexander Duyck 	 * Set Maximum number of Rx queues to 256 / 32 Descriptor
157b6fec18fSAlexander Duyck 	 */
158b6fec18fSAlexander Duyck 	dma_ctrl |= FM10K_DMA_CTRL_TX_ENABLE | FM10K_DMA_CTRL_RX_ENABLE |
159b6fec18fSAlexander Duyck 		    FM10K_DMA_CTRL_RX_DESC_SIZE | FM10K_DMA_CTRL_MINMSS_64 |
160b6fec18fSAlexander Duyck 		    FM10K_DMA_CTRL_32_DESC;
161b6fec18fSAlexander Duyck 
162b6fec18fSAlexander Duyck 	fm10k_write_reg(hw, FM10K_DMA_CTRL, dma_ctrl);
163b6fec18fSAlexander Duyck 
164b6fec18fSAlexander Duyck 	/* record maximum queue count, we limit ourselves to 128 */
165b6fec18fSAlexander Duyck 	hw->mac.max_queues = FM10K_MAX_QUEUES_PF;
166b6fec18fSAlexander Duyck 
167b6fec18fSAlexander Duyck 	return 0;
168b6fec18fSAlexander Duyck }
169b6fec18fSAlexander Duyck 
170b6fec18fSAlexander Duyck /**
171b6fec18fSAlexander Duyck  *  fm10k_is_slot_appropriate_pf - Indicate appropriate slot for this SKU
172b6fec18fSAlexander Duyck  *  @hw: pointer to hardware structure
173b6fec18fSAlexander Duyck  *
174b6fec18fSAlexander Duyck  *  Looks at the PCIe bus info to confirm whether or not this slot can support
175b6fec18fSAlexander Duyck  *  the necessary bandwidth for this device.
176b6fec18fSAlexander Duyck  **/
177b6fec18fSAlexander Duyck static bool fm10k_is_slot_appropriate_pf(struct fm10k_hw *hw)
178b6fec18fSAlexander Duyck {
179b6fec18fSAlexander Duyck 	return (hw->bus.speed == hw->bus_caps.speed) &&
180b6fec18fSAlexander Duyck 	       (hw->bus.width == hw->bus_caps.width);
181b6fec18fSAlexander Duyck }
182b6fec18fSAlexander Duyck 
183b6fec18fSAlexander Duyck /**
184401b5383SAlexander Duyck  *  fm10k_update_vlan_pf - Update status of VLAN ID in VLAN filter table
185401b5383SAlexander Duyck  *  @hw: pointer to hardware structure
186401b5383SAlexander Duyck  *  @vid: VLAN ID to add to table
187401b5383SAlexander Duyck  *  @vsi: Index indicating VF ID or PF ID in table
188401b5383SAlexander Duyck  *  @set: Indicates if this is a set or clear operation
189401b5383SAlexander Duyck  *
190401b5383SAlexander Duyck  *  This function adds or removes the corresponding VLAN ID from the VLAN
191401b5383SAlexander Duyck  *  filter table for the corresponding function.  In addition to the
192401b5383SAlexander Duyck  *  standard set/clear that supports one bit a multi-bit write is
193401b5383SAlexander Duyck  *  supported to set 64 bits at a time.
194401b5383SAlexander Duyck  **/
195401b5383SAlexander Duyck static s32 fm10k_update_vlan_pf(struct fm10k_hw *hw, u32 vid, u8 vsi, bool set)
196401b5383SAlexander Duyck {
197401b5383SAlexander Duyck 	u32 vlan_table, reg, mask, bit, len;
198401b5383SAlexander Duyck 
199401b5383SAlexander Duyck 	/* verify the VSI index is valid */
200401b5383SAlexander Duyck 	if (vsi > FM10K_VLAN_TABLE_VSI_MAX)
201401b5383SAlexander Duyck 		return FM10K_ERR_PARAM;
202401b5383SAlexander Duyck 
203401b5383SAlexander Duyck 	/* VLAN multi-bit write:
204401b5383SAlexander Duyck 	 * The multi-bit write has several parts to it.
205401b5383SAlexander Duyck 	 *    3			  2		      1			  0
206401b5383SAlexander Duyck 	 *  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
207401b5383SAlexander Duyck 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
208401b5383SAlexander Duyck 	 * | RSVD0 |         Length        |C|RSVD0|        VLAN ID        |
209401b5383SAlexander Duyck 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
210401b5383SAlexander Duyck 	 *
211401b5383SAlexander Duyck 	 * VLAN ID: Vlan Starting value
212401b5383SAlexander Duyck 	 * RSVD0: Reserved section, must be 0
213401b5383SAlexander Duyck 	 * C: Flag field, 0 is set, 1 is clear (Used in VF VLAN message)
214401b5383SAlexander Duyck 	 * Length: Number of times to repeat the bit being set
215401b5383SAlexander Duyck 	 */
216401b5383SAlexander Duyck 	len = vid >> 16;
217401b5383SAlexander Duyck 	vid = (vid << 17) >> 17;
218401b5383SAlexander Duyck 
219401b5383SAlexander Duyck 	/* verify the reserved 0 fields are 0 */
220401b5383SAlexander Duyck 	if (len >= FM10K_VLAN_TABLE_VID_MAX ||
221401b5383SAlexander Duyck 	    vid >= FM10K_VLAN_TABLE_VID_MAX)
222401b5383SAlexander Duyck 		return FM10K_ERR_PARAM;
223401b5383SAlexander Duyck 
224401b5383SAlexander Duyck 	/* Loop through the table updating all required VLANs */
225401b5383SAlexander Duyck 	for (reg = FM10K_VLAN_TABLE(vsi, vid / 32), bit = vid % 32;
226401b5383SAlexander Duyck 	     len < FM10K_VLAN_TABLE_VID_MAX;
227401b5383SAlexander Duyck 	     len -= 32 - bit, reg++, bit = 0) {
228401b5383SAlexander Duyck 		/* record the initial state of the register */
229401b5383SAlexander Duyck 		vlan_table = fm10k_read_reg(hw, reg);
230401b5383SAlexander Duyck 
231401b5383SAlexander Duyck 		/* truncate mask if we are at the start or end of the run */
232401b5383SAlexander Duyck 		mask = (~(u32)0 >> ((len < 31) ? 31 - len : 0)) << bit;
233401b5383SAlexander Duyck 
234401b5383SAlexander Duyck 		/* make necessary modifications to the register */
235401b5383SAlexander Duyck 		mask &= set ? ~vlan_table : vlan_table;
236401b5383SAlexander Duyck 		if (mask)
237401b5383SAlexander Duyck 			fm10k_write_reg(hw, reg, vlan_table ^ mask);
238401b5383SAlexander Duyck 	}
239401b5383SAlexander Duyck 
240401b5383SAlexander Duyck 	return 0;
241401b5383SAlexander Duyck }
242401b5383SAlexander Duyck 
243401b5383SAlexander Duyck /**
244b6fec18fSAlexander Duyck  *  fm10k_read_mac_addr_pf - Read device MAC address
245b6fec18fSAlexander Duyck  *  @hw: pointer to the HW structure
246b6fec18fSAlexander Duyck  *
247b6fec18fSAlexander Duyck  *  Reads the device MAC address from the SM_AREA and stores the value.
248b6fec18fSAlexander Duyck  **/
249b6fec18fSAlexander Duyck static s32 fm10k_read_mac_addr_pf(struct fm10k_hw *hw)
250b6fec18fSAlexander Duyck {
251b6fec18fSAlexander Duyck 	u8 perm_addr[ETH_ALEN];
252b6fec18fSAlexander Duyck 	u32 serial_num;
253b6fec18fSAlexander Duyck 	int i;
254b6fec18fSAlexander Duyck 
255b6fec18fSAlexander Duyck 	serial_num = fm10k_read_reg(hw, FM10K_SM_AREA(1));
256b6fec18fSAlexander Duyck 
257b6fec18fSAlexander Duyck 	/* last byte should be all 1's */
258b6fec18fSAlexander Duyck 	if ((~serial_num) << 24)
259b6fec18fSAlexander Duyck 		return  FM10K_ERR_INVALID_MAC_ADDR;
260b6fec18fSAlexander Duyck 
261b6fec18fSAlexander Duyck 	perm_addr[0] = (u8)(serial_num >> 24);
262b6fec18fSAlexander Duyck 	perm_addr[1] = (u8)(serial_num >> 16);
263b6fec18fSAlexander Duyck 	perm_addr[2] = (u8)(serial_num >> 8);
264b6fec18fSAlexander Duyck 
265b6fec18fSAlexander Duyck 	serial_num = fm10k_read_reg(hw, FM10K_SM_AREA(0));
266b6fec18fSAlexander Duyck 
267b6fec18fSAlexander Duyck 	/* first byte should be all 1's */
268b6fec18fSAlexander Duyck 	if ((~serial_num) >> 24)
269b6fec18fSAlexander Duyck 		return  FM10K_ERR_INVALID_MAC_ADDR;
270b6fec18fSAlexander Duyck 
271b6fec18fSAlexander Duyck 	perm_addr[3] = (u8)(serial_num >> 16);
272b6fec18fSAlexander Duyck 	perm_addr[4] = (u8)(serial_num >> 8);
273b6fec18fSAlexander Duyck 	perm_addr[5] = (u8)(serial_num);
274b6fec18fSAlexander Duyck 
275b6fec18fSAlexander Duyck 	for (i = 0; i < ETH_ALEN; i++) {
276b6fec18fSAlexander Duyck 		hw->mac.perm_addr[i] = perm_addr[i];
277b6fec18fSAlexander Duyck 		hw->mac.addr[i] = perm_addr[i];
278b6fec18fSAlexander Duyck 	}
279b6fec18fSAlexander Duyck 
280b6fec18fSAlexander Duyck 	return 0;
281b6fec18fSAlexander Duyck }
282b6fec18fSAlexander Duyck 
283b6fec18fSAlexander Duyck /**
284401b5383SAlexander Duyck  *  fm10k_glort_valid_pf - Validate that the provided glort is valid
285401b5383SAlexander Duyck  *  @hw: pointer to the HW structure
286401b5383SAlexander Duyck  *  @glort: base glort to be validated
287401b5383SAlexander Duyck  *
288401b5383SAlexander Duyck  *  This function will return an error if the provided glort is invalid
289401b5383SAlexander Duyck  **/
290401b5383SAlexander Duyck bool fm10k_glort_valid_pf(struct fm10k_hw *hw, u16 glort)
291401b5383SAlexander Duyck {
292401b5383SAlexander Duyck 	glort &= hw->mac.dglort_map >> FM10K_DGLORTMAP_MASK_SHIFT;
293401b5383SAlexander Duyck 
294401b5383SAlexander Duyck 	return glort == (hw->mac.dglort_map & FM10K_DGLORTMAP_NONE);
295401b5383SAlexander Duyck }
296401b5383SAlexander Duyck 
297401b5383SAlexander Duyck /**
298401b5383SAlexander Duyck  *  fm10k_update_uc_addr_pf - Update device unicast addresss
299401b5383SAlexander Duyck  *  @hw: pointer to the HW structure
300401b5383SAlexander Duyck  *  @glort: base resource tag for this request
301401b5383SAlexander Duyck  *  @mac: MAC address to add/remove from table
302401b5383SAlexander Duyck  *  @vid: VLAN ID to add/remove from table
303401b5383SAlexander Duyck  *  @add: Indicates if this is an add or remove operation
304401b5383SAlexander Duyck  *  @flags: flags field to indicate add and secure
305401b5383SAlexander Duyck  *
306401b5383SAlexander Duyck  *  This function generates a message to the Switch API requesting
307401b5383SAlexander Duyck  *  that the given logical port add/remove the given L2 MAC/VLAN address.
308401b5383SAlexander Duyck  **/
309401b5383SAlexander Duyck static s32 fm10k_update_xc_addr_pf(struct fm10k_hw *hw, u16 glort,
310401b5383SAlexander Duyck 				   const u8 *mac, u16 vid, bool add, u8 flags)
311401b5383SAlexander Duyck {
312401b5383SAlexander Duyck 	struct fm10k_mbx_info *mbx = &hw->mbx;
313401b5383SAlexander Duyck 	struct fm10k_mac_update mac_update;
314401b5383SAlexander Duyck 	u32 msg[5];
315401b5383SAlexander Duyck 
316401b5383SAlexander Duyck 	/* if glort is not valid return error */
317401b5383SAlexander Duyck 	if (!fm10k_glort_valid_pf(hw, glort))
318401b5383SAlexander Duyck 		return FM10K_ERR_PARAM;
319401b5383SAlexander Duyck 
320401b5383SAlexander Duyck 	/* drop upper 4 bits of VLAN ID */
321401b5383SAlexander Duyck 	vid = (vid << 4) >> 4;
322401b5383SAlexander Duyck 
323401b5383SAlexander Duyck 	/* record fields */
324401b5383SAlexander Duyck 	mac_update.mac_lower = cpu_to_le32(((u32)mac[2] << 24) |
325401b5383SAlexander Duyck 						 ((u32)mac[3] << 16) |
326401b5383SAlexander Duyck 						 ((u32)mac[4] << 8) |
327401b5383SAlexander Duyck 						 ((u32)mac[5]));
328401b5383SAlexander Duyck 	mac_update.mac_upper = cpu_to_le16(((u32)mac[0] << 8) |
329401b5383SAlexander Duyck 						 ((u32)mac[1]));
330401b5383SAlexander Duyck 	mac_update.vlan = cpu_to_le16(vid);
331401b5383SAlexander Duyck 	mac_update.glort = cpu_to_le16(glort);
332401b5383SAlexander Duyck 	mac_update.action = add ? 0 : 1;
333401b5383SAlexander Duyck 	mac_update.flags = flags;
334401b5383SAlexander Duyck 
335401b5383SAlexander Duyck 	/* populate mac_update fields */
336401b5383SAlexander Duyck 	fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_UPDATE_MAC_FWD_RULE);
337401b5383SAlexander Duyck 	fm10k_tlv_attr_put_le_struct(msg, FM10K_PF_ATTR_ID_MAC_UPDATE,
338401b5383SAlexander Duyck 				     &mac_update, sizeof(mac_update));
339401b5383SAlexander Duyck 
340401b5383SAlexander Duyck 	/* load onto outgoing mailbox */
341401b5383SAlexander Duyck 	return mbx->ops.enqueue_tx(hw, mbx, msg);
342401b5383SAlexander Duyck }
343401b5383SAlexander Duyck 
344401b5383SAlexander Duyck /**
345401b5383SAlexander Duyck  *  fm10k_update_uc_addr_pf - Update device unicast addresss
346401b5383SAlexander Duyck  *  @hw: pointer to the HW structure
347401b5383SAlexander Duyck  *  @glort: base resource tag for this request
348401b5383SAlexander Duyck  *  @mac: MAC address to add/remove from table
349401b5383SAlexander Duyck  *  @vid: VLAN ID to add/remove from table
350401b5383SAlexander Duyck  *  @add: Indicates if this is an add or remove operation
351401b5383SAlexander Duyck  *  @flags: flags field to indicate add and secure
352401b5383SAlexander Duyck  *
353401b5383SAlexander Duyck  *  This function is used to add or remove unicast addresses for
354401b5383SAlexander Duyck  *  the PF.
355401b5383SAlexander Duyck  **/
356401b5383SAlexander Duyck static s32 fm10k_update_uc_addr_pf(struct fm10k_hw *hw, u16 glort,
357401b5383SAlexander Duyck 				   const u8 *mac, u16 vid, bool add, u8 flags)
358401b5383SAlexander Duyck {
359401b5383SAlexander Duyck 	/* verify MAC address is valid */
360401b5383SAlexander Duyck 	if (!is_valid_ether_addr(mac))
361401b5383SAlexander Duyck 		return FM10K_ERR_PARAM;
362401b5383SAlexander Duyck 
363401b5383SAlexander Duyck 	return fm10k_update_xc_addr_pf(hw, glort, mac, vid, add, flags);
364401b5383SAlexander Duyck }
365401b5383SAlexander Duyck 
366401b5383SAlexander Duyck /**
367401b5383SAlexander Duyck  *  fm10k_update_mc_addr_pf - Update device multicast addresses
368401b5383SAlexander Duyck  *  @hw: pointer to the HW structure
369401b5383SAlexander Duyck  *  @glort: base resource tag for this request
370401b5383SAlexander Duyck  *  @mac: MAC address to add/remove from table
371401b5383SAlexander Duyck  *  @vid: VLAN ID to add/remove from table
372401b5383SAlexander Duyck  *  @add: Indicates if this is an add or remove operation
373401b5383SAlexander Duyck  *
374401b5383SAlexander Duyck  *  This function is used to add or remove multicast MAC addresses for
375401b5383SAlexander Duyck  *  the PF.
376401b5383SAlexander Duyck  **/
377401b5383SAlexander Duyck static s32 fm10k_update_mc_addr_pf(struct fm10k_hw *hw, u16 glort,
378401b5383SAlexander Duyck 				   const u8 *mac, u16 vid, bool add)
379401b5383SAlexander Duyck {
380401b5383SAlexander Duyck 	/* verify multicast address is valid */
381401b5383SAlexander Duyck 	if (!is_multicast_ether_addr(mac))
382401b5383SAlexander Duyck 		return FM10K_ERR_PARAM;
383401b5383SAlexander Duyck 
384401b5383SAlexander Duyck 	return fm10k_update_xc_addr_pf(hw, glort, mac, vid, add, 0);
385401b5383SAlexander Duyck }
386401b5383SAlexander Duyck 
387401b5383SAlexander Duyck /**
388401b5383SAlexander Duyck  *  fm10k_update_xcast_mode_pf - Request update of multicast mode
389401b5383SAlexander Duyck  *  @hw: pointer to hardware structure
390401b5383SAlexander Duyck  *  @glort: base resource tag for this request
391401b5383SAlexander Duyck  *  @mode: integer value indicating mode being requested
392401b5383SAlexander Duyck  *
393401b5383SAlexander Duyck  *  This function will attempt to request a higher mode for the port
394401b5383SAlexander Duyck  *  so that it can enable either multicast, multicast promiscuous, or
395401b5383SAlexander Duyck  *  promiscuous mode of operation.
396401b5383SAlexander Duyck  **/
397401b5383SAlexander Duyck static s32 fm10k_update_xcast_mode_pf(struct fm10k_hw *hw, u16 glort, u8 mode)
398401b5383SAlexander Duyck {
399401b5383SAlexander Duyck 	struct fm10k_mbx_info *mbx = &hw->mbx;
400401b5383SAlexander Duyck 	u32 msg[3], xcast_mode;
401401b5383SAlexander Duyck 
402401b5383SAlexander Duyck 	if (mode > FM10K_XCAST_MODE_NONE)
403401b5383SAlexander Duyck 		return FM10K_ERR_PARAM;
404401b5383SAlexander Duyck 	/* if glort is not valid return error */
405401b5383SAlexander Duyck 	if (!fm10k_glort_valid_pf(hw, glort))
406401b5383SAlexander Duyck 		return FM10K_ERR_PARAM;
407401b5383SAlexander Duyck 
408401b5383SAlexander Duyck 	/* write xcast mode as a single u32 value,
409401b5383SAlexander Duyck 	 * lower 16 bits: glort
410401b5383SAlexander Duyck 	 * upper 16 bits: mode
411401b5383SAlexander Duyck 	 */
412401b5383SAlexander Duyck 	xcast_mode = ((u32)mode << 16) | glort;
413401b5383SAlexander Duyck 
414401b5383SAlexander Duyck 	/* generate message requesting to change xcast mode */
415401b5383SAlexander Duyck 	fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_XCAST_MODES);
416401b5383SAlexander Duyck 	fm10k_tlv_attr_put_u32(msg, FM10K_PF_ATTR_ID_XCAST_MODE, xcast_mode);
417401b5383SAlexander Duyck 
418401b5383SAlexander Duyck 	/* load onto outgoing mailbox */
419401b5383SAlexander Duyck 	return mbx->ops.enqueue_tx(hw, mbx, msg);
420401b5383SAlexander Duyck }
421401b5383SAlexander Duyck 
422401b5383SAlexander Duyck /**
423401b5383SAlexander Duyck  *  fm10k_update_int_moderator_pf - Update interrupt moderator linked list
424401b5383SAlexander Duyck  *  @hw: pointer to hardware structure
425401b5383SAlexander Duyck  *
426401b5383SAlexander Duyck  *  This function walks through the MSI-X vector table to determine the
427401b5383SAlexander Duyck  *  number of active interrupts and based on that information updates the
428401b5383SAlexander Duyck  *  interrupt moderator linked list.
429401b5383SAlexander Duyck  **/
430401b5383SAlexander Duyck static void fm10k_update_int_moderator_pf(struct fm10k_hw *hw)
431401b5383SAlexander Duyck {
432401b5383SAlexander Duyck 	u32 i;
433401b5383SAlexander Duyck 
434401b5383SAlexander Duyck 	/* Disable interrupt moderator */
435401b5383SAlexander Duyck 	fm10k_write_reg(hw, FM10K_INT_CTRL, 0);
436401b5383SAlexander Duyck 
437401b5383SAlexander Duyck 	/* loop through PF from last to first looking enabled vectors */
438401b5383SAlexander Duyck 	for (i = FM10K_ITR_REG_COUNT_PF - 1; i; i--) {
439401b5383SAlexander Duyck 		if (!fm10k_read_reg(hw, FM10K_MSIX_VECTOR_MASK(i)))
440401b5383SAlexander Duyck 			break;
441401b5383SAlexander Duyck 	}
442401b5383SAlexander Duyck 
443401b5383SAlexander Duyck 	/* always reset VFITR2[0] to point to last enabled PF vector*/
444401b5383SAlexander Duyck 	fm10k_write_reg(hw, FM10K_ITR2(FM10K_ITR_REG_COUNT_PF), i);
445401b5383SAlexander Duyck 
446401b5383SAlexander Duyck 	/* reset ITR2[0] to point to last enabled PF vector */
447401b5383SAlexander Duyck 	fm10k_write_reg(hw, FM10K_ITR2(0), i);
448401b5383SAlexander Duyck 
449401b5383SAlexander Duyck 	/* Enable interrupt moderator */
450401b5383SAlexander Duyck 	fm10k_write_reg(hw, FM10K_INT_CTRL, FM10K_INT_CTRL_ENABLEMODERATOR);
451401b5383SAlexander Duyck }
452401b5383SAlexander Duyck 
453401b5383SAlexander Duyck /**
454401b5383SAlexander Duyck  *  fm10k_update_lport_state_pf - Notify the switch of a change in port state
455401b5383SAlexander Duyck  *  @hw: pointer to the HW structure
456401b5383SAlexander Duyck  *  @glort: base resource tag for this request
457401b5383SAlexander Duyck  *  @count: number of logical ports being updated
458401b5383SAlexander Duyck  *  @enable: boolean value indicating enable or disable
459401b5383SAlexander Duyck  *
460401b5383SAlexander Duyck  *  This function is used to add/remove a logical port from the switch.
461401b5383SAlexander Duyck  **/
462401b5383SAlexander Duyck static s32 fm10k_update_lport_state_pf(struct fm10k_hw *hw, u16 glort,
463401b5383SAlexander Duyck 				       u16 count, bool enable)
464401b5383SAlexander Duyck {
465401b5383SAlexander Duyck 	struct fm10k_mbx_info *mbx = &hw->mbx;
466401b5383SAlexander Duyck 	u32 msg[3], lport_msg;
467401b5383SAlexander Duyck 
468401b5383SAlexander Duyck 	/* do nothing if we are being asked to create or destroy 0 ports */
469401b5383SAlexander Duyck 	if (!count)
470401b5383SAlexander Duyck 		return 0;
471401b5383SAlexander Duyck 
472401b5383SAlexander Duyck 	/* if glort is not valid return error */
473401b5383SAlexander Duyck 	if (!fm10k_glort_valid_pf(hw, glort))
474401b5383SAlexander Duyck 		return FM10K_ERR_PARAM;
475401b5383SAlexander Duyck 
476401b5383SAlexander Duyck 	/* construct the lport message from the 2 pieces of data we have */
477401b5383SAlexander Duyck 	lport_msg = ((u32)count << 16) | glort;
478401b5383SAlexander Duyck 
479401b5383SAlexander Duyck 	/* generate lport create/delete message */
480401b5383SAlexander Duyck 	fm10k_tlv_msg_init(msg, enable ? FM10K_PF_MSG_ID_LPORT_CREATE :
481401b5383SAlexander Duyck 					 FM10K_PF_MSG_ID_LPORT_DELETE);
482401b5383SAlexander Duyck 	fm10k_tlv_attr_put_u32(msg, FM10K_PF_ATTR_ID_PORT, lport_msg);
483401b5383SAlexander Duyck 
484401b5383SAlexander Duyck 	/* load onto outgoing mailbox */
485401b5383SAlexander Duyck 	return mbx->ops.enqueue_tx(hw, mbx, msg);
486401b5383SAlexander Duyck }
487401b5383SAlexander Duyck 
488401b5383SAlexander Duyck /**
489401b5383SAlexander Duyck  *  fm10k_configure_dglort_map_pf - Configures GLORT entry and queues
490401b5383SAlexander Duyck  *  @hw: pointer to hardware structure
491401b5383SAlexander Duyck  *  @dglort: pointer to dglort configuration structure
492401b5383SAlexander Duyck  *
493401b5383SAlexander Duyck  *  Reads the configuration structure contained in dglort_cfg and uses
494401b5383SAlexander Duyck  *  that information to then populate a DGLORTMAP/DEC entry and the queues
495401b5383SAlexander Duyck  *  to which it has been assigned.
496401b5383SAlexander Duyck  **/
497401b5383SAlexander Duyck static s32 fm10k_configure_dglort_map_pf(struct fm10k_hw *hw,
498401b5383SAlexander Duyck 					 struct fm10k_dglort_cfg *dglort)
499401b5383SAlexander Duyck {
500401b5383SAlexander Duyck 	u16 glort, queue_count, vsi_count, pc_count;
501401b5383SAlexander Duyck 	u16 vsi, queue, pc, q_idx;
502401b5383SAlexander Duyck 	u32 txqctl, dglortdec, dglortmap;
503401b5383SAlexander Duyck 
504401b5383SAlexander Duyck 	/* verify the dglort pointer */
505401b5383SAlexander Duyck 	if (!dglort)
506401b5383SAlexander Duyck 		return FM10K_ERR_PARAM;
507401b5383SAlexander Duyck 
508401b5383SAlexander Duyck 	/* verify the dglort values */
509401b5383SAlexander Duyck 	if ((dglort->idx > 7) || (dglort->rss_l > 7) || (dglort->pc_l > 3) ||
510401b5383SAlexander Duyck 	    (dglort->vsi_l > 6) || (dglort->vsi_b > 64) ||
511401b5383SAlexander Duyck 	    (dglort->queue_l > 8) || (dglort->queue_b >= 256))
512401b5383SAlexander Duyck 		return FM10K_ERR_PARAM;
513401b5383SAlexander Duyck 
514401b5383SAlexander Duyck 	/* determine count of VSIs and queues */
515401b5383SAlexander Duyck 	queue_count = 1 << (dglort->rss_l + dglort->pc_l);
516401b5383SAlexander Duyck 	vsi_count = 1 << (dglort->vsi_l + dglort->queue_l);
517401b5383SAlexander Duyck 	glort = dglort->glort;
518401b5383SAlexander Duyck 	q_idx = dglort->queue_b;
519401b5383SAlexander Duyck 
520401b5383SAlexander Duyck 	/* configure SGLORT for queues */
521401b5383SAlexander Duyck 	for (vsi = 0; vsi < vsi_count; vsi++, glort++) {
522401b5383SAlexander Duyck 		for (queue = 0; queue < queue_count; queue++, q_idx++) {
523401b5383SAlexander Duyck 			if (q_idx >= FM10K_MAX_QUEUES)
524401b5383SAlexander Duyck 				break;
525401b5383SAlexander Duyck 
526401b5383SAlexander Duyck 			fm10k_write_reg(hw, FM10K_TX_SGLORT(q_idx), glort);
527401b5383SAlexander Duyck 			fm10k_write_reg(hw, FM10K_RX_SGLORT(q_idx), glort);
528401b5383SAlexander Duyck 		}
529401b5383SAlexander Duyck 	}
530401b5383SAlexander Duyck 
531401b5383SAlexander Duyck 	/* determine count of PCs and queues */
532401b5383SAlexander Duyck 	queue_count = 1 << (dglort->queue_l + dglort->rss_l + dglort->vsi_l);
533401b5383SAlexander Duyck 	pc_count = 1 << dglort->pc_l;
534401b5383SAlexander Duyck 
535401b5383SAlexander Duyck 	/* configure PC for Tx queues */
536401b5383SAlexander Duyck 	for (pc = 0; pc < pc_count; pc++) {
537401b5383SAlexander Duyck 		q_idx = pc + dglort->queue_b;
538401b5383SAlexander Duyck 		for (queue = 0; queue < queue_count; queue++) {
539401b5383SAlexander Duyck 			if (q_idx >= FM10K_MAX_QUEUES)
540401b5383SAlexander Duyck 				break;
541401b5383SAlexander Duyck 
542401b5383SAlexander Duyck 			txqctl = fm10k_read_reg(hw, FM10K_TXQCTL(q_idx));
543401b5383SAlexander Duyck 			txqctl &= ~FM10K_TXQCTL_PC_MASK;
544401b5383SAlexander Duyck 			txqctl |= pc << FM10K_TXQCTL_PC_SHIFT;
545401b5383SAlexander Duyck 			fm10k_write_reg(hw, FM10K_TXQCTL(q_idx), txqctl);
546401b5383SAlexander Duyck 
547401b5383SAlexander Duyck 			q_idx += pc_count;
548401b5383SAlexander Duyck 		}
549401b5383SAlexander Duyck 	}
550401b5383SAlexander Duyck 
551401b5383SAlexander Duyck 	/* configure DGLORTDEC */
552401b5383SAlexander Duyck 	dglortdec = ((u32)(dglort->rss_l) << FM10K_DGLORTDEC_RSSLENGTH_SHIFT) |
553401b5383SAlexander Duyck 		    ((u32)(dglort->queue_b) << FM10K_DGLORTDEC_QBASE_SHIFT) |
554401b5383SAlexander Duyck 		    ((u32)(dglort->pc_l) << FM10K_DGLORTDEC_PCLENGTH_SHIFT) |
555401b5383SAlexander Duyck 		    ((u32)(dglort->vsi_b) << FM10K_DGLORTDEC_VSIBASE_SHIFT) |
556401b5383SAlexander Duyck 		    ((u32)(dglort->vsi_l) << FM10K_DGLORTDEC_VSILENGTH_SHIFT) |
557401b5383SAlexander Duyck 		    ((u32)(dglort->queue_l));
558401b5383SAlexander Duyck 	if (dglort->inner_rss)
559401b5383SAlexander Duyck 		dglortdec |=  FM10K_DGLORTDEC_INNERRSS_ENABLE;
560401b5383SAlexander Duyck 
561401b5383SAlexander Duyck 	/* configure DGLORTMAP */
562401b5383SAlexander Duyck 	dglortmap = (dglort->idx == fm10k_dglort_default) ?
563401b5383SAlexander Duyck 			FM10K_DGLORTMAP_ANY : FM10K_DGLORTMAP_ZERO;
564401b5383SAlexander Duyck 	dglortmap <<= dglort->vsi_l + dglort->queue_l + dglort->shared_l;
565401b5383SAlexander Duyck 	dglortmap |= dglort->glort;
566401b5383SAlexander Duyck 
567401b5383SAlexander Duyck 	/* write values to hardware */
568401b5383SAlexander Duyck 	fm10k_write_reg(hw, FM10K_DGLORTDEC(dglort->idx), dglortdec);
569401b5383SAlexander Duyck 	fm10k_write_reg(hw, FM10K_DGLORTMAP(dglort->idx), dglortmap);
570401b5383SAlexander Duyck 
571401b5383SAlexander Duyck 	return 0;
572401b5383SAlexander Duyck }
573401b5383SAlexander Duyck 
574401b5383SAlexander Duyck /**
575b6fec18fSAlexander Duyck  *  fm10k_update_stats_hw_pf - Updates hardware related statistics of PF
576b6fec18fSAlexander Duyck  *  @hw: pointer to hardware structure
577b6fec18fSAlexander Duyck  *  @stats: pointer to the stats structure to update
578b6fec18fSAlexander Duyck  *
579b6fec18fSAlexander Duyck  *  This function collects and aggregates global and per queue hardware
580b6fec18fSAlexander Duyck  *  statistics.
581b6fec18fSAlexander Duyck  **/
582b6fec18fSAlexander Duyck static void fm10k_update_hw_stats_pf(struct fm10k_hw *hw,
583b6fec18fSAlexander Duyck 				     struct fm10k_hw_stats *stats)
584b6fec18fSAlexander Duyck {
585b6fec18fSAlexander Duyck 	u32 timeout, ur, ca, um, xec, vlan_drop, loopback_drop, nodesc_drop;
586b6fec18fSAlexander Duyck 	u32 id, id_prev;
587b6fec18fSAlexander Duyck 
588b6fec18fSAlexander Duyck 	/* Use Tx queue 0 as a canary to detect a reset */
589b6fec18fSAlexander Duyck 	id = fm10k_read_reg(hw, FM10K_TXQCTL(0));
590b6fec18fSAlexander Duyck 
591b6fec18fSAlexander Duyck 	/* Read Global Statistics */
592b6fec18fSAlexander Duyck 	do {
593b6fec18fSAlexander Duyck 		timeout = fm10k_read_hw_stats_32b(hw, FM10K_STATS_TIMEOUT,
594b6fec18fSAlexander Duyck 						  &stats->timeout);
595b6fec18fSAlexander Duyck 		ur = fm10k_read_hw_stats_32b(hw, FM10K_STATS_UR, &stats->ur);
596b6fec18fSAlexander Duyck 		ca = fm10k_read_hw_stats_32b(hw, FM10K_STATS_CA, &stats->ca);
597b6fec18fSAlexander Duyck 		um = fm10k_read_hw_stats_32b(hw, FM10K_STATS_UM, &stats->um);
598b6fec18fSAlexander Duyck 		xec = fm10k_read_hw_stats_32b(hw, FM10K_STATS_XEC, &stats->xec);
599b6fec18fSAlexander Duyck 		vlan_drop = fm10k_read_hw_stats_32b(hw, FM10K_STATS_VLAN_DROP,
600b6fec18fSAlexander Duyck 						    &stats->vlan_drop);
601b6fec18fSAlexander Duyck 		loopback_drop = fm10k_read_hw_stats_32b(hw,
602b6fec18fSAlexander Duyck 							FM10K_STATS_LOOPBACK_DROP,
603b6fec18fSAlexander Duyck 						     &stats->loopback_drop);
604b6fec18fSAlexander Duyck 		nodesc_drop = fm10k_read_hw_stats_32b(hw,
605b6fec18fSAlexander Duyck 						      FM10K_STATS_NODESC_DROP,
606b6fec18fSAlexander Duyck 						      &stats->nodesc_drop);
607b6fec18fSAlexander Duyck 
608b6fec18fSAlexander Duyck 		/* if value has not changed then we have consistent data */
609b6fec18fSAlexander Duyck 		id_prev = id;
610b6fec18fSAlexander Duyck 		id = fm10k_read_reg(hw, FM10K_TXQCTL(0));
611b6fec18fSAlexander Duyck 	} while ((id ^ id_prev) & FM10K_TXQCTL_ID_MASK);
612b6fec18fSAlexander Duyck 
613b6fec18fSAlexander Duyck 	/* drop non-ID bits and set VALID ID bit */
614b6fec18fSAlexander Duyck 	id &= FM10K_TXQCTL_ID_MASK;
615b6fec18fSAlexander Duyck 	id |= FM10K_STAT_VALID;
616b6fec18fSAlexander Duyck 
617b6fec18fSAlexander Duyck 	/* Update Global Statistics */
618b6fec18fSAlexander Duyck 	if (stats->stats_idx == id) {
619b6fec18fSAlexander Duyck 		stats->timeout.count += timeout;
620b6fec18fSAlexander Duyck 		stats->ur.count += ur;
621b6fec18fSAlexander Duyck 		stats->ca.count += ca;
622b6fec18fSAlexander Duyck 		stats->um.count += um;
623b6fec18fSAlexander Duyck 		stats->xec.count += xec;
624b6fec18fSAlexander Duyck 		stats->vlan_drop.count += vlan_drop;
625b6fec18fSAlexander Duyck 		stats->loopback_drop.count += loopback_drop;
626b6fec18fSAlexander Duyck 		stats->nodesc_drop.count += nodesc_drop;
627b6fec18fSAlexander Duyck 	}
628b6fec18fSAlexander Duyck 
629b6fec18fSAlexander Duyck 	/* Update bases and record current PF id */
630b6fec18fSAlexander Duyck 	fm10k_update_hw_base_32b(&stats->timeout, timeout);
631b6fec18fSAlexander Duyck 	fm10k_update_hw_base_32b(&stats->ur, ur);
632b6fec18fSAlexander Duyck 	fm10k_update_hw_base_32b(&stats->ca, ca);
633b6fec18fSAlexander Duyck 	fm10k_update_hw_base_32b(&stats->um, um);
634b6fec18fSAlexander Duyck 	fm10k_update_hw_base_32b(&stats->xec, xec);
635b6fec18fSAlexander Duyck 	fm10k_update_hw_base_32b(&stats->vlan_drop, vlan_drop);
636b6fec18fSAlexander Duyck 	fm10k_update_hw_base_32b(&stats->loopback_drop, loopback_drop);
637b6fec18fSAlexander Duyck 	fm10k_update_hw_base_32b(&stats->nodesc_drop, nodesc_drop);
638b6fec18fSAlexander Duyck 	stats->stats_idx = id;
639b6fec18fSAlexander Duyck 
640b6fec18fSAlexander Duyck 	/* Update Queue Statistics */
641b6fec18fSAlexander Duyck 	fm10k_update_hw_stats_q(hw, stats->q, 0, hw->mac.max_queues);
642b6fec18fSAlexander Duyck }
643b6fec18fSAlexander Duyck 
644b6fec18fSAlexander Duyck /**
645b6fec18fSAlexander Duyck  *  fm10k_rebind_hw_stats_pf - Resets base for hardware statistics of PF
646b6fec18fSAlexander Duyck  *  @hw: pointer to hardware structure
647b6fec18fSAlexander Duyck  *  @stats: pointer to the stats structure to update
648b6fec18fSAlexander Duyck  *
649b6fec18fSAlexander Duyck  *  This function resets the base for global and per queue hardware
650b6fec18fSAlexander Duyck  *  statistics.
651b6fec18fSAlexander Duyck  **/
652b6fec18fSAlexander Duyck static void fm10k_rebind_hw_stats_pf(struct fm10k_hw *hw,
653b6fec18fSAlexander Duyck 				     struct fm10k_hw_stats *stats)
654b6fec18fSAlexander Duyck {
655b6fec18fSAlexander Duyck 	/* Unbind Global Statistics */
656b6fec18fSAlexander Duyck 	fm10k_unbind_hw_stats_32b(&stats->timeout);
657b6fec18fSAlexander Duyck 	fm10k_unbind_hw_stats_32b(&stats->ur);
658b6fec18fSAlexander Duyck 	fm10k_unbind_hw_stats_32b(&stats->ca);
659b6fec18fSAlexander Duyck 	fm10k_unbind_hw_stats_32b(&stats->um);
660b6fec18fSAlexander Duyck 	fm10k_unbind_hw_stats_32b(&stats->xec);
661b6fec18fSAlexander Duyck 	fm10k_unbind_hw_stats_32b(&stats->vlan_drop);
662b6fec18fSAlexander Duyck 	fm10k_unbind_hw_stats_32b(&stats->loopback_drop);
663b6fec18fSAlexander Duyck 	fm10k_unbind_hw_stats_32b(&stats->nodesc_drop);
664b6fec18fSAlexander Duyck 
665b6fec18fSAlexander Duyck 	/* Unbind Queue Statistics */
666b6fec18fSAlexander Duyck 	fm10k_unbind_hw_stats_q(stats->q, 0, hw->mac.max_queues);
667b6fec18fSAlexander Duyck 
668b6fec18fSAlexander Duyck 	/* Reinitialize bases for all stats */
669b6fec18fSAlexander Duyck 	fm10k_update_hw_stats_pf(hw, stats);
670b6fec18fSAlexander Duyck }
671b6fec18fSAlexander Duyck 
672b6fec18fSAlexander Duyck /**
673401b5383SAlexander Duyck  *  fm10k_set_dma_mask_pf - Configures PhyAddrSpace to limit DMA to system
674401b5383SAlexander Duyck  *  @hw: pointer to hardware structure
675401b5383SAlexander Duyck  *  @dma_mask: 64 bit DMA mask required for platform
676401b5383SAlexander Duyck  *
677401b5383SAlexander Duyck  *  This function sets the PHYADDR.PhyAddrSpace bits for the endpoint in order
678401b5383SAlexander Duyck  *  to limit the access to memory beyond what is physically in the system.
679401b5383SAlexander Duyck  **/
680401b5383SAlexander Duyck static void fm10k_set_dma_mask_pf(struct fm10k_hw *hw, u64 dma_mask)
681401b5383SAlexander Duyck {
682401b5383SAlexander Duyck 	/* we need to write the upper 32 bits of DMA mask to PhyAddrSpace */
683401b5383SAlexander Duyck 	u32 phyaddr = (u32)(dma_mask >> 32);
684401b5383SAlexander Duyck 
685401b5383SAlexander Duyck 	fm10k_write_reg(hw, FM10K_PHYADDR, phyaddr);
686401b5383SAlexander Duyck }
687401b5383SAlexander Duyck 
688401b5383SAlexander Duyck /**
689b6fec18fSAlexander Duyck  *  fm10k_get_fault_pf - Record a fault in one of the interface units
690b6fec18fSAlexander Duyck  *  @hw: pointer to hardware structure
691b6fec18fSAlexander Duyck  *  @type: pointer to fault type register offset
692b6fec18fSAlexander Duyck  *  @fault: pointer to memory location to record the fault
693b6fec18fSAlexander Duyck  *
694b6fec18fSAlexander Duyck  *  Record the fault register contents to the fault data structure and
695b6fec18fSAlexander Duyck  *  clear the entry from the register.
696b6fec18fSAlexander Duyck  *
697b6fec18fSAlexander Duyck  *  Returns ERR_PARAM if invalid register is specified or no error is present.
698b6fec18fSAlexander Duyck  **/
699b6fec18fSAlexander Duyck static s32 fm10k_get_fault_pf(struct fm10k_hw *hw, int type,
700b6fec18fSAlexander Duyck 			      struct fm10k_fault *fault)
701b6fec18fSAlexander Duyck {
702b6fec18fSAlexander Duyck 	u32 func;
703b6fec18fSAlexander Duyck 
704b6fec18fSAlexander Duyck 	/* verify the fault register is in range and is aligned */
705b6fec18fSAlexander Duyck 	switch (type) {
706b6fec18fSAlexander Duyck 	case FM10K_PCA_FAULT:
707b6fec18fSAlexander Duyck 	case FM10K_THI_FAULT:
708b6fec18fSAlexander Duyck 	case FM10K_FUM_FAULT:
709b6fec18fSAlexander Duyck 		break;
710b6fec18fSAlexander Duyck 	default:
711b6fec18fSAlexander Duyck 		return FM10K_ERR_PARAM;
712b6fec18fSAlexander Duyck 	}
713b6fec18fSAlexander Duyck 
714b6fec18fSAlexander Duyck 	/* only service faults that are valid */
715b6fec18fSAlexander Duyck 	func = fm10k_read_reg(hw, type + FM10K_FAULT_FUNC);
716b6fec18fSAlexander Duyck 	if (!(func & FM10K_FAULT_FUNC_VALID))
717b6fec18fSAlexander Duyck 		return FM10K_ERR_PARAM;
718b6fec18fSAlexander Duyck 
719b6fec18fSAlexander Duyck 	/* read remaining fields */
720b6fec18fSAlexander Duyck 	fault->address = fm10k_read_reg(hw, type + FM10K_FAULT_ADDR_HI);
721b6fec18fSAlexander Duyck 	fault->address <<= 32;
722b6fec18fSAlexander Duyck 	fault->address = fm10k_read_reg(hw, type + FM10K_FAULT_ADDR_LO);
723b6fec18fSAlexander Duyck 	fault->specinfo = fm10k_read_reg(hw, type + FM10K_FAULT_SPECINFO);
724b6fec18fSAlexander Duyck 
725b6fec18fSAlexander Duyck 	/* clear valid bit to allow for next error */
726b6fec18fSAlexander Duyck 	fm10k_write_reg(hw, type + FM10K_FAULT_FUNC, FM10K_FAULT_FUNC_VALID);
727b6fec18fSAlexander Duyck 
728b6fec18fSAlexander Duyck 	/* Record which function triggered the error */
729b6fec18fSAlexander Duyck 	if (func & FM10K_FAULT_FUNC_PF)
730b6fec18fSAlexander Duyck 		fault->func = 0;
731b6fec18fSAlexander Duyck 	else
732b6fec18fSAlexander Duyck 		fault->func = 1 + ((func & FM10K_FAULT_FUNC_VF_MASK) >>
733b6fec18fSAlexander Duyck 				   FM10K_FAULT_FUNC_VF_SHIFT);
734b6fec18fSAlexander Duyck 
735b6fec18fSAlexander Duyck 	/* record fault type */
736b6fec18fSAlexander Duyck 	fault->type = func & FM10K_FAULT_FUNC_TYPE_MASK;
737b6fec18fSAlexander Duyck 
738b6fec18fSAlexander Duyck 	return 0;
739b6fec18fSAlexander Duyck }
740b6fec18fSAlexander Duyck 
741401b5383SAlexander Duyck /**
742401b5383SAlexander Duyck  *  fm10k_request_lport_map_pf - Request LPORT map from the switch API
743401b5383SAlexander Duyck  *  @hw: pointer to hardware structure
744401b5383SAlexander Duyck  *
745401b5383SAlexander Duyck  **/
746401b5383SAlexander Duyck static s32 fm10k_request_lport_map_pf(struct fm10k_hw *hw)
747401b5383SAlexander Duyck {
748401b5383SAlexander Duyck 	struct fm10k_mbx_info *mbx = &hw->mbx;
749401b5383SAlexander Duyck 	u32 msg[1];
750401b5383SAlexander Duyck 
751401b5383SAlexander Duyck 	/* issue request asking for LPORT map */
752401b5383SAlexander Duyck 	fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_LPORT_MAP);
753401b5383SAlexander Duyck 
754401b5383SAlexander Duyck 	/* load onto outgoing mailbox */
755401b5383SAlexander Duyck 	return mbx->ops.enqueue_tx(hw, mbx, msg);
756401b5383SAlexander Duyck }
757401b5383SAlexander Duyck 
758401b5383SAlexander Duyck /**
759401b5383SAlexander Duyck  *  fm10k_get_host_state_pf - Returns the state of the switch and mailbox
760401b5383SAlexander Duyck  *  @hw: pointer to hardware structure
761401b5383SAlexander Duyck  *  @switch_ready: pointer to boolean value that will record switch state
762401b5383SAlexander Duyck  *
763401b5383SAlexander Duyck  *  This funciton will check the DMA_CTRL2 register and mailbox in order
764401b5383SAlexander Duyck  *  to determine if the switch is ready for the PF to begin requesting
765401b5383SAlexander Duyck  *  addresses and mapping traffic to the local interface.
766401b5383SAlexander Duyck  **/
767401b5383SAlexander Duyck static s32 fm10k_get_host_state_pf(struct fm10k_hw *hw, bool *switch_ready)
768401b5383SAlexander Duyck {
769401b5383SAlexander Duyck 	s32 ret_val = 0;
770401b5383SAlexander Duyck 	u32 dma_ctrl2;
771401b5383SAlexander Duyck 
772401b5383SAlexander Duyck 	/* verify the switch is ready for interraction */
773401b5383SAlexander Duyck 	dma_ctrl2 = fm10k_read_reg(hw, FM10K_DMA_CTRL2);
774401b5383SAlexander Duyck 	if (!(dma_ctrl2 & FM10K_DMA_CTRL2_SWITCH_READY))
775401b5383SAlexander Duyck 		goto out;
776401b5383SAlexander Duyck 
777401b5383SAlexander Duyck 	/* retrieve generic host state info */
778401b5383SAlexander Duyck 	ret_val = fm10k_get_host_state_generic(hw, switch_ready);
779401b5383SAlexander Duyck 	if (ret_val)
780401b5383SAlexander Duyck 		goto out;
781401b5383SAlexander Duyck 
782401b5383SAlexander Duyck 	/* interface cannot receive traffic without logical ports */
783401b5383SAlexander Duyck 	if (hw->mac.dglort_map == FM10K_DGLORTMAP_NONE)
784401b5383SAlexander Duyck 		ret_val = fm10k_request_lport_map_pf(hw);
785401b5383SAlexander Duyck 
786401b5383SAlexander Duyck out:
787401b5383SAlexander Duyck 	return ret_val;
788401b5383SAlexander Duyck }
789401b5383SAlexander Duyck 
790401b5383SAlexander Duyck /* This structure defines the attibutes to be parsed below */
791401b5383SAlexander Duyck const struct fm10k_tlv_attr fm10k_lport_map_msg_attr[] = {
792401b5383SAlexander Duyck 	FM10K_TLV_ATTR_U32(FM10K_PF_ATTR_ID_LPORT_MAP),
793401b5383SAlexander Duyck 	FM10K_TLV_ATTR_LAST
794401b5383SAlexander Duyck };
795401b5383SAlexander Duyck 
796401b5383SAlexander Duyck /**
797401b5383SAlexander Duyck  *  fm10k_msg_lport_map_pf - Message handler for lport_map message from SM
798401b5383SAlexander Duyck  *  @hw: Pointer to hardware structure
799401b5383SAlexander Duyck  *  @results: pointer array containing parsed data
800401b5383SAlexander Duyck  *  @mbx: Pointer to mailbox information structure
801401b5383SAlexander Duyck  *
802401b5383SAlexander Duyck  *  This handler configures the lport mapping based on the reply from the
803401b5383SAlexander Duyck  *  switch API.
804401b5383SAlexander Duyck  **/
805401b5383SAlexander Duyck s32 fm10k_msg_lport_map_pf(struct fm10k_hw *hw, u32 **results,
806401b5383SAlexander Duyck 			   struct fm10k_mbx_info *mbx)
807401b5383SAlexander Duyck {
808401b5383SAlexander Duyck 	u16 glort, mask;
809401b5383SAlexander Duyck 	u32 dglort_map;
810401b5383SAlexander Duyck 	s32 err;
811401b5383SAlexander Duyck 
812401b5383SAlexander Duyck 	err = fm10k_tlv_attr_get_u32(results[FM10K_PF_ATTR_ID_LPORT_MAP],
813401b5383SAlexander Duyck 				     &dglort_map);
814401b5383SAlexander Duyck 	if (err)
815401b5383SAlexander Duyck 		return err;
816401b5383SAlexander Duyck 
817401b5383SAlexander Duyck 	/* extract values out of the header */
818401b5383SAlexander Duyck 	glort = FM10K_MSG_HDR_FIELD_GET(dglort_map, LPORT_MAP_GLORT);
819401b5383SAlexander Duyck 	mask = FM10K_MSG_HDR_FIELD_GET(dglort_map, LPORT_MAP_MASK);
820401b5383SAlexander Duyck 
821401b5383SAlexander Duyck 	/* verify mask is set and none of the masked bits in glort are set */
822401b5383SAlexander Duyck 	if (!mask || (glort & ~mask))
823401b5383SAlexander Duyck 		return FM10K_ERR_PARAM;
824401b5383SAlexander Duyck 
825401b5383SAlexander Duyck 	/* verify the mask is contiguous, and that it is 1's followed by 0's */
826401b5383SAlexander Duyck 	if (((~(mask - 1) & mask) + mask) & FM10K_DGLORTMAP_NONE)
827401b5383SAlexander Duyck 		return FM10K_ERR_PARAM;
828401b5383SAlexander Duyck 
829401b5383SAlexander Duyck 	/* record the glort, mask, and port count */
830401b5383SAlexander Duyck 	hw->mac.dglort_map = dglort_map;
831401b5383SAlexander Duyck 
832401b5383SAlexander Duyck 	return 0;
833401b5383SAlexander Duyck }
834401b5383SAlexander Duyck 
835401b5383SAlexander Duyck const struct fm10k_tlv_attr fm10k_update_pvid_msg_attr[] = {
836401b5383SAlexander Duyck 	FM10K_TLV_ATTR_U32(FM10K_PF_ATTR_ID_UPDATE_PVID),
837401b5383SAlexander Duyck 	FM10K_TLV_ATTR_LAST
838401b5383SAlexander Duyck };
839401b5383SAlexander Duyck 
840401b5383SAlexander Duyck /**
841401b5383SAlexander Duyck  *  fm10k_msg_update_pvid_pf - Message handler for port VLAN message from SM
842401b5383SAlexander Duyck  *  @hw: Pointer to hardware structure
843401b5383SAlexander Duyck  *  @results: pointer array containing parsed data
844401b5383SAlexander Duyck  *  @mbx: Pointer to mailbox information structure
845401b5383SAlexander Duyck  *
846401b5383SAlexander Duyck  *  This handler configures the default VLAN for the PF
847401b5383SAlexander Duyck  **/
848401b5383SAlexander Duyck s32 fm10k_msg_update_pvid_pf(struct fm10k_hw *hw, u32 **results,
849401b5383SAlexander Duyck 			     struct fm10k_mbx_info *mbx)
850401b5383SAlexander Duyck {
851401b5383SAlexander Duyck 	u16 glort, pvid;
852401b5383SAlexander Duyck 	u32 pvid_update;
853401b5383SAlexander Duyck 	s32 err;
854401b5383SAlexander Duyck 
855401b5383SAlexander Duyck 	err = fm10k_tlv_attr_get_u32(results[FM10K_PF_ATTR_ID_UPDATE_PVID],
856401b5383SAlexander Duyck 				     &pvid_update);
857401b5383SAlexander Duyck 	if (err)
858401b5383SAlexander Duyck 		return err;
859401b5383SAlexander Duyck 
860401b5383SAlexander Duyck 	/* extract values from the pvid update */
861401b5383SAlexander Duyck 	glort = FM10K_MSG_HDR_FIELD_GET(pvid_update, UPDATE_PVID_GLORT);
862401b5383SAlexander Duyck 	pvid = FM10K_MSG_HDR_FIELD_GET(pvid_update, UPDATE_PVID_PVID);
863401b5383SAlexander Duyck 
864401b5383SAlexander Duyck 	/* if glort is not valid return error */
865401b5383SAlexander Duyck 	if (!fm10k_glort_valid_pf(hw, glort))
866401b5383SAlexander Duyck 		return FM10K_ERR_PARAM;
867401b5383SAlexander Duyck 
868401b5383SAlexander Duyck 	/* verify VID is valid */
869401b5383SAlexander Duyck 	if (pvid >= FM10K_VLAN_TABLE_VID_MAX)
870401b5383SAlexander Duyck 		return FM10K_ERR_PARAM;
871401b5383SAlexander Duyck 
872401b5383SAlexander Duyck 	/* record the port VLAN ID value */
873401b5383SAlexander Duyck 	hw->mac.default_vid = pvid;
874401b5383SAlexander Duyck 
875401b5383SAlexander Duyck 	return 0;
876401b5383SAlexander Duyck }
877401b5383SAlexander Duyck 
878401b5383SAlexander Duyck /**
879401b5383SAlexander Duyck  *  fm10k_record_global_table_data - Move global table data to swapi table info
880401b5383SAlexander Duyck  *  @from: pointer to source table data structure
881401b5383SAlexander Duyck  *  @to: pointer to destination table info structure
882401b5383SAlexander Duyck  *
883401b5383SAlexander Duyck  *  This function is will copy table_data to the table_info contained in
884401b5383SAlexander Duyck  *  the hw struct.
885401b5383SAlexander Duyck  **/
886401b5383SAlexander Duyck static void fm10k_record_global_table_data(struct fm10k_global_table_data *from,
887401b5383SAlexander Duyck 					   struct fm10k_swapi_table_info *to)
888401b5383SAlexander Duyck {
889401b5383SAlexander Duyck 	/* convert from le32 struct to CPU byte ordered values */
890401b5383SAlexander Duyck 	to->used = le32_to_cpu(from->used);
891401b5383SAlexander Duyck 	to->avail = le32_to_cpu(from->avail);
892401b5383SAlexander Duyck }
893401b5383SAlexander Duyck 
894401b5383SAlexander Duyck const struct fm10k_tlv_attr fm10k_err_msg_attr[] = {
895401b5383SAlexander Duyck 	FM10K_TLV_ATTR_LE_STRUCT(FM10K_PF_ATTR_ID_ERR,
896401b5383SAlexander Duyck 				 sizeof(struct fm10k_swapi_error)),
897401b5383SAlexander Duyck 	FM10K_TLV_ATTR_LAST
898401b5383SAlexander Duyck };
899401b5383SAlexander Duyck 
900401b5383SAlexander Duyck /**
901401b5383SAlexander Duyck  *  fm10k_msg_err_pf - Message handler for error reply
902401b5383SAlexander Duyck  *  @hw: Pointer to hardware structure
903401b5383SAlexander Duyck  *  @results: pointer array containing parsed data
904401b5383SAlexander Duyck  *  @mbx: Pointer to mailbox information structure
905401b5383SAlexander Duyck  *
906401b5383SAlexander Duyck  *  This handler will capture the data for any error replies to previous
907401b5383SAlexander Duyck  *  messages that the PF has sent.
908401b5383SAlexander Duyck  **/
909401b5383SAlexander Duyck s32 fm10k_msg_err_pf(struct fm10k_hw *hw, u32 **results,
910401b5383SAlexander Duyck 		     struct fm10k_mbx_info *mbx)
911401b5383SAlexander Duyck {
912401b5383SAlexander Duyck 	struct fm10k_swapi_error err_msg;
913401b5383SAlexander Duyck 	s32 err;
914401b5383SAlexander Duyck 
915401b5383SAlexander Duyck 	/* extract structure from message */
916401b5383SAlexander Duyck 	err = fm10k_tlv_attr_get_le_struct(results[FM10K_PF_ATTR_ID_ERR],
917401b5383SAlexander Duyck 					   &err_msg, sizeof(err_msg));
918401b5383SAlexander Duyck 	if (err)
919401b5383SAlexander Duyck 		return err;
920401b5383SAlexander Duyck 
921401b5383SAlexander Duyck 	/* record table status */
922401b5383SAlexander Duyck 	fm10k_record_global_table_data(&err_msg.mac, &hw->swapi.mac);
923401b5383SAlexander Duyck 	fm10k_record_global_table_data(&err_msg.nexthop, &hw->swapi.nexthop);
924401b5383SAlexander Duyck 	fm10k_record_global_table_data(&err_msg.ffu, &hw->swapi.ffu);
925401b5383SAlexander Duyck 
926401b5383SAlexander Duyck 	/* record SW API status value */
927401b5383SAlexander Duyck 	hw->swapi.status = le32_to_cpu(err_msg.status);
928401b5383SAlexander Duyck 
929401b5383SAlexander Duyck 	return 0;
930401b5383SAlexander Duyck }
931401b5383SAlexander Duyck 
932401b5383SAlexander Duyck static const struct fm10k_msg_data fm10k_msg_data_pf[] = {
933401b5383SAlexander Duyck 	FM10K_PF_MSG_ERR_HANDLER(XCAST_MODES, fm10k_msg_err_pf),
934401b5383SAlexander Duyck 	FM10K_PF_MSG_ERR_HANDLER(UPDATE_MAC_FWD_RULE, fm10k_msg_err_pf),
935401b5383SAlexander Duyck 	FM10K_PF_MSG_LPORT_MAP_HANDLER(fm10k_msg_lport_map_pf),
936401b5383SAlexander Duyck 	FM10K_PF_MSG_ERR_HANDLER(LPORT_CREATE, fm10k_msg_err_pf),
937401b5383SAlexander Duyck 	FM10K_PF_MSG_ERR_HANDLER(LPORT_DELETE, fm10k_msg_err_pf),
938401b5383SAlexander Duyck 	FM10K_PF_MSG_UPDATE_PVID_HANDLER(fm10k_msg_update_pvid_pf),
939401b5383SAlexander Duyck 	FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
940401b5383SAlexander Duyck };
941401b5383SAlexander Duyck 
942b6fec18fSAlexander Duyck static struct fm10k_mac_ops mac_ops_pf = {
943b6fec18fSAlexander Duyck 	.get_bus_info		= &fm10k_get_bus_info_generic,
944b6fec18fSAlexander Duyck 	.reset_hw		= &fm10k_reset_hw_pf,
945b6fec18fSAlexander Duyck 	.init_hw		= &fm10k_init_hw_pf,
946b6fec18fSAlexander Duyck 	.start_hw		= &fm10k_start_hw_generic,
947b6fec18fSAlexander Duyck 	.stop_hw		= &fm10k_stop_hw_generic,
948b6fec18fSAlexander Duyck 	.is_slot_appropriate	= &fm10k_is_slot_appropriate_pf,
949401b5383SAlexander Duyck 	.update_vlan		= &fm10k_update_vlan_pf,
950b6fec18fSAlexander Duyck 	.read_mac_addr		= &fm10k_read_mac_addr_pf,
951401b5383SAlexander Duyck 	.update_uc_addr		= &fm10k_update_uc_addr_pf,
952401b5383SAlexander Duyck 	.update_mc_addr		= &fm10k_update_mc_addr_pf,
953401b5383SAlexander Duyck 	.update_xcast_mode	= &fm10k_update_xcast_mode_pf,
954401b5383SAlexander Duyck 	.update_int_moderator	= &fm10k_update_int_moderator_pf,
955401b5383SAlexander Duyck 	.update_lport_state	= &fm10k_update_lport_state_pf,
956b6fec18fSAlexander Duyck 	.update_hw_stats	= &fm10k_update_hw_stats_pf,
957b6fec18fSAlexander Duyck 	.rebind_hw_stats	= &fm10k_rebind_hw_stats_pf,
958401b5383SAlexander Duyck 	.configure_dglort_map	= &fm10k_configure_dglort_map_pf,
959401b5383SAlexander Duyck 	.set_dma_mask		= &fm10k_set_dma_mask_pf,
960b6fec18fSAlexander Duyck 	.get_fault		= &fm10k_get_fault_pf,
961401b5383SAlexander Duyck 	.get_host_state		= &fm10k_get_host_state_pf,
962b6fec18fSAlexander Duyck };
963b6fec18fSAlexander Duyck 
964401b5383SAlexander Duyck static s32 fm10k_get_invariants_pf(struct fm10k_hw *hw)
965401b5383SAlexander Duyck {
966401b5383SAlexander Duyck 	fm10k_get_invariants_generic(hw);
967401b5383SAlexander Duyck 
968401b5383SAlexander Duyck 	return fm10k_sm_mbx_init(hw, &hw->mbx, fm10k_msg_data_pf);
969401b5383SAlexander Duyck }
970401b5383SAlexander Duyck 
971b6fec18fSAlexander Duyck struct fm10k_info fm10k_pf_info = {
972b6fec18fSAlexander Duyck 	.mac		= fm10k_mac_pf,
973401b5383SAlexander Duyck 	.get_invariants	= &fm10k_get_invariants_pf,
974b6fec18fSAlexander Duyck 	.mac_ops	= &mac_ops_pf,
975b6fec18fSAlexander Duyck };
976