iPXE
bofm_test.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <stdint.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <byteswap.h>
30 #include <ipxe/init.h>
31 #include <ipxe/pci.h>
32 #include <ipxe/ethernet.h>
33 #include <ipxe/bofm.h>
34 
35 /** @file
36  *
37  * IBM BladeCenter Open Fabric Manager (BOFM) tests
38  *
39  */
40 
41 /** Harvest test table */
42 static struct {
45  struct bofm_en en;
47 } __attribute__ (( packed )) bofmtab_harvest = {
48  .header = {
49  .magic = BOFM_IOAA_MAGIC,
50  .action = BOFM_ACTION_HVST,
51  .version = 0x01,
52  .level = 0x01,
53  .length = sizeof ( bofmtab_harvest ),
54  .profile = "Harvest test profile",
55  },
56  .en_header = {
57  .magic = BOFM_EN_MAGIC,
58  .length = sizeof ( bofmtab_harvest.en ),
59  },
60  .en = {
61  .options = ( BOFM_EN_MAP_PFA | BOFM_EN_USAGE_HARVEST |
63  .mport = 1,
64  },
65  .done = {
66  .magic = BOFM_DONE_MAGIC,
67  },
68 };
69 
70 /** Update test table */
71 static struct {
74  struct bofm_en en;
76 } __attribute__ (( packed )) bofmtab_update = {
77  .header = {
78  .magic = BOFM_IOAA_MAGIC,
79  .action = BOFM_ACTION_UPDT,
80  .version = 0x01,
81  .level = 0x01,
82  .length = sizeof ( bofmtab_update ),
83  .profile = "Update test profile",
84  },
85  .en_header = {
86  .magic = BOFM_EN_MAGIC,
87  .length = sizeof ( bofmtab_update.en ),
88  },
89  .en = {
90  .options = ( BOFM_EN_MAP_PFA | BOFM_EN_EN_A |
92  .mport = 1,
93  .mac_a = { 0x02, 0x00, 0x69, 0x50, 0x58, 0x45 },
94  },
95  .done = {
96  .magic = BOFM_DONE_MAGIC,
97  },
98 };
99 
100 /**
101  * Perform BOFM test
102  *
103  * @v pci PCI device
104  */
105 void bofm_test ( struct pci_device *pci ) {
106  int bofmrc;
107 
108  printf ( "BOFMTEST using " PCI_FMT "\n", PCI_ARGS ( pci ) );
109 
110  /* Perform harvest test */
111  printf ( "BOFMTEST performing harvest\n" );
112  bofmtab_harvest.en.busdevfn = pci->busdevfn;
113  DBG_HDA ( 0, &bofmtab_harvest, sizeof ( bofmtab_harvest ) );
114  bofmrc = bofm ( &bofmtab_harvest, pci );
115  printf ( "BOFMTEST harvest result %08x\n", bofmrc );
116  if ( bofmtab_harvest.en.options & BOFM_EN_HVST ) {
117  printf ( "BOFMTEST harvested MAC address %s\n",
118  eth_ntoa ( &bofmtab_harvest.en.mac_a ) );
119  } else {
120  printf ( "BOFMTEST failed to harvest a MAC address\n" );
121  }
122  DBG_HDA ( 0, &bofmtab_harvest, sizeof ( bofmtab_harvest ) );
123 
124  /* Perform update test */
125  printf ( "BOFMTEST performing update\n" );
126  bofmtab_update.en.busdevfn = pci->busdevfn;
127  DBG_HDA ( 0, &bofmtab_update, sizeof ( bofmtab_update ) );
128  bofmrc = bofm ( &bofmtab_update, pci );
129  printf ( "BOFMTEST update result %08x\n", bofmrc );
130  if ( bofmtab_update.en.options & BOFM_EN_CSM_SUCCESS ) {
131  printf ( "BOFMTEST updated MAC address to %s\n",
132  eth_ntoa ( &bofmtab_update.en.mac_a ) );
133  } else {
134  printf ( "BOFMTEST failed to update MAC address\n" );
135  }
136  DBG_HDA ( 0, &bofmtab_update, sizeof ( bofmtab_update ) );
137 }
138 
139 /**
140  * Harvest dummy Ethernet MAC
141  *
142  * @v bofm BOFM device
143  * @v mport Multi-port index
144  * @v mac MAC to fill in
145  * @ret rc Return status code
146  */
147 static int bofm_dummy_harvest ( struct bofm_device *bofm, unsigned int mport,
148  uint8_t *mac ) {
149  struct {
152  uint16_t mport;
153  } __attribute__ (( packed )) dummy_mac;
154 
155  /* Construct dummy MAC address */
156  dummy_mac.vendor = cpu_to_be16 ( bofm->pci->vendor );
157  dummy_mac.device = cpu_to_be16 ( bofm->pci->device );
158  dummy_mac.mport = cpu_to_be16 ( mport );
159  memcpy ( mac, &dummy_mac, sizeof ( dummy_mac ) );
160  printf ( "BOFMTEST mport %d constructed dummy MAC %s\n",
161  mport, eth_ntoa ( mac ) );
162 
163  return 0;
164 }
165 
166 /**
167  * Update Ethernet MAC for BOFM
168  *
169  * @v bofm BOFM device
170  * @v mport Multi-port index
171  * @v mac MAC to fill in
172  * @ret rc Return status code
173  */
175  unsigned int mport, const uint8_t *mac ) {
176 
177  printf ( "BOFMTEST mport %d asked to update MAC to %s\n",
178  mport, eth_ntoa ( mac ) );
179  return 0;
180 }
181 
182 /** Dummy BOFM operations */
185  .update = bofm_dummy_update,
186 };
187 
188 /** Dummy BOFM device */
189 static struct bofm_device bofm_dummy;
190 
191 /**
192  * Probe dummy BOFM device
193  *
194  * @v pci PCI device
195  * @v id PCI ID
196  * @ret rc Return status code
197  */
198 static int bofm_dummy_probe ( struct pci_device *pci ) {
199  int rc;
200 
201  /* Ignore probe for any other devices */
202  if ( pci->busdevfn != bofm_dummy.pci->busdevfn )
203  return 0;
204 
205  /* Register BOFM device */
206  if ( ( rc = bofm_register ( &bofm_dummy ) ) != 0 )
207  return rc;
208 
209  printf ( "BOFMTEST using dummy BOFM driver\n" );
210  return 0;
211 }
212 
213 /**
214  * Remove dummy BOFM device
215  *
216  * @v pci PCI device
217  */
218 static void bofm_dummy_remove ( struct pci_device *pci ) {
219 
220  /* Ignore removal for any other devices */
221  if ( pci->busdevfn != bofm_dummy.pci->busdevfn )
222  return;
223 
224  /* Unregister BOFM device */
226 }
227 
228 /** Dummy BOFM driver PCI IDs */
229 static struct pci_device_id bofm_dummy_ids[1] = {
230  { .name = "dummy" },
231 };
232 
233 /** Dummy BOFM driver */
234 struct pci_driver bofm_dummy_driver __bofm_test_driver = {
235  .ids = bofm_dummy_ids,
236  .id_count = ( sizeof ( bofm_dummy_ids ) /
237  sizeof ( bofm_dummy_ids[0] ) ),
240 };
241 
242 /**
243  * Perform BOFM test at initialisation time
244  *
245  */
246 static void bofm_test_init ( void ) {
247  struct pci_device pci;
248  int busdevfn = -1;
249  int rc;
250 
251  /* Uncomment the following line and specify the correct PCI
252  * bus:dev.fn address in order to perform a BOFM test at
253  * initialisation time.
254  */
255  // busdevfn = PCI_BUSDEVFN ( <segment>, <bus>, <dev>, <fn> );
256 
257  /* Skip test if no PCI bus:dev.fn is defined */
258  if ( busdevfn < 0 )
259  return;
260 
261  /* Initialise PCI device */
262  memset ( &pci, 0, sizeof ( pci ) );
263  pci_init ( &pci, busdevfn );
264  if ( ( rc = pci_read_config ( &pci ) ) != 0 ) {
265  printf ( "BOFMTEST could not create " PCI_FMT " device: %s\n",
266  PCI_ARGS ( &pci ), strerror ( rc ) );
267  return;
268  }
269 
270  /* Initialise dummy BOFM device */
272  bofm_dummy_ids[0].vendor = pci.vendor;
273  bofm_dummy_ids[0].device = pci.device;
274 
275  /* Perform test */
276  bofm_test ( &pci );
277 }
278 
279 /** BOFM test initialisation function */
280 struct init_fn bofm_test_init_fn __init_fn ( INIT_NORMAL ) = {
281  .name = "bofm",
282  .initialise = bofm_test_init,
283 };
#define cpu_to_be16(value)
Definition: byteswap.h:109
#define __attribute__(x)
Definition: compiler.h:10
struct bofm_en en
Definition: bofm_test.c:45
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
static void bofm_init(struct bofm_device *bofm, struct pci_device *pci, struct bofm_operations *op)
Initialise BOFM device.
Definition: bofm.h:342
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
A PCI driver.
Definition: pci.h:251
#define DBG_HDA(...)
Definition: compiler.h:499
void bofm_test(struct pci_device *pci)
Perform BOFM test.
Definition: bofm_test.c:105
struct pci_device_id * ids
PCI ID table.
Definition: pci.h:253
static unsigned short vendor
Definition: davicom.c:128
#define BOFM_EN_EN_A
MAC address A is present.
Definition: bofm.h:225
#define BOFM_EN_USAGE_HARVEST
Ignore values - it's harvest time.
Definition: bofm.h:252
#define BOFM_EN_MAGIC
EN start marker.
Definition: bofm.h:151
static int bofm_dummy_harvest(struct bofm_device *bofm, unsigned int mport, uint8_t *mac)
Harvest dummy Ethernet MAC.
Definition: bofm_test.c:147
static void bofm_test_init(void)
Perform BOFM test at initialisation time.
Definition: bofm_test.c:246
struct pci_device * pci
Underlying PCI device.
Definition: bofm.h:288
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
uint16_t device
Device ID.
Definition: ena.h:24
static int bofm_dummy_probe(struct pci_device *pci)
Probe dummy BOFM device.
Definition: bofm_test.c:198
#define BOFM_ACTION_UPDT
Update MAC/WWN.
Definition: bofm.h:114
uint16_t busdevfn
PCI bus:dev.fn address.
Definition: ena.h:28
#define INIT_NORMAL
Normal initialisation.
Definition: init.h:31
void * memcpy(void *dest, const void *src, size_t len) __nonnull
IBM BladeCenter Open Fabric Manager (BOFM)
An initialisation function.
Definition: init.h:14
uint16_t device
Device ID.
Definition: pci.h:229
__be16 profile
Definition: CIB_PRM.h:30
Ethernet protocol.
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
static struct bofm_device bofm_dummy
Dummy BOFM device.
Definition: bofm_test.c:189
const char * name
Definition: init.h:15
static struct @439 bofmtab_harvest
Harvest test table.
#define BOFM_EN_MAP_PFA
Port mapping is by PCI bus:dev.fn.
Definition: bofm.h:213
#define BOFM_IOAA_MAGIC
BOFM table header signature.
Definition: bofm.h:103
#define BOFM_DONE_MAGIC
End marker.
Definition: bofm.h:154
BOFM table header.
Definition: bofm.h:77
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static struct @440 bofmtab_update
Update test table.
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:311
static struct pci_device_id bofm_dummy_ids[1]
Dummy BOFM driver PCI IDs.
Definition: bofm_test.c:229
PCI bus.
A PCI device.
Definition: pci.h:210
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition: ethernet.c:175
#define BOFM_EN_HVST
Harvest complete.
Definition: bofm.h:261
int pci_read_config(struct pci_device *pci)
Read PCI device configuration.
Definition: pci.c:268
A BOFM device.
Definition: bofm.h:286
struct bofm_global_header header
Definition: bofm_test.c:43
unsigned char uint8_t
Definition: stdint.h:10
BOFM section header.
Definition: bofm.h:135
#define BOFM_EN_USAGE_ENTRY
Use entry values for assignment.
Definition: bofm.h:255
int bofm_register(struct bofm_device *bofm)
Register BOFM device.
Definition: bofm.c:48
A PCI device ID list entry.
Definition: pci.h:174
static struct bofm_operations bofm_dummy_operations
Dummy BOFM operations.
Definition: bofm_test.c:183
const char * name
Name.
Definition: pci.h:176
static struct xen_remove_from_physmap * remove
Definition: xenmem.h:39
uint16_t vendor
Vendor ID.
Definition: pci.h:227
uint16_t vendor
PCI vendor ID.
Definition: pci.h:178
uint32_t busdevfn
Segment, bus, device, and function (bus:dev.fn) number.
Definition: pci.h:237
uint16_t device
PCI device ID.
Definition: pci.h:180
int bofm(void *bofmtab, struct pci_device *pci)
Process BOFM table.
Definition: bofm.c:235
int(* harvest)(struct bofm_device *bofm, unsigned int mport, uint8_t *mac)
Harvest Ethernet MAC.
Definition: bofm.h:304
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
struct init_fn bofm_test_init_fn __init_fn(INIT_NORMAL)
BOFM test initialisation function.
int(* probe)(struct pci_device *pci)
Probe device.
Definition: pci.h:264
BOFM Ethernet parameter entry.
Definition: bofm.h:163
struct bofm_section_header en_header
Definition: bofm_test.c:44
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:314
static int bofm_dummy_update(struct bofm_device *bofm __unused, unsigned int mport, const uint8_t *mac)
Update Ethernet MAC for BOFM.
Definition: bofm_test.c:174
#define BOFM_EN_RQ_HVST_ACTIVE
Harvest active values.
Definition: bofm.h:273
void bofm_unregister(struct bofm_device *bofm)
Unregister BOFM device.
Definition: bofm.c:61
static void bofm_dummy_remove(struct pci_device *pci)
Remove dummy BOFM device.
Definition: bofm_test.c:218
#define BOFM_EN_CSM_SUCCESS
Entry has been used successfully.
Definition: bofm.h:237
static void pci_init(struct pci_device *pci, unsigned int busdevfn)
Initialise PCI device.
Definition: pci.h:340
#define BOFM_ACTION_HVST
Harvest MAC/WWN.
Definition: bofm.h:120
BOFM device operations.
Definition: bofm.h:296
struct pci_driver bofm_dummy_driver __bofm_test_driver
Dummy BOFM driver.
Definition: bofm_test.c:234
String functions.
struct bofm_section_header done
Definition: bofm_test.c:46
void * memset(void *dest, int character, size_t len) __nonnull