Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F131702224
D8932.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D8932.diff
View Options
Index: head/sys/dev/sfxge/common/efx_bootcfg.c
===================================================================
--- head/sys/dev/sfxge/common/efx_bootcfg.c
+++ head/sys/dev/sfxge/common/efx_bootcfg.c
@@ -38,14 +38,69 @@
/*
* Maximum size of BOOTCFG block across all nics as understood by SFCgPXE.
- * A multiple of 0x100 so trailing 0xff characters don't contrinbute to the
- * checksum.
+ * NOTE: This is larger than the Medford per-PF bootcfg sector.
*/
#define BOOTCFG_MAX_SIZE 0x1000
#define DHCP_END ((uint8_t)0xff)
#define DHCP_PAD ((uint8_t)0)
+
+/* Report size and offset of bootcfg sector in NVRAM partition. */
+static __checkReturn efx_rc_t
+efx_bootcfg_sector(
+ __in efx_nic_t *enp,
+ __out size_t *offsetp,
+ __out size_t *max_sizep)
+{
+ size_t max_size;
+ size_t offset;
+ int rc;
+
+ switch (enp->en_family) {
+#if EFSYS_OPT_SIENA
+ case EFX_FAMILY_SIENA:
+ max_size = BOOTCFG_MAX_SIZE;
+ offset = 0;
+ break;
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ max_size = BOOTCFG_MAX_SIZE;
+ offset = 0;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+#if EFSYS_OPT_MEDFORD
+ case EFX_FAMILY_MEDFORD: {
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+
+ /* Shared partition (array indexed by PF) */
+ max_size = 0x0800;
+ offset = max_size * encp->enc_pf;
+ break;
+ }
+#endif /* EFSYS_OPT_MEDFORD */
+
+ default:
+ EFSYS_ASSERT(0);
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ EFSYS_ASSERT3U(max_size, <=, BOOTCFG_MAX_SIZE);
+
+ *offsetp = offset;
+ *max_sizep = max_size;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+ return (rc);
+}
+
+
static __checkReturn uint8_t
efx_bootcfg_csum(
__in efx_nic_t *enp,
@@ -136,40 +191,54 @@
{
uint8_t *payload = NULL;
size_t used_bytes;
+ size_t partn_length;
size_t sector_length;
+ size_t sector_offset;
efx_rc_t rc;
- rc = efx_nvram_size(enp, EFX_NVRAM_BOOTROM_CFG, §or_length);
+ rc = efx_nvram_size(enp, EFX_NVRAM_BOOTROM_CFG, &partn_length);
if (rc != 0)
goto fail1;
+ /* The bootcfg sector may be stored in a (larger) shared partition */
+ rc = efx_bootcfg_sector(enp, §or_offset, §or_length);
+ if (rc != 0)
+ goto fail2;
+
+ if (sector_length > BOOTCFG_MAX_SIZE)
+ sector_length = BOOTCFG_MAX_SIZE;
+
+ if (sector_offset + sector_length > partn_length) {
+ /* Partition is too small */
+ rc = EFBIG;
+ goto fail3;
+ }
+
/*
- * We need to read the entire BOOTCFG area to ensure we read all the
+ * We need to read the entire BOOTCFG sector to ensure we read all the
* tags, because legacy bootcfg sectors are not guaranteed to end with
* a DHCP_END character. If the user hasn't supplied a sufficiently
* large buffer then use our own buffer.
*/
- if (sector_length > BOOTCFG_MAX_SIZE)
- sector_length = BOOTCFG_MAX_SIZE;
if (sector_length > size) {
EFSYS_KMEM_ALLOC(enp->en_esip, sector_length, payload);
if (payload == NULL) {
rc = ENOMEM;
- goto fail2;
+ goto fail4;
}
} else
payload = (uint8_t *)data;
if ((rc = efx_nvram_rw_start(enp, EFX_NVRAM_BOOTROM_CFG, NULL)) != 0)
- goto fail3;
+ goto fail5;
- rc = efx_nvram_read_chunk(enp, EFX_NVRAM_BOOTROM_CFG, 0,
+ rc = efx_nvram_read_chunk(enp, EFX_NVRAM_BOOTROM_CFG, sector_offset,
(caddr_t)payload, sector_length);
efx_nvram_rw_finish(enp, EFX_NVRAM_BOOTROM_CFG);
if (rc != 0)
- goto fail4;
+ goto fail6;
/* Verify that the area is correctly formatted and checksummed */
rc = efx_bootcfg_verify(enp, (caddr_t)payload, sector_length,
@@ -205,7 +274,7 @@
*/
if (used_bytes > size) {
rc = ENOSPC;
- goto fail5;
+ goto fail7;
}
if (sector_length > size) {
memcpy(data, payload, used_bytes);
@@ -224,15 +293,18 @@
return (0);
+fail7:
+ EFSYS_PROBE(fail7);
+fail6:
+ EFSYS_PROBE(fail6);
fail5:
EFSYS_PROBE(fail5);
+ if (sector_length > size)
+ EFSYS_KMEM_FREE(enp->en_esip, sector_length, payload);
fail4:
EFSYS_PROBE(fail4);
fail3:
EFSYS_PROBE(fail3);
-
- if (sector_length > size)
- EFSYS_KMEM_FREE(enp->en_esip, sector_length, payload);
fail2:
EFSYS_PROBE(fail2);
fail1:
@@ -247,90 +319,109 @@
__in_bcount(size) caddr_t data,
__in size_t size)
{
- uint8_t *chunk;
+ uint8_t *partn_data;
uint8_t checksum;
+ size_t partn_length;
size_t sector_length;
- size_t chunk_length;
+ size_t sector_offset;
size_t used_bytes;
- size_t offset;
- size_t remaining;
efx_rc_t rc;
- rc = efx_nvram_size(enp, EFX_NVRAM_BOOTROM_CFG, §or_length);
+ rc = efx_nvram_size(enp, EFX_NVRAM_BOOTROM_CFG, &partn_length);
if (rc != 0)
goto fail1;
+ /* The bootcfg sector may be stored in a (larger) shared partition */
+ rc = efx_bootcfg_sector(enp, §or_offset, §or_length);
+ if (rc != 0)
+ goto fail2;
+
if (sector_length > BOOTCFG_MAX_SIZE)
sector_length = BOOTCFG_MAX_SIZE;
+ if (sector_offset + sector_length > partn_length) {
+ /* Partition is too small */
+ rc = EFBIG;
+ goto fail3;
+ }
+
if ((rc = efx_bootcfg_verify(enp, data, size, &used_bytes)) != 0)
- goto fail2;
+ goto fail4;
/* The caller *must* terminate their block with a DHCP_END character */
- EFSYS_ASSERT(used_bytes >= 2); /* checksum and DHCP_END */
- if ((uint8_t)data[used_bytes - 1] != DHCP_END) {
+ if ((used_bytes < 2) || ((uint8_t)data[used_bytes - 1] != DHCP_END)) {
+ /* Block too short or DHCP_END missing */
rc = ENOENT;
- goto fail3;
+ goto fail5;
}
/* Check that the hardware has support for this much data */
if (used_bytes > MIN(sector_length, BOOTCFG_MAX_SIZE)) {
rc = ENOSPC;
- goto fail4;
+ goto fail6;
}
- rc = efx_nvram_rw_start(enp, EFX_NVRAM_BOOTROM_CFG, &chunk_length);
- if (rc != 0)
- goto fail5;
-
- EFSYS_KMEM_ALLOC(enp->en_esip, chunk_length, chunk);
- if (chunk == NULL) {
+ /*
+ * If the BOOTCFG sector is stored in a shared partition, then we must
+ * read the whole partition and insert the updated bootcfg sector at the
+ * correct offset.
+ */
+ EFSYS_KMEM_ALLOC(enp->en_esip, partn_length, partn_data);
+ if (partn_data == NULL) {
rc = ENOMEM;
- goto fail6;
+ goto fail7;
}
- if ((rc = efx_nvram_erase(enp, EFX_NVRAM_BOOTROM_CFG)) != 0)
- goto fail7;
+ rc = efx_nvram_rw_start(enp, EFX_NVRAM_BOOTROM_CFG, NULL);
+ if (rc != 0)
+ goto fail8;
+
+ /* Read the entire partition */
+ rc = efx_nvram_read_chunk(enp, EFX_NVRAM_BOOTROM_CFG, 0,
+ (caddr_t)partn_data, partn_length);
+ if (rc != 0)
+ goto fail9;
/*
- * Write the entire sector_length bytes of data in chunks. Zero out
- * all data following the DHCP_END, and adjust the checksum
+ * Insert the BOOTCFG sector into the partition, Zero out all data after
+ * the DHCP_END tag, and adjust the checksum.
*/
+ (void) memset(partn_data + sector_offset, 0x0, sector_length);
+ (void) memcpy(partn_data + sector_offset, data, used_bytes);
+
checksum = efx_bootcfg_csum(enp, data, used_bytes);
- for (offset = 0; offset < sector_length; offset += remaining) {
- remaining = MIN(chunk_length, sector_length - offset);
+ partn_data[sector_offset] -= checksum;
- /* Fill chunk */
- (void) memset(chunk, 0x0, chunk_length);
- if (offset < used_bytes)
- memcpy(chunk, data + offset,
- MIN(remaining, used_bytes - offset));
-
- /* Adjust checksum */
- if (offset == 0)
- chunk[0] -= checksum;
-
- if ((rc = efx_nvram_write_chunk(enp, EFX_NVRAM_BOOTROM_CFG,
- offset, (caddr_t)chunk, remaining)) != 0)
- goto fail8;
+ if ((rc = efx_nvram_erase(enp, EFX_NVRAM_BOOTROM_CFG)) != 0)
+ goto fail10;
+
+ if ((rc = efx_nvram_write_chunk(enp, EFX_NVRAM_BOOTROM_CFG,
+ 0, partn_data, partn_length)) != 0) {
+ goto fail11;
}
efx_nvram_rw_finish(enp, EFX_NVRAM_BOOTROM_CFG);
- EFSYS_KMEM_FREE(enp->en_esip, chunk_length, chunk);
+ EFSYS_KMEM_FREE(enp->en_esip, partn_length, partn_data);
return (0);
+fail11:
+ EFSYS_PROBE(fail11);
+fail10:
+ EFSYS_PROBE(fail10);
+fail9:
+ EFSYS_PROBE(fail9);
+
+ efx_nvram_rw_finish(enp, EFX_NVRAM_BOOTROM_CFG);
fail8:
EFSYS_PROBE(fail8);
+
+ EFSYS_KMEM_FREE(enp->en_esip, partn_length, partn_data);
fail7:
EFSYS_PROBE(fail7);
-
- EFSYS_KMEM_FREE(enp->en_esip, chunk_length, chunk);
fail6:
EFSYS_PROBE(fail6);
-
- efx_nvram_rw_finish(enp, EFX_NVRAM_BOOTROM_CFG);
fail5:
EFSYS_PROBE(fail5);
fail4:
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Oct 11, 11:39 AM (18 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23575466
Default Alt Text
D8932.diff (8 KB)
Attached To
Mode
D8932: sfxge(4): support Medford bootcfg partition layout in common code
Attached
Detach File
Event Timeline
Log In to Comment