This source file includes following definitions.
- fm10k_get_bus_info_generic
- fm10k_get_pcie_msix_count_generic
- fm10k_get_invariants_generic
- fm10k_start_hw_generic
- fm10k_disable_queues_generic
- fm10k_stop_hw_generic
- fm10k_read_hw_stats_32b
- fm10k_read_hw_stats_48b
- fm10k_update_hw_base_48b
- fm10k_update_hw_stats_tx_q
- fm10k_update_hw_stats_rx_q
- fm10k_update_hw_stats_q
- fm10k_unbind_hw_stats_q
- fm10k_get_host_state_generic
1
2
3
4 #include "fm10k_common.h"
5
6
7
8
9
10
11
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
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
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
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
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
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
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
147
148
149
150
151 s32 fm10k_get_invariants_generic(struct fm10k_hw *hw)
152 {
153 struct fm10k_mac_info *mac = &hw->mac;
154
155
156 mac->dglort_map = FM10K_DGLORTMAP_NONE;
157
158
159 mac->max_msix_vectors = fm10k_get_pcie_msix_count_generic(hw);
160
161 return 0;
162 }
163
164
165
166
167
168
169
170
171 s32 fm10k_start_hw_generic(struct fm10k_hw *hw)
172 {
173
174 hw->mac.tx_ready = true;
175
176 return 0;
177 }
178
179
180
181
182
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
191 hw->mac.tx_ready = false;
192
193 if (FM10K_REMOVED(hw->hw_addr))
194 return 0;
195
196
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
210 for (i = 0, time = FM10K_QUEUE_DISABLE_TIMEOUT; time;) {
211
212 if (i == q_cnt)
213 return 0;
214
215
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
226 time--;
227 if (time)
228 udelay(1);
229 }
230
231 return FM10K_ERR_REQUESTS_PENDING;
232 }
233
234
235
236
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
246
247
248
249
250
251
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
266
267
268
269
270
271
272
273
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
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
300
301
302
303
304
305
306 static void fm10k_update_hw_base_48b(struct fm10k_hw_stat *stat, u64 delta)
307 {
308 if (!delta)
309 return;
310
311
312 delta += stat->base_l;
313 stat->base_l = (u32)delta;
314
315
316 stat->base_h += (u32)(delta >> 32);
317 }
318
319
320
321
322
323
324
325
326
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
336 id_tx = fm10k_read_reg(hw, FM10K_TXQCTL(idx));
337
338
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
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
354 id_tx &= FM10K_TXQCTL_ID_MASK;
355 id_tx |= FM10K_STAT_VALID;
356
357
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
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
372
373
374
375
376
377
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
387 id_rx = fm10k_read_reg(hw, FM10K_RXQCTL(idx));
388
389
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
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
408 id_rx &= FM10K_RXQCTL_ID_MASK;
409 id_rx |= FM10K_STAT_VALID;
410
411
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
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
428
429
430
431
432
433
434
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
449
450
451
452
453
454
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
468
469
470
471
472
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
482 mbx->ops.process(hw, mbx);
483
484
485 if (!(~txdctl) || !(txdctl & FM10K_TXDCTL_ENABLE))
486 mac->get_host_state = true;
487
488
489 if (!mac->get_host_state || !(~txdctl))
490 goto out;
491
492
493 if (mac->tx_ready && !(txdctl & FM10K_TXDCTL_ENABLE)) {
494 ret_val = FM10K_ERR_RESET_REQUESTED;
495 goto out;
496 }
497
498
499 if (!mbx->timeout) {
500 ret_val = FM10K_ERR_RESET_REQUESTED;
501 goto out;
502 }
503
504
505 if (mbx->state != FM10K_STATE_OPEN)
506 goto out;
507
508
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
517
518
519 mac->get_host_state = false;
520
521 out:
522 *host_ready = !mac->get_host_state;
523 return ret_val;
524 }