xref: /linux/drivers/net/ethernet/intel/fm10k/fm10k_common.c (revision 3d0fe49454652117522f60bfbefb978ba0e5300b)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2013 - 2018 Intel Corporation. */
3 
4 #include "fm10k_common.h"
5 
6 /**
7  *  fm10k_get_bus_info_generic - Generic set PCI bus info
8  *  @hw: pointer to hardware structure
9  *
10  *  Gets the PCI bus info (speed, width, type) then calls helper function to
11  *  store this data within the fm10k_hw structure.
12  **/
13 s32 fm10k_get_bus_info_generic(struct fm10k_hw *hw)
14 {
15 	u16 link_cap, link_status, device_cap, device_control;
16 
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);
19 
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;
23 		break;
24 	case FM10K_PCIE_LINK_WIDTH_2:
25 		hw->bus_caps.width = fm10k_bus_width_pcie_x2;
26 		break;
27 	case FM10K_PCIE_LINK_WIDTH_4:
28 		hw->bus_caps.width = fm10k_bus_width_pcie_x4;
29 		break;
30 	case FM10K_PCIE_LINK_WIDTH_8:
31 		hw->bus_caps.width = fm10k_bus_width_pcie_x8;
32 		break;
33 	default:
34 		hw->bus_caps.width = fm10k_bus_width_unknown;
35 		break;
36 	}
37 
38 	switch (link_cap & FM10K_PCIE_LINK_SPEED) {
39 	case FM10K_PCIE_LINK_SPEED_2500:
40 		hw->bus_caps.speed = fm10k_bus_speed_2500;
41 		break;
42 	case FM10K_PCIE_LINK_SPEED_5000:
43 		hw->bus_caps.speed = fm10k_bus_speed_5000;
44 		break;
45 	case FM10K_PCIE_LINK_SPEED_8000:
46 		hw->bus_caps.speed = fm10k_bus_speed_8000;
47 		break;
48 	default:
49 		hw->bus_caps.speed = fm10k_bus_speed_unknown;
50 		break;
51 	}
52 
53 	/* Get the PCIe maximum payload size for the PCIe function */
54 	device_cap = fm10k_read_pci_cfg_word(hw, FM10K_PCIE_DEV_CAP);
55 
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;
59 		break;
60 	case FM10K_PCIE_DEV_CAP_PAYLOAD_256:
61 		hw->bus_caps.payload = fm10k_bus_payload_256;
62 		break;
63 	case FM10K_PCIE_DEV_CAP_PAYLOAD_512:
64 		hw->bus_caps.payload = fm10k_bus_payload_512;
65 		break;
66 	default:
67 		hw->bus_caps.payload = fm10k_bus_payload_unknown;
68 		break;
69 	}
70 
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);
73 
74 	switch (link_status & FM10K_PCIE_LINK_WIDTH) {
75 	case FM10K_PCIE_LINK_WIDTH_1:
76 		hw->bus.width = fm10k_bus_width_pcie_x1;
77 		break;
78 	case FM10K_PCIE_LINK_WIDTH_2:
79 		hw->bus.width = fm10k_bus_width_pcie_x2;
80 		break;
81 	case FM10K_PCIE_LINK_WIDTH_4:
82 		hw->bus.width = fm10k_bus_width_pcie_x4;
83 		break;
84 	case FM10K_PCIE_LINK_WIDTH_8:
85 		hw->bus.width = fm10k_bus_width_pcie_x8;
86 		break;
87 	default:
88 		hw->bus.width = fm10k_bus_width_unknown;
89 		break;
90 	}
91 
92 	switch (link_status & FM10K_PCIE_LINK_SPEED) {
93 	case FM10K_PCIE_LINK_SPEED_2500:
94 		hw->bus.speed = fm10k_bus_speed_2500;
95 		break;
96 	case FM10K_PCIE_LINK_SPEED_5000:
97 		hw->bus.speed = fm10k_bus_speed_5000;
98 		break;
99 	case FM10K_PCIE_LINK_SPEED_8000:
100 		hw->bus.speed = fm10k_bus_speed_8000;
101 		break;
102 	default:
103 		hw->bus.speed = fm10k_bus_speed_unknown;
104 		break;
105 	}
106 
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);
109 
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;
113 		break;
114 	case FM10K_PCIE_DEV_CTRL_PAYLOAD_256:
115 		hw->bus.payload = fm10k_bus_payload_256;
116 		break;
117 	case FM10K_PCIE_DEV_CTRL_PAYLOAD_512:
118 		hw->bus.payload = fm10k_bus_payload_512;
119 		break;
120 	default:
121 		hw->bus.payload = fm10k_bus_payload_unknown;
122 		break;
123 	}
124 
125 	return 0;
126 }
127 
128 static u16 fm10k_get_pcie_msix_count_generic(struct fm10k_hw *hw)
129 {
130 	u16 msix_count;
131 
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;
135 
136 	/* MSI-X count is zero-based in HW */
137 	msix_count++;
138 
139 	if (msix_count > FM10K_MAX_MSIX_VECTORS)
140 		msix_count = FM10K_MAX_MSIX_VECTORS;
141 
142 	return msix_count;
143 }
144 
145 /**
146  *  fm10k_get_invariants_generic - Inits constant values
147  *  @hw: pointer to the hardware structure
148  *
149  *  Initialize the common invariants for the device.
150  **/
151 s32 fm10k_get_invariants_generic(struct fm10k_hw *hw)
152 {
153 	struct fm10k_mac_info *mac = &hw->mac;
154 
155 	/* initialize GLORT state to avoid any false hits */
156 	mac->dglort_map = FM10K_DGLORTMAP_NONE;
157 
158 	/* record maximum number of MSI-X vectors */
159 	mac->max_msix_vectors = fm10k_get_pcie_msix_count_generic(hw);
160 
161 	return 0;
162 }
163 
164 /**
165  *  fm10k_start_hw_generic - Prepare hardware for Tx/Rx
166  *  @hw: pointer to hardware structure
167  *
168  *  This function sets the Tx ready flag to indicate that the Tx path has
169  *  been initialized.
170  **/
171 s32 fm10k_start_hw_generic(struct fm10k_hw *hw)
172 {
173 	/* set flag indicating we are beginning Tx */
174 	hw->mac.tx_ready = true;
175 
176 	return 0;
177 }
178 
179 /**
180  *  fm10k_disable_queues_generic - Stop Tx/Rx queues
181  *  @hw: pointer to hardware structure
182  *  @q_cnt: number of queues to be disabled
183  *
184  **/
185 s32 fm10k_disable_queues_generic(struct fm10k_hw *hw, u16 q_cnt)
186 {
187 	u32 reg;
188 	u16 i, time;
189 
190 	/* clear tx_ready to prevent any false hits for reset */
191 	hw->mac.tx_ready = false;
192 
193 	if (FM10K_REMOVED(hw->hw_addr))
194 		return 0;
195 
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);
204 	}
205 
206 	fm10k_write_flush(hw);
207 	udelay(1);
208 
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 */
212 		if (i == q_cnt)
213 			return 0;
214 
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)) {
220 				i++;
221 				continue;
222 			}
223 		}
224 
225 		/* decrement time and wait 1 usec */
226 		time--;
227 		if (time)
228 			udelay(1);
229 	}
230 
231 	return FM10K_ERR_REQUESTS_PENDING;
232 }
233 
234 /**
235  *  fm10k_stop_hw_generic - Stop Tx/Rx units
236  *  @hw: pointer to hardware structure
237  *
238  **/
239 s32 fm10k_stop_hw_generic(struct fm10k_hw *hw)
240 {
241 	return fm10k_disable_queues_generic(hw, hw->mac.max_queues);
242 }
243 
244 /**
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
249  *
250  *  Function reads the content of the register and returns the delta
251  *  between the base and the current value.
252  *  **/
253 u32 fm10k_read_hw_stats_32b(struct fm10k_hw *hw, u32 addr,
254 			    struct fm10k_hw_stat *stat)
255 {
256 	u32 delta = fm10k_read_reg(hw, addr) - stat->base_l;
257 
258 	if (FM10K_REMOVED(hw->hw_addr))
259 		stat->base_h = 0;
260 
261 	return delta;
262 }
263 
264 /**
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
269  *
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.
274  *  **/
275 static u64 fm10k_read_hw_stats_48b(struct fm10k_hw *hw, u32 addr,
276 				   struct fm10k_hw_stat *stat)
277 {
278 	u32 count_l;
279 	u32 count_h;
280 	u32 count_tmp;
281 	u64 delta;
282 
283 	count_h = fm10k_read_reg(hw, addr + 1);
284 
285 	/* Check for overflow */
286 	do {
287 		count_tmp = count_h;
288 		count_l = fm10k_read_reg(hw, addr);
289 		count_h = fm10k_read_reg(hw, addr + 1);
290 	} while (count_h != count_tmp);
291 
292 	delta = ((u64)(count_h - stat->base_h) << 32) + count_l;
293 	delta -= stat->base_l;
294 
295 	return delta & FM10K_48_BIT_MASK;
296 }
297 
298 /**
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
302  *
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.
305  **/
306 static void fm10k_update_hw_base_48b(struct fm10k_hw_stat *stat, u64 delta)
307 {
308 	if (!delta)
309 		return;
310 
311 	/* update lower 32 bits */
312 	delta += stat->base_l;
313 	stat->base_l = (u32)delta;
314 
315 	/* update upper 32 bits */
316 	stat->base_h += (u32)(delta >> 32);
317 }
318 
319 /**
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
324  *
325  *  Function updates the TX queue statistics counters that are related to the
326  *  hardware.
327  **/
328 static void fm10k_update_hw_stats_tx_q(struct fm10k_hw *hw,
329 				       struct fm10k_hw_stats_q *q,
330 				       u32 idx)
331 {
332 	u32 id_tx, id_tx_prev, tx_packets;
333 	u64 tx_bytes = 0;
334 
335 	/* Retrieve TX Owner Data */
336 	id_tx = fm10k_read_reg(hw, FM10K_TXQCTL(idx));
337 
338 	/* Process TX Ring */
339 	do {
340 		tx_packets = fm10k_read_hw_stats_32b(hw, FM10K_QPTC(idx),
341 						     &q->tx_packets);
342 
343 		if (tx_packets)
344 			tx_bytes = fm10k_read_hw_stats_48b(hw,
345 							   FM10K_QBTC_L(idx),
346 							   &q->tx_bytes);
347 
348 		/* Re-Check Owner Data */
349 		id_tx_prev = id_tx;
350 		id_tx = fm10k_read_reg(hw, FM10K_TXQCTL(idx));
351 	} while ((id_tx ^ id_tx_prev) & FM10K_TXQCTL_ID_MASK);
352 
353 	/* drop non-ID bits and set VALID ID bit */
354 	id_tx &= FM10K_TXQCTL_ID_MASK;
355 	id_tx |= FM10K_STAT_VALID;
356 
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;
361 	}
362 
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);
366 
367 	q->tx_stats_idx = id_tx;
368 }
369 
370 /**
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
375  *
376  *  Function updates the RX queue statistics counters that are related to the
377  *  hardware.
378  **/
379 static void fm10k_update_hw_stats_rx_q(struct fm10k_hw *hw,
380 				       struct fm10k_hw_stats_q *q,
381 				       u32 idx)
382 {
383 	u32 id_rx, id_rx_prev, rx_packets, rx_drops;
384 	u64 rx_bytes = 0;
385 
386 	/* Retrieve RX Owner Data */
387 	id_rx = fm10k_read_reg(hw, FM10K_RXQCTL(idx));
388 
389 	/* Process RX Ring */
390 	do {
391 		rx_drops = fm10k_read_hw_stats_32b(hw, FM10K_QPRDC(idx),
392 						   &q->rx_drops);
393 
394 		rx_packets = fm10k_read_hw_stats_32b(hw, FM10K_QPRC(idx),
395 						     &q->rx_packets);
396 
397 		if (rx_packets)
398 			rx_bytes = fm10k_read_hw_stats_48b(hw,
399 							   FM10K_QBRC_L(idx),
400 							   &q->rx_bytes);
401 
402 		/* Re-Check Owner Data */
403 		id_rx_prev = id_rx;
404 		id_rx = fm10k_read_reg(hw, FM10K_RXQCTL(idx));
405 	} while ((id_rx ^ id_rx_prev) & FM10K_RXQCTL_ID_MASK);
406 
407 	/* drop non-ID bits and set VALID ID bit */
408 	id_rx &= FM10K_RXQCTL_ID_MASK;
409 	id_rx |= FM10K_STAT_VALID;
410 
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;
416 	}
417 
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);
422 
423 	q->rx_stats_idx = id_rx;
424 }
425 
426 /**
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
432  *
433  *  Function updates the queue statistics counters that are related to the
434  *  hardware.
435  **/
436 void fm10k_update_hw_stats_q(struct fm10k_hw *hw, struct fm10k_hw_stats_q *q,
437 			     u32 idx, u32 count)
438 {
439 	u32 i;
440 
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);
444 	}
445 }
446 
447 /**
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
452  *
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.
455  **/
456 void fm10k_unbind_hw_stats_q(struct fm10k_hw_stats_q *q, u32 idx, u32 count)
457 {
458 	u32 i;
459 
460 	for (i = 0; i < count; i++, idx++, q++) {
461 		q->rx_stats_idx = 0;
462 		q->tx_stats_idx = 0;
463 	}
464 }
465 
466 /**
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
470  *
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.
473  **/
474 s32 fm10k_get_host_state_generic(struct fm10k_hw *hw, bool *host_ready)
475 {
476 	struct fm10k_mbx_info *mbx = &hw->mbx;
477 	struct fm10k_mac_info *mac = &hw->mac;
478 	s32 ret_val = 0;
479 	u32 txdctl = fm10k_read_reg(hw, FM10K_TXDCTL(0));
480 
481 	/* process upstream mailbox in case interrupts were disabled */
482 	mbx->ops.process(hw, mbx);
483 
484 	/* If Tx is no longer enabled link should come down */
485 	if (!(~txdctl) || !(txdctl & FM10K_TXDCTL_ENABLE))
486 		mac->get_host_state = true;
487 
488 	/* exit if not checking for link, or link cannot be changed */
489 	if (!mac->get_host_state || !(~txdctl))
490 		goto out;
491 
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;
495 		goto out;
496 	}
497 
498 	/* if Mailbox timed out we should request reset */
499 	if (!mbx->timeout) {
500 		ret_val = FM10K_ERR_RESET_REQUESTED;
501 		goto out;
502 	}
503 
504 	/* verify Mailbox is still open */
505 	if (mbx->state != FM10K_STATE_OPEN)
506 		goto out;
507 
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);
512 
513 		goto out;
514 	}
515 
516 	/* if we passed all the tests above then the switch is ready and we no
517 	 * longer need to check for link
518 	 */
519 	mac->get_host_state = false;
520 
521 out:
522 	*host_ready = !mac->get_host_state;
523 	return ret_val;
524 }
525