2 * Copyright 2014 Google Inc.
4 * See file CREDITS for list of people who contributed to this
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but without any warranty; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
18 #include <libpayload.h>
19 #include "base/device_tree.h"
22 * This file provides functions retrieving WiFi calibration data from CBMEM
23 * and placing it in the kernel device tree.
25 * Per interface calibration data is stored in a CBMEM entry as a header
26 * followed by a few adjacent blobs, as described by the following structures.
29 /* A single calibration data blob */
30 struct calibration_blob {
31 uint32_t blob_size; /* Total size. rounded up to fall on a 4 byte
33 uint32_t key_size; /* Size of the name of this entry, \0 included. */
34 uint32_t value_size; /* Size of the value of this entry */
35 /* Zero terminated name(key) goes here, immediately followed by value */
39 * This is the structure of the CBMEM entry containing WiFi calibration blobs.
40 * It starts with the total size (header size included) followed by an
41 * arbitrary number of concatenated 4 byte aligned calibration blobs.
43 struct calibration_entry {
45 struct calibration_blob entries[0]; /* A varialble size container. */
48 static int blob_is_valid(struct calibration_entry *cal_entry,
49 struct calibration_blob *cal_blob)
51 uintptr_t entry_base, blob_base;
54 entry_base = (uintptr_t)cal_entry;
55 blob_base = (uintptr_t)cal_blob;
57 if ((blob_base <= entry_base) ||
58 (blob_base > (entry_base + cal_entry->size)) ||
62 blob_size = sizeof(struct calibration_blob) +
66 if (cal_blob->blob_size < blob_size)
69 if ((blob_base + blob_size) > (entry_base + cal_entry->size))
75 int dt_set_wifi_calibration(DeviceTree *tree, const DtPathMap *maps)
78 struct calibration_entry *cal_entry;
79 struct calibration_blob *cal_blob;
81 cal_entry = lib_sysinfo.wifi_calibration;
84 return 0; /* No calibration data was found. */
86 /* The first blob starts right above the header */
87 cal_blob = cal_entry->entries;
89 while(blob_is_valid(cal_entry, cal_blob)) {
90 const DtPathMap *map = maps;
92 while (map->dt_path) {
93 char *key = (char *)(cal_blob + 1);
95 if (!strcmp(map->key, key)) {
96 rv |= dt_set_bin_prop_by_path
98 key + cal_blob->key_size,
108 printf("%s: did not find mapping for %s\n",
111 cal_blob = (struct calibration_blob *)
112 ((uintptr_t)cal_blob + cal_blob->blob_size);