summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/meta/fbnic/fbnic_csr.c
blob: aeb9f333f4c7a36d0dd961e8edd07c1f7367a3a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) Meta Platforms, Inc. and affiliates. */

#include "fbnic.h"

#define FBNIC_BOUNDS(section) { \
	.start = FBNIC_CSR_START_##section, \
	.end = FBNIC_CSR_END_##section + 1, \
}

struct fbnic_csr_bounds {
	u32	start;
	u32	end;
};

static const struct fbnic_csr_bounds fbnic_csr_sects[] = {
	FBNIC_BOUNDS(INTR),
	FBNIC_BOUNDS(INTR_CQ),
	FBNIC_BOUNDS(QM_TX),
	FBNIC_BOUNDS(QM_RX),
	FBNIC_BOUNDS(TCE),
	FBNIC_BOUNDS(TCE_RAM),
	FBNIC_BOUNDS(TMI),
	FBNIC_BOUNDS(PTP),
	FBNIC_BOUNDS(RXB),
	FBNIC_BOUNDS(RPC),
	FBNIC_BOUNDS(FAB),
	FBNIC_BOUNDS(MASTER),
	FBNIC_BOUNDS(PCS),
	FBNIC_BOUNDS(RSFEC),
	FBNIC_BOUNDS(MAC_MAC),
	FBNIC_BOUNDS(SIG),
	FBNIC_BOUNDS(PUL_USER),
	FBNIC_BOUNDS(QUEUE),
	FBNIC_BOUNDS(RPC_RAM),
};

#define FBNIC_RPC_TCAM_ACT_DW_PER_ENTRY			14
#define FBNIC_RPC_TCAM_ACT_NUM_ENTRIES			64

#define FBNIC_RPC_TCAM_MACDA_DW_PER_ENTRY		4
#define FBNIC_RPC_TCAM_MACDA_NUM_ENTRIES		32

#define FBNIC_RPC_TCAM_OUTER_IPSRC_DW_PER_ENTRY		9
#define FBNIC_RPC_TCAM_OUTER_IPSRC_NUM_ENTRIES		8

#define FBNIC_RPC_TCAM_OUTER_IPDST_DW_PER_ENTRY		9
#define FBNIC_RPC_TCAM_OUTER_IPDST_NUM_ENTRIES		8

#define FBNIC_RPC_TCAM_IPSRC_DW_PER_ENTRY		9
#define FBNIC_RPC_TCAM_IPSRC_NUM_ENTRIES		8

#define FBNIC_RPC_TCAM_IPDST_DW_PER_ENTRY		9
#define FBNIC_RPC_TCAM_IPDST_NUM_ENTRIES		8

#define FBNIC_RPC_RSS_TBL_DW_PER_ENTRY			2
#define FBNIC_RPC_RSS_TBL_NUM_ENTRIES			256

static void fbnic_csr_get_regs_rpc_ram(struct fbnic_dev *fbd, u32 **data_p)
{
	u32 start = FBNIC_CSR_START_RPC_RAM;
	u32 end = FBNIC_CSR_END_RPC_RAM;
	u32 *data = *data_p;
	u32 i, j;

	*(data++) = start;
	*(data++) = end;

	/* FBNIC_RPC_TCAM_ACT */
	for (i = 0; i < FBNIC_RPC_TCAM_ACT_NUM_ENTRIES; i++) {
		for (j = 0; j < FBNIC_RPC_TCAM_ACT_DW_PER_ENTRY; j++)
			*(data++) = rd32(fbd, FBNIC_RPC_TCAM_ACT(i, j));
	}

	/* FBNIC_RPC_TCAM_MACDA */
	for (i = 0; i < FBNIC_RPC_TCAM_MACDA_NUM_ENTRIES; i++) {
		for (j = 0; j < FBNIC_RPC_TCAM_MACDA_DW_PER_ENTRY; j++)
			*(data++) = rd32(fbd, FBNIC_RPC_TCAM_MACDA(i, j));
	}

	/* FBNIC_RPC_TCAM_OUTER_IPSRC */
	for (i = 0; i < FBNIC_RPC_TCAM_OUTER_IPSRC_NUM_ENTRIES; i++) {
		for (j = 0; j < FBNIC_RPC_TCAM_OUTER_IPSRC_DW_PER_ENTRY; j++)
			*(data++) = rd32(fbd, FBNIC_RPC_TCAM_OUTER_IPSRC(i, j));
	}

	/* FBNIC_RPC_TCAM_OUTER_IPDST */
	for (i = 0; i < FBNIC_RPC_TCAM_OUTER_IPDST_NUM_ENTRIES; i++) {
		for (j = 0; j < FBNIC_RPC_TCAM_OUTER_IPDST_DW_PER_ENTRY; j++)
			*(data++) = rd32(fbd, FBNIC_RPC_TCAM_OUTER_IPDST(i, j));
	}

	/* FBNIC_RPC_TCAM_IPSRC */
	for (i = 0; i < FBNIC_RPC_TCAM_IPSRC_NUM_ENTRIES; i++) {
		for (j = 0; j < FBNIC_RPC_TCAM_IPSRC_DW_PER_ENTRY; j++)
			*(data++) = rd32(fbd, FBNIC_RPC_TCAM_IPSRC(i, j));
	}

	/* FBNIC_RPC_TCAM_IPDST */
	for (i = 0; i < FBNIC_RPC_TCAM_IPDST_NUM_ENTRIES; i++) {
		for (j = 0; j < FBNIC_RPC_TCAM_IPDST_DW_PER_ENTRY; j++)
			*(data++) = rd32(fbd, FBNIC_RPC_TCAM_IPDST(i, j));
	}

	/* FBNIC_RPC_RSS_TBL */
	for (i = 0; i < FBNIC_RPC_RSS_TBL_NUM_ENTRIES; i++) {
		for (j = 0; j < FBNIC_RPC_RSS_TBL_DW_PER_ENTRY; j++)
			*(data++) = rd32(fbd, FBNIC_RPC_RSS_TBL(i, j));
	}

	*data_p = data;
}

void fbnic_csr_get_regs(struct fbnic_dev *fbd, u32 *data, u32 *regs_version)
{
	const struct fbnic_csr_bounds *bound;
	u32 *start = data;
	int i, j;

	*regs_version = 1u;

	/* Skip RPC_RAM section which cannot be dumped linearly */
	for (i = 0, bound = fbnic_csr_sects;
	     i < ARRAY_SIZE(fbnic_csr_sects) - 1; i++, ++bound) {
		*(data++) = bound->start;
		*(data++) = bound->end - 1;
		for (j = bound->start; j < bound->end; j++)
			*(data++) = rd32(fbd, j);
	}

	/* Dump the RPC_RAM as special case registers */
	fbnic_csr_get_regs_rpc_ram(fbd, &data);

	WARN_ON(data - start != fbnic_csr_regs_len(fbd));
}

int fbnic_csr_regs_len(struct fbnic_dev *fbd)
{
	int i, len = 0;

	/* Dump includes start and end information of each section
	 * which results in an offset of 2
	 */
	for (i = 0; i < ARRAY_SIZE(fbnic_csr_sects); i++)
		len += fbnic_csr_sects[i].end - fbnic_csr_sects[i].start + 2;

	return len;
}