drivers/intel/wifi: Add DID for Intel WIFI module 8260, 8275
[coreboot.git] / src / drivers / intel / wifi / wifi.c
blobcdce6e2b831adf86ba0c7a471d3e01e227f663d0
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2014 Vladimir Serbinenko
5 * Copyright (C) 2018 Intel Corp.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 or (at your option)
10 * any later version of the License.
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 <compiler.h>
19 #include <arch/acpi_device.h>
20 #include <arch/acpigen.h>
21 #include <console/console.h>
22 #include <device/device.h>
23 #include <device/pci.h>
24 #include <device/pci_ids.h>
25 #include <elog.h>
26 #include <sar.h>
27 #include <smbios.h>
28 #include <string.h>
29 #include <wrdd.h>
30 #include "chip.h"
32 #define PMCS_DR 0xcc
33 #define PME_STS (1 << 15)
35 #if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLES)
36 static int smbios_write_wifi(struct device *dev, int *handle,
37 unsigned long *current)
39 struct smbios_type_intel_wifi {
40 u8 type;
41 u8 length;
42 u16 handle;
43 u8 str;
44 u8 eos[2];
45 } __packed;
47 struct smbios_type_intel_wifi *t =
48 (struct smbios_type_intel_wifi *)*current;
49 int len = sizeof(struct smbios_type_intel_wifi);
51 memset(t, 0, sizeof(struct smbios_type_intel_wifi));
52 t->type = 0x85;
53 t->length = len - 2;
54 t->handle = *handle;
56 * Intel wifi driver expects this string to be in the table 0x85
57 * with PCI IDs enumerated below.
59 t->str = smbios_add_string(t->eos, "KHOIHGIUCCHHII");
61 len = t->length + smbios_string_table_len(t->eos);
62 *current += len;
63 *handle += 1;
64 return len;
66 #endif
68 __weak
69 int get_wifi_sar_limits(struct wifi_sar_limits *sar_limits)
71 return -1;
74 #if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
75 static void emit_sar_acpi_structures(void)
77 int i, j, package_size;
78 struct wifi_sar_limits sar_limits;
79 struct wifi_sar_delta_table *wgds;
81 /* Retrieve the sar limits data */
82 if (get_wifi_sar_limits(&sar_limits) < 0) {
83 printk(BIOS_ERR, "Error: failed from getting SAR limits!\n");
84 return;
88 * Name ("WRDS", Package () {
89 * Revision,
90 * Package () {
91 * Domain Type, // 0x7:WiFi
92 * WiFi SAR BIOS, // BIOS SAR Enable/disable
93 * SAR Table Set // Set#1 of SAR Table (10 bytes)
94 * }
95 * })
97 acpigen_write_name("WRDS");
98 acpigen_write_package(2);
99 acpigen_write_dword(WRDS_REVISION);
100 /* Emit 'Domain Type' + 'WiFi SAR BIOS' + 10 bytes for Set#1 */
101 package_size = 1 + 1 + BYTES_PER_SAR_LIMIT;
102 acpigen_write_package(package_size);
103 acpigen_write_dword(WRDS_DOMAIN_TYPE_WIFI);
104 acpigen_write_dword(CONFIG_SAR_ENABLE);
105 for (i = 0; i < BYTES_PER_SAR_LIMIT; i++)
106 acpigen_write_byte(sar_limits.sar_limit[0][i]);
107 acpigen_pop_len();
108 acpigen_pop_len();
111 * Name ("EWRD", Package () {
112 * Revision,
113 * Package () {
114 * Domain Type, // 0x7:WiFi
115 * Dynamic SAR Enable, // Dynamic SAR Enable/disable
116 * Extended SAR sets, // Number of optional SAR table sets
117 * SAR Table Set, // Set#2 of SAR Table (10 bytes)
118 * SAR Table Set, // Set#3 of SAR Table (10 bytes)
119 * SAR Table Set // Set#4 of SAR Table (10 bytes)
121 * })
123 acpigen_write_name("EWRD");
124 acpigen_write_package(2);
125 acpigen_write_dword(EWRD_REVISION);
127 * Emit 'Domain Type' + "Dynamic SAR Enable' + 'Extended SAR sets'
128 * + number of bytes for Set#2 & 3 & 4
130 package_size = 1 + 1 + 1 + (NUM_SAR_LIMITS - 1) * BYTES_PER_SAR_LIMIT;
131 acpigen_write_package(package_size);
132 acpigen_write_dword(EWRD_DOMAIN_TYPE_WIFI);
133 acpigen_write_dword(CONFIG_DSAR_ENABLE);
134 acpigen_write_dword(CONFIG_DSAR_SET_NUM);
135 for (i = 1; i < NUM_SAR_LIMITS; i++)
136 for (j = 0; j < BYTES_PER_SAR_LIMIT; j++)
137 acpigen_write_byte(sar_limits.sar_limit[i][j]);
138 acpigen_pop_len();
139 acpigen_pop_len();
142 if (!IS_ENABLED(CONFIG_GEO_SAR_ENABLE))
143 return;
146 * Name ("WGDS", Package() {
147 * Revision,
148 * Package() {
149 * DomainType, // 0x7:WiFi
150 * WgdsWiFiSarDeltaGroup1PowerMax1, // Group 1 FCC 2400 Max
151 * WgdsWiFiSarDeltaGroup1PowerChainA1, // Group 1 FCC 2400 A Offset
152 * WgdsWiFiSarDeltaGroup1PowerChainB1, // Group 1 FCC 2400 B Offset
153 * WgdsWiFiSarDeltaGroup1PowerMax2, // Group 1 FCC 5200 Max
154 * WgdsWiFiSarDeltaGroup1PowerChainA2, // Group 1 FCC 5200 A Offset
155 * WgdsWiFiSarDeltaGroup1PowerChainB2, // Group 1 FCC 5200 B Offset
156 * WgdsWiFiSarDeltaGroup2PowerMax1, // Group 2 EC Jap 2400 Max
157 * WgdsWiFiSarDeltaGroup2PowerChainA1, // Group 2 EC Jap 2400 A Offset
158 * WgdsWiFiSarDeltaGroup2PowerChainB1, // Group 2 EC Jap 2400 B Offset
159 * WgdsWiFiSarDeltaGroup2PowerMax2, // Group 2 EC Jap 5200 Max
160 * WgdsWiFiSarDeltaGroup2PowerChainA2, // Group 2 EC Jap 5200 A Offset
161 * WgdsWiFiSarDeltaGroup2PowerChainB2, // Group 2 EC Jap 5200 B Offset
162 * WgdsWiFiSarDeltaGroup3PowerMax1, // Group 3 ROW 2400 Max
163 * WgdsWiFiSarDeltaGroup3PowerChainA1, // Group 3 ROW 2400 A Offset
164 * WgdsWiFiSarDeltaGroup3PowerChainB1, // Group 3 ROW 2400 B Offset
165 * WgdsWiFiSarDeltaGroup3PowerMax2, // Group 3 ROW 5200 Max
166 * WgdsWiFiSarDeltaGroup3PowerChainA2, // Group 3 ROW 5200 A Offset
167 * WgdsWiFiSarDeltaGroup3PowerChainB2, // Group 3 ROW 5200 B Offset
169 * })
172 wgds = &sar_limits.wgds;
173 acpigen_write_name("WGDS");
174 acpigen_write_package(2);
175 acpigen_write_dword(wgds->version);
176 /* Emit 'Domain Type' +
177 * Group specific delta of power ( 6 bytes * NUM_WGDS_SAR_GROUPS )
179 package_size = sizeof(sar_limits.wgds.group) + 1;
180 acpigen_write_package(package_size);
181 acpigen_write_dword(WGDS_DOMAIN_TYPE_WIFI);
182 for (i = 0; i < SAR_NUM_WGDS_GROUPS; i++) {
183 acpigen_write_byte(wgds->group[i].power_max_2400mhz);
184 acpigen_write_byte(wgds->group[i].power_chain_a_2400mhz);
185 acpigen_write_byte(wgds->group[i].power_chain_b_2400mhz);
186 acpigen_write_byte(wgds->group[i].power_max_5200mhz);
187 acpigen_write_byte(wgds->group[i].power_chain_a_5200mhz);
188 acpigen_write_byte(wgds->group[i].power_chain_b_5200mhz);
191 acpigen_pop_len();
192 acpigen_pop_len();
195 static void intel_wifi_fill_ssdt(struct device *dev)
197 struct drivers_intel_wifi_config *config = dev->chip_info;
198 const char *path = acpi_device_path(dev->bus->dev);
199 u32 address;
201 if (!path || !dev->enabled)
202 return;
204 /* Device */
205 acpigen_write_scope(path);
206 acpigen_write_device(acpi_device_name(dev));
207 acpigen_write_name_integer("_UID", 0);
208 if (dev->chip_ops)
209 acpigen_write_name_string("_DDN", dev->chip_ops->name);
211 /* Address */
212 address = PCI_SLOT(dev->path.pci.devfn) & 0xffff;
213 address <<= 16;
214 address |= PCI_FUNC(dev->path.pci.devfn) & 0xffff;
215 acpigen_write_name_dword("_ADR", address);
217 /* Wake capabilities */
218 if (config && config->wake)
219 acpigen_write_PRW(config->wake, 3);
221 /* Fill regulatory domain structure */
222 if (IS_ENABLED(CONFIG_HAVE_REGULATORY_DOMAIN)) {
224 * Name ("WRDD", Package () {
225 * WRDD_REVISION, // Revision
226 * Package () {
227 * WRDD_DOMAIN_TYPE_WIFI, // Domain Type, 7:WiFi
228 * wifi_regulatory_domain() // Country Identifier
230 * })
232 acpigen_write_name("WRDD");
233 acpigen_write_package(2);
234 acpigen_write_integer(WRDD_REVISION);
235 acpigen_write_package(2);
236 acpigen_write_dword(WRDD_DOMAIN_TYPE_WIFI);
237 acpigen_write_dword(wifi_regulatory_domain());
238 acpigen_pop_len();
239 acpigen_pop_len();
242 /* Fill Wifi sar related ACPI structures */
243 if (IS_ENABLED(CONFIG_USE_SAR))
244 emit_sar_acpi_structures();
246 acpigen_pop_len(); /* Device */
247 acpigen_pop_len(); /* Scope */
249 printk(BIOS_INFO, "%s.%s: %s %s\n", path, acpi_device_name(dev),
250 dev->chip_ops ? dev->chip_ops->name : "", dev_path(dev));
253 static const char *intel_wifi_acpi_name(const struct device *dev)
255 return "WIFI";
257 #endif
259 static void wifi_pci_dev_init(struct device *dev)
261 pci_dev_init(dev);
263 if (IS_ENABLED(CONFIG_ELOG)) {
264 uint32_t val;
265 val = pci_read_config16(dev, PMCS_DR);
266 if (val & PME_STS)
267 elog_add_event_wake(ELOG_WAKE_SOURCE_PME_WIFI, 0);
271 static struct pci_operations pci_ops = {
272 .set_subsystem = pci_dev_set_subsystem,
275 struct device_operations device_ops = {
276 .read_resources = pci_dev_read_resources,
277 .set_resources = pci_dev_set_resources,
278 .enable_resources = pci_dev_enable_resources,
279 .init = wifi_pci_dev_init,
280 #if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLES)
281 .get_smbios_data = smbios_write_wifi,
282 #endif
283 .ops_pci = &pci_ops,
284 #if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
285 .acpi_name = &intel_wifi_acpi_name,
286 .acpi_fill_ssdt_generator = &intel_wifi_fill_ssdt,
287 #endif
290 static const unsigned short pci_device_ids[] = {
291 PCI_DEVICE_ID_1000_SERIES_WIFI,
292 PCI_DEVICE_ID_6005_SERIES_WIFI,
293 PCI_DEVICE_ID_6005_I_SERIES_WIFI,
294 PCI_DEVICE_ID_1030_SERIES_WIFI,
295 PCI_DEVICE_ID_6030_I_SERIES_WIFI,
296 PCI_DEVICE_ID_6030_SERIES_WIFI,
297 PCI_DEVICE_ID_6150_SERIES_WIFI,
298 PCI_DEVICE_ID_2030_SERIES_WIFI,
299 PCI_DEVICE_ID_2000_SERIES_WIFI,
300 PCI_DEVICE_ID_0135_SERIES_WIFI,
301 PCI_DEVICE_ID_0105_SERIES_WIFI,
302 PCI_DEVICE_ID_6035_SERIES_WIFI,
303 PCI_DEVICE_ID_5300_SERIES_WIFI,
304 PCI_DEVICE_ID_5100_SERIES_WIFI,
305 PCI_DEVICE_ID_6000_SERIES_WIFI,
306 PCI_DEVICE_ID_6000_I_SERIES_WIFI,
307 PCI_DEVICE_ID_5350_SERIES_WIFI,
308 PCI_DEVICE_ID_5150_SERIES_WIFI,
309 /* Wilkins Peak 2 */
310 PCI_DEVICE_ID_WP_7260_SERIES_1_WIFI,
311 PCI_DEVICE_ID_WP_7260_SERIES_2_WIFI,
312 /* Stone Peak 2 */
313 PCI_DEVICE_ID_SP_7265_SERIES_1_WIFI,
314 PCI_DEVICE_ID_SP_7265_SERIES_2_WIFI,
315 /* Stone Field Peak */
316 PCI_DEVICE_ID_SFP_8260_SERIES_1_WIFI,
317 PCI_DEVICE_ID_SFP_8260_SERIES_2_WIFI,
318 /* Windstorm Peak */
319 PCI_DEVICE_ID_WSP_8275_SERIES_1_WIFI,
320 /* Jefferson Peak */
321 PCI_DEVICE_ID_JP_9000_SERIES_1_WIFI,
322 PCI_DEVICE_ID_JP_9000_SERIES_2_WIFI,
323 PCI_DEVICE_ID_JP_9000_SERIES_3_WIFI,
324 /* Thunder Peak 2 */
325 PCI_DEVICE_ID_TP_9260_SERIES_WIFI,
326 /* Harrison Peak */
327 PCI_DEVICE_ID_HrP_9560_SERIES_1_WIFI,
328 PCI_DEVICE_ID_HrP_9560_SERIES_2_WIFI,
332 static const struct pci_driver pch_intel_wifi __pci_driver = {
333 .ops = &device_ops,
334 .vendor = PCI_VENDOR_ID_INTEL,
335 .devices = pci_device_ids,
338 static void intel_wifi_enable(struct device *dev)
340 dev->ops = &device_ops;
343 struct chip_operations drivers_intel_wifi_ops = {
344 CHIP_NAME("Intel WiFi")
345 .enable_dev = &intel_wifi_enable