Commit | Line | Data |
---|---|---|
86641094 | 1 | /* Intel(R) Ethernet Switch Host Interface Driver |
9de6a1a6 | 2 | * Copyright(c) 2013 - 2016 Intel Corporation. |
5cb8db4a AD |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | |
5 | * under the terms and conditions of the GNU General Public License, | |
6 | * version 2, as published by the Free Software Foundation. | |
7 | * | |
8 | * This program is distributed in the hope it will be useful, but WITHOUT | |
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
11 | * more details. | |
12 | * | |
13 | * The full GNU General Public License is included in this distribution in | |
14 | * the file called "COPYING". | |
15 | * | |
16 | * Contact Information: | |
17 | * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | |
18 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | |
19 | */ | |
20 | ||
21 | #include "fm10k_vf.h" | |
22 | ||
23 | /** | |
24 | * fm10k_stop_hw_vf - Stop Tx/Rx units | |
25 | * @hw: pointer to hardware structure | |
26 | * | |
27 | **/ | |
28 | static s32 fm10k_stop_hw_vf(struct fm10k_hw *hw) | |
29 | { | |
30 | u8 *perm_addr = hw->mac.perm_addr; | |
20076fa1 | 31 | u32 bal = 0, bah = 0, tdlen; |
5cb8db4a AD |
32 | s32 err; |
33 | u16 i; | |
34 | ||
35 | /* we need to disable the queues before taking further steps */ | |
36 | err = fm10k_stop_hw_generic(hw); | |
ce33624f | 37 | if (err && err != FM10K_ERR_REQUESTS_PENDING) |
5cb8db4a AD |
38 | return err; |
39 | ||
eca32047 | 40 | /* If permanent address is set then we need to restore it */ |
5cb8db4a AD |
41 | if (is_valid_ether_addr(perm_addr)) { |
42 | bal = (((u32)perm_addr[3]) << 24) | | |
43 | (((u32)perm_addr[4]) << 16) | | |
44 | (((u32)perm_addr[5]) << 8); | |
45 | bah = (((u32)0xFF) << 24) | | |
46 | (((u32)perm_addr[0]) << 16) | | |
47 | (((u32)perm_addr[1]) << 8) | | |
48 | ((u32)perm_addr[2]); | |
49 | } | |
50 | ||
20076fa1 JK |
51 | /* restore default itr_scale for next VF initialization */ |
52 | tdlen = hw->mac.itr_scale << FM10K_TDLEN_ITR_SCALE_SHIFT; | |
53 | ||
5cb8db4a AD |
54 | /* The queues have already been disabled so we just need to |
55 | * update their base address registers | |
56 | */ | |
57 | for (i = 0; i < hw->mac.max_queues; i++) { | |
58 | fm10k_write_reg(hw, FM10K_TDBAL(i), bal); | |
59 | fm10k_write_reg(hw, FM10K_TDBAH(i), bah); | |
60 | fm10k_write_reg(hw, FM10K_RDBAL(i), bal); | |
61 | fm10k_write_reg(hw, FM10K_RDBAH(i), bah); | |
20076fa1 JK |
62 | /* Restore ITR scale in software-defined mechanism in TDLEN |
63 | * for next VF initialization. See definition of | |
64 | * FM10K_TDLEN_ITR_SCALE_SHIFT for more details on the use of | |
65 | * TDLEN here. | |
66 | */ | |
67 | fm10k_write_reg(hw, FM10K_TDLEN(i), tdlen); | |
5cb8db4a AD |
68 | } |
69 | ||
ce33624f | 70 | return err; |
5cb8db4a AD |
71 | } |
72 | ||
73 | /** | |
74 | * fm10k_reset_hw_vf - VF hardware reset | |
75 | * @hw: pointer to hardware structure | |
76 | * | |
eca32047 | 77 | * This function should return the hardware to a state similar to the |
5cb8db4a AD |
78 | * one it is in after just being initialized. |
79 | **/ | |
80 | static s32 fm10k_reset_hw_vf(struct fm10k_hw *hw) | |
81 | { | |
82 | s32 err; | |
83 | ||
84 | /* shut down queues we own and reset DMA configuration */ | |
85 | err = fm10k_stop_hw_vf(hw); | |
ce33624f JK |
86 | if (err == FM10K_ERR_REQUESTS_PENDING) |
87 | hw->mac.reset_while_pending++; | |
88 | else if (err) | |
5cb8db4a AD |
89 | return err; |
90 | ||
91 | /* Inititate VF reset */ | |
92 | fm10k_write_reg(hw, FM10K_VFCTRL, FM10K_VFCTRL_RST); | |
93 | ||
94 | /* Flush write and allow 100us for reset to complete */ | |
95 | fm10k_write_flush(hw); | |
96 | udelay(FM10K_RESET_TIMEOUT); | |
97 | ||
98 | /* Clear reset bit and verify it was cleared */ | |
99 | fm10k_write_reg(hw, FM10K_VFCTRL, 0); | |
100 | if (fm10k_read_reg(hw, FM10K_VFCTRL) & FM10K_VFCTRL_RST) | |
ce33624f | 101 | return FM10K_ERR_RESET_FAILED; |
5cb8db4a | 102 | |
ce33624f | 103 | return 0; |
5cb8db4a AD |
104 | } |
105 | ||
106 | /** | |
107 | * fm10k_init_hw_vf - VF hardware initialization | |
108 | * @hw: pointer to hardware structure | |
109 | * | |
110 | **/ | |
111 | static s32 fm10k_init_hw_vf(struct fm10k_hw *hw) | |
112 | { | |
113 | u32 tqdloc, tqdloc0 = ~fm10k_read_reg(hw, FM10K_TQDLOC(0)); | |
114 | s32 err; | |
115 | u16 i; | |
116 | ||
1340181f JK |
117 | /* verify we have at least 1 queue */ |
118 | if (!~fm10k_read_reg(hw, FM10K_TXQCTL(0)) || | |
0e8d5b59 JK |
119 | !~fm10k_read_reg(hw, FM10K_RXQCTL(0))) { |
120 | err = FM10K_ERR_NO_RESOURCES; | |
121 | goto reset_max_queues; | |
122 | } | |
1340181f JK |
123 | |
124 | /* determine how many queues we have */ | |
5cb8db4a AD |
125 | for (i = 1; tqdloc0 && (i < FM10K_MAX_QUEUES_POOL); i++) { |
126 | /* verify the Descriptor cache offsets are increasing */ | |
127 | tqdloc = ~fm10k_read_reg(hw, FM10K_TQDLOC(i)); | |
128 | if (!tqdloc || (tqdloc == tqdloc0)) | |
129 | break; | |
130 | ||
131 | /* check to verify the PF doesn't own any of our queues */ | |
132 | if (!~fm10k_read_reg(hw, FM10K_TXQCTL(i)) || | |
133 | !~fm10k_read_reg(hw, FM10K_RXQCTL(i))) | |
134 | break; | |
135 | } | |
136 | ||
137 | /* shut down queues we own and reset DMA configuration */ | |
138 | err = fm10k_disable_queues_generic(hw, i); | |
139 | if (err) | |
0e8d5b59 | 140 | goto reset_max_queues; |
5cb8db4a AD |
141 | |
142 | /* record maximum queue count */ | |
143 | hw->mac.max_queues = i; | |
144 | ||
20076fa1 | 145 | /* fetch default VLAN and ITR scale */ |
4c16ceae JK |
146 | hw->mac.default_vid = (fm10k_read_reg(hw, FM10K_TXQCTL(0)) & |
147 | FM10K_TXQCTL_VID_MASK) >> FM10K_TXQCTL_VID_SHIFT; | |
20076fa1 JK |
148 | /* Read the ITR scale from TDLEN. See the definition of |
149 | * FM10K_TDLEN_ITR_SCALE_SHIFT for more information about how TDLEN is | |
150 | * used here. | |
151 | */ | |
152 | hw->mac.itr_scale = (fm10k_read_reg(hw, FM10K_TDLEN(0)) & | |
153 | FM10K_TDLEN_ITR_SCALE_MASK) >> | |
154 | FM10K_TDLEN_ITR_SCALE_SHIFT; | |
4c16ceae | 155 | |
5cb8db4a | 156 | return 0; |
0e8d5b59 JK |
157 | |
158 | reset_max_queues: | |
159 | hw->mac.max_queues = 0; | |
160 | ||
161 | return err; | |
5cb8db4a AD |
162 | } |
163 | ||
5cb8db4a AD |
164 | /* This structure defines the attibutes to be parsed below */ |
165 | const struct fm10k_tlv_attr fm10k_mac_vlan_msg_attr[] = { | |
166 | FM10K_TLV_ATTR_U32(FM10K_MAC_VLAN_MSG_VLAN), | |
167 | FM10K_TLV_ATTR_BOOL(FM10K_MAC_VLAN_MSG_SET), | |
168 | FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_MAC), | |
169 | FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_DEFAULT_MAC), | |
170 | FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_MULTICAST), | |
171 | FM10K_TLV_ATTR_LAST | |
172 | }; | |
173 | ||
174 | /** | |
175 | * fm10k_update_vlan_vf - Update status of VLAN ID in VLAN filter table | |
176 | * @hw: pointer to hardware structure | |
177 | * @vid: VLAN ID to add to table | |
178 | * @vsi: Reserved, should always be 0 | |
179 | * @set: Indicates if this is a set or clear operation | |
180 | * | |
181 | * This function adds or removes the corresponding VLAN ID from the VLAN | |
182 | * filter table for this VF. | |
183 | **/ | |
184 | static s32 fm10k_update_vlan_vf(struct fm10k_hw *hw, u32 vid, u8 vsi, bool set) | |
185 | { | |
186 | struct fm10k_mbx_info *mbx = &hw->mbx; | |
187 | u32 msg[4]; | |
188 | ||
189 | /* verify the index is not set */ | |
190 | if (vsi) | |
191 | return FM10K_ERR_PARAM; | |
192 | ||
fb6515c8 | 193 | /* clever trick to verify reserved bits in both vid and length */ |
5cb8db4a AD |
194 | if ((vid << 16 | vid) >> 28) |
195 | return FM10K_ERR_PARAM; | |
196 | ||
197 | /* encode set bit into the VLAN ID */ | |
198 | if (!set) | |
199 | vid |= FM10K_VLAN_CLEAR; | |
200 | ||
201 | /* generate VLAN request */ | |
202 | fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN); | |
203 | fm10k_tlv_attr_put_u32(msg, FM10K_MAC_VLAN_MSG_VLAN, vid); | |
204 | ||
205 | /* load onto outgoing mailbox */ | |
206 | return mbx->ops.enqueue_tx(hw, mbx, msg); | |
207 | } | |
208 | ||
209 | /** | |
210 | * fm10k_msg_mac_vlan_vf - Read device MAC address from mailbox message | |
211 | * @hw: pointer to the HW structure | |
212 | * @results: Attributes for message | |
213 | * @mbx: unused mailbox data | |
214 | * | |
215 | * This function should determine the MAC address for the VF | |
216 | **/ | |
217 | s32 fm10k_msg_mac_vlan_vf(struct fm10k_hw *hw, u32 **results, | |
218 | struct fm10k_mbx_info *mbx) | |
219 | { | |
220 | u8 perm_addr[ETH_ALEN]; | |
221 | u16 vid; | |
222 | s32 err; | |
223 | ||
224 | /* record MAC address requested */ | |
225 | err = fm10k_tlv_attr_get_mac_vlan( | |
226 | results[FM10K_MAC_VLAN_MSG_DEFAULT_MAC], | |
227 | perm_addr, &vid); | |
228 | if (err) | |
229 | return err; | |
230 | ||
231 | ether_addr_copy(hw->mac.perm_addr, perm_addr); | |
232 | hw->mac.default_vid = vid & (FM10K_VLAN_TABLE_VID_MAX - 1); | |
5c69df8a | 233 | hw->mac.vlan_override = !!(vid & FM10K_VLAN_OVERRIDE); |
5cb8db4a AD |
234 | |
235 | return 0; | |
236 | } | |
237 | ||
238 | /** | |
239 | * fm10k_read_mac_addr_vf - Read device MAC address | |
240 | * @hw: pointer to the HW structure | |
241 | * | |
242 | * This function should determine the MAC address for the VF | |
243 | **/ | |
244 | static s32 fm10k_read_mac_addr_vf(struct fm10k_hw *hw) | |
245 | { | |
246 | u8 perm_addr[ETH_ALEN]; | |
247 | u32 base_addr; | |
248 | ||
249 | base_addr = fm10k_read_reg(hw, FM10K_TDBAL(0)); | |
250 | ||
251 | /* last byte should be 0 */ | |
252 | if (base_addr << 24) | |
253 | return FM10K_ERR_INVALID_MAC_ADDR; | |
254 | ||
255 | perm_addr[3] = (u8)(base_addr >> 24); | |
256 | perm_addr[4] = (u8)(base_addr >> 16); | |
257 | perm_addr[5] = (u8)(base_addr >> 8); | |
258 | ||
259 | base_addr = fm10k_read_reg(hw, FM10K_TDBAH(0)); | |
260 | ||
261 | /* first byte should be all 1's */ | |
262 | if ((~base_addr) >> 24) | |
263 | return FM10K_ERR_INVALID_MAC_ADDR; | |
264 | ||
265 | perm_addr[0] = (u8)(base_addr >> 16); | |
266 | perm_addr[1] = (u8)(base_addr >> 8); | |
267 | perm_addr[2] = (u8)(base_addr); | |
268 | ||
269 | ether_addr_copy(hw->mac.perm_addr, perm_addr); | |
270 | ether_addr_copy(hw->mac.addr, perm_addr); | |
271 | ||
272 | return 0; | |
273 | } | |
274 | ||
275 | /** | |
eca32047 | 276 | * fm10k_update_uc_addr_vf - Update device unicast addresses |
5cb8db4a AD |
277 | * @hw: pointer to the HW structure |
278 | * @glort: unused | |
279 | * @mac: MAC address to add/remove from table | |
280 | * @vid: VLAN ID to add/remove from table | |
281 | * @add: Indicates if this is an add or remove operation | |
282 | * @flags: flags field to indicate add and secure - unused | |
283 | * | |
284 | * This function is used to add or remove unicast MAC addresses for | |
285 | * the VF. | |
286 | **/ | |
287 | static s32 fm10k_update_uc_addr_vf(struct fm10k_hw *hw, u16 glort, | |
288 | const u8 *mac, u16 vid, bool add, u8 flags) | |
289 | { | |
290 | struct fm10k_mbx_info *mbx = &hw->mbx; | |
291 | u32 msg[7]; | |
292 | ||
293 | /* verify VLAN ID is valid */ | |
294 | if (vid >= FM10K_VLAN_TABLE_VID_MAX) | |
295 | return FM10K_ERR_PARAM; | |
296 | ||
297 | /* verify MAC address is valid */ | |
298 | if (!is_valid_ether_addr(mac)) | |
299 | return FM10K_ERR_PARAM; | |
300 | ||
301 | /* verify we are not locked down on the MAC address */ | |
302 | if (is_valid_ether_addr(hw->mac.perm_addr) && | |
6186ddf0 | 303 | !ether_addr_equal(hw->mac.perm_addr, mac)) |
5cb8db4a AD |
304 | return FM10K_ERR_PARAM; |
305 | ||
eca32047 | 306 | /* add bit to notify us if this is a set or clear operation */ |
5cb8db4a AD |
307 | if (!add) |
308 | vid |= FM10K_VLAN_CLEAR; | |
309 | ||
310 | /* generate VLAN request */ | |
311 | fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN); | |
312 | fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_MAC, mac, vid); | |
313 | ||
314 | /* load onto outgoing mailbox */ | |
315 | return mbx->ops.enqueue_tx(hw, mbx, msg); | |
316 | } | |
317 | ||
318 | /** | |
eca32047 | 319 | * fm10k_update_mc_addr_vf - Update device multicast addresses |
5cb8db4a AD |
320 | * @hw: pointer to the HW structure |
321 | * @glort: unused | |
322 | * @mac: MAC address to add/remove from table | |
323 | * @vid: VLAN ID to add/remove from table | |
324 | * @add: Indicates if this is an add or remove operation | |
325 | * | |
326 | * This function is used to add or remove multicast MAC addresses for | |
327 | * the VF. | |
328 | **/ | |
329 | static s32 fm10k_update_mc_addr_vf(struct fm10k_hw *hw, u16 glort, | |
330 | const u8 *mac, u16 vid, bool add) | |
331 | { | |
332 | struct fm10k_mbx_info *mbx = &hw->mbx; | |
333 | u32 msg[7]; | |
334 | ||
335 | /* verify VLAN ID is valid */ | |
336 | if (vid >= FM10K_VLAN_TABLE_VID_MAX) | |
337 | return FM10K_ERR_PARAM; | |
338 | ||
339 | /* verify multicast address is valid */ | |
340 | if (!is_multicast_ether_addr(mac)) | |
341 | return FM10K_ERR_PARAM; | |
342 | ||
eca32047 | 343 | /* add bit to notify us if this is a set or clear operation */ |
5cb8db4a AD |
344 | if (!add) |
345 | vid |= FM10K_VLAN_CLEAR; | |
346 | ||
347 | /* generate VLAN request */ | |
348 | fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN); | |
349 | fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_MULTICAST, | |
350 | mac, vid); | |
351 | ||
352 | /* load onto outgoing mailbox */ | |
353 | return mbx->ops.enqueue_tx(hw, mbx, msg); | |
354 | } | |
355 | ||
356 | /** | |
357 | * fm10k_update_int_moderator_vf - Request update of interrupt moderator list | |
358 | * @hw: pointer to hardware structure | |
359 | * | |
360 | * This function will issue a request to the PF to rescan our MSI-X table | |
361 | * and to update the interrupt moderator linked list. | |
362 | **/ | |
363 | static void fm10k_update_int_moderator_vf(struct fm10k_hw *hw) | |
364 | { | |
365 | struct fm10k_mbx_info *mbx = &hw->mbx; | |
366 | u32 msg[1]; | |
367 | ||
368 | /* generate MSI-X request */ | |
369 | fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MSIX); | |
370 | ||
371 | /* load onto outgoing mailbox */ | |
372 | mbx->ops.enqueue_tx(hw, mbx, msg); | |
373 | } | |
374 | ||
375 | /* This structure defines the attibutes to be parsed below */ | |
376 | const struct fm10k_tlv_attr fm10k_lport_state_msg_attr[] = { | |
377 | FM10K_TLV_ATTR_BOOL(FM10K_LPORT_STATE_MSG_DISABLE), | |
378 | FM10K_TLV_ATTR_U8(FM10K_LPORT_STATE_MSG_XCAST_MODE), | |
379 | FM10K_TLV_ATTR_BOOL(FM10K_LPORT_STATE_MSG_READY), | |
380 | FM10K_TLV_ATTR_LAST | |
381 | }; | |
382 | ||
383 | /** | |
384 | * fm10k_msg_lport_state_vf - Message handler for lport_state message from PF | |
385 | * @hw: Pointer to hardware structure | |
386 | * @results: pointer array containing parsed data | |
387 | * @mbx: Pointer to mailbox information structure | |
388 | * | |
389 | * This handler is meant to capture the indication from the PF that we | |
390 | * are ready to bring up the interface. | |
391 | **/ | |
392 | s32 fm10k_msg_lport_state_vf(struct fm10k_hw *hw, u32 **results, | |
393 | struct fm10k_mbx_info *mbx) | |
394 | { | |
395 | hw->mac.dglort_map = !results[FM10K_LPORT_STATE_MSG_READY] ? | |
396 | FM10K_DGLORTMAP_NONE : FM10K_DGLORTMAP_ZERO; | |
397 | ||
398 | return 0; | |
399 | } | |
400 | ||
401 | /** | |
402 | * fm10k_update_lport_state_vf - Update device state in lower device | |
403 | * @hw: pointer to the HW structure | |
404 | * @glort: unused | |
405 | * @count: number of logical ports to enable - unused (always 1) | |
406 | * @enable: boolean value indicating if this is an enable or disable request | |
407 | * | |
408 | * Notify the lower device of a state change. If the lower device is | |
409 | * enabled we can add filters, if it is disabled all filters for this | |
410 | * logical port are flushed. | |
411 | **/ | |
412 | static s32 fm10k_update_lport_state_vf(struct fm10k_hw *hw, u16 glort, | |
413 | u16 count, bool enable) | |
414 | { | |
415 | struct fm10k_mbx_info *mbx = &hw->mbx; | |
416 | u32 msg[2]; | |
417 | ||
418 | /* reset glort mask 0 as we have to wait to be enabled */ | |
419 | hw->mac.dglort_map = FM10K_DGLORTMAP_NONE; | |
420 | ||
421 | /* generate port state request */ | |
422 | fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE); | |
423 | if (!enable) | |
424 | fm10k_tlv_attr_put_bool(msg, FM10K_LPORT_STATE_MSG_DISABLE); | |
425 | ||
426 | /* load onto outgoing mailbox */ | |
427 | return mbx->ops.enqueue_tx(hw, mbx, msg); | |
428 | } | |
429 | ||
430 | /** | |
431 | * fm10k_update_xcast_mode_vf - Request update of multicast mode | |
432 | * @hw: pointer to hardware structure | |
433 | * @glort: unused | |
434 | * @mode: integer value indicating mode being requested | |
435 | * | |
436 | * This function will attempt to request a higher mode for the port | |
437 | * so that it can enable either multicast, multicast promiscuous, or | |
438 | * promiscuous mode of operation. | |
439 | **/ | |
440 | static s32 fm10k_update_xcast_mode_vf(struct fm10k_hw *hw, u16 glort, u8 mode) | |
441 | { | |
442 | struct fm10k_mbx_info *mbx = &hw->mbx; | |
443 | u32 msg[3]; | |
444 | ||
445 | if (mode > FM10K_XCAST_MODE_NONE) | |
446 | return FM10K_ERR_PARAM; | |
a4fcad65 | 447 | |
5cb8db4a AD |
448 | /* generate message requesting to change xcast mode */ |
449 | fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE); | |
450 | fm10k_tlv_attr_put_u8(msg, FM10K_LPORT_STATE_MSG_XCAST_MODE, mode); | |
451 | ||
452 | /* load onto outgoing mailbox */ | |
453 | return mbx->ops.enqueue_tx(hw, mbx, msg); | |
454 | } | |
455 | ||
456 | /** | |
457 | * fm10k_update_hw_stats_vf - Updates hardware related statistics of VF | |
458 | * @hw: pointer to hardware structure | |
459 | * @stats: pointer to statistics structure | |
460 | * | |
461 | * This function collects and aggregates per queue hardware statistics. | |
462 | **/ | |
463 | static void fm10k_update_hw_stats_vf(struct fm10k_hw *hw, | |
464 | struct fm10k_hw_stats *stats) | |
465 | { | |
466 | fm10k_update_hw_stats_q(hw, stats->q, 0, hw->mac.max_queues); | |
467 | } | |
468 | ||
469 | /** | |
470 | * fm10k_rebind_hw_stats_vf - Resets base for hardware statistics of VF | |
471 | * @hw: pointer to hardware structure | |
472 | * @stats: pointer to the stats structure to update | |
473 | * | |
474 | * This function resets the base for queue hardware statistics. | |
475 | **/ | |
476 | static void fm10k_rebind_hw_stats_vf(struct fm10k_hw *hw, | |
477 | struct fm10k_hw_stats *stats) | |
478 | { | |
479 | /* Unbind Queue Statistics */ | |
480 | fm10k_unbind_hw_stats_q(stats->q, 0, hw->mac.max_queues); | |
481 | ||
482 | /* Reinitialize bases for all stats */ | |
483 | fm10k_update_hw_stats_vf(hw, stats); | |
484 | } | |
485 | ||
486 | /** | |
487 | * fm10k_configure_dglort_map_vf - Configures GLORT entry and queues | |
488 | * @hw: pointer to hardware structure | |
489 | * @dglort: pointer to dglort configuration structure | |
490 | * | |
491 | * Reads the configuration structure contained in dglort_cfg and uses | |
492 | * that information to then populate a DGLORTMAP/DEC entry and the queues | |
493 | * to which it has been assigned. | |
494 | **/ | |
495 | static s32 fm10k_configure_dglort_map_vf(struct fm10k_hw *hw, | |
496 | struct fm10k_dglort_cfg *dglort) | |
497 | { | |
498 | /* verify the dglort pointer */ | |
499 | if (!dglort) | |
500 | return FM10K_ERR_PARAM; | |
501 | ||
502 | /* stub for now until we determine correct message for this */ | |
503 | ||
504 | return 0; | |
505 | } | |
506 | ||
507 | static const struct fm10k_msg_data fm10k_msg_data_vf[] = { | |
508 | FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test), | |
509 | FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_msg_mac_vlan_vf), | |
510 | FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_msg_lport_state_vf), | |
511 | FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error), | |
512 | }; | |
513 | ||
f329ad73 | 514 | static const struct fm10k_mac_ops mac_ops_vf = { |
4e458cfb BA |
515 | .get_bus_info = fm10k_get_bus_info_generic, |
516 | .reset_hw = fm10k_reset_hw_vf, | |
517 | .init_hw = fm10k_init_hw_vf, | |
518 | .start_hw = fm10k_start_hw_generic, | |
519 | .stop_hw = fm10k_stop_hw_vf, | |
520 | .update_vlan = fm10k_update_vlan_vf, | |
521 | .read_mac_addr = fm10k_read_mac_addr_vf, | |
522 | .update_uc_addr = fm10k_update_uc_addr_vf, | |
523 | .update_mc_addr = fm10k_update_mc_addr_vf, | |
524 | .update_xcast_mode = fm10k_update_xcast_mode_vf, | |
525 | .update_int_moderator = fm10k_update_int_moderator_vf, | |
526 | .update_lport_state = fm10k_update_lport_state_vf, | |
527 | .update_hw_stats = fm10k_update_hw_stats_vf, | |
528 | .rebind_hw_stats = fm10k_rebind_hw_stats_vf, | |
529 | .configure_dglort_map = fm10k_configure_dglort_map_vf, | |
530 | .get_host_state = fm10k_get_host_state_generic, | |
5cb8db4a AD |
531 | }; |
532 | ||
533 | static s32 fm10k_get_invariants_vf(struct fm10k_hw *hw) | |
534 | { | |
535 | fm10k_get_invariants_generic(hw); | |
536 | ||
537 | return fm10k_pfvf_mbx_init(hw, &hw->mbx, fm10k_msg_data_vf, 0); | |
538 | } | |
539 | ||
f329ad73 | 540 | const struct fm10k_info fm10k_vf_info = { |
5cb8db4a | 541 | .mac = fm10k_mac_vf, |
4e458cfb | 542 | .get_invariants = fm10k_get_invariants_vf, |
5cb8db4a AD |
543 | .mac_ops = &mac_ops_vf, |
544 | }; |