/*
 * This file is part of the coreboot project.
 *
 * Copyright 2014 Google Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <cbmem.h>
#include <console/console.h>
#include <string.h>

#include <vendorcode/google/chromeos/chromeos.h>
#include <vendorcode/google/chromeos/cros_vpd.h>

/*
 * This file provides functions looking in the VPD for WiFi calibration data,
 * and if found, copying the calibration blobs into CBMEM.
 *
 * Per interface calibration data is stored in the VPD in opaque blobs. The
 * keys of the blobs follow one of two possible patterns:
 * "wifi_base64_calibration<N>" or "wifi_calibration<N>", where <N> is the
 * interface number.
 *
 * This function accommodates up to 4 interfaces. All calibration blobs found
 * in the VPD are packed into a single CBMEM entry as describe by the
 * structures below:
 */

/* This structure describes a single calibration data blob */
struct calibration_blob {
	uint32_t blob_size;  /* Total size. rounded up to fall on a 4 byte
				   boundary. */
	uint32_t key_size;   /* Size of the name of this entry, \0 included. */
	uint32_t value_size; /* Size of the value of this entry */
	/* Zero terminated name(key) goes here, immediately followed by value */
};

/*
 * This is the structure of the CBMEM entry containing WiFi calibration blobs.
 * It starts with the total size (header size included) followed by an
 * arbitrary number of concatenated 4 byte aligned calibration blobs.
 */
struct calibration_entry {
	uint32_t size;
	struct calibration_blob entries[0];  /* A varialble size container. */
};


#define MAX_WIFI_INTERFACE_COUNT 4

/*
 * Structure of the cache to keep information about calibration blobs present
 * in the VPD, one cache entry per VPD blob.
 *
 * Maintaing the cache allows to scan the VPD once, determine the CBMEM entry
 * memory requirements, then allocate as much room as necessary and fill it
 * up.
 */
struct vpd_blob_cache_t {
	/* The longest name template must fit with an extra character. */
	char key_name[40];
	const void  *value_pointer;
	unsigned blob_size;
	unsigned key_size;
	unsigned value_size;
};

static const char * const templates[] = {
	"wifi_base64_calibrationX",
	"wifi_calibrationX"
};

/*
 * Scan the VPD for WiFi calibration data, checking for all possible key names
 * and caching discovered blobs.
 *
 * Return the sum of sizes of all blobs, as stored in CBMEM.
 */
static size_t fill_up_entries_cache(struct vpd_blob_cache_t *cache,
				    size_t max_entries, size_t *filled_entries)
{
	int i;
	int cbmem_entry_size = 0;
	size_t used_entries = 0;


	for (i = 0;
	     (i < ARRAY_SIZE(templates)) && (used_entries < max_entries);
	     i++) {
		int j;
		const int index_location = strlen(templates[i]) - 1;
		const int key_length = index_location + 2;

		if (key_length > sizeof(cache->key_name))
			continue;

		for (j = 0; j < MAX_WIFI_INTERFACE_COUNT; j++) {
			const void *payload;
			int payload_size;

			strcpy(cache->key_name, templates[i]);
			cache->key_name[index_location] = j + '0';

			payload = cros_vpd_find(cache->key_name, &payload_size);
			if (!payload)
				continue;

			cache->value_pointer = payload;
			cache->key_size = key_length;
			cache->value_size = payload_size;
			cache->blob_size =
				ALIGN(sizeof(struct calibration_blob) +
				      cache->key_size +
				      cache->value_size, 4);
			cbmem_entry_size += cache->blob_size;

			used_entries++;
			if (used_entries == max_entries)
				break;

			cache++;
		}
	}

	*filled_entries = used_entries;
	return cbmem_entry_size;
}

void cbmem_add_vpd_calibration_data(void)
{
	size_t cbmem_entry_size, filled_entries;
	struct calibration_entry *cbmem_entry;
	struct calibration_blob *cal_blob;
	int i;
	/*
	 * Allocate one more cache entry than max required, to make sure that
	 * the last entry can be identified by the key size of zero.
	 */
	struct vpd_blob_cache_t vpd_blob_cache[ARRAY_SIZE(templates) *
					       MAX_WIFI_INTERFACE_COUNT];

	cbmem_entry_size = fill_up_entries_cache(vpd_blob_cache,
						 ARRAY_SIZE(vpd_blob_cache),
						 &filled_entries);

	if (!cbmem_entry_size)
		return; /* No calibration data found in the VPD. */

	cbmem_entry_size += sizeof(struct calibration_entry);
	cbmem_entry = cbmem_add(CBMEM_ID_WIFI_CALIBRATION, cbmem_entry_size);
	if (!cbmem_entry) {
		printk(BIOS_ERR, "%s: no room in cbmem to add %zd bytes\n",
		       __func__, cbmem_entry_size);
		return;
	}

	cbmem_entry->size = cbmem_entry_size;

	/* Copy cached data into the CBMEM entry. */
	cal_blob = cbmem_entry->entries;

	for (i = 0; i < filled_entries; i++) {
		/* Use this as a pointer to the current cache entry. */
		struct vpd_blob_cache_t *cache = vpd_blob_cache + i;
		char *pointer;

		cal_blob->blob_size = cache->blob_size;
		cal_blob->key_size = cache->key_size;
		cal_blob->value_size = cache->value_size;

		/* copy the key */
		pointer = (char *)(cal_blob + 1);
		memcpy(pointer, cache->key_name, cache->key_size);

		/* and the value */
		pointer += cache->key_size;
		memcpy(pointer, cache->value_pointer, cache->value_size);

		printk(BIOS_INFO, "%s: added %s to CBMEM\n",
		       __func__, cache->key_name);

		cal_blob = (struct calibration_blob *)
			((char *)cal_blob + cal_blob->blob_size);
	}
}
