Преглед изворни кода

[smsc95xx] Fetch MAC from SMBIOS OEM string for Honeywell VM3

The Honeywell VM3 has no attached EEPROM, and records the MAC address
within an SMBIOS OEM string.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown пре 8 година
родитељ
комит
ae8dfd74c0
3 измењених фајлова са 119 додато и 0 уклоњено
  1. 113
    0
      src/drivers/net/smsc95xx.c
  2. 3
    0
      src/drivers/net/smsc95xx.h
  3. 3
    0
      src/include/ipxe/smbios.h

+ 113
- 0
src/drivers/net/smsc95xx.c Прегледај датотеку

@@ -31,6 +31,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
31 31
 #include <ipxe/usb.h>
32 32
 #include <ipxe/usbnet.h>
33 33
 #include <ipxe/profile.h>
34
+#include <ipxe/base16.h>
35
+#include <ipxe/smbios.h>
34 36
 #include "smsc95xx.h"
35 37
 
36 38
 /** @file
@@ -279,6 +281,111 @@ static int smsc95xx_fetch_mac_eeprom ( struct smsc95xx_device *smsc95xx,
279 281
 		return -ENODEV;
280 282
 	}
281 283
 
284
+	DBGC ( smsc95xx, "SMSC95XX %p using EEPROM MAC %s\n",
285
+	       smsc95xx, eth_ntoa ( hw_addr ) );
286
+	return 0;
287
+}
288
+
289
+/**
290
+ * Construct MAC address for Honeywell VM3
291
+ *
292
+ * @v smsc95xx		SMSC95xx device
293
+ * @v hw_addr		Hardware address to fill in
294
+ * @ret rc		Return status code
295
+ */
296
+static int smsc95xx_fetch_mac_vm3 ( struct smsc95xx_device *smsc95xx,
297
+				    uint8_t *hw_addr ) {
298
+	struct smbios_structure structure;
299
+	struct smbios_system_information system;
300
+	struct {
301
+		char manufacturer[ 10 /* "Honeywell" + NUL */ ];
302
+		char product[ 4 /* "VM3" + NUL */ ];
303
+		char mac[ base16_encoded_len ( ETH_ALEN ) + 1 /* NUL */ ];
304
+	} strings;
305
+	int len;
306
+	int rc;
307
+
308
+	/* Find system information */
309
+	if ( ( rc = find_smbios_structure ( SMBIOS_TYPE_SYSTEM_INFORMATION, 0,
310
+					    &structure ) ) != 0 ) {
311
+		DBGC ( smsc95xx, "SMSC95XX %p could not find system "
312
+		       "information: %s\n", smsc95xx, strerror ( rc ) );
313
+		return rc;
314
+	}
315
+
316
+	/* Read system information */
317
+	if ( ( rc = read_smbios_structure ( &structure, &system,
318
+					    sizeof ( system ) ) ) != 0 ) {
319
+		DBGC ( smsc95xx, "SMSC95XX %p could not read system "
320
+		       "information: %s\n", smsc95xx, strerror ( rc ) );
321
+		return rc;
322
+	}
323
+
324
+	/* NUL-terminate all strings to be fetched */
325
+	memset ( &strings, 0, sizeof ( strings ) );
326
+
327
+	/* Fetch system manufacturer name */
328
+	len = read_smbios_string ( &structure, system.manufacturer,
329
+				   strings.manufacturer,
330
+				   ( sizeof ( strings.manufacturer ) - 1 ) );
331
+	if ( len < 0 ) {
332
+		rc = len;
333
+		DBGC ( smsc95xx, "SMSC95XX %p could not read manufacturer "
334
+		       "name: %s\n", smsc95xx, strerror ( rc ) );
335
+		return rc;
336
+	}
337
+
338
+	/* Fetch system product name */
339
+	len = read_smbios_string ( &structure, system.product, strings.product,
340
+				   ( sizeof ( strings.product ) - 1 ) );
341
+	if ( len < 0 ) {
342
+		rc = len;
343
+		DBGC ( smsc95xx, "SMSC95XX %p could not read product name: "
344
+		       "%s\n", smsc95xx, strerror ( rc ) );
345
+		return rc;
346
+	}
347
+
348
+	/* Ignore non-VM3 devices */
349
+	if ( ( strcmp ( strings.manufacturer, "Honeywell" ) != 0 ) ||
350
+	     ( strcmp ( strings.product, "VM3" ) != 0 ) )
351
+		return -ENOTTY;
352
+
353
+	/* Find OEM strings */
354
+	if ( ( rc = find_smbios_structure ( SMBIOS_TYPE_OEM_STRINGS, 0,
355
+					    &structure ) ) != 0 ) {
356
+		DBGC ( smsc95xx, "SMSC95XX %p could not find OEM strings: %s\n",
357
+		       smsc95xx, strerror ( rc ) );
358
+		return rc;
359
+	}
360
+
361
+	/* Fetch MAC address */
362
+	len = read_smbios_string ( &structure, SMSC95XX_VM3_OEM_STRING_MAC,
363
+				   strings.mac, ( sizeof ( strings.mac ) - 1 ));
364
+	if ( len < 0 ) {
365
+		rc = len;
366
+		DBGC ( smsc95xx, "SMSC95XX %p could not read OEM string: %s\n",
367
+		       smsc95xx, strerror ( rc ) );
368
+		return rc;
369
+	}
370
+
371
+	/* Sanity check */
372
+	if ( len != ( ( int ) ( sizeof ( strings.mac ) - 1 ) ) ) {
373
+		DBGC ( smsc95xx, "SMSC95XX %p invalid MAC address \"%s\"\n",
374
+		       smsc95xx, strings.mac );
375
+		return -EINVAL;
376
+	}
377
+
378
+	/* Decode MAC address */
379
+	len = base16_decode ( strings.mac, hw_addr, ETH_ALEN );
380
+	if ( len < 0 ) {
381
+		rc = len;
382
+		DBGC ( smsc95xx, "SMSC95XX %p invalid MAC address \"%s\"\n",
383
+		       smsc95xx, strings.mac );
384
+		return rc;
385
+	}
386
+
387
+	DBGC ( smsc95xx, "SMSC95XX %p using VM3 MAC %s\n",
388
+	       smsc95xx, eth_ntoa ( hw_addr ) );
282 389
 	return 0;
283 390
 }
284 391
 
@@ -297,8 +404,14 @@ static int smsc95xx_fetch_mac ( struct smsc95xx_device *smsc95xx,
297 404
 	if ( ( rc = smsc95xx_fetch_mac_eeprom ( smsc95xx, hw_addr ) ) == 0 )
298 405
 		return 0;
299 406
 
407
+	/* Construct MAC address for Honeywell VM3, if applicable */
408
+	if ( ( rc = smsc95xx_fetch_mac_vm3 ( smsc95xx, hw_addr ) ) == 0 )
409
+		return 0;
410
+
300 411
 	/* Otherwise, generate a random MAC address */
301 412
 	eth_random_addr ( hw_addr );
413
+	DBGC ( smsc95xx, "SMSC95XX %p using random MAC %s\n",
414
+	       smsc95xx, eth_ntoa ( hw_addr ) );
302 415
 	return 0;
303 416
 }
304 417
 

+ 3
- 0
src/drivers/net/smsc95xx.h Прегледај датотеку

@@ -251,4 +251,7 @@ struct smsc95xx_device {
251 251
 	  ETH_FRAME_LEN + 4 /* possible VLAN header */		\
252 252
 	  + 4 /* CRC */ )
253 253
 
254
+/** Honeywell VM3 MAC address OEM string index */
255
+#define SMSC95XX_VM3_OEM_STRING_MAC 2
256
+
254 257
 #endif /* _SMSC95XX_H */

+ 3
- 0
src/include/ipxe/smbios.h Прегледај датотеку

@@ -152,6 +152,9 @@ struct smbios_enclosure_information {
152 152
 /** SMBIOS enclosure information structure type */
153 153
 #define SMBIOS_TYPE_ENCLOSURE_INFORMATION 3
154 154
 
155
+/** SMBIOS OEM strings structure type */
156
+#define SMBIOS_TYPE_OEM_STRINGS 11
157
+
155 158
 /**
156 159
  * SMBIOS entry point descriptor
157 160
  *

Loading…
Откажи
Сачувај