1
2
3
4
5
6
7
8
9
10
11#include <linux/bitops.h>
12#include <linux/delay.h>
13#include <linux/interrupt.h>
14#include <linux/pci.h>
15#include <linux/module.h>
16#include <linux/seq_file.h>
17#include <linux/cpu_rmap.h>
18#include "net_driver.h"
19#include "bitfield.h"
20#include "efx.h"
21#include "nic.h"
22#include "farch_regs.h"
23#include "io.h"
24#include "workarounds.h"
25
26
27
28
29
30
31
32
33int ef4_nic_alloc_buffer(struct ef4_nic *efx, struct ef4_buffer *buffer,
34 unsigned int len, gfp_t gfp_flags)
35{
36 buffer->addr = dma_zalloc_coherent(&efx->pci_dev->dev, len,
37 &buffer->dma_addr, gfp_flags);
38 if (!buffer->addr)
39 return -ENOMEM;
40 buffer->len = len;
41 return 0;
42}
43
44void ef4_nic_free_buffer(struct ef4_nic *efx, struct ef4_buffer *buffer)
45{
46 if (buffer->addr) {
47 dma_free_coherent(&efx->pci_dev->dev, buffer->len,
48 buffer->addr, buffer->dma_addr);
49 buffer->addr = NULL;
50 }
51}
52
53
54
55
56bool ef4_nic_event_present(struct ef4_channel *channel)
57{
58 return ef4_event_present(ef4_event(channel, channel->eventq_read_ptr));
59}
60
61void ef4_nic_event_test_start(struct ef4_channel *channel)
62{
63 channel->event_test_cpu = -1;
64 smp_wmb();
65 channel->efx->type->ev_test_generate(channel);
66}
67
68int ef4_nic_irq_test_start(struct ef4_nic *efx)
69{
70 efx->last_irq_cpu = -1;
71 smp_wmb();
72 return efx->type->irq_test_generate(efx);
73}
74
75
76
77
78int ef4_nic_init_interrupt(struct ef4_nic *efx)
79{
80 struct ef4_channel *channel;
81 unsigned int n_irqs;
82 int rc;
83
84 if (!EF4_INT_MODE_USE_MSI(efx)) {
85 rc = request_irq(efx->legacy_irq,
86 efx->type->irq_handle_legacy, IRQF_SHARED,
87 efx->name, efx);
88 if (rc) {
89 netif_err(efx, drv, efx->net_dev,
90 "failed to hook legacy IRQ %d\n",
91 efx->pci_dev->irq);
92 goto fail1;
93 }
94 return 0;
95 }
96
97#ifdef CONFIG_RFS_ACCEL
98 if (efx->interrupt_mode == EF4_INT_MODE_MSIX) {
99 efx->net_dev->rx_cpu_rmap =
100 alloc_irq_cpu_rmap(efx->n_rx_channels);
101 if (!efx->net_dev->rx_cpu_rmap) {
102 rc = -ENOMEM;
103 goto fail1;
104 }
105 }
106#endif
107
108
109 n_irqs = 0;
110 ef4_for_each_channel(channel, efx) {
111 rc = request_irq(channel->irq, efx->type->irq_handle_msi,
112 IRQF_PROBE_SHARED,
113 efx->msi_context[channel->channel].name,
114 &efx->msi_context[channel->channel]);
115 if (rc) {
116 netif_err(efx, drv, efx->net_dev,
117 "failed to hook IRQ %d\n", channel->irq);
118 goto fail2;
119 }
120 ++n_irqs;
121
122#ifdef CONFIG_RFS_ACCEL
123 if (efx->interrupt_mode == EF4_INT_MODE_MSIX &&
124 channel->channel < efx->n_rx_channels) {
125 rc = irq_cpu_rmap_add(efx->net_dev->rx_cpu_rmap,
126 channel->irq);
127 if (rc)
128 goto fail2;
129 }
130#endif
131 }
132
133 return 0;
134
135 fail2:
136#ifdef CONFIG_RFS_ACCEL
137 free_irq_cpu_rmap(efx->net_dev->rx_cpu_rmap);
138 efx->net_dev->rx_cpu_rmap = NULL;
139#endif
140 ef4_for_each_channel(channel, efx) {
141 if (n_irqs-- == 0)
142 break;
143 free_irq(channel->irq, &efx->msi_context[channel->channel]);
144 }
145 fail1:
146 return rc;
147}
148
149void ef4_nic_fini_interrupt(struct ef4_nic *efx)
150{
151 struct ef4_channel *channel;
152
153#ifdef CONFIG_RFS_ACCEL
154 free_irq_cpu_rmap(efx->net_dev->rx_cpu_rmap);
155 efx->net_dev->rx_cpu_rmap = NULL;
156#endif
157
158 if (EF4_INT_MODE_USE_MSI(efx)) {
159
160 ef4_for_each_channel(channel, efx)
161 free_irq(channel->irq,
162 &efx->msi_context[channel->channel]);
163 } else {
164
165 free_irq(efx->legacy_irq, efx);
166 }
167}
168
169
170
171#define REGISTER_REVISION_FA 1
172#define REGISTER_REVISION_FB 2
173#define REGISTER_REVISION_FC 3
174#define REGISTER_REVISION_FZ 3
175#define REGISTER_REVISION_ED 4
176#define REGISTER_REVISION_EZ 4
177
178struct ef4_nic_reg {
179 u32 offset:24;
180 u32 min_revision:3, max_revision:3;
181};
182
183#define REGISTER(name, arch, min_rev, max_rev) { \
184 arch ## R_ ## min_rev ## max_rev ## _ ## name, \
185 REGISTER_REVISION_ ## arch ## min_rev, \
186 REGISTER_REVISION_ ## arch ## max_rev \
187}
188#define REGISTER_AA(name) REGISTER(name, F, A, A)
189#define REGISTER_AB(name) REGISTER(name, F, A, B)
190#define REGISTER_AZ(name) REGISTER(name, F, A, Z)
191#define REGISTER_BB(name) REGISTER(name, F, B, B)
192#define REGISTER_BZ(name) REGISTER(name, F, B, Z)
193#define REGISTER_CZ(name) REGISTER(name, F, C, Z)
194
195static const struct ef4_nic_reg ef4_nic_regs[] = {
196 REGISTER_AZ(ADR_REGION),
197 REGISTER_AZ(INT_EN_KER),
198 REGISTER_BZ(INT_EN_CHAR),
199 REGISTER_AZ(INT_ADR_KER),
200 REGISTER_BZ(INT_ADR_CHAR),
201
202
203 REGISTER_AZ(HW_INIT),
204 REGISTER_CZ(USR_EV_CFG),
205 REGISTER_AB(EE_SPI_HCMD),
206 REGISTER_AB(EE_SPI_HADR),
207 REGISTER_AB(EE_SPI_HDATA),
208 REGISTER_AB(EE_BASE_PAGE),
209 REGISTER_AB(EE_VPD_CFG0),
210
211
212
213 REGISTER_AB(NIC_STAT),
214 REGISTER_AB(GPIO_CTL),
215 REGISTER_AB(GLB_CTL),
216
217 REGISTER_BZ(DP_CTRL),
218 REGISTER_AZ(MEM_STAT),
219 REGISTER_AZ(CS_DEBUG),
220 REGISTER_AZ(ALTERA_BUILD),
221 REGISTER_AZ(CSR_SPARE),
222 REGISTER_AB(PCIE_SD_CTL0123),
223 REGISTER_AB(PCIE_SD_CTL45),
224 REGISTER_AB(PCIE_PCS_CTL_STAT),
225
226
227 REGISTER_AZ(EVQ_CTL),
228 REGISTER_AZ(EVQ_CNT1),
229 REGISTER_AZ(EVQ_CNT2),
230 REGISTER_AZ(BUF_TBL_CFG),
231 REGISTER_AZ(SRM_RX_DC_CFG),
232 REGISTER_AZ(SRM_TX_DC_CFG),
233 REGISTER_AZ(SRM_CFG),
234
235 REGISTER_AZ(SRM_UPD_EVQ),
236 REGISTER_AZ(SRAM_PARITY),
237 REGISTER_AZ(RX_CFG),
238 REGISTER_BZ(RX_FILTER_CTL),
239
240 REGISTER_AZ(RX_DC_CFG),
241 REGISTER_AZ(RX_DC_PF_WM),
242 REGISTER_BZ(RX_RSS_TKEY),
243
244 REGISTER_AA(RX_SELF_RST),
245
246 REGISTER_CZ(RX_RSS_IPV6_REG1),
247 REGISTER_CZ(RX_RSS_IPV6_REG2),
248 REGISTER_CZ(RX_RSS_IPV6_REG3),
249
250 REGISTER_AZ(TX_DC_CFG),
251 REGISTER_AA(TX_CHKSM_CFG),
252 REGISTER_AZ(TX_CFG),
253
254 REGISTER_AZ(TX_RESERVED),
255 REGISTER_BZ(TX_PACE),
256
257 REGISTER_BB(TX_VLAN),
258 REGISTER_BZ(TX_IPFIL_PORTEN),
259 REGISTER_AB(MD_TXD),
260 REGISTER_AB(MD_RXD),
261 REGISTER_AB(MD_CS),
262 REGISTER_AB(MD_PHY_ADR),
263 REGISTER_AB(MD_ID),
264
265 REGISTER_AB(MAC_STAT_DMA),
266 REGISTER_AB(MAC_CTRL),
267 REGISTER_BB(GEN_MODE),
268 REGISTER_AB(MAC_MC_HASH_REG0),
269 REGISTER_AB(MAC_MC_HASH_REG1),
270 REGISTER_AB(GM_CFG1),
271 REGISTER_AB(GM_CFG2),
272
273 REGISTER_AB(GM_MAX_FLEN),
274
275 REGISTER_AB(GM_ADR1),
276 REGISTER_AB(GM_ADR2),
277 REGISTER_AB(GMF_CFG0),
278 REGISTER_AB(GMF_CFG1),
279 REGISTER_AB(GMF_CFG2),
280 REGISTER_AB(GMF_CFG3),
281 REGISTER_AB(GMF_CFG4),
282 REGISTER_AB(GMF_CFG5),
283 REGISTER_BB(TX_SRC_MAC_CTL),
284 REGISTER_AB(XM_ADR_LO),
285 REGISTER_AB(XM_ADR_HI),
286 REGISTER_AB(XM_GLB_CFG),
287 REGISTER_AB(XM_TX_CFG),
288 REGISTER_AB(XM_RX_CFG),
289 REGISTER_AB(XM_MGT_INT_MASK),
290 REGISTER_AB(XM_FC),
291 REGISTER_AB(XM_PAUSE_TIME),
292 REGISTER_AB(XM_TX_PARAM),
293 REGISTER_AB(XM_RX_PARAM),
294
295 REGISTER_AB(XX_PWR_RST),
296 REGISTER_AB(XX_SD_CTL),
297 REGISTER_AB(XX_TXDRV_CTL),
298
299
300};
301
302struct ef4_nic_reg_table {
303 u32 offset:24;
304 u32 min_revision:3, max_revision:3;
305 u32 step:6, rows:21;
306};
307
308#define REGISTER_TABLE_DIMENSIONS(_, offset, arch, min_rev, max_rev, step, rows) { \
309 offset, \
310 REGISTER_REVISION_ ## arch ## min_rev, \
311 REGISTER_REVISION_ ## arch ## max_rev, \
312 step, rows \
313}
314#define REGISTER_TABLE(name, arch, min_rev, max_rev) \
315 REGISTER_TABLE_DIMENSIONS( \
316 name, arch ## R_ ## min_rev ## max_rev ## _ ## name, \
317 arch, min_rev, max_rev, \
318 arch ## R_ ## min_rev ## max_rev ## _ ## name ## _STEP, \
319 arch ## R_ ## min_rev ## max_rev ## _ ## name ## _ROWS)
320#define REGISTER_TABLE_AA(name) REGISTER_TABLE(name, F, A, A)
321#define REGISTER_TABLE_AZ(name) REGISTER_TABLE(name, F, A, Z)
322#define REGISTER_TABLE_BB(name) REGISTER_TABLE(name, F, B, B)
323#define REGISTER_TABLE_BZ(name) REGISTER_TABLE(name, F, B, Z)
324#define REGISTER_TABLE_BB_CZ(name) \
325 REGISTER_TABLE_DIMENSIONS(name, FR_BZ_ ## name, F, B, B, \
326 FR_BZ_ ## name ## _STEP, \
327 FR_BB_ ## name ## _ROWS), \
328 REGISTER_TABLE_DIMENSIONS(name, FR_BZ_ ## name, F, C, Z, \
329 FR_BZ_ ## name ## _STEP, \
330 FR_CZ_ ## name ## _ROWS)
331#define REGISTER_TABLE_CZ(name) REGISTER_TABLE(name, F, C, Z)
332
333static const struct ef4_nic_reg_table ef4_nic_reg_tables[] = {
334
335
336 REGISTER_TABLE_BB(TX_IPFIL_TBL),
337 REGISTER_TABLE_BB(TX_SRC_MAC_TBL),
338 REGISTER_TABLE_AA(RX_DESC_PTR_TBL_KER),
339 REGISTER_TABLE_BB_CZ(RX_DESC_PTR_TBL),
340 REGISTER_TABLE_AA(TX_DESC_PTR_TBL_KER),
341 REGISTER_TABLE_BB_CZ(TX_DESC_PTR_TBL),
342 REGISTER_TABLE_AA(EVQ_PTR_TBL_KER),
343 REGISTER_TABLE_BB_CZ(EVQ_PTR_TBL),
344
345
346
347
348 REGISTER_TABLE_DIMENSIONS(BUF_FULL_TBL_KER, FR_AA_BUF_FULL_TBL_KER,
349 F, A, A, 8, 1024),
350 REGISTER_TABLE_DIMENSIONS(BUF_FULL_TBL, FR_BZ_BUF_FULL_TBL,
351 F, B, Z, 8, 1024),
352 REGISTER_TABLE_CZ(RX_MAC_FILTER_TBL0),
353 REGISTER_TABLE_BB_CZ(TIMER_TBL),
354 REGISTER_TABLE_BB_CZ(TX_PACE_TBL),
355 REGISTER_TABLE_BZ(RX_INDIRECTION_TBL),
356
357 REGISTER_TABLE_CZ(TX_MAC_FILTER_TBL0),
358 REGISTER_TABLE_CZ(MC_TREG_SMEM),
359
360
361 REGISTER_TABLE_BZ(RX_FILTER_TBL0),
362};
363
364size_t ef4_nic_get_regs_len(struct ef4_nic *efx)
365{
366 const struct ef4_nic_reg *reg;
367 const struct ef4_nic_reg_table *table;
368 size_t len = 0;
369
370 for (reg = ef4_nic_regs;
371 reg < ef4_nic_regs + ARRAY_SIZE(ef4_nic_regs);
372 reg++)
373 if (efx->type->revision >= reg->min_revision &&
374 efx->type->revision <= reg->max_revision)
375 len += sizeof(ef4_oword_t);
376
377 for (table = ef4_nic_reg_tables;
378 table < ef4_nic_reg_tables + ARRAY_SIZE(ef4_nic_reg_tables);
379 table++)
380 if (efx->type->revision >= table->min_revision &&
381 efx->type->revision <= table->max_revision)
382 len += table->rows * min_t(size_t, table->step, 16);
383
384 return len;
385}
386
387void ef4_nic_get_regs(struct ef4_nic *efx, void *buf)
388{
389 const struct ef4_nic_reg *reg;
390 const struct ef4_nic_reg_table *table;
391
392 for (reg = ef4_nic_regs;
393 reg < ef4_nic_regs + ARRAY_SIZE(ef4_nic_regs);
394 reg++) {
395 if (efx->type->revision >= reg->min_revision &&
396 efx->type->revision <= reg->max_revision) {
397 ef4_reado(efx, (ef4_oword_t *)buf, reg->offset);
398 buf += sizeof(ef4_oword_t);
399 }
400 }
401
402 for (table = ef4_nic_reg_tables;
403 table < ef4_nic_reg_tables + ARRAY_SIZE(ef4_nic_reg_tables);
404 table++) {
405 size_t size, i;
406
407 if (!(efx->type->revision >= table->min_revision &&
408 efx->type->revision <= table->max_revision))
409 continue;
410
411 size = min_t(size_t, table->step, 16);
412
413 for (i = 0; i < table->rows; i++) {
414 switch (table->step) {
415 case 4:
416 ef4_readd(efx, buf, table->offset + 4 * i);
417 break;
418 case 8:
419 ef4_sram_readq(efx,
420 efx->membase + table->offset,
421 buf, i);
422 break;
423 case 16:
424 ef4_reado_table(efx, buf, table->offset, i);
425 break;
426 case 32:
427 ef4_reado_table(efx, buf, table->offset, 2 * i);
428 break;
429 default:
430 WARN_ON(1);
431 return;
432 }
433 buf += size;
434 }
435 }
436}
437
438
439
440
441
442
443
444
445
446
447
448
449size_t ef4_nic_describe_stats(const struct ef4_hw_stat_desc *desc, size_t count,
450 const unsigned long *mask, u8 *names)
451{
452 size_t visible = 0;
453 size_t index;
454
455 for_each_set_bit(index, mask, count) {
456 if (desc[index].name) {
457 if (names) {
458 strlcpy(names, desc[index].name,
459 ETH_GSTRING_LEN);
460 names += ETH_GSTRING_LEN;
461 }
462 ++visible;
463 }
464 }
465
466 return visible;
467}
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483void ef4_nic_update_stats(const struct ef4_hw_stat_desc *desc, size_t count,
484 const unsigned long *mask,
485 u64 *stats, const void *dma_buf, bool accumulate)
486{
487 size_t index;
488
489 for_each_set_bit(index, mask, count) {
490 if (desc[index].dma_width) {
491 const void *addr = dma_buf + desc[index].offset;
492 u64 val;
493
494 switch (desc[index].dma_width) {
495 case 16:
496 val = le16_to_cpup((__le16 *)addr);
497 break;
498 case 32:
499 val = le32_to_cpup((__le32 *)addr);
500 break;
501 case 64:
502 val = le64_to_cpup((__le64 *)addr);
503 break;
504 default:
505 WARN_ON(1);
506 val = 0;
507 break;
508 }
509
510 if (accumulate)
511 stats[index] += val;
512 else
513 stats[index] = val;
514 }
515 }
516}
517
518void ef4_nic_fix_nodesc_drop_stat(struct ef4_nic *efx, u64 *rx_nodesc_drops)
519{
520
521 if (!(efx->net_dev->flags & IFF_UP) || !efx->rx_nodesc_drops_prev_state)
522 efx->rx_nodesc_drops_while_down +=
523 *rx_nodesc_drops - efx->rx_nodesc_drops_total;
524 efx->rx_nodesc_drops_total = *rx_nodesc_drops;
525 efx->rx_nodesc_drops_prev_state = !!(efx->net_dev->flags & IFF_UP);
526 *rx_nodesc_drops -= efx->rx_nodesc_drops_while_down;
527}
528