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