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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
|
#ifndef _IPXE_BOFM_H
#define _IPXE_BOFM_H
/**
* @file
*
* IBM BladeCenter Open Fabric Manager (BOFM)
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/list.h>
#include <ipxe/pci.h>
#include <config/sideband.h>
/** 'IBM ' signature
*
* Present in %edi when the BIOS initialisation entry point is called,
* with the BOFM table pointer in %esi.
*
* Defined in section 4.1.2 of the POST/BIOS BOFM I/O Address
* Re-Assignment Architecture document.
*/
#define IBMs_SIGNATURE ( ( 'I' << 24 ) + ( 'B' << 16 ) + ( 'M' << 8 ) + ' ' )
/** ' IBM' signature
*
* Returned in %edi from the BIOS initialisation entry point, with the
* return code in %dl.
*
* Defined in section 4.1.2 of the POST/BIOS BOFM I/O Address
* Re-Assignment Architecture document.
*/
#define sIBM_SIGNATURE ( ( ' ' << 24 ) + ( 'I' << 16 ) + ( 'B' << 8 ) + 'M' )
/** @defgroup bofmrc BOFM return codes
*
* Defined in section 4.1.3 of the POST/BIOS BOFM I/O Address
* Re-Assignment Architecture document.
*
* @{
*/
/** Successful */
#define BOFM_SUCCESS 0x00
/** Invalid action string */
#define BOFM_ERR_INVALID_ACTION 0x01
/** Unsupported parameter structure version */
#define BOFM_ERR_UNSUPPORTED 0x02
/** Device error prohibited MAC/WWN update */
#define BOFM_ERR_DEVICE_ERROR 0x03
/** PCI reset required (may be combined with another return code) */
#define BOFM_PCI_RESET 0x80
/** @} */
/** Skip option ROM initialisation
*
* A BOFM BIOS may call the initialisation entry point multiple times;
* only the last call should result in actual initialisation.
*
* This flag is internal to iPXE.
*/
#define BOFM_SKIP_INIT 0x80000000UL
/** BOFM table header
*
* Defined in section 4.1 of the Open Fabric Manager Parameter
* Specification document.
*/
struct bofm_global_header {
/** Signature */
uint32_t magic;
/** Subsignature (action string) */
uint32_t action;
/** Data structure version */
uint8_t version;
/** Data structure level */
uint8_t level;
/** Data structure length */
uint16_t length;
/** Data structure checksum */
uint8_t checksum;
/** Data structure profile */
char profile[32];
/** Data structure global options */
uint32_t options;
/** Data structure sequence stamp */
uint32_t sequence;
} __attribute__ (( packed ));
/** BOFM table header signature
*
* Defined in section 4.1.2 of the POST/BIOS BOFM I/O Address
* Re-Assignment Architecture document.
*/
#define BOFM_IOAA_MAGIC ( 'I' + ( 'O' << 8 ) + ( 'A' << 16 ) + ( 'A' << 24 ) )
/** @defgroup bofmaction BOFM header subsignatures (action strings)
*
* Defined in section 4.1.2 of the POST/BIOS BOFM I/O Address
* Re-Assignment Architecture document.
*
* @{
*/
/** Update MAC/WWN */
#define BOFM_ACTION_UPDT ( 'U' + ( 'P' << 8 ) + ( 'D' << 16 ) + ( 'T' << 24 ) )
/** Restore MAC/WWN to factory default */
#define BOFM_ACTION_DFLT ( 'D' + ( 'F' << 8 ) + ( 'L' << 16 ) + ( 'T' << 24 ) )
/** Harvest MAC/WWN */
#define BOFM_ACTION_HVST ( 'H' + ( 'V' << 8 ) + ( 'S' << 16 ) + ( 'T' << 24 ) )
/** Update MAC/WWN and initialise device */
#define BOFM_ACTION_PARM ( 'P' + ( 'A' << 8 ) + ( 'R' << 16 ) + ( 'M' << 24 ) )
/** Just initialise the device */
#define BOFM_ACTION_NONE ( 'N' + ( 'O' << 8 ) + ( 'N' << 16 ) + ( 'E' << 24 ) )
/** @} */
/** BOFM section header
*
* Defined in section 4.2 of the Open Fabric Manager Parameter
* Specification document.
*/
struct bofm_section_header {
/** Signature */
uint32_t magic;
/** Length */
uint16_t length;
} __attribute__ (( packed ));
/** @defgroup bofmsections BOFM section header signatures
*
* Defined in section 4.2 of the Open Fabric Manager Parameter
* Specification document.
*
* @{
*/
/** EN start marker */
#define BOFM_EN_MAGIC ( ' ' + ( ' ' << 8 ) + ( 'E' << 16 ) + ( 'N' << 24 ) )
/** End marker */
#define BOFM_DONE_MAGIC ( 'D' + ( 'O' << 8 ) + ( 'N' << 16 ) + ( 'E' << 24 ) )
/** @} */
/** BOFM Ethernet parameter entry
*
* Defined in section 5.1 of the Open Fabric Manager Parameter
* Specification document.
*/
struct bofm_en {
/** Options */
uint16_t options;
/** PCI bus:dev.fn
*
* Valid only if @c options indicates @c BOFM_EN_MAP_PFA
*/
uint16_t busdevfn;
/** Slot or mezzanine number
*
* Valid only if @c options indicates @c BOFM_EN_MAP_SLOT_PORT
*/
uint8_t slot;
/** Port number
*
* Valid only if @c options indicates @c BOFM_EN_MAP_SLOT_PORT
*/
uint8_t port;
/** Multi-port index */
uint8_t mport;
/** VLAN tag for MAC address A */
uint16_t vlan_a;
/** MAC address A
*
* MAC address A is the sole MAC address, or the lower
* (inclusive) bound of a range of MAC addresses.
*/
uint8_t mac_a[6];
/** VLAN tag for MAC address B */
uint16_t vlan_b;
/** MAC address B
*
* MAC address B is unset, or the upper (inclusive) bound of a
* range of MAC addresses
*/
uint8_t mac_b[6];
} __attribute__ (( packed ));
/** @defgroup bofmenopts BOFM Ethernet parameter entry options
*
* Defined in section 5.1 of the Open Fabric Manager Parameter
* Specification document.
*
* @{
*/
/** Port mapping mask */
#define BOFM_EN_MAP_MASK 0x0001
/** Port mapping is by PCI bus:dev.fn */
#define BOFM_EN_MAP_PFA 0x0000
/** Port mapping is by slot/port */
#define BOFM_EN_MAP_SLOT_PORT 0x0001
/** MAC address B is present */
#define BOFM_EN_EN_B 0x0002
/** VLAN tag for MAC address B is present */
#define BOFM_EN_VLAN_B 0x0004
/** MAC address A is present */
#define BOFM_EN_EN_A 0x0008
/** VLAN tag for MAC address A is present */
#define BOFM_EN_VLAN_A 0x0010
/** Entry consumption indicator mask */
#define BOFM_EN_CSM_MASK 0x00c0
/** Entry has not been used */
#define BOFM_EN_CSM_UNUSED 0x0000
/** Entry has been used successfully */
#define BOFM_EN_CSM_SUCCESS 0x0040
/** Entry has been used but failed */
#define BOFM_EN_CSM_FAILED 0x0080
/** Consumed entry change mask */
#define BOFM_EN_CHG_MASK 0x0100
/** Consumed entry is same as previous active entry */
#define BOFM_EN_CHG_UNCHANGED 0x0000
/** Consumed entry is different than previous active entry */
#define BOFM_EN_CHG_CHANGED 0x0100
/** Ignore values - it's harvest time */
#define BOFM_EN_USAGE_HARVEST 0x1000
/** Use entry values for assignment */
#define BOFM_EN_USAGE_ENTRY 0x0800
/** Use factory default values */
#define BOFM_EN_USAGE_DEFAULT 0x0400
/** Harvest complete */
#define BOFM_EN_HVST 0x2000
/** Harvest request mask */
#define BOFM_EN_RQ_HVST_MASK 0xc000
/** Do not harvest */
#define BOFM_EN_RQ_HVST_NONE 0x0000
/** Harvest factory default values */
#define BOFM_EN_RQ_HVST_DEFAULT 0x4000
/** Harvest active values */
#define BOFM_EN_RQ_HVST_ACTIVE 0xc000
/** @} */
/** BOFM magic value debug message format */
#define BOFM_MAGIC_FMT "'%c%c%c%c'"
/** BOFM magic value debug message arguments */
#define BOFM_MAGIC_ARGS( magic ) \
( ( (magic) >> 0 ) & 0xff ), ( ( (magic) >> 8 ) & 0xff ), \
( ( (magic) >> 16 ) & 0xff ), ( ( (magic) >> 24 ) & 0xff )
/** A BOFM device */
struct bofm_device {
/** Underlying PCI device */
struct pci_device *pci;
/** BOFM device operations */
struct bofm_operations *op;
/** List of BOFM devices */
struct list_head list;
};
/** BOFM device operations */
struct bofm_operations {
/** Harvest Ethernet MAC
*
* @v bofm BOFM device
* @v mport Multi-port index
* @v mac MAC to fill in
* @ret rc Return status code
*/
int ( * harvest ) ( struct bofm_device *bofm, unsigned int mport,
uint8_t *mac );
/** Update Ethernet MAC
*
* @v bofm BOFM device
* @v mport Multi-port index
* @v mac New MAC
* @ret rc Return status code
*/
int ( * update ) ( struct bofm_device *bofm, unsigned int mport,
const uint8_t *mac );
};
/** BOFM driver table */
#define BOFM_DRIVERS __table ( struct pci_driver, "bofm_drivers" )
/** Declare a BOFM driver
*
* In the common case of non-BOFM-enabled builds, allow any BOFM code
* to be garbage-collected at link time to save space.
*/
#ifdef CONFIG_BOFM
#define __bofm_driver __table_entry ( BOFM_DRIVERS, 01 )
#else
#define __bofm_driver
#endif
/**
* Initialise BOFM device
*
* @v bofm BOFM device
* @v pci PCI device
* @v op BOFM device operations
*/
static inline __attribute__ (( always_inline )) void
bofm_init ( struct bofm_device *bofm, struct pci_device *pci,
struct bofm_operations *op ) {
bofm->pci = pci;
bofm->op = op;
}
extern int bofm_register ( struct bofm_device *bofm );
extern void bofm_unregister ( struct bofm_device *bofm );
extern int bofm_find_driver ( struct pci_device *pci );
extern int bofm ( userptr_t bofmtab, struct pci_device *pci );
extern void bofm_test ( struct pci_device *pci );
#endif /* _IPXE_BOFM_H */
|