• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 #include <console/console.h>
3 #include <cpu/cpu.h>
4 #include <types.h>
5 #include <string.h>
6 #include <wrdd.h>
7 #include <drivers/vpd/vpd.h>
8 
9 #define CROS_VPD_REGION_NAME	"region"
10 
11 /*
12  * wrdd_domain_value is ISO 3166-2
13  * ISO 3166-2 code consists of two parts, separated by a hyphen
14  * The first part is the ISO 3166-1 alpha-2 code of the country;
15  * The second part is a string of up to three alphanumeric characters
16  */
17 #define VARIANT_SEPARATOR '.'
18 struct wrdd_code_value_pair {
19 	const char *code;
20 	u16 value;
21 };
22 
23 /* Retrieve the regulatory domain information from VPD and
24  * return it as an uint16.
25  * WARNING: if domain information is not found in the VPD,
26  * this function will fall back to the default value
27  */
wifi_regulatory_domain(void)28 uint16_t wifi_regulatory_domain(void)
29 {
30 	static struct wrdd_code_value_pair wrdd_table[] = {
31 		{
32 			/* Indonesia
33 			 * Alpha-2 code         'ID'
34 			 * Full name            'the Republic of Indonesia'
35 			 * Alpha-3 code         'IDN'
36 			 * Numeric code         '360'
37 			 */
38 			.code = "id",
39 			.value = WRDD_REGULATORY_DOMAIN_INDONESIA
40 		}
41 	};
42 	const char *wrdd_domain_key = CROS_VPD_REGION_NAME;
43 	int i;
44 	struct wrdd_code_value_pair *p;
45 	/* wrdd_domain_value is ISO 3166-2 */
46 	char wrdd_domain_code[7];
47 	char *separator;
48 
49 	/* If not found for any reason fall backto the default value */
50 	if (!vpd_gets(wrdd_domain_key, wrdd_domain_code,
51 		ARRAY_SIZE(wrdd_domain_code), VPD_RO_THEN_RW)) {
52 		printk(BIOS_DEBUG,
53 		"Error: Could not locate '%s' in VPD\n", wrdd_domain_key);
54 		return WRDD_DEFAULT_REGULATORY_DOMAIN;
55 	}
56 	printk(BIOS_DEBUG, "Found '%s'='%s' in VPD\n",
57 		wrdd_domain_key, wrdd_domain_code);
58 	separator = memchr(wrdd_domain_code, VARIANT_SEPARATOR,
59 				ARRAY_SIZE(wrdd_domain_code));
60 	if (separator) {
61 		*separator = '\0';
62 	}
63 
64 	for (i = 0; i < ARRAY_SIZE(wrdd_table); i++) {
65 		p = &wrdd_table[i];
66 		if (strncmp(p->code, wrdd_domain_code,
67 			ARRAY_SIZE(wrdd_domain_code)) == 0)
68 			return p->value;
69 	}
70 	return WRDD_DEFAULT_REGULATORY_DOMAIN;
71 }
72