vc/google/chromeos: Deprecate support for SAR tables in VPD

SAR table in VPD has been deprecated for Chrome OS platforms for > 1
year now. All new Chrome OS platforms have switched to using SAR
tables from CBFS.

This change drops the support for SAR table in VPD from coreboot to
align with the factory changes. `get_wifi_sar_limits()` is thus
updated to look for SAR file in CBFS only.

Anyone building ToT coreboot for an already released Chrome OS
platform with SAR table in VPD will have to extract the "wifi_sar" key
from VPD and add it as a file to CBFS using following steps:

 - On DUT, read SAR value using `vpd -i RO_VPD -g wifi_sar`
 - In coreboot repo, generate CBFS SAR file using:
   `echo ${SAR_STRING} > site-local/${BOARD}-sar.hex`
 - Add to site-local/Kconfig:
   ```
   config WIFI_SAR_CBFS_FILEPATH
     string
     default "site-local/${BOARD}-sar.hex"
   ```

BUG=b:173465272

Change-Id: I21d190dcc9f3554fab6e21b4498e7588a32bb1f0
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/51483
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
This commit is contained in:
Furquan Shaikh 2021-03-13 12:35:20 -08:00 committed by Patrick Georgi
parent a94fea1ee4
commit eb876a5830
1 changed files with 64 additions and 88 deletions

View File

@ -2,111 +2,87 @@
#include <cbfs.h>
#include <console/console.h>
#include <lib.h>
#include <types.h>
#include <string.h>
#include <sar.h>
#include <drivers/vpd/vpd.h>
#include <lib.h>
#include <sar.h>
#include <stdlib.h>
#include <string.h>
#include <types.h>
#define WIFI_SAR_CBFS_FILENAME "wifi_sar_defaults.hex"
#define CROS_VPD_WIFI_SAR_NAME "wifi_sar"
static int load_sar_file_from_cbfs(void *buf, size_t buffer_size)
{
const char *filename = get_wifi_sar_cbfs_filename();
if (filename == NULL)
filename = WIFI_SAR_CBFS_FILENAME;
return cbfs_load(filename, buf, buffer_size);
}
/* Retrieve the wifi SAR limits data from VPD and decode it
For VPD: key,value pair is in this format
"wifi_sar"=[<WRDD><EWRD>][WGDS]
WIFI SAR data in CBFS file is expected in same format: [<WRDD><EWRD>][WGDS]
[<WRDD><EWRD>] = NUM_SAR_LIMITS * BYTES_PER_SAR_LIMIT bytes.
[WGDS]=[WGDS_VERSION][WGDS_DATA]
For [WGDS_VERSION] 0x00,
[WGDS_DATA] = [GROUP#0][GROUP#1][GROUP#2]
[GROUP#<i>] =
[2.4Ghz Max Allowed][2.4Ghz Chain A Offset]
[2.4Ghz Chain B Offset][5Ghz Max Allowed]
[5Ghz Chain A Offset][5Ghz Chain B Offset]
[GROUP#0] is for FCC
[GROUP#1] is for Europe/Japan
[GROUP#2] is for ROW
/*
* Retrieve WiFi SAR limits data from CBFS and decode it
* WiFi SAR data is expected in the format: [<WRDD><EWRD>][WGDS]
*
* [<WRDD><EWRD>] = NUM_SAR_LIMITS * BYTES_PER_SAR_LIMIT bytes.
* [WGDS]=[WGDS_VERSION][WGDS_DATA]
*
* For [WGDS_VERSION] 0x00,
* [WGDS_DATA] = [GROUP#0][GROUP#1][GROUP#2]
*
* [GROUP#<i>] =
* [2.4Ghz Max Allowed][2.4Ghz Chain A Offset]
* [2.4Ghz Chain B Offset][5Ghz Max Allowed]
* [5Ghz Chain A Offset][5Ghz Chain B Offset]
*
* [GROUP#0] is for FCC
* [GROUP#1] is for Europe/Japan
* [GROUP#2] is for ROW
*/
int get_wifi_sar_limits(struct wifi_sar_limits *sar_limits)
{
const char *wifi_sar_limit_key = CROS_VPD_WIFI_SAR_NAME;
/* vpd_gets() reads in one less than size characters from the VPD
* with a terminating null byte ('\0') stored as the last character into
* the buffer, thus the increasing by 1 for the buffer size. */
char wifi_sar_limit_str[2 * sizeof(struct wifi_sar_limits) + 1];
uint8_t bin_buffer[sizeof(struct wifi_sar_limits)];
const size_t buffer_size = ARRAY_SIZE(wifi_sar_limit_str);
size_t sar_cbfs_len, sar_expected_len, bin_buff_adjusted_size;
const char *filename;
size_t sar_str_len, sar_bin_len;
char *sar_str;
int ret = -1;
/* keep it backward compatible. Some older platform are shipping
without GEO SAR and so older wifi_sar VPD key */
/*
* If GEO_SAR_ENABLE is not selected, SAR file does not contain
* delta table settings.
*/
if (CONFIG(GEO_SAR_ENABLE))
sar_bin_len = sizeof(struct wifi_sar_limits);
else
sar_bin_len = sizeof(struct wifi_sar_limits) -
sizeof(struct wifi_sar_delta_table);
sar_expected_len = buffer_size;
bin_buff_adjusted_size = sizeof(struct wifi_sar_limits);
/*
* Each hex digit is represented as a character in CBFS SAR file. Thus,
* the SAR file is double the size of its binary buffer equivalent.
* Hence, the buffer size allocated for SAR file is:
* `2 * sar_bin_len + 1`
* 1 additional byte is allocated to store the terminating '\0'.
*/
sar_str_len = 2 * sar_bin_len + 1;
sar_str = malloc(sar_str_len);
if (!CONFIG(GEO_SAR_ENABLE)) {
sar_expected_len = buffer_size -
sizeof(struct wifi_sar_delta_table) *
sizeof(uint8_t) * 2;
bin_buff_adjusted_size = sizeof(struct wifi_sar_limits) -
sizeof(struct wifi_sar_delta_table);
if (!sar_str) {
printk(BIOS_ERR, "Failed to allocate space for SAR string!\n");
return ret;
}
/* Try to read the SAR limit entry from VPD */
if (!vpd_gets(wifi_sar_limit_key, wifi_sar_limit_str,
buffer_size, VPD_RO_THEN_RW)) {
printk(BIOS_DEBUG, "Could not locate '%s' in VPD.\n",
wifi_sar_limit_key);
printk(BIOS_DEBUG, "Checking CBFS for default SAR values\n");
if (!CONFIG(WIFI_SAR_CBFS))
return -1;
filename = get_wifi_sar_cbfs_filename();
if (filename == NULL)
filename = WIFI_SAR_CBFS_FILENAME;
printk(BIOS_DEBUG, "Checking CBFS for default SAR values\n");
sar_cbfs_len = load_sar_file_from_cbfs(
(void *) wifi_sar_limit_str,
sar_expected_len);
if (sar_cbfs_len != sar_expected_len) {
printk(BIOS_ERR, "%s has bad len in CBFS\n",
WIFI_SAR_CBFS_FILENAME);
return -1;
}
} else {
/* VPD key "wifi_sar" found. strlen is checked with addition of
* 1 as we have created buffer size 1 char larger for the reason
* mentioned at start of this function itself */
if (strlen(wifi_sar_limit_str) + 1 != sar_expected_len) {
printk(BIOS_ERR, "WIFI SAR key has bad len in VPD\n");
return -1;
}
}
/* Decode the heximal encoded string to binary values */
if (hexstrtobin(wifi_sar_limit_str, bin_buffer, bin_buff_adjusted_size)
< bin_buff_adjusted_size) {
printk(BIOS_ERR, "Error: wifi_sar contains non-hex value!\n");
return -1;
if (cbfs_load(filename, sar_str, sar_str_len) != sar_str_len) {
printk(BIOS_ERR, "%s has bad len in CBFS\n", filename);
goto done;
}
memset(sar_limits, 0, sizeof(*sar_limits));
memcpy(sar_limits, bin_buffer, bin_buff_adjusted_size);
return 0;
if (hexstrtobin(sar_str, (uint8_t *)sar_limits, sar_bin_len) != sar_bin_len) {
printk(BIOS_ERR, "Error: wifi_sar contains non-hex value!\n");
goto done;
}
ret = 0;
done:
free(sar_str);
return ret;
}
__weak