1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2013 - 2015 Intel Corporation
3 */
4
5 #include "fm10k_common.h"
6
7 /**
8 * fm10k_get_bus_info_generic - Generic set PCI bus info
9 * @hw: pointer to hardware structure
10 *
11 * Gets the PCI bus info (speed, width, type) then calls helper function to
12 * store this data within the fm10k_hw structure.
13 **/
fm10k_get_bus_info_generic(struct fm10k_hw * hw)14 STATIC s32 fm10k_get_bus_info_generic(struct fm10k_hw *hw)
15 {
16 u16 link_cap, link_status, device_cap, device_control;
17
18 DEBUGFUNC("fm10k_get_bus_info_generic");
19
20 /* Get the maximum link width and speed from PCIe config space */
21 link_cap = FM10K_READ_PCI_WORD(hw, FM10K_PCIE_LINK_CAP);
22
23 switch (link_cap & FM10K_PCIE_LINK_WIDTH) {
24 case FM10K_PCIE_LINK_WIDTH_1:
25 hw->bus_caps.width = fm10k_bus_width_pcie_x1;
26 break;
27 case FM10K_PCIE_LINK_WIDTH_2:
28 hw->bus_caps.width = fm10k_bus_width_pcie_x2;
29 break;
30 case FM10K_PCIE_LINK_WIDTH_4:
31 hw->bus_caps.width = fm10k_bus_width_pcie_x4;
32 break;
33 case FM10K_PCIE_LINK_WIDTH_8:
34 hw->bus_caps.width = fm10k_bus_width_pcie_x8;
35 break;
36 default:
37 hw->bus_caps.width = fm10k_bus_width_unknown;
38 break;
39 }
40
41 switch (link_cap & FM10K_PCIE_LINK_SPEED) {
42 case FM10K_PCIE_LINK_SPEED_2500:
43 hw->bus_caps.speed = fm10k_bus_speed_2500;
44 break;
45 case FM10K_PCIE_LINK_SPEED_5000:
46 hw->bus_caps.speed = fm10k_bus_speed_5000;
47 break;
48 case FM10K_PCIE_LINK_SPEED_8000:
49 hw->bus_caps.speed = fm10k_bus_speed_8000;
50 break;
51 default:
52 hw->bus_caps.speed = fm10k_bus_speed_unknown;
53 break;
54 }
55
56 /* Get the PCIe maximum payload size for the PCIe function */
57 device_cap = FM10K_READ_PCI_WORD(hw, FM10K_PCIE_DEV_CAP);
58
59 switch (device_cap & FM10K_PCIE_DEV_CAP_PAYLOAD) {
60 case FM10K_PCIE_DEV_CAP_PAYLOAD_128:
61 hw->bus_caps.payload = fm10k_bus_payload_128;
62 break;
63 case FM10K_PCIE_DEV_CAP_PAYLOAD_256:
64 hw->bus_caps.payload = fm10k_bus_payload_256;
65 break;
66 case FM10K_PCIE_DEV_CAP_PAYLOAD_512:
67 hw->bus_caps.payload = fm10k_bus_payload_512;
68 break;
69 default:
70 hw->bus_caps.payload = fm10k_bus_payload_unknown;
71 break;
72 }
73
74 /* Get the negotiated link width and speed from PCIe config space */
75 link_status = FM10K_READ_PCI_WORD(hw, FM10K_PCIE_LINK_STATUS);
76
77 switch (link_status & FM10K_PCIE_LINK_WIDTH) {
78 case FM10K_PCIE_LINK_WIDTH_1:
79 hw->bus.width = fm10k_bus_width_pcie_x1;
80 break;
81 case FM10K_PCIE_LINK_WIDTH_2:
82 hw->bus.width = fm10k_bus_width_pcie_x2;
83 break;
84 case FM10K_PCIE_LINK_WIDTH_4:
85 hw->bus.width = fm10k_bus_width_pcie_x4;
86 break;
87 case FM10K_PCIE_LINK_WIDTH_8:
88 hw->bus.width = fm10k_bus_width_pcie_x8;
89 break;
90 default:
91 hw->bus.width = fm10k_bus_width_unknown;
92 break;
93 }
94
95 switch (link_status & FM10K_PCIE_LINK_SPEED) {
96 case FM10K_PCIE_LINK_SPEED_2500:
97 hw->bus.speed = fm10k_bus_speed_2500;
98 break;
99 case FM10K_PCIE_LINK_SPEED_5000:
100 hw->bus.speed = fm10k_bus_speed_5000;
101 break;
102 case FM10K_PCIE_LINK_SPEED_8000:
103 hw->bus.speed = fm10k_bus_speed_8000;
104 break;
105 default:
106 hw->bus.speed = fm10k_bus_speed_unknown;
107 break;
108 }
109
110 /* Get the negotiated PCIe maximum payload size for the PCIe function */
111 device_control = FM10K_READ_PCI_WORD(hw, FM10K_PCIE_DEV_CTRL);
112
113 switch (device_control & FM10K_PCIE_DEV_CTRL_PAYLOAD) {
114 case FM10K_PCIE_DEV_CTRL_PAYLOAD_128:
115 hw->bus.payload = fm10k_bus_payload_128;
116 break;
117 case FM10K_PCIE_DEV_CTRL_PAYLOAD_256:
118 hw->bus.payload = fm10k_bus_payload_256;
119 break;
120 case FM10K_PCIE_DEV_CTRL_PAYLOAD_512:
121 hw->bus.payload = fm10k_bus_payload_512;
122 break;
123 default:
124 hw->bus.payload = fm10k_bus_payload_unknown;
125 break;
126 }
127
128 return FM10K_SUCCESS;
129 }
130
fm10k_get_pcie_msix_count_generic(struct fm10k_hw * hw)131 u16 fm10k_get_pcie_msix_count_generic(struct fm10k_hw *hw)
132 {
133 u16 msix_count;
134
135 DEBUGFUNC("fm10k_get_pcie_msix_count_generic");
136
137 /* read in value from MSI-X capability register */
138 msix_count = FM10K_READ_PCI_WORD(hw, FM10K_PCI_MSIX_MSG_CTRL);
139 msix_count &= FM10K_PCI_MSIX_MSG_CTRL_TBL_SZ_MASK;
140
141 /* MSI-X count is zero-based in HW */
142 msix_count++;
143
144 if (msix_count > FM10K_MAX_MSIX_VECTORS)
145 msix_count = FM10K_MAX_MSIX_VECTORS;
146
147 return msix_count;
148 }
149
150 /**
151 * fm10k_init_ops_generic - Inits function ptrs
152 * @hw: pointer to the hardware structure
153 *
154 * Initialize the function pointers.
155 **/
fm10k_init_ops_generic(struct fm10k_hw * hw)156 s32 fm10k_init_ops_generic(struct fm10k_hw *hw)
157 {
158 struct fm10k_mac_info *mac = &hw->mac;
159
160 DEBUGFUNC("fm10k_init_ops_generic");
161
162 /* MAC */
163 mac->ops.get_bus_info = &fm10k_get_bus_info_generic;
164
165 /* initialize GLORT state to avoid any false hits */
166 mac->dglort_map = FM10K_DGLORTMAP_NONE;
167
168 return FM10K_SUCCESS;
169 }
170
171 /**
172 * fm10k_start_hw_generic - Prepare hardware for Tx/Rx
173 * @hw: pointer to hardware structure
174 *
175 * This function sets the Tx ready flag to indicate that the Tx path has
176 * been initialized.
177 **/
fm10k_start_hw_generic(struct fm10k_hw * hw)178 s32 fm10k_start_hw_generic(struct fm10k_hw *hw)
179 {
180 DEBUGFUNC("fm10k_start_hw_generic");
181
182 /* set flag indicating we are beginning Tx */
183 hw->mac.tx_ready = true;
184
185 return FM10K_SUCCESS;
186 }
187
188 /**
189 * fm10k_disable_queues_generic - Stop Tx/Rx queues
190 * @hw: pointer to hardware structure
191 * @q_cnt: number of queues to be disabled
192 *
193 **/
fm10k_disable_queues_generic(struct fm10k_hw * hw,u16 q_cnt)194 s32 fm10k_disable_queues_generic(struct fm10k_hw *hw, u16 q_cnt)
195 {
196 u32 reg;
197 u16 i, time;
198
199 DEBUGFUNC("fm10k_disable_queues_generic");
200
201 /* clear tx_ready to prevent any false hits for reset */
202 hw->mac.tx_ready = false;
203
204 if (FM10K_REMOVED(hw->hw_addr))
205 return FM10K_SUCCESS;
206
207 /* clear the enable bit for all rings */
208 for (i = 0; i < q_cnt; i++) {
209 reg = FM10K_READ_REG(hw, FM10K_TXDCTL(i));
210 FM10K_WRITE_REG(hw, FM10K_TXDCTL(i),
211 reg & ~FM10K_TXDCTL_ENABLE);
212 reg = FM10K_READ_REG(hw, FM10K_RXQCTL(i));
213 FM10K_WRITE_REG(hw, FM10K_RXQCTL(i),
214 reg & ~FM10K_RXQCTL_ENABLE);
215 }
216
217 FM10K_WRITE_FLUSH(hw);
218 usec_delay(1);
219
220 /* loop through all queues to verify that they are all disabled */
221 for (i = 0, time = FM10K_QUEUE_DISABLE_TIMEOUT; time;) {
222 /* if we are at end of rings all rings are disabled */
223 if (i == q_cnt)
224 return FM10K_SUCCESS;
225
226 /* if queue enables cleared, then move to next ring pair */
227 reg = FM10K_READ_REG(hw, FM10K_TXDCTL(i));
228 if (!~reg || !(reg & FM10K_TXDCTL_ENABLE)) {
229 reg = FM10K_READ_REG(hw, FM10K_RXQCTL(i));
230 if (!~reg || !(reg & FM10K_RXQCTL_ENABLE)) {
231 i++;
232 continue;
233 }
234 }
235
236 /* decrement time and wait 1 usec */
237 time--;
238 if (time)
239 usec_delay(1);
240 }
241
242 return FM10K_ERR_REQUESTS_PENDING;
243 }
244
245 /**
246 * fm10k_stop_hw_generic - Stop Tx/Rx units
247 * @hw: pointer to hardware structure
248 *
249 **/
fm10k_stop_hw_generic(struct fm10k_hw * hw)250 s32 fm10k_stop_hw_generic(struct fm10k_hw *hw)
251 {
252 DEBUGFUNC("fm10k_stop_hw_generic");
253
254 return fm10k_disable_queues_generic(hw, hw->mac.max_queues);
255 }
256
257 /**
258 * fm10k_read_hw_stats_32b - Reads value of 32-bit registers
259 * @hw: pointer to the hardware structure
260 * @addr: address of register containing a 32-bit value
261 *
262 * Function reads the content of the register and returns the delta
263 * between the base and the current value.
264 * **/
fm10k_read_hw_stats_32b(struct fm10k_hw * hw,u32 addr,struct fm10k_hw_stat * stat)265 u32 fm10k_read_hw_stats_32b(struct fm10k_hw *hw, u32 addr,
266 struct fm10k_hw_stat *stat)
267 {
268 u32 delta = FM10K_READ_REG(hw, addr) - stat->base_l;
269
270 DEBUGFUNC("fm10k_read_hw_stats_32b");
271
272 if (FM10K_REMOVED(hw->hw_addr))
273 stat->base_h = 0;
274
275 return delta;
276 }
277
278 /**
279 * fm10k_read_hw_stats_48b - Reads value of 48-bit registers
280 * @hw: pointer to the hardware structure
281 * @addr: address of register containing the lower 32-bit value
282 *
283 * Function reads the content of 2 registers, combined to represent a 48-bit
284 * statistical value. Extra processing is required to handle overflowing.
285 * Finally, a delta value is returned representing the difference between the
286 * values stored in registers and values stored in the statistic counters.
287 * **/
fm10k_read_hw_stats_48b(struct fm10k_hw * hw,u32 addr,struct fm10k_hw_stat * stat)288 STATIC u64 fm10k_read_hw_stats_48b(struct fm10k_hw *hw, u32 addr,
289 struct fm10k_hw_stat *stat)
290 {
291 u32 count_l;
292 u32 count_h;
293 u32 count_tmp;
294 u64 delta;
295
296 DEBUGFUNC("fm10k_read_hw_stats_48b");
297
298 count_h = FM10K_READ_REG(hw, addr + 1);
299
300 /* Check for overflow */
301 do {
302 count_tmp = count_h;
303 count_l = FM10K_READ_REG(hw, addr);
304 count_h = FM10K_READ_REG(hw, addr + 1);
305 } while (count_h != count_tmp);
306
307 delta = ((u64)(count_h - stat->base_h) << 32) + count_l;
308 delta -= stat->base_l;
309
310 return delta & FM10K_48_BIT_MASK;
311 }
312
313 /**
314 * fm10k_update_hw_base_48b - Updates 48-bit statistic base value
315 * @stat: pointer to the hardware statistic structure
316 * @delta: value to be updated into the hardware statistic structure
317 *
318 * Function receives a value and determines if an update is required based on
319 * a delta calculation. Only the base value will be updated.
320 **/
fm10k_update_hw_base_48b(struct fm10k_hw_stat * stat,u64 delta)321 STATIC void fm10k_update_hw_base_48b(struct fm10k_hw_stat *stat, u64 delta)
322 {
323 DEBUGFUNC("fm10k_update_hw_base_48b");
324
325 if (!delta)
326 return;
327
328 /* update lower 32 bits */
329 delta += stat->base_l;
330 stat->base_l = (u32)delta;
331
332 /* update upper 32 bits */
333 stat->base_h += (u32)(delta >> 32);
334 }
335
336 /**
337 * fm10k_update_hw_stats_tx_q - Updates TX queue statistics counters
338 * @hw: pointer to the hardware structure
339 * @q: pointer to the ring of hardware statistics queue
340 * @idx: index pointing to the start of the ring iteration
341 *
342 * Function updates the TX queue statistics counters that are related to the
343 * hardware.
344 **/
fm10k_update_hw_stats_tx_q(struct fm10k_hw * hw,struct fm10k_hw_stats_q * q,u32 idx)345 STATIC void fm10k_update_hw_stats_tx_q(struct fm10k_hw *hw,
346 struct fm10k_hw_stats_q *q,
347 u32 idx)
348 {
349 u32 id_tx, id_tx_prev, tx_packets;
350 u64 tx_bytes = 0;
351
352 DEBUGFUNC("fm10k_update_hw_stats_tx_q");
353
354 /* Retrieve TX Owner Data */
355 id_tx = FM10K_READ_REG(hw, FM10K_TXQCTL(idx));
356
357 /* Process TX Ring */
358 do {
359 tx_packets = fm10k_read_hw_stats_32b(hw, FM10K_QPTC(idx),
360 &q->tx_packets);
361
362 if (tx_packets)
363 tx_bytes = fm10k_read_hw_stats_48b(hw,
364 FM10K_QBTC_L(idx),
365 &q->tx_bytes);
366
367 /* Re-Check Owner Data */
368 id_tx_prev = id_tx;
369 id_tx = FM10K_READ_REG(hw, FM10K_TXQCTL(idx));
370 } while ((id_tx ^ id_tx_prev) & FM10K_TXQCTL_ID_MASK);
371
372 /* drop non-ID bits and set VALID ID bit */
373 id_tx &= FM10K_TXQCTL_ID_MASK;
374 id_tx |= FM10K_STAT_VALID;
375
376 /* update packet counts */
377 if (q->tx_stats_idx == id_tx) {
378 q->tx_packets.count += tx_packets;
379 q->tx_bytes.count += tx_bytes;
380 }
381
382 /* update bases and record ID */
383 fm10k_update_hw_base_32b(&q->tx_packets, tx_packets);
384 fm10k_update_hw_base_48b(&q->tx_bytes, tx_bytes);
385
386 q->tx_stats_idx = id_tx;
387 }
388
389 /**
390 * fm10k_update_hw_stats_rx_q - Updates RX queue statistics counters
391 * @hw: pointer to the hardware structure
392 * @q: pointer to the ring of hardware statistics queue
393 * @idx: index pointing to the start of the ring iteration
394 *
395 * Function updates the RX queue statistics counters that are related to the
396 * hardware.
397 **/
fm10k_update_hw_stats_rx_q(struct fm10k_hw * hw,struct fm10k_hw_stats_q * q,u32 idx)398 STATIC void fm10k_update_hw_stats_rx_q(struct fm10k_hw *hw,
399 struct fm10k_hw_stats_q *q,
400 u32 idx)
401 {
402 u32 id_rx, id_rx_prev, rx_packets, rx_drops;
403 u64 rx_bytes = 0;
404
405 DEBUGFUNC("fm10k_update_hw_stats_rx_q");
406
407 /* Retrieve RX Owner Data */
408 id_rx = FM10K_READ_REG(hw, FM10K_RXQCTL(idx));
409
410 /* Process RX Ring */
411 do {
412 rx_drops = fm10k_read_hw_stats_32b(hw, FM10K_QPRDC(idx),
413 &q->rx_drops);
414
415 rx_packets = fm10k_read_hw_stats_32b(hw, FM10K_QPRC(idx),
416 &q->rx_packets);
417
418 if (rx_packets)
419 rx_bytes = fm10k_read_hw_stats_48b(hw,
420 FM10K_QBRC_L(idx),
421 &q->rx_bytes);
422
423 /* Re-Check Owner Data */
424 id_rx_prev = id_rx;
425 id_rx = FM10K_READ_REG(hw, FM10K_RXQCTL(idx));
426 } while ((id_rx ^ id_rx_prev) & FM10K_RXQCTL_ID_MASK);
427
428 /* drop non-ID bits and set VALID ID bit */
429 id_rx &= FM10K_RXQCTL_ID_MASK;
430 id_rx |= FM10K_STAT_VALID;
431
432 /* update packet counts */
433 if (q->rx_stats_idx == id_rx) {
434 q->rx_drops.count += rx_drops;
435 q->rx_packets.count += rx_packets;
436 q->rx_bytes.count += rx_bytes;
437 }
438
439 /* update bases and record ID */
440 fm10k_update_hw_base_32b(&q->rx_drops, rx_drops);
441 fm10k_update_hw_base_32b(&q->rx_packets, rx_packets);
442 fm10k_update_hw_base_48b(&q->rx_bytes, rx_bytes);
443
444 q->rx_stats_idx = id_rx;
445 }
446
447 /**
448 * fm10k_update_hw_stats_q - Updates queue statistics counters
449 * @hw: pointer to the hardware structure
450 * @q: pointer to the ring of hardware statistics queue
451 * @idx: index pointing to the start of the ring iteration
452 * @count: number of queues to iterate over
453 *
454 * Function updates the queue statistics counters that are related to the
455 * hardware.
456 **/
fm10k_update_hw_stats_q(struct fm10k_hw * hw,struct fm10k_hw_stats_q * q,u32 idx,u32 count)457 void fm10k_update_hw_stats_q(struct fm10k_hw *hw, struct fm10k_hw_stats_q *q,
458 u32 idx, u32 count)
459 {
460 u32 i;
461
462 DEBUGFUNC("fm10k_update_hw_stats_q");
463
464 for (i = 0; i < count; i++, idx++, q++) {
465 fm10k_update_hw_stats_tx_q(hw, q, idx);
466 fm10k_update_hw_stats_rx_q(hw, q, idx);
467 }
468 }
469
470 /**
471 * fm10k_unbind_hw_stats_q - Unbind the queue counters from their queues
472 * @hw: pointer to the hardware structure
473 * @q: pointer to the ring of hardware statistics queue
474 * @idx: index pointing to the start of the ring iteration
475 * @count: number of queues to iterate over
476 *
477 * Function invalidates the index values for the queues so any updates that
478 * may have happened are ignored and the base for the queue stats is reset.
479 **/
fm10k_unbind_hw_stats_q(struct fm10k_hw_stats_q * q,u32 idx,u32 count)480 void fm10k_unbind_hw_stats_q(struct fm10k_hw_stats_q *q, u32 idx, u32 count)
481 {
482 u32 i;
483
484 for (i = 0; i < count; i++, idx++, q++) {
485 q->rx_stats_idx = 0;
486 q->tx_stats_idx = 0;
487 }
488 }
489
490 /**
491 * fm10k_get_host_state_generic - Returns the state of the host
492 * @hw: pointer to hardware structure
493 * @host_ready: pointer to boolean value that will record host state
494 *
495 * This function will check the health of the mailbox and Tx queue 0
496 * in order to determine if we should report that the link is up or not.
497 **/
fm10k_get_host_state_generic(struct fm10k_hw * hw,bool * host_ready)498 s32 fm10k_get_host_state_generic(struct fm10k_hw *hw, bool *host_ready)
499 {
500 struct fm10k_mbx_info *mbx = &hw->mbx;
501 struct fm10k_mac_info *mac = &hw->mac;
502 s32 ret_val = FM10K_SUCCESS;
503 u32 txdctl = FM10K_READ_REG(hw, FM10K_TXDCTL(0));
504
505 DEBUGFUNC("fm10k_get_host_state_generic");
506
507 /* process upstream mailbox in case interrupts were disabled */
508 mbx->ops.process(hw, mbx);
509
510 /* If Tx is no longer enabled link should come down */
511 if (!(~txdctl) || !(txdctl & FM10K_TXDCTL_ENABLE))
512 mac->get_host_state = true;
513
514 /* exit if not checking for link, or link cannot be changed */
515 if (!mac->get_host_state || !(~txdctl))
516 goto out;
517
518 /* if we somehow dropped the Tx enable we should reset */
519 if (mac->tx_ready && !(txdctl & FM10K_TXDCTL_ENABLE)) {
520 ret_val = FM10K_ERR_RESET_REQUESTED;
521 goto out;
522 }
523
524 /* if Mailbox timed out we should request reset */
525 if (!mbx->timeout) {
526 ret_val = FM10K_ERR_RESET_REQUESTED;
527 goto out;
528 }
529
530 /* verify Mailbox is still valid */
531 if (!mbx->ops.tx_ready(mbx, FM10K_VFMBX_MSG_MTU))
532 goto out;
533
534 /* interface cannot receive traffic without logical ports */
535 if (mac->dglort_map == FM10K_DGLORTMAP_NONE) {
536 if (mac->ops.request_lport_map)
537 ret_val = mac->ops.request_lport_map(hw);
538
539 goto out;
540 }
541
542 /* if we passed all the tests above then the switch is ready and we no
543 * longer need to check for link
544 */
545 mac->get_host_state = false;
546
547 out:
548 *host_ready = !mac->get_host_state;
549 return ret_val;
550 }
551