1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2013 - 2018 Intel Corporation. */
4 #include "fm10k_common.h"
7 * fm10k_get_bus_info_generic - Generic set PCI bus info
8 * @hw: pointer to hardware structure
10 * Gets the PCI bus info (speed, width, type) then calls helper function to
11 * store this data within the fm10k_hw structure.
13 s32
fm10k_get_bus_info_generic(struct fm10k_hw
*hw
)
15 u16 link_cap
, link_status
, device_cap
, device_control
;
17 /* Get the maximum link width and speed from PCIe config space */
18 link_cap
= fm10k_read_pci_cfg_word(hw
, FM10K_PCIE_LINK_CAP
);
20 switch (link_cap
& FM10K_PCIE_LINK_WIDTH
) {
21 case FM10K_PCIE_LINK_WIDTH_1
:
22 hw
->bus_caps
.width
= fm10k_bus_width_pcie_x1
;
24 case FM10K_PCIE_LINK_WIDTH_2
:
25 hw
->bus_caps
.width
= fm10k_bus_width_pcie_x2
;
27 case FM10K_PCIE_LINK_WIDTH_4
:
28 hw
->bus_caps
.width
= fm10k_bus_width_pcie_x4
;
30 case FM10K_PCIE_LINK_WIDTH_8
:
31 hw
->bus_caps
.width
= fm10k_bus_width_pcie_x8
;
34 hw
->bus_caps
.width
= fm10k_bus_width_unknown
;
38 switch (link_cap
& FM10K_PCIE_LINK_SPEED
) {
39 case FM10K_PCIE_LINK_SPEED_2500
:
40 hw
->bus_caps
.speed
= fm10k_bus_speed_2500
;
42 case FM10K_PCIE_LINK_SPEED_5000
:
43 hw
->bus_caps
.speed
= fm10k_bus_speed_5000
;
45 case FM10K_PCIE_LINK_SPEED_8000
:
46 hw
->bus_caps
.speed
= fm10k_bus_speed_8000
;
49 hw
->bus_caps
.speed
= fm10k_bus_speed_unknown
;
53 /* Get the PCIe maximum payload size for the PCIe function */
54 device_cap
= fm10k_read_pci_cfg_word(hw
, FM10K_PCIE_DEV_CAP
);
56 switch (device_cap
& FM10K_PCIE_DEV_CAP_PAYLOAD
) {
57 case FM10K_PCIE_DEV_CAP_PAYLOAD_128
:
58 hw
->bus_caps
.payload
= fm10k_bus_payload_128
;
60 case FM10K_PCIE_DEV_CAP_PAYLOAD_256
:
61 hw
->bus_caps
.payload
= fm10k_bus_payload_256
;
63 case FM10K_PCIE_DEV_CAP_PAYLOAD_512
:
64 hw
->bus_caps
.payload
= fm10k_bus_payload_512
;
67 hw
->bus_caps
.payload
= fm10k_bus_payload_unknown
;
71 /* Get the negotiated link width and speed from PCIe config space */
72 link_status
= fm10k_read_pci_cfg_word(hw
, FM10K_PCIE_LINK_STATUS
);
74 switch (link_status
& FM10K_PCIE_LINK_WIDTH
) {
75 case FM10K_PCIE_LINK_WIDTH_1
:
76 hw
->bus
.width
= fm10k_bus_width_pcie_x1
;
78 case FM10K_PCIE_LINK_WIDTH_2
:
79 hw
->bus
.width
= fm10k_bus_width_pcie_x2
;
81 case FM10K_PCIE_LINK_WIDTH_4
:
82 hw
->bus
.width
= fm10k_bus_width_pcie_x4
;
84 case FM10K_PCIE_LINK_WIDTH_8
:
85 hw
->bus
.width
= fm10k_bus_width_pcie_x8
;
88 hw
->bus
.width
= fm10k_bus_width_unknown
;
92 switch (link_status
& FM10K_PCIE_LINK_SPEED
) {
93 case FM10K_PCIE_LINK_SPEED_2500
:
94 hw
->bus
.speed
= fm10k_bus_speed_2500
;
96 case FM10K_PCIE_LINK_SPEED_5000
:
97 hw
->bus
.speed
= fm10k_bus_speed_5000
;
99 case FM10K_PCIE_LINK_SPEED_8000
:
100 hw
->bus
.speed
= fm10k_bus_speed_8000
;
103 hw
->bus
.speed
= fm10k_bus_speed_unknown
;
107 /* Get the negotiated PCIe maximum payload size for the PCIe function */
108 device_control
= fm10k_read_pci_cfg_word(hw
, FM10K_PCIE_DEV_CTRL
);
110 switch (device_control
& FM10K_PCIE_DEV_CTRL_PAYLOAD
) {
111 case FM10K_PCIE_DEV_CTRL_PAYLOAD_128
:
112 hw
->bus
.payload
= fm10k_bus_payload_128
;
114 case FM10K_PCIE_DEV_CTRL_PAYLOAD_256
:
115 hw
->bus
.payload
= fm10k_bus_payload_256
;
117 case FM10K_PCIE_DEV_CTRL_PAYLOAD_512
:
118 hw
->bus
.payload
= fm10k_bus_payload_512
;
121 hw
->bus
.payload
= fm10k_bus_payload_unknown
;
128 static u16
fm10k_get_pcie_msix_count_generic(struct fm10k_hw
*hw
)
132 /* read in value from MSI-X capability register */
133 msix_count
= fm10k_read_pci_cfg_word(hw
, FM10K_PCI_MSIX_MSG_CTRL
);
134 msix_count
&= FM10K_PCI_MSIX_MSG_CTRL_TBL_SZ_MASK
;
136 /* MSI-X count is zero-based in HW */
139 if (msix_count
> FM10K_MAX_MSIX_VECTORS
)
140 msix_count
= FM10K_MAX_MSIX_VECTORS
;
146 * fm10k_get_invariants_generic - Inits constant values
147 * @hw: pointer to the hardware structure
149 * Initialize the common invariants for the device.
151 s32
fm10k_get_invariants_generic(struct fm10k_hw
*hw
)
153 struct fm10k_mac_info
*mac
= &hw
->mac
;
155 /* initialize GLORT state to avoid any false hits */
156 mac
->dglort_map
= FM10K_DGLORTMAP_NONE
;
158 /* record maximum number of MSI-X vectors */
159 mac
->max_msix_vectors
= fm10k_get_pcie_msix_count_generic(hw
);
165 * fm10k_start_hw_generic - Prepare hardware for Tx/Rx
166 * @hw: pointer to hardware structure
168 * This function sets the Tx ready flag to indicate that the Tx path has
171 s32
fm10k_start_hw_generic(struct fm10k_hw
*hw
)
173 /* set flag indicating we are beginning Tx */
174 hw
->mac
.tx_ready
= true;
180 * fm10k_disable_queues_generic - Stop Tx/Rx queues
181 * @hw: pointer to hardware structure
182 * @q_cnt: number of queues to be disabled
185 s32
fm10k_disable_queues_generic(struct fm10k_hw
*hw
, u16 q_cnt
)
190 /* clear tx_ready to prevent any false hits for reset */
191 hw
->mac
.tx_ready
= false;
193 if (FM10K_REMOVED(hw
->hw_addr
))
196 /* clear the enable bit for all rings */
197 for (i
= 0; i
< q_cnt
; i
++) {
198 reg
= fm10k_read_reg(hw
, FM10K_TXDCTL(i
));
199 fm10k_write_reg(hw
, FM10K_TXDCTL(i
),
200 reg
& ~FM10K_TXDCTL_ENABLE
);
201 reg
= fm10k_read_reg(hw
, FM10K_RXQCTL(i
));
202 fm10k_write_reg(hw
, FM10K_RXQCTL(i
),
203 reg
& ~FM10K_RXQCTL_ENABLE
);
206 fm10k_write_flush(hw
);
209 /* loop through all queues to verify that they are all disabled */
210 for (i
= 0, time
= FM10K_QUEUE_DISABLE_TIMEOUT
; time
;) {
211 /* if we are at end of rings all rings are disabled */
215 /* if queue enables cleared, then move to next ring pair */
216 reg
= fm10k_read_reg(hw
, FM10K_TXDCTL(i
));
217 if (!~reg
|| !(reg
& FM10K_TXDCTL_ENABLE
)) {
218 reg
= fm10k_read_reg(hw
, FM10K_RXQCTL(i
));
219 if (!~reg
|| !(reg
& FM10K_RXQCTL_ENABLE
)) {
225 /* decrement time and wait 1 usec */
231 return FM10K_ERR_REQUESTS_PENDING
;
235 * fm10k_stop_hw_generic - Stop Tx/Rx units
236 * @hw: pointer to hardware structure
239 s32
fm10k_stop_hw_generic(struct fm10k_hw
*hw
)
241 return fm10k_disable_queues_generic(hw
, hw
->mac
.max_queues
);
245 * fm10k_read_hw_stats_32b - Reads value of 32-bit registers
246 * @hw: pointer to the hardware structure
247 * @addr: address of register containing a 32-bit value
248 * @stat: pointer to structure holding hw stat information
250 * Function reads the content of the register and returns the delta
251 * between the base and the current value.
253 u32
fm10k_read_hw_stats_32b(struct fm10k_hw
*hw
, u32 addr
,
254 struct fm10k_hw_stat
*stat
)
256 u32 delta
= fm10k_read_reg(hw
, addr
) - stat
->base_l
;
258 if (FM10K_REMOVED(hw
->hw_addr
))
265 * fm10k_read_hw_stats_48b - Reads value of 48-bit registers
266 * @hw: pointer to the hardware structure
267 * @addr: address of register containing the lower 32-bit value
268 * @stat: pointer to structure holding hw stat information
270 * Function reads the content of 2 registers, combined to represent a 48-bit
271 * statistical value. Extra processing is required to handle overflowing.
272 * Finally, a delta value is returned representing the difference between the
273 * values stored in registers and values stored in the statistic counters.
275 static u64
fm10k_read_hw_stats_48b(struct fm10k_hw
*hw
, u32 addr
,
276 struct fm10k_hw_stat
*stat
)
283 count_h
= fm10k_read_reg(hw
, addr
+ 1);
285 /* Check for overflow */
288 count_l
= fm10k_read_reg(hw
, addr
);
289 count_h
= fm10k_read_reg(hw
, addr
+ 1);
290 } while (count_h
!= count_tmp
);
292 delta
= ((u64
)(count_h
- stat
->base_h
) << 32) + count_l
;
293 delta
-= stat
->base_l
;
295 return delta
& FM10K_48_BIT_MASK
;
299 * fm10k_update_hw_base_48b - Updates 48-bit statistic base value
300 * @stat: pointer to the hardware statistic structure
301 * @delta: value to be updated into the hardware statistic structure
303 * Function receives a value and determines if an update is required based on
304 * a delta calculation. Only the base value will be updated.
306 static void fm10k_update_hw_base_48b(struct fm10k_hw_stat
*stat
, u64 delta
)
311 /* update lower 32 bits */
312 delta
+= stat
->base_l
;
313 stat
->base_l
= (u32
)delta
;
315 /* update upper 32 bits */
316 stat
->base_h
+= (u32
)(delta
>> 32);
320 * fm10k_update_hw_stats_tx_q - Updates TX queue statistics counters
321 * @hw: pointer to the hardware structure
322 * @q: pointer to the ring of hardware statistics queue
323 * @idx: index pointing to the start of the ring iteration
325 * Function updates the TX queue statistics counters that are related to the
328 static void fm10k_update_hw_stats_tx_q(struct fm10k_hw
*hw
,
329 struct fm10k_hw_stats_q
*q
,
332 u32 id_tx
, id_tx_prev
, tx_packets
;
335 /* Retrieve TX Owner Data */
336 id_tx
= fm10k_read_reg(hw
, FM10K_TXQCTL(idx
));
338 /* Process TX Ring */
340 tx_packets
= fm10k_read_hw_stats_32b(hw
, FM10K_QPTC(idx
),
344 tx_bytes
= fm10k_read_hw_stats_48b(hw
,
348 /* Re-Check Owner Data */
350 id_tx
= fm10k_read_reg(hw
, FM10K_TXQCTL(idx
));
351 } while ((id_tx
^ id_tx_prev
) & FM10K_TXQCTL_ID_MASK
);
353 /* drop non-ID bits and set VALID ID bit */
354 id_tx
&= FM10K_TXQCTL_ID_MASK
;
355 id_tx
|= FM10K_STAT_VALID
;
357 /* update packet counts */
358 if (q
->tx_stats_idx
== id_tx
) {
359 q
->tx_packets
.count
+= tx_packets
;
360 q
->tx_bytes
.count
+= tx_bytes
;
363 /* update bases and record ID */
364 fm10k_update_hw_base_32b(&q
->tx_packets
, tx_packets
);
365 fm10k_update_hw_base_48b(&q
->tx_bytes
, tx_bytes
);
367 q
->tx_stats_idx
= id_tx
;
371 * fm10k_update_hw_stats_rx_q - Updates RX queue statistics counters
372 * @hw: pointer to the hardware structure
373 * @q: pointer to the ring of hardware statistics queue
374 * @idx: index pointing to the start of the ring iteration
376 * Function updates the RX queue statistics counters that are related to the
379 static void fm10k_update_hw_stats_rx_q(struct fm10k_hw
*hw
,
380 struct fm10k_hw_stats_q
*q
,
383 u32 id_rx
, id_rx_prev
, rx_packets
, rx_drops
;
386 /* Retrieve RX Owner Data */
387 id_rx
= fm10k_read_reg(hw
, FM10K_RXQCTL(idx
));
389 /* Process RX Ring */
391 rx_drops
= fm10k_read_hw_stats_32b(hw
, FM10K_QPRDC(idx
),
394 rx_packets
= fm10k_read_hw_stats_32b(hw
, FM10K_QPRC(idx
),
398 rx_bytes
= fm10k_read_hw_stats_48b(hw
,
402 /* Re-Check Owner Data */
404 id_rx
= fm10k_read_reg(hw
, FM10K_RXQCTL(idx
));
405 } while ((id_rx
^ id_rx_prev
) & FM10K_RXQCTL_ID_MASK
);
407 /* drop non-ID bits and set VALID ID bit */
408 id_rx
&= FM10K_RXQCTL_ID_MASK
;
409 id_rx
|= FM10K_STAT_VALID
;
411 /* update packet counts */
412 if (q
->rx_stats_idx
== id_rx
) {
413 q
->rx_drops
.count
+= rx_drops
;
414 q
->rx_packets
.count
+= rx_packets
;
415 q
->rx_bytes
.count
+= rx_bytes
;
418 /* update bases and record ID */
419 fm10k_update_hw_base_32b(&q
->rx_drops
, rx_drops
);
420 fm10k_update_hw_base_32b(&q
->rx_packets
, rx_packets
);
421 fm10k_update_hw_base_48b(&q
->rx_bytes
, rx_bytes
);
423 q
->rx_stats_idx
= id_rx
;
427 * fm10k_update_hw_stats_q - Updates queue statistics counters
428 * @hw: pointer to the hardware structure
429 * @q: pointer to the ring of hardware statistics queue
430 * @idx: index pointing to the start of the ring iteration
431 * @count: number of queues to iterate over
433 * Function updates the queue statistics counters that are related to the
436 void fm10k_update_hw_stats_q(struct fm10k_hw
*hw
, struct fm10k_hw_stats_q
*q
,
441 for (i
= 0; i
< count
; i
++, idx
++, q
++) {
442 fm10k_update_hw_stats_tx_q(hw
, q
, idx
);
443 fm10k_update_hw_stats_rx_q(hw
, q
, idx
);
448 * fm10k_unbind_hw_stats_q - Unbind the queue counters from their queues
449 * @q: pointer to the ring of hardware statistics queue
450 * @idx: index pointing to the start of the ring iteration
451 * @count: number of queues to iterate over
453 * Function invalidates the index values for the queues so any updates that
454 * may have happened are ignored and the base for the queue stats is reset.
456 void fm10k_unbind_hw_stats_q(struct fm10k_hw_stats_q
*q
, u32 idx
, u32 count
)
460 for (i
= 0; i
< count
; i
++, idx
++, q
++) {
467 * fm10k_get_host_state_generic - Returns the state of the host
468 * @hw: pointer to hardware structure
469 * @host_ready: pointer to boolean value that will record host state
471 * This function will check the health of the mailbox and Tx queue 0
472 * in order to determine if we should report that the link is up or not.
474 s32
fm10k_get_host_state_generic(struct fm10k_hw
*hw
, bool *host_ready
)
476 struct fm10k_mbx_info
*mbx
= &hw
->mbx
;
477 struct fm10k_mac_info
*mac
= &hw
->mac
;
479 u32 txdctl
= fm10k_read_reg(hw
, FM10K_TXDCTL(0));
481 /* process upstream mailbox in case interrupts were disabled */
482 mbx
->ops
.process(hw
, mbx
);
484 /* If Tx is no longer enabled link should come down */
485 if (!(~txdctl
) || !(txdctl
& FM10K_TXDCTL_ENABLE
))
486 mac
->get_host_state
= true;
488 /* exit if not checking for link, or link cannot be changed */
489 if (!mac
->get_host_state
|| !(~txdctl
))
492 /* if we somehow dropped the Tx enable we should reset */
493 if (mac
->tx_ready
&& !(txdctl
& FM10K_TXDCTL_ENABLE
)) {
494 ret_val
= FM10K_ERR_RESET_REQUESTED
;
498 /* if Mailbox timed out we should request reset */
500 ret_val
= FM10K_ERR_RESET_REQUESTED
;
504 /* verify Mailbox is still open */
505 if (mbx
->state
!= FM10K_STATE_OPEN
)
508 /* interface cannot receive traffic without logical ports */
509 if (mac
->dglort_map
== FM10K_DGLORTMAP_NONE
) {
510 if (mac
->ops
.request_lport_map
)
511 ret_val
= mac
->ops
.request_lport_map(hw
);
516 /* if we passed all the tests above then the switch is ready and we no
517 * longer need to check for link
519 mac
->get_host_state
= false;
522 *host_ready
= !mac
->get_host_state
;