Browse Source

[sfc] Add driver for Solarflare SFC8XXX adapters

Signed-off-by: Martin Habets <mhabets@solarflare.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Martin Habets 7 years ago
parent
commit
f3788fa837

+ 1
- 0
src/Makefile View File

@@ -78,6 +78,7 @@ SRCDIRS		+= drivers/net/ath/ath9k
78 78
 SRCDIRS		+= drivers/net/vxge
79 79
 SRCDIRS		+= drivers/net/efi
80 80
 SRCDIRS		+= drivers/net/tg3
81
+SRCDIRS		+= drivers/net/sfc
81 82
 SRCDIRS		+= drivers/block
82 83
 SRCDIRS		+= drivers/nvs
83 84
 SRCDIRS		+= drivers/bitbash

+ 364
- 0
src/drivers/net/sfc/ef10_regs.h View File

@@ -0,0 +1,364 @@
1
+/****************************************************************************
2
+ *
3
+ * Driver for Solarflare network controllers and boards
4
+ * Copyright 2012-2017 Solarflare Communications Inc.
5
+ *
6
+ * This program is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU General Public License as
8
+ * published by the Free Software Foundation; either version 2 of the
9
+ * License, or any later version.
10
+ *
11
+ * You can also choose to distribute this program under the terms of
12
+ * the Unmodified Binary Distribution Licence (as given in the file
13
+ * COPYING.UBDL), provided that you have satisfied its requirements.
14
+ */
15
+
16
+#ifndef EFX_EF10_REGS_H
17
+#define EFX_EF10_REGS_H
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
20
+
21
+/** \file ef10_regs.h
22
+ * EF10 hardware architecture definitions
23
+ *
24
+ * EF10 hardware architecture definitions have a name prefix following
25
+ * the format:
26
+ *
27
+ *     E<type>_<min-rev><max-rev>_
28
+ *
29
+ * The following <type> strings are used:
30
+ *
31
+ *             MMIO register  Host memory structure
32
+ * Address     R
33
+ * Bitfield    RF             SF
34
+ * Enumerator  FE             SE
35
+ *
36
+ * <min-rev> is the first revision to which the definition applies:
37
+ *
38
+ *     D: Huntington A0
39
+ *
40
+ * If the definition has been changed or removed in later revisions
41
+ * then <max-rev> is the last revision to which the definition applies;
42
+ * otherwise it is "Z".
43
+ */
44
+
45
+/**************************************************************************
46
+ *
47
+ * EF10 registers and descriptors
48
+ *
49
+ **************************************************************************
50
+ */
51
+
52
+/* BIU_HW_REV_ID_REG:  */
53
+#define	ER_DZ_BIU_HW_REV_ID 0x00000000
54
+#define	ERF_DZ_HW_REV_ID_LBN 0
55
+#define	ERF_DZ_HW_REV_ID_WIDTH 32
56
+
57
+/* BIU_MC_SFT_STATUS_REG:  */
58
+#define	ER_DZ_BIU_MC_SFT_STATUS 0x00000010
59
+#define	ER_DZ_BIU_MC_SFT_STATUS_STEP 4
60
+#define	ER_DZ_BIU_MC_SFT_STATUS_ROWS 8
61
+#define	ERF_DZ_MC_SFT_STATUS_LBN 0
62
+#define	ERF_DZ_MC_SFT_STATUS_WIDTH 32
63
+
64
+/* BIU_INT_ISR_REG:  */
65
+#define	ER_DZ_BIU_INT_ISR 0x00000090
66
+#define	ERF_DZ_ISR_REG_LBN 0
67
+#define	ERF_DZ_ISR_REG_WIDTH 32
68
+
69
+/* MC_DB_LWRD_REG:  */
70
+#define	ER_DZ_MC_DB_LWRD 0x00000200
71
+#define	ERF_DZ_MC_DOORBELL_L_LBN 0
72
+#define	ERF_DZ_MC_DOORBELL_L_WIDTH 32
73
+
74
+/* MC_DB_HWRD_REG:  */
75
+#define	ER_DZ_MC_DB_HWRD 0x00000204
76
+#define	ERF_DZ_MC_DOORBELL_H_LBN 0
77
+#define	ERF_DZ_MC_DOORBELL_H_WIDTH 32
78
+
79
+/* EVQ_RPTR_REG:  */
80
+#define	ER_DZ_EVQ_RPTR 0x00000400
81
+#define	ER_DZ_EVQ_RPTR_STEP 8192
82
+#define	ER_DZ_EVQ_RPTR_ROWS 2048
83
+#define	ERF_DZ_EVQ_RPTR_VLD_LBN 15
84
+#define	ERF_DZ_EVQ_RPTR_VLD_WIDTH 1
85
+#define	ERF_DZ_EVQ_RPTR_LBN 0
86
+#define	ERF_DZ_EVQ_RPTR_WIDTH 15
87
+
88
+/* EVQ_TMR_REG:  */
89
+#define	ER_DZ_EVQ_TMR 0x00000420
90
+#define	ER_DZ_EVQ_TMR_STEP 8192
91
+#define	ER_DZ_EVQ_TMR_ROWS 2048
92
+#define	ERF_DZ_TC_TIMER_MODE_LBN 14
93
+#define	ERF_DZ_TC_TIMER_MODE_WIDTH 2
94
+#define	ERF_DZ_TC_TIMER_VAL_LBN 0
95
+#define	ERF_DZ_TC_TIMER_VAL_WIDTH 14
96
+
97
+/* RX_DESC_UPD_REG:  */
98
+#define	ER_DZ_RX_DESC_UPD 0x00000830
99
+#define	ER_DZ_RX_DESC_UPD_STEP 8192
100
+#define	ER_DZ_RX_DESC_UPD_ROWS 2048
101
+#define	ERF_DZ_RX_DESC_WPTR_LBN 0
102
+#define	ERF_DZ_RX_DESC_WPTR_WIDTH 12
103
+
104
+/* TX_DESC_UPD_REG:  */
105
+#define	ER_DZ_TX_DESC_UPD 0x00000a10
106
+#define	ER_DZ_TX_DESC_UPD_STEP 8192
107
+#define	ER_DZ_TX_DESC_UPD_ROWS 2048
108
+#define	ERF_DZ_RSVD_LBN 76
109
+#define	ERF_DZ_RSVD_WIDTH 20
110
+#define	ERF_DZ_TX_DESC_WPTR_LBN 64
111
+#define	ERF_DZ_TX_DESC_WPTR_WIDTH 12
112
+#define	ERF_DZ_TX_DESC_HWORD_LBN 32
113
+#define	ERF_DZ_TX_DESC_HWORD_WIDTH 32
114
+#define	ERF_DZ_TX_DESC_LWORD_LBN 0
115
+#define	ERF_DZ_TX_DESC_LWORD_WIDTH 32
116
+
117
+/* DRIVER_EV */
118
+#define	ESF_DZ_DRV_CODE_LBN 60
119
+#define	ESF_DZ_DRV_CODE_WIDTH 4
120
+#define	ESF_DZ_DRV_SUB_CODE_LBN 56
121
+#define	ESF_DZ_DRV_SUB_CODE_WIDTH 4
122
+#define	ESE_DZ_DRV_TIMER_EV 3
123
+#define	ESE_DZ_DRV_START_UP_EV 2
124
+#define	ESE_DZ_DRV_WAKE_UP_EV 1
125
+#define	ESF_DZ_DRV_SUB_DATA_LBN 0
126
+#define	ESF_DZ_DRV_SUB_DATA_WIDTH 56
127
+#define	ESF_DZ_DRV_EVQ_ID_LBN 0
128
+#define	ESF_DZ_DRV_EVQ_ID_WIDTH 14
129
+#define	ESF_DZ_DRV_TMR_ID_LBN 0
130
+#define	ESF_DZ_DRV_TMR_ID_WIDTH 14
131
+
132
+/* EVENT_ENTRY */
133
+#define	ESF_DZ_EV_CODE_LBN 60
134
+#define	ESF_DZ_EV_CODE_WIDTH 4
135
+#define	ESE_DZ_EV_CODE_MCDI_EV 12
136
+#define	ESE_DZ_EV_CODE_DRIVER_EV 5
137
+#define	ESE_DZ_EV_CODE_TX_EV 2
138
+#define	ESE_DZ_EV_CODE_RX_EV 0
139
+#define	ESE_DZ_OTHER other
140
+#define	ESF_DZ_EV_DATA_LBN 0
141
+#define	ESF_DZ_EV_DATA_WIDTH 60
142
+
143
+/* MC_EVENT */
144
+#define	ESF_DZ_MC_CODE_LBN 60
145
+#define	ESF_DZ_MC_CODE_WIDTH 4
146
+#define	ESF_DZ_MC_OVERRIDE_HOLDOFF_LBN 59
147
+#define	ESF_DZ_MC_OVERRIDE_HOLDOFF_WIDTH 1
148
+#define	ESF_DZ_MC_DROP_EVENT_LBN 58
149
+#define	ESF_DZ_MC_DROP_EVENT_WIDTH 1
150
+#define	ESF_DZ_MC_SOFT_LBN 0
151
+#define	ESF_DZ_MC_SOFT_WIDTH 58
152
+
153
+/* RX_EVENT */
154
+#define	ESF_DZ_RX_CODE_LBN 60
155
+#define	ESF_DZ_RX_CODE_WIDTH 4
156
+#define	ESF_DZ_RX_OVERRIDE_HOLDOFF_LBN 59
157
+#define	ESF_DZ_RX_OVERRIDE_HOLDOFF_WIDTH 1
158
+#define	ESF_DZ_RX_DROP_EVENT_LBN 58
159
+#define	ESF_DZ_RX_DROP_EVENT_WIDTH 1
160
+#define	ESF_DZ_RX_EV_RSVD2_LBN 54
161
+#define	ESF_DZ_RX_EV_RSVD2_WIDTH 4
162
+#define	ESF_DZ_RX_EV_SOFT2_LBN 52
163
+#define	ESF_DZ_RX_EV_SOFT2_WIDTH 2
164
+#define	ESF_DZ_RX_DSC_PTR_LBITS_LBN 48
165
+#define	ESF_DZ_RX_DSC_PTR_LBITS_WIDTH 4
166
+#define	ESF_DZ_RX_L4_CLASS_LBN 45
167
+#define	ESF_DZ_RX_L4_CLASS_WIDTH 3
168
+#define	ESE_DZ_L4_CLASS_RSVD7 7
169
+#define	ESE_DZ_L4_CLASS_RSVD6 6
170
+#define	ESE_DZ_L4_CLASS_RSVD5 5
171
+#define	ESE_DZ_L4_CLASS_RSVD4 4
172
+#define	ESE_DZ_L4_CLASS_RSVD3 3
173
+#define	ESE_DZ_L4_CLASS_UDP 2
174
+#define	ESE_DZ_L4_CLASS_TCP 1
175
+#define	ESE_DZ_L4_CLASS_UNKNOWN 0
176
+#define	ESF_DZ_RX_L3_CLASS_LBN 42
177
+#define	ESF_DZ_RX_L3_CLASS_WIDTH 3
178
+#define	ESE_DZ_L3_CLASS_RSVD7 7
179
+#define	ESE_DZ_L3_CLASS_IP6_FRAG 6
180
+#define	ESE_DZ_L3_CLASS_ARP 5
181
+#define	ESE_DZ_L3_CLASS_IP4_FRAG 4
182
+#define	ESE_DZ_L3_CLASS_FCOE 3
183
+#define	ESE_DZ_L3_CLASS_IP6 2
184
+#define	ESE_DZ_L3_CLASS_IP4 1
185
+#define	ESE_DZ_L3_CLASS_UNKNOWN 0
186
+#define	ESF_DZ_RX_ETH_TAG_CLASS_LBN 39
187
+#define	ESF_DZ_RX_ETH_TAG_CLASS_WIDTH 3
188
+#define	ESE_DZ_ETH_TAG_CLASS_RSVD7 7
189
+#define	ESE_DZ_ETH_TAG_CLASS_RSVD6 6
190
+#define	ESE_DZ_ETH_TAG_CLASS_RSVD5 5
191
+#define	ESE_DZ_ETH_TAG_CLASS_RSVD4 4
192
+#define	ESE_DZ_ETH_TAG_CLASS_RSVD3 3
193
+#define	ESE_DZ_ETH_TAG_CLASS_VLAN2 2
194
+#define	ESE_DZ_ETH_TAG_CLASS_VLAN1 1
195
+#define	ESE_DZ_ETH_TAG_CLASS_NONE 0
196
+#define	ESF_DZ_RX_ETH_BASE_CLASS_LBN 36
197
+#define	ESF_DZ_RX_ETH_BASE_CLASS_WIDTH 3
198
+#define	ESE_DZ_ETH_BASE_CLASS_LLC_SNAP 2
199
+#define	ESE_DZ_ETH_BASE_CLASS_LLC 1
200
+#define	ESE_DZ_ETH_BASE_CLASS_ETH2 0
201
+#define	ESF_DZ_RX_MAC_CLASS_LBN 35
202
+#define	ESF_DZ_RX_MAC_CLASS_WIDTH 1
203
+#define	ESE_DZ_MAC_CLASS_MCAST 1
204
+#define	ESE_DZ_MAC_CLASS_UCAST 0
205
+#define	ESF_DZ_RX_EV_SOFT1_LBN 32
206
+#define	ESF_DZ_RX_EV_SOFT1_WIDTH 3
207
+#define	ESF_DZ_RX_EV_RSVD1_LBN 31
208
+#define	ESF_DZ_RX_EV_RSVD1_WIDTH 1
209
+#define	ESF_DZ_RX_ABORT_LBN 30
210
+#define	ESF_DZ_RX_ABORT_WIDTH 1
211
+#define	ESF_DZ_RX_ECC_ERR_LBN 29
212
+#define	ESF_DZ_RX_ECC_ERR_WIDTH 1
213
+#define	ESF_DZ_RX_CRC1_ERR_LBN 28
214
+#define	ESF_DZ_RX_CRC1_ERR_WIDTH 1
215
+#define	ESF_DZ_RX_CRC0_ERR_LBN 27
216
+#define	ESF_DZ_RX_CRC0_ERR_WIDTH 1
217
+#define	ESF_DZ_RX_TCPUDP_CKSUM_ERR_LBN 26
218
+#define	ESF_DZ_RX_TCPUDP_CKSUM_ERR_WIDTH 1
219
+#define	ESF_DZ_RX_IPCKSUM_ERR_LBN 25
220
+#define	ESF_DZ_RX_IPCKSUM_ERR_WIDTH 1
221
+#define	ESF_DZ_RX_ECRC_ERR_LBN 24
222
+#define	ESF_DZ_RX_ECRC_ERR_WIDTH 1
223
+#define	ESF_DZ_RX_QLABEL_LBN 16
224
+#define	ESF_DZ_RX_QLABEL_WIDTH 5
225
+#define	ESF_DZ_RX_PARSE_INCOMPLETE_LBN 15
226
+#define	ESF_DZ_RX_PARSE_INCOMPLETE_WIDTH 1
227
+#define	ESF_DZ_RX_CONT_LBN 14
228
+#define	ESF_DZ_RX_CONT_WIDTH 1
229
+#define	ESF_DZ_RX_BYTES_LBN 0
230
+#define	ESF_DZ_RX_BYTES_WIDTH 14
231
+
232
+/* RX_KER_DESC */
233
+#define	ESF_DZ_RX_KER_RESERVED_LBN 62
234
+#define	ESF_DZ_RX_KER_RESERVED_WIDTH 2
235
+#define	ESF_DZ_RX_KER_BYTE_CNT_LBN 48
236
+#define	ESF_DZ_RX_KER_BYTE_CNT_WIDTH 14
237
+#define	ESF_DZ_RX_KER_BUF_ADDR_LBN 0
238
+#define	ESF_DZ_RX_KER_BUF_ADDR_WIDTH 48
239
+
240
+/* TX_CSUM_TSTAMP_DESC */
241
+#define	ESF_DZ_TX_DESC_IS_OPT_LBN 63
242
+#define	ESF_DZ_TX_DESC_IS_OPT_WIDTH 1
243
+#define	ESF_DZ_TX_OPTION_TYPE_LBN 60
244
+#define	ESF_DZ_TX_OPTION_TYPE_WIDTH 3
245
+#define	ESE_DZ_TX_OPTION_DESC_TSO 7
246
+#define	ESE_DZ_TX_OPTION_DESC_VLAN 6
247
+#define	ESE_DZ_TX_OPTION_DESC_CRC_CSUM 0
248
+#define	ESF_DZ_TX_TIMESTAMP_LBN 5
249
+#define	ESF_DZ_TX_TIMESTAMP_WIDTH 1
250
+#define	ESF_DZ_TX_OPTION_CRC_MODE_LBN 2
251
+#define	ESF_DZ_TX_OPTION_CRC_MODE_WIDTH 3
252
+#define	ESE_DZ_TX_OPTION_CRC_FCOIP_MPA 5
253
+#define	ESE_DZ_TX_OPTION_CRC_FCOIP_FCOE 4
254
+#define	ESE_DZ_TX_OPTION_CRC_ISCSI_HDR_AND_PYLD 3
255
+#define	ESE_DZ_TX_OPTION_CRC_ISCSI_HDR 2
256
+#define	ESE_DZ_TX_OPTION_CRC_FCOE 1
257
+#define	ESE_DZ_TX_OPTION_CRC_OFF 0
258
+#define	ESF_DZ_TX_OPTION_UDP_TCP_CSUM_LBN 1
259
+#define	ESF_DZ_TX_OPTION_UDP_TCP_CSUM_WIDTH 1
260
+#define	ESF_DZ_TX_OPTION_IP_CSUM_LBN 0
261
+#define	ESF_DZ_TX_OPTION_IP_CSUM_WIDTH 1
262
+
263
+/* TX_EVENT */
264
+#define	ESF_DZ_TX_CODE_LBN 60
265
+#define	ESF_DZ_TX_CODE_WIDTH 4
266
+#define	ESF_DZ_TX_OVERRIDE_HOLDOFF_LBN 59
267
+#define	ESF_DZ_TX_OVERRIDE_HOLDOFF_WIDTH 1
268
+#define	ESF_DZ_TX_DROP_EVENT_LBN 58
269
+#define	ESF_DZ_TX_DROP_EVENT_WIDTH 1
270
+#define	ESF_DZ_TX_EV_RSVD_LBN 48
271
+#define	ESF_DZ_TX_EV_RSVD_WIDTH 10
272
+#define	ESF_DZ_TX_SOFT2_LBN 32
273
+#define	ESF_DZ_TX_SOFT2_WIDTH 16
274
+#define	ESF_DZ_TX_CAN_MERGE_LBN 31
275
+#define	ESF_DZ_TX_CAN_MERGE_WIDTH 1
276
+#define	ESF_DZ_TX_SOFT1_LBN 24
277
+#define	ESF_DZ_TX_SOFT1_WIDTH 7
278
+#define	ESF_DZ_TX_QLABEL_LBN 16
279
+#define	ESF_DZ_TX_QLABEL_WIDTH 5
280
+#define	ESF_DZ_TX_DESCR_INDX_LBN 0
281
+#define	ESF_DZ_TX_DESCR_INDX_WIDTH 16
282
+
283
+/* TX_KER_DESC */
284
+#define	ESF_DZ_TX_KER_TYPE_LBN 63
285
+#define	ESF_DZ_TX_KER_TYPE_WIDTH 1
286
+#define	ESF_DZ_TX_KER_CONT_LBN 62
287
+#define	ESF_DZ_TX_KER_CONT_WIDTH 1
288
+#define	ESF_DZ_TX_KER_BYTE_CNT_LBN 48
289
+#define	ESF_DZ_TX_KER_BYTE_CNT_WIDTH 14
290
+#define	ESF_DZ_TX_KER_BUF_ADDR_LBN 0
291
+#define	ESF_DZ_TX_KER_BUF_ADDR_WIDTH 48
292
+
293
+/* TX_PIO_DESC */
294
+#define	ESF_DZ_TX_PIO_TYPE_LBN 63
295
+#define	ESF_DZ_TX_PIO_TYPE_WIDTH 1
296
+#define	ESF_DZ_TX_PIO_OPT_LBN 60
297
+#define	ESF_DZ_TX_PIO_OPT_WIDTH 3
298
+#define	ESF_DZ_TX_PIO_CONT_LBN 59
299
+#define	ESF_DZ_TX_PIO_CONT_WIDTH 1
300
+#define	ESF_DZ_TX_PIO_BYTE_CNT_LBN 32
301
+#define	ESF_DZ_TX_PIO_BYTE_CNT_WIDTH 12
302
+#define	ESF_DZ_TX_PIO_BUF_ADDR_LBN 0
303
+#define	ESF_DZ_TX_PIO_BUF_ADDR_WIDTH 12
304
+
305
+/* TX_TSO_DESC */
306
+#define	ESF_DZ_TX_DESC_IS_OPT_LBN 63
307
+#define	ESF_DZ_TX_DESC_IS_OPT_WIDTH 1
308
+#define	ESF_DZ_TX_OPTION_TYPE_LBN 60
309
+#define	ESF_DZ_TX_OPTION_TYPE_WIDTH 3
310
+#define	ESE_DZ_TX_OPTION_DESC_TSO 7
311
+#define	ESE_DZ_TX_OPTION_DESC_VLAN 6
312
+#define	ESE_DZ_TX_OPTION_DESC_CRC_CSUM 0
313
+#define	ESF_DZ_TX_TSO_TCP_FLAGS_LBN 48
314
+#define	ESF_DZ_TX_TSO_TCP_FLAGS_WIDTH 8
315
+#define	ESF_DZ_TX_TSO_IP_ID_LBN 32
316
+#define	ESF_DZ_TX_TSO_IP_ID_WIDTH 16
317
+#define	ESF_DZ_TX_TSO_TCP_SEQNO_LBN 0
318
+#define	ESF_DZ_TX_TSO_TCP_SEQNO_WIDTH 32
319
+
320
+/*************************************************************************/
321
+
322
+/* TX_DESC_UPD_REG: Transmit descriptor update register.
323
+ * We may write just one dword of these registers.
324
+ */
325
+#define ER_DZ_TX_DESC_UPD_DWORD		(ER_DZ_TX_DESC_UPD + 2 * 4)
326
+#define ERF_DZ_TX_DESC_WPTR_DWORD_LBN	(ERF_DZ_TX_DESC_WPTR_LBN - 2 * 32)
327
+#define ERF_DZ_TX_DESC_WPTR_DWORD_WIDTH	ERF_DZ_TX_DESC_WPTR_WIDTH
328
+
329
+/* The workaround for bug 35388 requires multiplexing writes through
330
+ * the TX_DESC_UPD_DWORD address.
331
+ * TX_DESC_UPD: 0ppppppppppp               (bit 11 lost)
332
+ * EVQ_RPTR:    1000hhhhhhhh, 1001llllllll (split into high and low bits)
333
+ * EVQ_TMR:     11mmvvvvvvvv               (bits 8:13 of value lost)
334
+ */
335
+#define ER_DD_EVQ_INDIRECT		ER_DZ_TX_DESC_UPD_DWORD
336
+#define ERF_DD_EVQ_IND_RPTR_FLAGS_LBN	8
337
+#define ERF_DD_EVQ_IND_RPTR_FLAGS_WIDTH	4
338
+#define EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH	8
339
+#define EFE_DD_EVQ_IND_RPTR_FLAGS_LOW	9
340
+#define ERF_DD_EVQ_IND_RPTR_LBN		0
341
+#define ERF_DD_EVQ_IND_RPTR_WIDTH	8
342
+#define ERF_DD_EVQ_IND_TIMER_FLAGS_LBN	10
343
+#define ERF_DD_EVQ_IND_TIMER_FLAGS_WIDTH 2
344
+#define EFE_DD_EVQ_IND_TIMER_FLAGS	3
345
+#define ERF_DD_EVQ_IND_TIMER_MODE_LBN	8
346
+#define ERF_DD_EVQ_IND_TIMER_MODE_WIDTH	2
347
+#define ERF_DD_EVQ_IND_TIMER_VAL_LBN	0
348
+#define ERF_DD_EVQ_IND_TIMER_VAL_WIDTH	8
349
+
350
+/* TX_PIOBUF
351
+ * PIO buffer aperture (paged)
352
+ */
353
+#define ER_DZ_TX_PIOBUF 4096
354
+#define ER_DZ_TX_PIOBUF_SIZE 2048
355
+
356
+/* RX packet prefix */
357
+#define ES_DZ_RX_PREFIX_HASH_OFST 0
358
+#define ES_DZ_RX_PREFIX_VLAN1_OFST 4
359
+#define ES_DZ_RX_PREFIX_VLAN2_OFST 6
360
+#define ES_DZ_RX_PREFIX_PKTLEN_OFST 8
361
+#define ES_DZ_RX_PREFIX_TSTAMP_OFST 10
362
+#define ES_DZ_RX_PREFIX_SIZE 14
363
+
364
+#endif /* EFX_EF10_REGS_H */

+ 555
- 0
src/drivers/net/sfc/efx_bitfield.h View File

@@ -0,0 +1,555 @@
1
+/****************************************************************************
2
+ *
3
+ * Driver for Solarflare network controllers and boards
4
+ * Copyright 2005-2006 Fen Systems Ltd.
5
+ * Copyright 2006-2017 Solarflare Communications Inc.
6
+ *
7
+ * This program is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU General Public License as
9
+ * published by the Free Software Foundation; either version 2 of the
10
+ * License, or any later version.
11
+ *
12
+ * You can also choose to distribute this program under the terms of
13
+ * the Unmodified Binary Distribution Licence (as given in the file
14
+ * COPYING.UBDL), provided that you have satisfied its requirements.
15
+ */
16
+
17
+#ifndef EFX_BITFIELD_H
18
+#define EFX_BITFIELD_H
19
+
20
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
21
+
22
+#include <byteswap.h>
23
+
24
+/** \file efx_bitfield.h
25
+ * Efx bitfield access
26
+ *
27
+ * Efx NICs make extensive use of bitfields up to 128 bits
28
+ * wide.  Since there is no native 128-bit datatype on most systems,
29
+ * and since 64-bit datatypes are inefficient on 32-bit systems and
30
+ * vice versa, we wrap accesses in a way that uses the most efficient
31
+ * datatype.
32
+ *
33
+ * The NICs are PCI devices and therefore little-endian.  Since most
34
+ * of the quantities that we deal with are DMAed to/from host memory,
35
+ * we define our datatypes (efx_oword_t, efx_qword_t and
36
+ * efx_dword_t) to be little-endian.
37
+ */
38
+
39
+/* Lowest bit numbers and widths */
40
+#define EFX_DUMMY_FIELD_LBN 0
41
+#define EFX_DUMMY_FIELD_WIDTH 0
42
+#define EFX_WORD_0_LBN 0
43
+#define EFX_WORD_0_WIDTH 16
44
+#define EFX_WORD_1_LBN 16
45
+#define EFX_WORD_1_WIDTH 16
46
+#define EFX_DWORD_0_LBN 0
47
+#define EFX_DWORD_0_WIDTH 32
48
+#define EFX_DWORD_1_LBN 32
49
+#define EFX_DWORD_1_WIDTH 32
50
+#define EFX_DWORD_2_LBN 64
51
+#define EFX_DWORD_2_WIDTH 32
52
+#define EFX_DWORD_3_LBN 96
53
+#define EFX_DWORD_3_WIDTH 32
54
+#define EFX_QWORD_0_LBN 0
55
+#define EFX_QWORD_0_WIDTH 64
56
+
57
+/* Specified attribute (e.g. LBN) of the specified field */
58
+#define EFX_VAL(field, attribute) field ## _ ## attribute
59
+/* Low bit number of the specified field */
60
+#define EFX_LOW_BIT(field) EFX_VAL(field, LBN)
61
+/* Bit width of the specified field */
62
+#define EFX_WIDTH(field) EFX_VAL(field, WIDTH)
63
+/* High bit number of the specified field */
64
+#define EFX_HIGH_BIT(field) (EFX_LOW_BIT(field) + EFX_WIDTH(field) - 1)
65
+/* Mask equal in width to the specified field.
66
+ *
67
+ * For example, a field with width 5 would have a mask of 0x1f.
68
+ *
69
+ * The maximum width mask that can be generated is 64 bits.
70
+ */
71
+#define EFX_MASK64(width)			\
72
+	((width) == 64 ? ~((u64) 0) :		\
73
+	 (((((u64) 1) << (width))) - 1))
74
+
75
+/* Mask equal in width to the specified field.
76
+ *
77
+ * For example, a field with width 5 would have a mask of 0x1f.
78
+ *
79
+ * The maximum width mask that can be generated is 32 bits.  Use
80
+ * EFX_MASK64 for higher width fields.
81
+ */
82
+#define EFX_MASK32(width)			\
83
+	((width) == 32 ? ~((u32) 0) :		\
84
+	 (((((u32) 1) << (width))) - 1))
85
+
86
+/** A doubleword (4 byte) datatype - little-endian in HW */
87
+typedef union efx_dword {
88
+	__le32 u32[1];
89
+} efx_dword_t;
90
+
91
+/** A quadword (8 byte) datatype - little-endian in HW */
92
+typedef union efx_qword {
93
+	__le64 u64[1];
94
+	__le32 u32[2];
95
+	efx_dword_t dword[2];
96
+} efx_qword_t;
97
+
98
+/** An octword (eight-word, so 16 byte) datatype - little-endian in HW */
99
+typedef union efx_oword {
100
+	__le64 u64[2];
101
+	efx_qword_t qword[2];
102
+	__le32 u32[4];
103
+	efx_dword_t dword[4];
104
+} efx_oword_t;
105
+
106
+/* Format string and value expanders for printk */
107
+#define EFX_DWORD_FMT "%08x"
108
+#define EFX_QWORD_FMT "%08x:%08x"
109
+#define EFX_OWORD_FMT "%08x:%08x:%08x:%08x"
110
+#define EFX_DWORD_VAL(dword)				\
111
+	((unsigned int) le32_to_cpu((dword).u32[0]))
112
+#define EFX_QWORD_VAL(qword)				\
113
+	((unsigned int) le32_to_cpu((qword).u32[1])),	\
114
+	((unsigned int) le32_to_cpu((qword).u32[0]))
115
+#define EFX_OWORD_VAL(oword)				\
116
+	((unsigned int) le32_to_cpu((oword).u32[3])),	\
117
+	((unsigned int) le32_to_cpu((oword).u32[2])),	\
118
+	((unsigned int) le32_to_cpu((oword).u32[1])),	\
119
+	((unsigned int) le32_to_cpu((oword).u32[0]))
120
+
121
+/*
122
+ * Extract bit field portion [low,high) from the native-endian element
123
+ * which contains bits [min,max).
124
+ *
125
+ * For example, suppose "element" represents the high 32 bits of a
126
+ * 64-bit value, and we wish to extract the bits belonging to the bit
127
+ * field occupying bits 28-45 of this 64-bit value.
128
+ *
129
+ * Then EFX_EXTRACT ( element, 32, 63, 28, 45 ) would give
130
+ *
131
+ *   ( element ) << 4
132
+ *
133
+ * The result will contain the relevant bits filled in in the range
134
+ * [0,high-low), with garbage in bits [high-low+1,...).
135
+ */
136
+#define EFX_EXTRACT_NATIVE(native_element, min, max, low, high)		\
137
+	((low) > (max) || (high) < (min) ? 0 :				\
138
+	 (low) > (min) ?						\
139
+	 (native_element) >> ((low) - (min)) :				\
140
+	 (native_element) << ((min) - (low)))
141
+
142
+/*
143
+ * Extract bit field portion [low,high) from the 64-bit little-endian
144
+ * element which contains bits [min,max)
145
+ */
146
+#define EFX_EXTRACT64(element, min, max, low, high)			\
147
+	EFX_EXTRACT_NATIVE(le64_to_cpu(element), min, max, low, high)
148
+
149
+/*
150
+ * Extract bit field portion [low,high) from the 32-bit little-endian
151
+ * element which contains bits [min,max)
152
+ */
153
+#define EFX_EXTRACT32(element, min, max, low, high)			\
154
+	EFX_EXTRACT_NATIVE(le32_to_cpu(element), min, max, low, high)
155
+
156
+#define EFX_EXTRACT_OWORD64(oword, low, high)				\
157
+	((EFX_EXTRACT64((oword).u64[0], 0, 63, low, high) |		\
158
+	  EFX_EXTRACT64((oword).u64[1], 64, 127, low, high)) &		\
159
+	 EFX_MASK64((high) + 1 - (low)))
160
+
161
+#define EFX_EXTRACT_QWORD64(qword, low, high)				\
162
+	(EFX_EXTRACT64((qword).u64[0], 0, 63, low, high) &		\
163
+	 EFX_MASK64((high) + 1 - (low)))
164
+
165
+#define EFX_EXTRACT_OWORD32(oword, low, high)				\
166
+	((EFX_EXTRACT32((oword).u32[0], 0, 31, low, high) |		\
167
+	  EFX_EXTRACT32((oword).u32[1], 32, 63, low, high) |		\
168
+	  EFX_EXTRACT32((oword).u32[2], 64, 95, low, high) |		\
169
+	  EFX_EXTRACT32((oword).u32[3], 96, 127, low, high)) &		\
170
+	 EFX_MASK32((high) + 1 - (low)))
171
+
172
+#define EFX_EXTRACT_QWORD32(qword, low, high)				\
173
+	((EFX_EXTRACT32((qword).u32[0], 0, 31, low, high) |		\
174
+	  EFX_EXTRACT32((qword).u32[1], 32, 63, low, high)) &		\
175
+	 EFX_MASK32((high) + 1 - (low)))
176
+
177
+#define EFX_EXTRACT_DWORD(dword, low, high)			\
178
+	(EFX_EXTRACT32((dword).u32[0], 0, 31, low, high) &	\
179
+	 EFX_MASK32((high) + 1 - (low)))
180
+
181
+#define EFX_OWORD_FIELD64(oword, field)				\
182
+	EFX_EXTRACT_OWORD64(oword, EFX_LOW_BIT(field),		\
183
+			    EFX_HIGH_BIT(field))
184
+
185
+#define EFX_QWORD_FIELD64(qword, field)				\
186
+	EFX_EXTRACT_QWORD64(qword, EFX_LOW_BIT(field),		\
187
+			    EFX_HIGH_BIT(field))
188
+
189
+#define EFX_OWORD_FIELD32(oword, field)				\
190
+	EFX_EXTRACT_OWORD32(oword, EFX_LOW_BIT(field),		\
191
+			    EFX_HIGH_BIT(field))
192
+
193
+#define EFX_QWORD_FIELD32(qword, field)				\
194
+	EFX_EXTRACT_QWORD32(qword, EFX_LOW_BIT(field),		\
195
+			    EFX_HIGH_BIT(field))
196
+
197
+#define EFX_DWORD_FIELD(dword, field)				\
198
+	EFX_EXTRACT_DWORD(dword, EFX_LOW_BIT(field),		\
199
+			  EFX_HIGH_BIT(field))
200
+
201
+#define EFX_OWORD_IS_ZERO64(oword)					\
202
+	(((oword).u64[0] | (oword).u64[1]) == (__force __le64) 0)
203
+
204
+#define EFX_QWORD_IS_ZERO64(qword)					\
205
+	(((qword).u64[0]) == (__force __le64) 0)
206
+
207
+#define EFX_OWORD_IS_ZERO32(oword)					     \
208
+	(((oword).u32[0] | (oword).u32[1] | (oword).u32[2] | (oword).u32[3]) \
209
+	 == (__force __le32) 0)
210
+
211
+#define EFX_QWORD_IS_ZERO32(qword)					\
212
+	(((qword).u32[0] | (qword).u32[1]) == (__force __le32) 0)
213
+
214
+#define EFX_DWORD_IS_ZERO(dword)					\
215
+	(((dword).u32[0]) == (__force __le32) 0)
216
+
217
+#define EFX_OWORD_IS_ALL_ONES64(oword)					\
218
+	(((oword).u64[0] & (oword).u64[1]) == ~((__force __le64) 0))
219
+
220
+#define EFX_QWORD_IS_ALL_ONES64(qword)					\
221
+	((qword).u64[0] == ~((__force __le64) 0))
222
+
223
+#define EFX_OWORD_IS_ALL_ONES32(oword)					\
224
+	(((oword).u32[0] & (oword).u32[1] & (oword).u32[2] & (oword).u32[3]) \
225
+	 == ~((__force __le32) 0))
226
+
227
+#define EFX_QWORD_IS_ALL_ONES32(qword)					\
228
+	(((qword).u32[0] & (qword).u32[1]) == ~((__force __le32) 0))
229
+
230
+#define EFX_DWORD_IS_ALL_ONES(dword)					\
231
+	((dword).u32[0] == ~((__force __le32) 0))
232
+
233
+#if BITS_PER_LONG == 64
234
+#define EFX_OWORD_FIELD		EFX_OWORD_FIELD64
235
+#define EFX_QWORD_FIELD		EFX_QWORD_FIELD64
236
+#define EFX_OWORD_IS_ZERO	EFX_OWORD_IS_ZERO64
237
+#define EFX_QWORD_IS_ZERO	EFX_QWORD_IS_ZERO64
238
+#define EFX_OWORD_IS_ALL_ONES	EFX_OWORD_IS_ALL_ONES64
239
+#define EFX_QWORD_IS_ALL_ONES	EFX_QWORD_IS_ALL_ONES64
240
+#else
241
+#define EFX_OWORD_FIELD		EFX_OWORD_FIELD32
242
+#define EFX_QWORD_FIELD		EFX_QWORD_FIELD32
243
+#define EFX_OWORD_IS_ZERO	EFX_OWORD_IS_ZERO32
244
+#define EFX_QWORD_IS_ZERO	EFX_QWORD_IS_ZERO32
245
+#define EFX_OWORD_IS_ALL_ONES	EFX_OWORD_IS_ALL_ONES32
246
+#define EFX_QWORD_IS_ALL_ONES	EFX_QWORD_IS_ALL_ONES32
247
+#endif
248
+
249
+/*
250
+ * Construct bit field portion
251
+ *
252
+ * Creates the portion of the bit field [low,high) that lies within
253
+ * the range [min,max).
254
+ */
255
+#define EFX_INSERT_NATIVE64(min, max, low, high, value)		\
256
+	(((low > max) || (high < min)) ? 0 :			\
257
+	 ((low > min) ?						\
258
+	  (((u64) (value)) << (low - min)) :		\
259
+	  (((u64) (value)) >> (min - low))))
260
+
261
+#define EFX_INSERT_NATIVE32(min, max, low, high, value)		\
262
+	(((low > max) || (high < min)) ? 0 :			\
263
+	 ((low > min) ?						\
264
+	  (((u32) (value)) << (low - min)) :		\
265
+	  (((u32) (value)) >> (min - low))))
266
+
267
+#define EFX_INSERT_NATIVE(min, max, low, high, value)		\
268
+	((((max - min) >= 32) || ((high - low) >= 32)) ?	\
269
+	 EFX_INSERT_NATIVE64(min, max, low, high, value) :	\
270
+	 EFX_INSERT_NATIVE32(min, max, low, high, value))
271
+
272
+/*
273
+ * Construct bit field portion
274
+ *
275
+ * Creates the portion of the named bit field that lies within the
276
+ * range [min,max).
277
+ */
278
+#define EFX_INSERT_FIELD_NATIVE(min, max, field, value)		\
279
+	EFX_INSERT_NATIVE(min, max, EFX_LOW_BIT(field),		\
280
+			  EFX_HIGH_BIT(field), value)
281
+
282
+/*
283
+ * Construct bit field
284
+ *
285
+ * Creates the portion of the named bit fields that lie within the
286
+ * range [min,max).
287
+ */
288
+#define EFX_INSERT_FIELDS_NATIVE(min, max,				\
289
+				 field1, value1,			\
290
+				 field2, value2,			\
291
+				 field3, value3,			\
292
+				 field4, value4,			\
293
+				 field5, value5,			\
294
+				 field6, value6,			\
295
+				 field7, value7,			\
296
+				 field8, value8,			\
297
+				 field9, value9,			\
298
+				 field10, value10)			\
299
+	(EFX_INSERT_FIELD_NATIVE((min), (max), field1, (value1)) |	\
300
+	 EFX_INSERT_FIELD_NATIVE((min), (max), field2, (value2)) |	\
301
+	 EFX_INSERT_FIELD_NATIVE((min), (max), field3, (value3)) |	\
302
+	 EFX_INSERT_FIELD_NATIVE((min), (max), field4, (value4)) |	\
303
+	 EFX_INSERT_FIELD_NATIVE((min), (max), field5, (value5)) |	\
304
+	 EFX_INSERT_FIELD_NATIVE((min), (max), field6, (value6)) |	\
305
+	 EFX_INSERT_FIELD_NATIVE((min), (max), field7, (value7)) |	\
306
+	 EFX_INSERT_FIELD_NATIVE((min), (max), field8, (value8)) |	\
307
+	 EFX_INSERT_FIELD_NATIVE((min), (max), field9, (value9)) |	\
308
+	 EFX_INSERT_FIELD_NATIVE((min), (max), field10, (value10)))
309
+
310
+#define EFX_INSERT_FIELDS64(...)				\
311
+	cpu_to_le64(EFX_INSERT_FIELDS_NATIVE(__VA_ARGS__))
312
+
313
+#define EFX_INSERT_FIELDS32(...)				\
314
+	cpu_to_le32(EFX_INSERT_FIELDS_NATIVE(__VA_ARGS__))
315
+
316
+#define EFX_POPULATE_OWORD64(oword, ...) do {				\
317
+	(oword).u64[0] = EFX_INSERT_FIELDS64(0, 63, __VA_ARGS__);	\
318
+	(oword).u64[1] = EFX_INSERT_FIELDS64(64, 127, __VA_ARGS__);	\
319
+	} while (0)
320
+
321
+#define EFX_POPULATE_QWORD64(qword, ...) do {				\
322
+	(qword).u64[0] = EFX_INSERT_FIELDS64(0, 63, __VA_ARGS__);	\
323
+	} while (0)
324
+
325
+#define EFX_POPULATE_OWORD32(oword, ...) do {				\
326
+	(oword).u32[0] = EFX_INSERT_FIELDS32(0, 31, __VA_ARGS__);	\
327
+	(oword).u32[1] = EFX_INSERT_FIELDS32(32, 63, __VA_ARGS__);	\
328
+	(oword).u32[2] = EFX_INSERT_FIELDS32(64, 95, __VA_ARGS__);	\
329
+	(oword).u32[3] = EFX_INSERT_FIELDS32(96, 127, __VA_ARGS__);	\
330
+	} while (0)
331
+
332
+#define EFX_POPULATE_QWORD32(qword, ...) do {				\
333
+	(qword).u32[0] = EFX_INSERT_FIELDS32(0, 31, __VA_ARGS__);	\
334
+	(qword).u32[1] = EFX_INSERT_FIELDS32(32, 63, __VA_ARGS__);	\
335
+	} while (0)
336
+
337
+#define EFX_POPULATE_DWORD(dword, ...) do {				\
338
+	(dword).u32[0] = EFX_INSERT_FIELDS32(0, 31, __VA_ARGS__);	\
339
+	} while (0)
340
+
341
+#if BITS_PER_LONG == 64
342
+#define EFX_POPULATE_OWORD EFX_POPULATE_OWORD64
343
+#define EFX_POPULATE_QWORD EFX_POPULATE_QWORD64
344
+#else
345
+#define EFX_POPULATE_OWORD EFX_POPULATE_OWORD32
346
+#define EFX_POPULATE_QWORD EFX_POPULATE_QWORD32
347
+#endif
348
+
349
+/* Populate an octword field with various numbers of arguments */
350
+#define EFX_POPULATE_OWORD_10 EFX_POPULATE_OWORD
351
+#define EFX_POPULATE_OWORD_9(oword, ...) \
352
+	EFX_POPULATE_OWORD_10(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
353
+#define EFX_POPULATE_OWORD_8(oword, ...) \
354
+	EFX_POPULATE_OWORD_9(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
355
+#define EFX_POPULATE_OWORD_7(oword, ...) \
356
+	EFX_POPULATE_OWORD_8(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
357
+#define EFX_POPULATE_OWORD_6(oword, ...) \
358
+	EFX_POPULATE_OWORD_7(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
359
+#define EFX_POPULATE_OWORD_5(oword, ...) \
360
+	EFX_POPULATE_OWORD_6(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
361
+#define EFX_POPULATE_OWORD_4(oword, ...) \
362
+	EFX_POPULATE_OWORD_5(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
363
+#define EFX_POPULATE_OWORD_3(oword, ...) \
364
+	EFX_POPULATE_OWORD_4(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
365
+#define EFX_POPULATE_OWORD_2(oword, ...) \
366
+	EFX_POPULATE_OWORD_3(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
367
+#define EFX_POPULATE_OWORD_1(oword, ...) \
368
+	EFX_POPULATE_OWORD_2(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
369
+#define EFX_ZERO_OWORD(oword) \
370
+	EFX_POPULATE_OWORD_1(oword, EFX_DUMMY_FIELD, 0)
371
+#define EFX_SET_OWORD(oword) \
372
+	EFX_POPULATE_OWORD_4(oword, \
373
+			     EFX_DWORD_0, 0xffffffff, \
374
+			     EFX_DWORD_1, 0xffffffff, \
375
+			     EFX_DWORD_2, 0xffffffff, \
376
+			     EFX_DWORD_3, 0xffffffff)
377
+
378
+/* Populate a quadword field with various numbers of arguments */
379
+#define EFX_POPULATE_QWORD_10 EFX_POPULATE_QWORD
380
+#define EFX_POPULATE_QWORD_9(qword, ...) \
381
+	EFX_POPULATE_QWORD_10(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
382
+#define EFX_POPULATE_QWORD_8(qword, ...) \
383
+	EFX_POPULATE_QWORD_9(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
384
+#define EFX_POPULATE_QWORD_7(qword, ...) \
385
+	EFX_POPULATE_QWORD_8(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
386
+#define EFX_POPULATE_QWORD_6(qword, ...) \
387
+	EFX_POPULATE_QWORD_7(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
388
+#define EFX_POPULATE_QWORD_5(qword, ...) \
389
+	EFX_POPULATE_QWORD_6(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
390
+#define EFX_POPULATE_QWORD_4(qword, ...) \
391
+	EFX_POPULATE_QWORD_5(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
392
+#define EFX_POPULATE_QWORD_3(qword, ...) \
393
+	EFX_POPULATE_QWORD_4(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
394
+#define EFX_POPULATE_QWORD_2(qword, ...) \
395
+	EFX_POPULATE_QWORD_3(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
396
+#define EFX_POPULATE_QWORD_1(qword, ...) \
397
+	EFX_POPULATE_QWORD_2(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
398
+#define EFX_ZERO_QWORD(qword) \
399
+	EFX_POPULATE_QWORD_1(qword, EFX_DUMMY_FIELD, 0)
400
+#define EFX_SET_QWORD(qword) \
401
+	EFX_POPULATE_QWORD_2(qword, \
402
+			     EFX_DWORD_0, 0xffffffff, \
403
+			     EFX_DWORD_1, 0xffffffff)
404
+
405
+/* Populate a dword field with various numbers of arguments */
406
+#define EFX_POPULATE_DWORD_10 EFX_POPULATE_DWORD
407
+#define EFX_POPULATE_DWORD_9(dword, ...) \
408
+	EFX_POPULATE_DWORD_10(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
409
+#define EFX_POPULATE_DWORD_8(dword, ...) \
410
+	EFX_POPULATE_DWORD_9(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
411
+#define EFX_POPULATE_DWORD_7(dword, ...) \
412
+	EFX_POPULATE_DWORD_8(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
413
+#define EFX_POPULATE_DWORD_6(dword, ...) \
414
+	EFX_POPULATE_DWORD_7(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
415
+#define EFX_POPULATE_DWORD_5(dword, ...) \
416
+	EFX_POPULATE_DWORD_6(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
417
+#define EFX_POPULATE_DWORD_4(dword, ...) \
418
+	EFX_POPULATE_DWORD_5(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
419
+#define EFX_POPULATE_DWORD_3(dword, ...) \
420
+	EFX_POPULATE_DWORD_4(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
421
+#define EFX_POPULATE_DWORD_2(dword, ...) \
422
+	EFX_POPULATE_DWORD_3(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
423
+#define EFX_POPULATE_DWORD_1(dword, ...) \
424
+	EFX_POPULATE_DWORD_2(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
425
+#define EFX_ZERO_DWORD(dword) \
426
+	EFX_POPULATE_DWORD_1(dword, EFX_DUMMY_FIELD, 0)
427
+#define EFX_SET_DWORD(dword) \
428
+	EFX_POPULATE_DWORD_1(dword, EFX_DWORD_0, 0xffffffff)
429
+
430
+/*
431
+ * Modify a named field within an already-populated structure.  Used
432
+ * for read-modify-write operations.
433
+ *
434
+ */
435
+#define EFX_INVERT_OWORD(oword) do {		\
436
+	(oword).u64[0] = ~((oword).u64[0]);	\
437
+	(oword).u64[1] = ~((oword).u64[1]);	\
438
+	} while (0)
439
+
440
+#define EFX_AND_OWORD(oword, from, mask)			\
441
+	do {							\
442
+		(oword).u64[0] = (from).u64[0] & (mask).u64[0];	\
443
+		(oword).u64[1] = (from).u64[1] & (mask).u64[1];	\
444
+	} while (0)
445
+
446
+#define EFX_AND_QWORD(qword, from, mask)			\
447
+		(qword).u64[0] = (from).u64[0] & (mask).u64[0]
448
+
449
+#define EFX_OR_OWORD(oword, from, mask)				\
450
+	do {							\
451
+		(oword).u64[0] = (from).u64[0] | (mask).u64[0];	\
452
+		(oword).u64[1] = (from).u64[1] | (mask).u64[1];	\
453
+	} while (0)
454
+
455
+#define EFX_INSERT64(min, max, low, high, value)			\
456
+	cpu_to_le64(EFX_INSERT_NATIVE(min, max, low, high, value))
457
+
458
+#define EFX_INSERT32(min, max, low, high, value)			\
459
+	cpu_to_le32(EFX_INSERT_NATIVE(min, max, low, high, value))
460
+
461
+#define EFX_INPLACE_MASK64(min, max, low, high)				\
462
+	EFX_INSERT64(min, max, low, high, EFX_MASK64((high) + 1 - (low)))
463
+
464
+#define EFX_INPLACE_MASK32(min, max, low, high)				\
465
+	EFX_INSERT32(min, max, low, high, EFX_MASK32((high) + 1 - (low)))
466
+
467
+#define EFX_SET_OWORD64(oword, low, high, value) do {			\
468
+	(oword).u64[0] = (((oword).u64[0]				\
469
+			   & ~EFX_INPLACE_MASK64(0,  63, low, high))	\
470
+			  | EFX_INSERT64(0,  63, low, high, value));	\
471
+	(oword).u64[1] = (((oword).u64[1]				\
472
+			   & ~EFX_INPLACE_MASK64(64, 127, low, high))	\
473
+			  | EFX_INSERT64(64, 127, low, high, value));	\
474
+	} while (0)
475
+
476
+#define EFX_SET_QWORD64(qword, low, high, value) do {			\
477
+	(qword).u64[0] = (((qword).u64[0]				\
478
+			   & ~EFX_INPLACE_MASK64(0, 63, low, high))	\
479
+			  | EFX_INSERT64(0, 63, low, high, value));	\
480
+	} while (0)
481
+
482
+#define EFX_SET_OWORD32(oword, low, high, value) do {			\
483
+	(oword).u32[0] = (((oword).u32[0]				\
484
+			   & ~EFX_INPLACE_MASK32(0, 31, low, high))	\
485
+			  | EFX_INSERT32(0, 31, low, high, value));	\
486
+	(oword).u32[1] = (((oword).u32[1]				\
487
+			   & ~EFX_INPLACE_MASK32(32, 63, low, high))	\
488
+			  | EFX_INSERT32(32, 63, low, high, value));	\
489
+	(oword).u32[2] = (((oword).u32[2]				\
490
+			   & ~EFX_INPLACE_MASK32(64, 95, low, high))	\
491
+			  | EFX_INSERT32(64, 95, low, high, value));	\
492
+	(oword).u32[3] = (((oword).u32[3]				\
493
+			   & ~EFX_INPLACE_MASK32(96, 127, low, high))	\
494
+			  | EFX_INSERT32(96, 127, low, high, value));	\
495
+	} while (0)
496
+
497
+#define EFX_SET_QWORD32(qword, low, high, value) do {			\
498
+	(qword).u32[0] = (((qword).u32[0]				\
499
+			   & ~EFX_INPLACE_MASK32(0, 31, low, high))	\
500
+			  | EFX_INSERT32(0, 31, low, high, value));	\
501
+	(qword).u32[1] = (((qword).u32[1]				\
502
+			   & ~EFX_INPLACE_MASK32(32, 63, low, high))	\
503
+			  | EFX_INSERT32(32, 63, low, high, value));	\
504
+	} while (0)
505
+
506
+#define EFX_SET_DWORD32(dword, low, high, value) do {			\
507
+	(dword).u32[0] = (((dword).u32[0]				\
508
+			   & ~EFX_INPLACE_MASK32(0, 31, low, high))	\
509
+			  | EFX_INSERT32(0, 31, low, high, value));	\
510
+	} while (0)
511
+
512
+#define EFX_SET_OWORD_FIELD64(oword, field, value)			\
513
+	EFX_SET_OWORD64(oword, EFX_LOW_BIT(field),			\
514
+			 EFX_HIGH_BIT(field), value)
515
+
516
+#define EFX_SET_QWORD_FIELD64(qword, field, value)			\
517
+	EFX_SET_QWORD64(qword, EFX_LOW_BIT(field),			\
518
+			 EFX_HIGH_BIT(field), value)
519
+
520
+#define EFX_SET_OWORD_FIELD32(oword, field, value)			\
521
+	EFX_SET_OWORD32(oword, EFX_LOW_BIT(field),			\
522
+			 EFX_HIGH_BIT(field), value)
523
+
524
+#define EFX_SET_QWORD_FIELD32(qword, field, value)			\
525
+	EFX_SET_QWORD32(qword, EFX_LOW_BIT(field),			\
526
+			 EFX_HIGH_BIT(field), value)
527
+
528
+#define EFX_SET_DWORD_FIELD(dword, field, value)			\
529
+	EFX_SET_DWORD32(dword, EFX_LOW_BIT(field),			\
530
+			 EFX_HIGH_BIT(field), value)
531
+
532
+
533
+
534
+#if BITS_PER_LONG == 64
535
+#define EFX_SET_OWORD_FIELD EFX_SET_OWORD_FIELD64
536
+#define EFX_SET_QWORD_FIELD EFX_SET_QWORD_FIELD64
537
+#else
538
+#define EFX_SET_OWORD_FIELD EFX_SET_OWORD_FIELD32
539
+#define EFX_SET_QWORD_FIELD EFX_SET_QWORD_FIELD32
540
+#endif
541
+
542
+/* Used to avoid compiler warnings about shift range exceeding width
543
+ * of the data types when dma_addr_t is only 32 bits wide.
544
+ */
545
+#define DMA_ADDR_T_WIDTH	(8 * sizeof(dma_addr_t))
546
+#define EFX_DMA_TYPE_WIDTH(width) \
547
+	(((width) < DMA_ADDR_T_WIDTH) ? (width) : DMA_ADDR_T_WIDTH)
548
+
549
+
550
+/* Static initialiser */
551
+#define EFX_OWORD32(a, b, c, d)				\
552
+	{ .u32 = { cpu_to_le32(a), cpu_to_le32(b),	\
553
+		   cpu_to_le32(c), cpu_to_le32(d) } }
554
+
555
+#endif /* EFX_BITFIELD_H */

+ 97
- 0
src/drivers/net/sfc/efx_common.c View File

@@ -0,0 +1,97 @@
1
+/**************************************************************************
2
+ *
3
+ * Driver datapath common code for Solarflare network cards
4
+ *
5
+ * Written by Shradha Shah <sshah@solarflare.com>
6
+ *
7
+ * Copyright Fen Systems Ltd. 2005
8
+ * Copyright Level 5 Networks Inc. 2005
9
+ * Copyright 2006-2017 Solarflare Communications Inc.
10
+ *
11
+ * This program is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU General Public License as
13
+ * published by the Free Software Foundation; either version 2 of the
14
+ * License, or any later version.
15
+ *
16
+ * You can also choose to distribute this program under the terms of
17
+ * the Unmodified Binary Distribution Licence (as given in the file
18
+ * COPYING.UBDL), provided that you have satisfied its requirements.
19
+ *
20
+ ***************************************************************************/
21
+#include <stdint.h>
22
+#include <stdlib.h>
23
+#include <stdio.h>
24
+#include <unistd.h>
25
+#include <errno.h>
26
+#include <assert.h>
27
+#include <byteswap.h>
28
+#include <ipxe/io.h>
29
+#include <ipxe/pci.h>
30
+#include <ipxe/malloc.h>
31
+#include <ipxe/iobuf.h>
32
+#include <ipxe/netdevice.h>
33
+#include "efx_common.h"
34
+#include "efx_bitfield.h"
35
+#include "mc_driver_pcol.h"
36
+
37
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
38
+
39
+/*******************************************************************************
40
+ *
41
+ *
42
+ * Low-level hardware access
43
+ *
44
+ *
45
+ ******************************************************************************/
46
+
47
+void
48
+efx_writel(struct efx_nic *efx, efx_dword_t *value, unsigned int reg)
49
+{
50
+	DBGCIO(efx, "Writing partial register %x with " EFX_DWORD_FMT "\n",
51
+	       reg, EFX_DWORD_VAL(*value));
52
+	_efx_writel(efx, value->u32[0], reg);
53
+}
54
+
55
+void
56
+efx_readl(struct efx_nic *efx, efx_dword_t *value, unsigned int reg)
57
+{
58
+	value->u32[0] = _efx_readl(efx, reg);
59
+	DBGCIO(efx, "Read from register %x, got " EFX_DWORD_FMT "\n",
60
+	       reg, EFX_DWORD_VAL(*value));
61
+}
62
+
63
+/*******************************************************************************
64
+ *
65
+ *
66
+ * Inititialization and Close
67
+ *
68
+ *
69
+ ******************************************************************************/
70
+void efx_probe(struct net_device *netdev, enum efx_revision revision)
71
+{
72
+	struct efx_nic *efx = netdev_priv(netdev);
73
+	struct pci_device *pci = container_of(netdev->dev,
74
+					      struct pci_device, dev);
75
+
76
+	efx->netdev = netdev;
77
+	efx->revision = revision;
78
+
79
+	/* MMIO bar */
80
+	efx->mmio_start = pci_bar_start(pci, PCI_BASE_ADDRESS_2);
81
+	efx->mmio_len = pci_bar_size(pci, PCI_BASE_ADDRESS_2);
82
+	efx->membase = ioremap(efx->mmio_start, efx->mmio_len);
83
+
84
+	DBGCP(efx, "BAR of %lx bytes at phys %lx mapped at %p\n",
85
+	      efx->mmio_len, efx->mmio_start, efx->membase);
86
+
87
+	/* Enable PCI access */
88
+	adjust_pci_device(pci);
89
+}
90
+
91
+void efx_remove(struct net_device *netdev)
92
+{
93
+	struct efx_nic *efx = netdev_priv(netdev);
94
+
95
+	iounmap(efx->membase);
96
+	efx->membase = NULL;
97
+}

+ 232
- 0
src/drivers/net/sfc/efx_common.h View File

@@ -0,0 +1,232 @@
1
+/**************************************************************************
2
+ *
3
+ * GPL common net driver for Solarflare network cards
4
+ *
5
+ * Written by Michael Brown <mbrown@fensystems.co.uk>
6
+ *
7
+ * Copyright Fen Systems Ltd. 2005
8
+ * Copyright Level 5 Networks Inc. 2005
9
+ * Copyright Solarflare Communications Inc. 2013-2017
10
+ *
11
+ * This program is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU General Public License as
13
+ * published by the Free Software Foundation; either version 2 of the
14
+ * License, or any later version.
15
+ *
16
+ * You can also choose to distribute this program under the terms of
17
+ * the Unmodified Binary Distribution Licence (as given in the file
18
+ * COPYING.UBDL), provided that you have satisfied its requirements.
19
+ *
20
+ ***************************************************************************/
21
+#ifndef EFX_COMMON_H
22
+#define EFX_COMMON_H
23
+
24
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
+
26
+#define __packed    __attribute__((__packed__))
27
+#define __force     /*nothing*/
28
+
29
+typedef uint16_t    __le16;
30
+typedef uint32_t    __le32;
31
+typedef uint64_t    __le64;
32
+
33
+#define BUILD_BUG_ON_ZERO(e) (sizeof(struct{int: -!!(e); }))
34
+#define BUILD_BUG_ON(e) ((void)BUILD_BUG_ON_ZERO(e))
35
+
36
+#include <stdbool.h>
37
+#include <ipxe/io.h>
38
+#include <ipxe/netdevice.h>
39
+#include "efx_bitfield.h"
40
+#include "mcdi.h"
41
+
42
+#ifndef ARRAY_SIZE
43
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
44
+#endif
45
+
46
+/**************************************************************************
47
+ *
48
+ * Hardware data structures and sizing
49
+ *
50
+ ***************************************************************************/
51
+typedef efx_qword_t efx_rx_desc_t;
52
+typedef efx_qword_t efx_tx_desc_t;
53
+typedef efx_qword_t efx_event_t;
54
+
55
+#define EFX_BUF_ALIGN		4096
56
+#define EFX_RXD_SIZE		512
57
+#define EFX_RXD_MASK            (EFX_RXD_SIZE - 1)
58
+#define EFX_TXD_SIZE		512
59
+#define EFX_TXD_MASK            (EFX_TXD_SIZE - 1)
60
+#define EFX_EVQ_SIZE		512
61
+#define EFX_EVQ_MASK            (EFX_EVQ_SIZE - 1)
62
+
63
+/* There is space for 512 rx descriptors available. This number can be
64
+ * anything between 1 and 512 in powers of 2. This value will affect the
65
+ * network performance. During a test we were able to push 239 descriptors
66
+ * before we ran out of space.
67
+ */
68
+#define EFX_NUM_RX_DESC		64
69
+#define EFX_NUM_RX_DESC_MASK    (EFX_NUM_RX_DESC - 1)
70
+
71
+/* The packet size is usually 1500 bytes hence we choose 1600 as the buf size,
72
+ * which is (1500+metadata)
73
+ */
74
+#define EFX_RX_BUF_SIZE		1600
75
+
76
+/* Settings for the state field in efx_nic.
77
+ */
78
+#define EFX_STATE_POLLING	1
79
+
80
+typedef unsigned long long dma_addr_t;
81
+
82
+/** A buffer table allocation backing a tx dma, rx dma or eventq */
83
+struct efx_special_buffer {
84
+	dma_addr_t dma_addr;
85
+	int id;
86
+};
87
+
88
+/** A transmit queue */
89
+struct efx_tx_queue {
90
+	/* The hardware ring */
91
+	efx_tx_desc_t *ring;
92
+
93
+	/* The software ring storing io_buffers. */
94
+	struct io_buffer *buf[EFX_TXD_SIZE];
95
+
96
+	/* The buffer table reservation pushed to hardware */
97
+	struct efx_special_buffer entry;
98
+
99
+	/* Software descriptor write ptr */
100
+	unsigned int write_ptr;
101
+
102
+	/* Hardware descriptor read ptr */
103
+	unsigned int read_ptr;
104
+};
105
+
106
+/** A receive queue */
107
+struct efx_rx_queue {
108
+	/* The hardware ring */
109
+	efx_rx_desc_t *ring;
110
+
111
+	/* The software ring storing io_buffers */
112
+	struct io_buffer *buf[EFX_NUM_RX_DESC];
113
+
114
+	/* The buffer table reservation pushed to hardware */
115
+	struct efx_special_buffer entry;
116
+
117
+	/* Descriptor write ptr, into both the hardware and software rings */
118
+	unsigned int write_ptr;
119
+
120
+	/* Hardware completion ptr */
121
+	unsigned int read_ptr;
122
+
123
+	/* The value of RX_CONT in the previous RX event */
124
+	unsigned int rx_cont_prev;
125
+};
126
+
127
+/** An event queue */
128
+struct efx_ev_queue {
129
+	/* The hardware ring to push to hardware.
130
+	 * Must be the first entry in the structure.
131
+	 */
132
+	efx_event_t *ring;
133
+
134
+	/* The buffer table reservation pushed to hardware */
135
+	struct efx_special_buffer entry;
136
+
137
+	/* Pointers into the ring */
138
+	unsigned int read_ptr;
139
+};
140
+
141
+/* Hardware revisions */
142
+enum efx_revision {
143
+	EFX_HUNTINGTON,
144
+};
145
+
146
+/** Hardware access */
147
+struct efx_nic {
148
+	struct net_device *netdev;
149
+	enum efx_revision revision;
150
+	const struct efx_nic_type *type;
151
+
152
+	int port;
153
+	u32 state;
154
+
155
+	/** Memory and IO base */
156
+	void *membase;
157
+	unsigned long mmio_start;
158
+	unsigned long mmio_len;
159
+
160
+	/* Buffer table allocation head */
161
+	int buffer_head;
162
+
163
+	/* Queues */
164
+	struct efx_rx_queue rxq;
165
+	struct efx_tx_queue txq;
166
+	struct efx_ev_queue evq;
167
+
168
+	unsigned int rx_prefix_size;
169
+
170
+	/** INT_REG_KER */
171
+	int int_en;
172
+	efx_oword_t int_ker __aligned;
173
+
174
+	/* Set to true if firmware supports the workaround for bug35388 */
175
+	bool workaround_35388;
176
+
177
+};
178
+
179
+
180
+/** Efx device type definition */
181
+struct efx_nic_type {
182
+	int (*mcdi_rpc)(struct efx_nic *efx, unsigned int cmd,
183
+			const efx_dword_t *inbuf, size_t inlen,
184
+			efx_dword_t *outbuf, size_t outlen,
185
+			size_t *outlen_actual, bool quiet);
186
+};
187
+
188
+extern const struct efx_nic_type hunt_nic_type;
189
+
190
+#define EFX_MAC_FRAME_LEN(_mtu)					\
191
+	(((_mtu)						\
192
+	  + /* EtherII already included */			\
193
+	  + 4 /* FCS */						\
194
+	  /* No VLAN supported */				\
195
+	  + 16 /* bug16772 */					\
196
+	  + 7) & ~7)
197
+
198
+/*******************************************************************************
199
+ *
200
+ *
201
+ * Hardware API
202
+ *
203
+ *
204
+ ******************************************************************************/
205
+static inline void _efx_writel(struct efx_nic *efx, uint32_t value,
206
+			       unsigned int reg)
207
+{
208
+	writel((value), (efx)->membase + (reg));
209
+}
210
+
211
+static inline uint32_t _efx_readl(struct efx_nic *efx, unsigned int reg)
212
+{
213
+	return readl((efx)->membase + (reg));
214
+}
215
+
216
+#define efx_writel_table(efx, value, index, reg)		\
217
+	efx_writel(efx, value, (reg) + ((index) * reg##_STEP))
218
+
219
+#define efx_writel_page(efx, value, index, reg)			\
220
+	efx_writel(efx, value, (reg) + ((index) * 0x2000))
221
+
222
+/* Hardware access */
223
+extern void efx_writel(struct efx_nic *efx, efx_dword_t *value,
224
+		       unsigned int reg);
225
+extern void efx_readl(struct efx_nic *efx, efx_dword_t *value,
226
+		      unsigned int reg);
227
+
228
+/* Initialisation */
229
+extern void efx_probe(struct net_device *netdev, enum efx_revision rev);
230
+extern void efx_remove(struct net_device *netdev);
231
+
232
+#endif /* EFX_COMMON_H */

+ 510
- 0
src/drivers/net/sfc/efx_hunt.c View File

@@ -0,0 +1,510 @@
1
+/**************************************************************************
2
+ *
3
+ * Driver datapath for Solarflare network cards
4
+ *
5
+ * Written by Shradha Shah <sshah@solarflare.com>
6
+ *
7
+ * Copyright 2012-2017 Solarflare Communications Inc.
8
+ *
9
+ * This program is free software; you can redistribute it and/or
10
+ * modify it under the terms of the GNU General Public License as
11
+ * published by the Free Software Foundation; either version 2 of the
12
+ * License, or any later version.
13
+ *
14
+ * You can also choose to distribute this program under the terms of
15
+ * the Unmodified Binary Distribution Licence (as given in the file
16
+ * COPYING.UBDL), provided that you have satisfied its requirements.
17
+ *
18
+ ***************************************************************************/
19
+
20
+#include <stdint.h>
21
+#include <stdlib.h>
22
+#include <stdio.h>
23
+#include <unistd.h>
24
+#include <errno.h>
25
+#include <assert.h>
26
+#include <byteswap.h>
27
+#include <ipxe/io.h>
28
+#include <ipxe/pci.h>
29
+#include <ipxe/malloc.h>
30
+#include <ipxe/iobuf.h>
31
+#include <ipxe/netdevice.h>
32
+#include "efx_hunt.h"
33
+#include "efx_bitfield.h"
34
+#include "ef10_regs.h"
35
+
36
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
37
+
38
+void efx_hunt_free_special_buffer(void *buf, int bytes)
39
+{
40
+	free_dma(buf, bytes);
41
+}
42
+
43
+static void *efx_hunt_alloc_special_buffer(int bytes,
44
+					   struct efx_special_buffer *entry)
45
+{
46
+	void *buffer;
47
+	dma_addr_t dma_addr;
48
+
49
+	/* Allocate the buffer, aligned on a buffer address boundary.  This
50
+	 * buffer will be passed into an MC_CMD_INIT_*Q command to setup the
51
+	 * appropriate type of queue via MCDI.
52
+	 */
53
+	buffer = malloc_dma(bytes, EFX_BUF_ALIGN);
54
+	if (!buffer)
55
+		return NULL;
56
+
57
+	entry->dma_addr = dma_addr = virt_to_bus(buffer);
58
+	assert((dma_addr & (EFX_BUF_ALIGN - 1)) == 0);
59
+
60
+	/* Buffer table entries aren't allocated, so set id to zero */
61
+	entry->id = 0;
62
+	DBGP("Allocated 0x%x bytes at %p\n", bytes, buffer);
63
+
64
+	return buffer;
65
+}
66
+
67
+/*******************************************************************************
68
+ *
69
+ *
70
+ * TX
71
+ *
72
+ *
73
+ ******************************************************************************/
74
+static void
75
+efx_hunt_build_tx_desc(efx_tx_desc_t *txd, struct io_buffer *iob)
76
+{
77
+	dma_addr_t dma_addr;
78
+
79
+	dma_addr = virt_to_bus(iob->data);
80
+
81
+	EFX_POPULATE_QWORD_4(*txd,
82
+			     ESF_DZ_TX_KER_TYPE, 0,
83
+			     ESF_DZ_TX_KER_CONT, 0,
84
+			     ESF_DZ_TX_KER_BYTE_CNT, iob_len(iob),
85
+			     ESF_DZ_TX_KER_BUF_ADDR, dma_addr);
86
+}
87
+
88
+static void
89
+efx_hunt_notify_tx_desc(struct efx_nic *efx)
90
+{
91
+	struct efx_tx_queue *txq = &efx->txq;
92
+	int ptr = txq->write_ptr & EFX_TXD_MASK;
93
+	efx_dword_t reg;
94
+
95
+	EFX_POPULATE_DWORD_1(reg, ERF_DZ_TX_DESC_WPTR_DWORD, ptr);
96
+	efx_writel_page(efx, &reg, 0, ER_DZ_TX_DESC_UPD_DWORD);
97
+}
98
+
99
+int
100
+efx_hunt_transmit(struct net_device *netdev, struct io_buffer *iob)
101
+{
102
+	struct efx_nic *efx = netdev_priv(netdev);
103
+	struct efx_tx_queue *txq = &efx->txq;
104
+	int fill_level, space;
105
+	efx_tx_desc_t *txd;
106
+	int buf_id;
107
+
108
+	fill_level = txq->write_ptr - txq->read_ptr;
109
+	space = EFX_TXD_SIZE - fill_level - 1;
110
+	if (space < 1)
111
+		return -ENOBUFS;
112
+
113
+	/* Save the iobuffer for later completion */
114
+	buf_id = txq->write_ptr & EFX_TXD_MASK;
115
+	assert(txq->buf[buf_id] == NULL);
116
+	txq->buf[buf_id] = iob;
117
+
118
+	DBGCIO(efx, "tx_buf[%d] for iob %p data %p len %zd\n",
119
+	       buf_id, iob, iob->data, iob_len(iob));
120
+
121
+	/* Form the descriptor, and push it to hardware */
122
+	txd = txq->ring + buf_id;
123
+	efx_hunt_build_tx_desc(txd, iob);
124
+	++txq->write_ptr;
125
+	efx_hunt_notify_tx_desc(efx);
126
+
127
+	return 0;
128
+}
129
+
130
+static void
131
+efx_hunt_transmit_done(struct efx_nic *efx, int id)
132
+{
133
+	struct efx_tx_queue *txq = &efx->txq;
134
+	unsigned int read_ptr, stop;
135
+
136
+	/* Complete all buffers from read_ptr up to and including id */
137
+	read_ptr = txq->read_ptr & EFX_TXD_MASK;
138
+	stop = (id + 1) & EFX_TXD_MASK;
139
+
140
+	while (read_ptr != stop) {
141
+		struct io_buffer *iob = txq->buf[read_ptr];
142
+
143
+		assert(iob);
144
+		/* Complete the tx buffer */
145
+		if (iob)
146
+			netdev_tx_complete(efx->netdev, iob);
147
+		DBGCIO(efx, "tx_buf[%d] for iob %p done\n", read_ptr, iob);
148
+		txq->buf[read_ptr] = NULL;
149
+
150
+		++txq->read_ptr;
151
+		read_ptr = txq->read_ptr & EFX_TXD_MASK;
152
+	}
153
+}
154
+
155
+int efx_hunt_tx_init(struct net_device *netdev, dma_addr_t *dma_addr)
156
+{
157
+	struct efx_nic *efx = netdev_priv(netdev);
158
+	struct efx_tx_queue *txq = &efx->txq;
159
+	size_t bytes;
160
+
161
+	/* Allocate hardware transmit queue */
162
+	bytes = sizeof(efx_tx_desc_t) * EFX_TXD_SIZE;
163
+	txq->ring = efx_hunt_alloc_special_buffer(bytes, &txq->entry);
164
+	if (!txq->ring)
165
+		return -ENOMEM;
166
+
167
+	txq->read_ptr = txq->write_ptr = 0;
168
+	*dma_addr = txq->entry.dma_addr;
169
+	return 0;
170
+}
171
+
172
+/*******************************************************************************
173
+ *
174
+ *
175
+ * RX
176
+ *
177
+ *
178
+ ******************************************************************************/
179
+static void
180
+efx_hunt_build_rx_desc(efx_rx_desc_t *rxd, struct io_buffer *iob)
181
+{
182
+	dma_addr_t dma_addr = virt_to_bus(iob->data);
183
+
184
+	EFX_POPULATE_QWORD_2(*rxd,
185
+			     ESF_DZ_RX_KER_BYTE_CNT, EFX_RX_BUF_SIZE,
186
+			     ESF_DZ_RX_KER_BUF_ADDR, dma_addr);
187
+}
188
+
189
+static void
190
+efx_hunt_notify_rx_desc(struct efx_nic *efx)
191
+{
192
+	struct efx_rx_queue *rxq = &efx->rxq;
193
+	int ptr = rxq->write_ptr & EFX_RXD_MASK;
194
+	efx_dword_t reg;
195
+
196
+	EFX_POPULATE_DWORD_1(reg, ERF_DZ_RX_DESC_WPTR, ptr);
197
+	efx_writel_page(efx, &reg, 0, ER_DZ_RX_DESC_UPD);
198
+}
199
+
200
+static void
201
+efx_hunt_rxq_fill(struct efx_nic *efx)
202
+{
203
+	struct efx_rx_queue *rxq = &efx->rxq;
204
+	int fill_level = rxq->write_ptr - rxq->read_ptr;
205
+	int space = EFX_NUM_RX_DESC - fill_level - 1;
206
+	int pushed = 0;
207
+
208
+	while (space) {
209
+		int buf_id = rxq->write_ptr & (EFX_NUM_RX_DESC - 1);
210
+		int desc_id = rxq->write_ptr & EFX_RXD_MASK;
211
+		struct io_buffer *iob;
212
+		efx_rx_desc_t *rxd;
213
+
214
+		assert(rxq->buf[buf_id] == NULL);
215
+		iob = alloc_iob(EFX_RX_BUF_SIZE);
216
+		if (!iob)
217
+			break;
218
+
219
+		DBGCP(efx, "pushing rx_buf[%d] iob %p data %p\n",
220
+		      buf_id, iob, iob->data);
221
+
222
+		rxq->buf[buf_id] = iob;
223
+		rxd = rxq->ring + desc_id;
224
+		efx_hunt_build_rx_desc(rxd, iob);
225
+		++rxq->write_ptr;
226
+		++pushed;
227
+		--space;
228
+	}
229
+
230
+	/* Push the ptr to hardware */
231
+	if (pushed > 0) {
232
+		efx_hunt_notify_rx_desc(efx);
233
+
234
+		DBGCP(efx, "pushed %d rx buffers to fill level %d\n",
235
+		      pushed, rxq->write_ptr - rxq->read_ptr);
236
+	}
237
+}
238
+
239
+static void
240
+efx_hunt_receive(struct efx_nic *efx, unsigned int id, int len, int drop)
241
+{
242
+	struct efx_rx_queue *rxq = &efx->rxq;
243
+	unsigned int read_ptr = rxq->read_ptr & EFX_RXD_MASK;
244
+	unsigned int buf_ptr = rxq->read_ptr & EFX_NUM_RX_DESC_MASK;
245
+	struct io_buffer *iob;
246
+
247
+	/* id is the lower 4 bits of the desc index + 1 in huntington*/
248
+	/* hence anding with 15 */
249
+	assert((id & 15) == ((read_ptr + (len != 0)) & 15));
250
+
251
+	/* Pop this rx buffer out of the software ring */
252
+	iob = rxq->buf[buf_ptr];
253
+	rxq->buf[buf_ptr] = NULL;
254
+
255
+	DBGCIO(efx, "popping rx_buf[%d] iob %p data %p with %d bytes %s %x\n",
256
+	       read_ptr, iob, iob->data, len, drop ? "bad" : "ok", drop);
257
+
258
+	/* Pass the packet up if required */
259
+	if (drop)
260
+		netdev_rx_err(efx->netdev, iob, EBADMSG);
261
+	else {
262
+		iob_put(iob, len);
263
+		iob_pull(iob, efx->rx_prefix_size);
264
+		netdev_rx(efx->netdev, iob);
265
+	}
266
+
267
+	++rxq->read_ptr;
268
+}
269
+
270
+int efx_hunt_rx_init(struct net_device *netdev, dma_addr_t *dma_addr)
271
+{
272
+	struct efx_nic *efx = netdev_priv(netdev);
273
+	struct efx_rx_queue *rxq = &efx->rxq;
274
+	size_t bytes;
275
+
276
+	/* Allocate hardware receive queue */
277
+	bytes = sizeof(efx_rx_desc_t) * EFX_RXD_SIZE;
278
+	rxq->ring = efx_hunt_alloc_special_buffer(bytes, &rxq->entry);
279
+	if (rxq->ring == NULL)
280
+		return -ENOMEM;
281
+
282
+	rxq->read_ptr = rxq->write_ptr = 0;
283
+	*dma_addr = rxq->entry.dma_addr;
284
+	return 0;
285
+}
286
+
287
+/*******************************************************************************
288
+ *
289
+ *
290
+ * Event queues and interrupts
291
+ *
292
+ *
293
+ ******************************************************************************/
294
+int efx_hunt_ev_init(struct net_device *netdev, dma_addr_t *dma_addr)
295
+{
296
+	struct efx_nic *efx = netdev_priv(netdev);
297
+	struct efx_ev_queue *evq = &efx->evq;
298
+	size_t bytes;
299
+
300
+	/* Allocate the hardware event queue */
301
+	bytes = sizeof(efx_event_t) * EFX_EVQ_SIZE;
302
+	evq->ring = efx_hunt_alloc_special_buffer(bytes, &evq->entry);
303
+	if (evq->ring == NULL)
304
+		return -ENOMEM;
305
+
306
+	memset(evq->ring, 0xff, bytes);
307
+	evq->read_ptr = 0;
308
+	*dma_addr = evq->entry.dma_addr;
309
+	return 0;
310
+}
311
+
312
+static void
313
+efx_hunt_clear_interrupts(struct efx_nic *efx)
314
+{
315
+	efx_dword_t reg;
316
+	/* read the ISR */
317
+	efx_readl(efx, &reg, ER_DZ_BIU_INT_ISR);
318
+}
319
+
320
+/**
321
+ * See if an event is present
322
+ *
323
+ * @v event            EFX event structure
324
+ * @ret True           An event is pending
325
+ * @ret False          No event is pending
326
+ *
327
+ * We check both the high and low dword of the event for all ones.  We
328
+ * wrote all ones when we cleared the event, and no valid event can
329
+ * have all ones in either its high or low dwords.  This approach is
330
+ * robust against reordering.
331
+ *
332
+ * Note that using a single 64-bit comparison is incorrect; even
333
+ * though the CPU read will be atomic, the DMA write may not be.
334
+ */
335
+static inline int
336
+efx_hunt_event_present(efx_event_t *event)
337
+{
338
+	return (!(EFX_DWORD_IS_ALL_ONES(event->dword[0]) |
339
+		  EFX_DWORD_IS_ALL_ONES(event->dword[1])));
340
+}
341
+
342
+static void
343
+efx_hunt_evq_read_ack(struct efx_nic *efx)
344
+{
345
+	struct efx_ev_queue *evq = &efx->evq;
346
+	efx_dword_t reg;
347
+
348
+	if (efx->workaround_35388) {
349
+		EFX_POPULATE_DWORD_2(reg, ERF_DD_EVQ_IND_RPTR_FLAGS,
350
+				     EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH,
351
+				     ERF_DD_EVQ_IND_RPTR,
352
+				    evq->read_ptr >> ERF_DD_EVQ_IND_RPTR_WIDTH);
353
+		efx_writel_page(efx, &reg, 0, ER_DD_EVQ_INDIRECT);
354
+		EFX_POPULATE_DWORD_2(reg, ERF_DD_EVQ_IND_RPTR_FLAGS,
355
+				     EFE_DD_EVQ_IND_RPTR_FLAGS_LOW,
356
+				     ERF_DD_EVQ_IND_RPTR, evq->read_ptr &
357
+				     ((1 << ERF_DD_EVQ_IND_RPTR_WIDTH) - 1));
358
+		efx_writel_page(efx, &reg, 0, ER_DD_EVQ_INDIRECT);
359
+	} else {
360
+		EFX_POPULATE_DWORD_1(reg, ERF_DZ_EVQ_RPTR, evq->read_ptr);
361
+		efx_writel_table(efx, &reg, 0, ER_DZ_EVQ_RPTR);
362
+	}
363
+}
364
+
365
+static unsigned int
366
+efx_hunt_handle_event(struct efx_nic *efx, efx_event_t *evt)
367
+{
368
+	struct efx_rx_queue *rxq = &efx->rxq;
369
+	int ev_code, desc_ptr, len;
370
+	int next_ptr_lbits, packet_drop;
371
+	int rx_cont;
372
+
373
+	/* Decode event */
374
+	ev_code = EFX_QWORD_FIELD(*evt, ESF_DZ_EV_CODE);
375
+
376
+	switch (ev_code) {
377
+	case ESE_DZ_EV_CODE_TX_EV:
378
+		desc_ptr = EFX_QWORD_FIELD(*evt, ESF_DZ_TX_DESCR_INDX);
379
+		efx_hunt_transmit_done(efx, desc_ptr);
380
+		break;
381
+
382
+	case ESE_DZ_EV_CODE_RX_EV:
383
+		len = EFX_QWORD_FIELD(*evt, ESF_DZ_RX_BYTES);
384
+		next_ptr_lbits = EFX_QWORD_FIELD(*evt, ESF_DZ_RX_DSC_PTR_LBITS);
385
+		rx_cont = EFX_QWORD_FIELD(*evt, ESF_DZ_RX_CONT);
386
+
387
+		/* We don't expect to receive scattered packets, so drop the
388
+		 * packet if RX_CONT is set on the current or previous event, or
389
+		 * if len is zero.
390
+		 */
391
+		packet_drop = (len == 0) | (rx_cont << 1) |
392
+			      (rxq->rx_cont_prev << 2);
393
+		efx_hunt_receive(efx, next_ptr_lbits, len, packet_drop);
394
+		rxq->rx_cont_prev = rx_cont;
395
+		return 1;
396
+
397
+	default:
398
+		DBGCP(efx, "Unknown event type %d\n", ev_code);
399
+		break;
400
+	}
401
+	return 0;
402
+}
403
+
404
+void efx_hunt_poll(struct net_device *netdev)
405
+{
406
+	struct efx_nic *efx = netdev_priv(netdev);
407
+	struct efx_ev_queue *evq = &efx->evq;
408
+	efx_event_t *evt;
409
+	int budget = 10;
410
+
411
+	/* Read the event queue by directly looking for events
412
+	 * (we don't even bother to read the eventq write ptr)
413
+	 */
414
+	evt = evq->ring + evq->read_ptr;
415
+	while (efx_hunt_event_present(evt) && (budget > 0)) {
416
+		DBGCP(efx, "Event at index 0x%x address %p is "
417
+		      EFX_QWORD_FMT "\n", evq->read_ptr,
418
+		      evt, EFX_QWORD_VAL(*evt));
419
+
420
+		budget -= efx_hunt_handle_event(efx, evt);
421
+
422
+		/* Clear the event */
423
+		EFX_SET_QWORD(*evt);
424
+
425
+		/* Move to the next event. We don't ack the event
426
+		 * queue until the end
427
+		 */
428
+		evq->read_ptr = ((evq->read_ptr + 1) & EFX_EVQ_MASK);
429
+		evt = evq->ring + evq->read_ptr;
430
+	}
431
+
432
+	/* Push more rx buffers if needed */
433
+	efx_hunt_rxq_fill(efx);
434
+
435
+	/* Clear any pending interrupts */
436
+	efx_hunt_clear_interrupts(efx);
437
+
438
+	/* Ack the event queue if interrupts are enabled */
439
+	if (efx->int_en)
440
+		efx_hunt_evq_read_ack(efx);
441
+}
442
+
443
+void efx_hunt_irq(struct net_device *netdev, int enable)
444
+{
445
+	struct efx_nic *efx = netdev_priv(netdev);
446
+
447
+	efx->int_en = enable;
448
+
449
+	/* If interrupts are enabled, prime the event queue.  Otherwise ack any
450
+	 * pending interrupts
451
+	 */
452
+	if (enable)
453
+		efx_hunt_evq_read_ack(efx);
454
+	else if (efx->netdev->state & NETDEV_OPEN)
455
+		efx_hunt_clear_interrupts(efx);
456
+}
457
+
458
+/*******************************************************************************
459
+ *
460
+ *
461
+ * Initialization and Close
462
+ *
463
+ *
464
+ ******************************************************************************/
465
+int efx_hunt_open(struct net_device *netdev)
466
+{
467
+	struct efx_nic *efx = netdev_priv(netdev);
468
+	efx_dword_t cmd;
469
+
470
+	/* Set interrupt moderation to 0*/
471
+	EFX_POPULATE_DWORD_2(cmd,
472
+			     ERF_DZ_TC_TIMER_MODE, 0,
473
+			     ERF_DZ_TC_TIMER_VAL, 0);
474
+	efx_writel_page(efx, &cmd, 0, ER_DZ_EVQ_TMR);
475
+
476
+	/* Ack the eventq */
477
+	if (efx->int_en)
478
+		efx_hunt_evq_read_ack(efx);
479
+
480
+	/* Push receive buffers */
481
+	efx_hunt_rxq_fill(efx);
482
+
483
+	return 0;
484
+}
485
+
486
+void efx_hunt_close(struct net_device *netdev)
487
+{
488
+	struct efx_nic *efx = netdev_priv(netdev);
489
+	struct efx_rx_queue *rxq = &efx->rxq;
490
+	struct efx_tx_queue *txq = &efx->txq;
491
+	int i;
492
+
493
+	/* Complete outstanding descriptors */
494
+	for (i = 0; i < EFX_NUM_RX_DESC; i++) {
495
+		if (rxq->buf[i]) {
496
+			free_iob(rxq->buf[i]);
497
+			rxq->buf[i] = NULL;
498
+		}
499
+	}
500
+
501
+	for (i = 0; i < EFX_TXD_SIZE; i++) {
502
+		if (txq->buf[i]) {
503
+			netdev_tx_complete(efx->netdev, txq->buf[i]);
504
+			txq->buf[i] = NULL;
505
+		}
506
+	}
507
+
508
+	/* Clear interrupts */
509
+	efx_hunt_clear_interrupts(efx);
510
+}

+ 75
- 0
src/drivers/net/sfc/efx_hunt.h View File

@@ -0,0 +1,75 @@
1
+/**************************************************************************
2
+ *
3
+ * GPL net driver for Solarflare network cards
4
+ *
5
+ * Written by Shradha Shah <sshah@solarflare.com>
6
+ *
7
+ * Copyright 2012-2017 Solarflare Communications Inc.
8
+ *
9
+ * This program is free software; you can redistribute it and/or
10
+ * modify it under the terms of the GNU General Public License as
11
+ * published by the Free Software Foundation; either version 2 of the
12
+ * License, or any later version.
13
+ *
14
+ * You can also choose to distribute this program under the terms of
15
+ * the Unmodified Binary Distribution Licence (as given in the file
16
+ * COPYING.UBDL), provided that you have satisfied its requirements.
17
+ *
18
+ ***************************************************************************/
19
+
20
+#ifndef EFX_HUNT_H
21
+#define EFX_HUNT_H
22
+
23
+#include "efx_common.h"
24
+
25
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
26
+
27
+/**************************************************************************
28
+ *
29
+ * Hardware data structures and sizing
30
+ *
31
+ ***************************************************************************/
32
+
33
+#define EFX_EV_SIZE(_nevs)     ((_nevs) * sizeof(efx_qword_t))
34
+#define EFX_EVQ_NBUFS(_nevs)    (EFX_EV_SIZE(_nevs) / EFX_BUF_ALIGN)
35
+
36
+#define	EFX_RXQ_SIZE(_ndescs)	((_ndescs) * sizeof(efx_qword_t))
37
+#define	EFX_RXQ_NBUFS(_ndescs)	(EFX_RXQ_SIZE(_ndescs) / EFX_BUF_ALIGN)
38
+
39
+#define	EFX_TXQ_SIZE(_ndescs)	((_ndescs) * sizeof(efx_qword_t))
40
+#define	EFX_TXQ_NBUFS(_ndescs)	(EFX_TXQ_SIZE(_ndescs) / EFX_BUF_ALIGN)
41
+
42
+/** MCDI request structure */
43
+struct efx_mcdi_req_s {
44
+	unsigned int    emr_cmd;
45
+	efx_dword_t     *emr_in_buf;
46
+	size_t          emr_in_length;
47
+	int             emr_rc;
48
+	efx_dword_t     *emr_out_buf;
49
+	size_t          emr_out_length;
50
+	size_t          emr_out_length_used;
51
+};
52
+
53
+/*******************************************************************************
54
+ *
55
+ *
56
+ * Hardware API
57
+ *
58
+ *
59
+ ******************************************************************************/
60
+
61
+extern void efx_hunt_free_special_buffer(void *buf, int bytes);
62
+
63
+/* Data path entry points */
64
+extern int efx_hunt_transmit(struct net_device *netdev, struct io_buffer *iob);
65
+extern void efx_hunt_poll(struct net_device *netdev);
66
+extern void efx_hunt_irq(struct net_device *netdev, int enable);
67
+
68
+/* Initialisation */
69
+extern int efx_hunt_ev_init(struct net_device *netdev, dma_addr_t *dma_addr);
70
+extern int efx_hunt_rx_init(struct net_device *netdev, dma_addr_t *dma_addr);
71
+extern int efx_hunt_tx_init(struct net_device *netdev, dma_addr_t *dma_addr);
72
+extern int efx_hunt_open(struct net_device *netdev);
73
+extern void efx_hunt_close(struct net_device *netdev);
74
+
75
+#endif /* EFX_HUNT_H */

+ 2281
- 0
src/drivers/net/sfc/mc_driver_pcol.h
File diff suppressed because it is too large
View File


+ 164
- 0
src/drivers/net/sfc/mcdi.h View File

@@ -0,0 +1,164 @@
1
+/****************************************************************************
2
+ * Driver for Solarflare network controllers and boards
3
+ *
4
+ * Written by Martin Habets <mhabets@solarflare.com>
5
+ *
6
+ * Copyright 2012-2017 Solarflare Communications Inc.
7
+ *
8
+ * This program is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License as
10
+ * published by the Free Software Foundation; either version 2 of the
11
+ * License, or any later version.
12
+ *
13
+ * You can also choose to distribute this program under the terms of
14
+ * the Unmodified Binary Distribution Licence (as given in the file
15
+ * COPYING.UBDL), provided that you have satisfied its requirements.
16
+ */
17
+#ifndef SFC_MCDI_H
18
+#define SFC_MCDI_H
19
+
20
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
21
+
22
+#ifndef DIV_ROUND_UP
23
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
24
+#endif
25
+
26
+#define MCDI_SEQ_MASK 0xf
27
+
28
+/* We expect that 16- and 32-bit fields in MCDI requests and responses
29
+ * are appropriately aligned, but 64-bit fields are only
30
+ * 32-bit-aligned.  Also, on Siena we must copy to the MC shared
31
+ * memory strictly 32 bits at a time, so add any necessary padding.
32
+ */
33
+#define MCDI_DECLARE_BUF(_name, _len)					\
34
+	efx_dword_t _name[DIV_ROUND_UP(_len, 4)]
35
+#define MCDI_DECLARE_BUF_OUT_OR_ERR(_name, _len)			\
36
+	MCDI_DECLARE_BUF(_name, max_t(size_t, _len, 8))
37
+#define _MCDI_PTR(_buf, _offset)					\
38
+	((u8 *)(_buf) + (_offset))
39
+#define MCDI_PTR(_buf, _field)						\
40
+	_MCDI_PTR(_buf, MC_CMD_ ## _field ## _OFST)
41
+#define _MCDI_CHECK_ALIGN(_ofst, _align)				\
42
+	((_ofst) + BUILD_BUG_ON_ZERO((_ofst) & (_align - 1)))
43
+#define _MCDI_DWORD(_buf, _field)					\
44
+	((_buf) + (_MCDI_CHECK_ALIGN(MC_CMD_ ## _field ## _OFST, 4) >> 2))
45
+
46
+#define MCDI_WORD(_buf, _field)						\
47
+	((u16)BUILD_BUG_ON_ZERO(MC_CMD_ ## _field ## _LEN != 2) +	\
48
+	 le16_to_cpu(*(__force const __le16 *)MCDI_PTR(_buf, _field)))
49
+#define MCDI_SET_DWORD(_buf, _field, _value)				\
50
+	EFX_POPULATE_DWORD_1(*_MCDI_DWORD(_buf, _field), EFX_DWORD_0, _value)
51
+#define MCDI_DWORD(_buf, _field)					\
52
+	EFX_DWORD_FIELD(*_MCDI_DWORD(_buf, _field), EFX_DWORD_0)
53
+#define MCDI_POPULATE_DWORD_1(_buf, _field, _name1, _value1)		\
54
+	EFX_POPULATE_DWORD_1(*_MCDI_DWORD(_buf, _field),		\
55
+			     MC_CMD_ ## _name1, _value1)
56
+#define MCDI_POPULATE_DWORD_2(_buf, _field, _name1, _value1,		\
57
+			      _name2, _value2)				\
58
+	EFX_POPULATE_DWORD_2(*_MCDI_DWORD(_buf, _field),		\
59
+			     MC_CMD_ ## _name1, _value1,		\
60
+			     MC_CMD_ ## _name2, _value2)
61
+#define MCDI_POPULATE_DWORD_3(_buf, _field, _name1, _value1,		\
62
+			      _name2, _value2, _name3, _value3)		\
63
+	EFX_POPULATE_DWORD_3(*_MCDI_DWORD(_buf, _field),		\
64
+			     MC_CMD_ ## _name1, _value1,		\
65
+			     MC_CMD_ ## _name2, _value2,		\
66
+			     MC_CMD_ ## _name3, _value3)
67
+#define MCDI_POPULATE_DWORD_4(_buf, _field, _name1, _value1,		\
68
+			      _name2, _value2, _name3, _value3,		\
69
+			      _name4, _value4)				\
70
+	EFX_POPULATE_DWORD_4(*_MCDI_DWORD(_buf, _field),		\
71
+			     MC_CMD_ ## _name1, _value1,		\
72
+			     MC_CMD_ ## _name2, _value2,		\
73
+			     MC_CMD_ ## _name3, _value3,		\
74
+			     MC_CMD_ ## _name4, _value4)
75
+#define MCDI_POPULATE_DWORD_5(_buf, _field, _name1, _value1,		\
76
+			      _name2, _value2, _name3, _value3,		\
77
+			      _name4, _value4, _name5, _value5)		\
78
+	EFX_POPULATE_DWORD_5(*_MCDI_DWORD(_buf, _field),		\
79
+			     MC_CMD_ ## _name1, _value1,		\
80
+			     MC_CMD_ ## _name2, _value2,		\
81
+			     MC_CMD_ ## _name3, _value3,		\
82
+			     MC_CMD_ ## _name4, _value4,		\
83
+			     MC_CMD_ ## _name5, _value5)
84
+#define MCDI_POPULATE_DWORD_6(_buf, _field, _name1, _value1,		\
85
+			      _name2, _value2, _name3, _value3,		\
86
+			      _name4, _value4, _name5, _value5,		\
87
+			      _name6, _value6)				\
88
+	EFX_POPULATE_DWORD_6(*_MCDI_DWORD(_buf, _field),		\
89
+			     MC_CMD_ ## _name1, _value1,		\
90
+			     MC_CMD_ ## _name2, _value2,		\
91
+			     MC_CMD_ ## _name3, _value3,		\
92
+			     MC_CMD_ ## _name4, _value4,		\
93
+			     MC_CMD_ ## _name5, _value5,		\
94
+			     MC_CMD_ ## _name6, _value6)
95
+#define MCDI_POPULATE_DWORD_7(_buf, _field, _name1, _value1,		\
96
+			      _name2, _value2, _name3, _value3,		\
97
+			      _name4, _value4, _name5, _value5,		\
98
+			      _name6, _value6, _name7, _value7)		\
99
+	EFX_POPULATE_DWORD_7(*_MCDI_DWORD(_buf, _field),		\
100
+			     MC_CMD_ ## _name1, _value1,		\
101
+			     MC_CMD_ ## _name2, _value2,		\
102
+			     MC_CMD_ ## _name3, _value3,		\
103
+			     MC_CMD_ ## _name4, _value4,		\
104
+			     MC_CMD_ ## _name5, _value5,		\
105
+			     MC_CMD_ ## _name6, _value6,		\
106
+			     MC_CMD_ ## _name7, _value7)
107
+#define MCDI_SET_QWORD(_buf, _field, _value)				\
108
+	do {								\
109
+		EFX_POPULATE_DWORD_1(_MCDI_DWORD(_buf, _field)[0],	\
110
+				     EFX_DWORD_0, (u32)(_value));	\
111
+		EFX_POPULATE_DWORD_1(_MCDI_DWORD(_buf, _field)[1],	\
112
+				     EFX_DWORD_0, (u64)(_value) >> 32);	\
113
+	} while (0)
114
+#define MCDI_QWORD(_buf, _field)					\
115
+	(EFX_DWORD_FIELD(_MCDI_DWORD(_buf, _field)[0], EFX_DWORD_0) |	\
116
+	(u64)EFX_DWORD_FIELD(_MCDI_DWORD(_buf, _field)[1], EFX_DWORD_0) << 32)
117
+#define MCDI_FIELD(_ptr, _type, _field)					\
118
+	EFX_EXTRACT_DWORD(						\
119
+		*(efx_dword_t *)					\
120
+		_MCDI_PTR(_ptr, MC_CMD_ ## _type ## _ ## _field ## _OFST & ~3),\
121
+		MC_CMD_ ## _type ## _ ## _field ## _LBN & 0x1f,	\
122
+		(MC_CMD_ ## _type ## _ ## _field ## _LBN & 0x1f) +	\
123
+		MC_CMD_ ## _type ## _ ## _field ## _WIDTH - 1)
124
+
125
+#define _MCDI_ARRAY_PTR(_buf, _field, _index, _align)			\
126
+	(_MCDI_PTR(_buf, _MCDI_CHECK_ALIGN(MC_CMD_ ## _field ## _OFST, _align))\
127
+	 + (_index) * _MCDI_CHECK_ALIGN(MC_CMD_ ## _field ## _LEN, _align))
128
+#define MCDI_DECLARE_STRUCT_PTR(_name)					\
129
+	efx_dword_t *_name
130
+#define MCDI_ARRAY_STRUCT_PTR(_buf, _field, _index)			\
131
+	((efx_dword_t *)_MCDI_ARRAY_PTR(_buf, _field, _index, 4))
132
+#define MCDI_VAR_ARRAY_LEN(_len, _field)				\
133
+	min_t(size_t, MC_CMD_ ## _field ## _MAXNUM,			\
134
+	      ((_len) - MC_CMD_ ## _field ## _OFST) / MC_CMD_ ## _field ## _LEN)
135
+#define MCDI_ARRAY_WORD(_buf, _field, _index)				\
136
+	(BUILD_BUG_ON_ZERO(MC_CMD_ ## _field ## _LEN != 2) +		\
137
+	 le16_to_cpu(*(__force const __le16 *)				\
138
+		     _MCDI_ARRAY_PTR(_buf, _field, _index, 2)))
139
+#define _MCDI_ARRAY_DWORD(_buf, _field, _index)				\
140
+	(BUILD_BUG_ON_ZERO(MC_CMD_ ## _field ## _LEN != 4) +		\
141
+	 (efx_dword_t *)_MCDI_ARRAY_PTR(_buf, _field, _index, 4))
142
+#define MCDI_SET_ARRAY_DWORD(_buf, _field, _index, _value)		\
143
+	EFX_SET_DWORD_FIELD(*_MCDI_ARRAY_DWORD(_buf, _field, _index),	\
144
+			    EFX_DWORD_0, _value)
145
+#define MCDI_ARRAY_DWORD(_buf, _field, _index)				\
146
+	EFX_DWORD_FIELD(*_MCDI_ARRAY_DWORD(_buf, _field, _index), EFX_DWORD_0)
147
+#define _MCDI_ARRAY_QWORD(_buf, _field, _index)				\
148
+	(BUILD_BUG_ON_ZERO(MC_CMD_ ## _field ## _LEN != 8) +		\
149
+	 (efx_dword_t *)_MCDI_ARRAY_PTR(_buf, _field, _index, 4))
150
+#define MCDI_SET_ARRAY_QWORD(_buf, _field, _index, _value)		\
151
+	do {								\
152
+		EFX_SET_DWORD_FIELD(_MCDI_ARRAY_QWORD(_buf, _field, _index)[0],\
153
+				    EFX_DWORD_0, (u32)(_value));	\
154
+		EFX_SET_DWORD_FIELD(_MCDI_ARRAY_QWORD(_buf, _field, _index)[1],\
155
+				    EFX_DWORD_0, (u64)(_value) >> 32);	\
156
+	} while (0)
157
+#define MCDI_ARRAY_FIELD(_buf, _field1, _type, _index, _field2)		\
158
+	MCDI_FIELD(MCDI_ARRAY_STRUCT_PTR(_buf, _field1, _index),	\
159
+		   _type ## _TYPEDEF, _field2)
160
+
161
+#define MCDI_EVENT_FIELD(_ev, _field)			\
162
+	EFX_QWORD_FIELD(_ev, MCDI_EVENT_ ## _field)
163
+
164
+#endif

+ 1324
- 0
src/drivers/net/sfc/sfc_hunt.c
File diff suppressed because it is too large
View File


+ 2
- 0
src/include/ipxe/errfile.h View File

@@ -197,6 +197,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
197 197
 #define ERRFILE_axge		     ( ERRFILE_DRIVER | 0x00c10000 )
198 198
 #define ERRFILE_thunderx	     ( ERRFILE_DRIVER | 0x00c20000 )
199 199
 #define ERRFILE_af_packet	     ( ERRFILE_DRIVER | 0x00c30000 )
200
+#define ERRFILE_sfc_hunt	     ( ERRFILE_DRIVER | 0x00c40000 )
201
+#define ERRFILE_efx_hunt	     ( ERRFILE_DRIVER | 0x00c50000 )
200 202
 
201 203
 #define ERRFILE_aoe			( ERRFILE_NET | 0x00000000 )
202 204
 #define ERRFILE_arp			( ERRFILE_NET | 0x00010000 )

Loading…
Cancel
Save