blob: 9aeda87aad3527dbbcb7b69a7a9dda6a6a3b2339 [file] [log] [blame]
Patrick Georgi02363b52020-05-05 20:48:50 +02001/* This file is part of the coreboot project. */
Patrick Georgiac959032020-05-05 22:49:26 +02002/* SPDX-License-Identifier: GPL-2.0-only */
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +01003
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +01004#include <device/device.h>
5#include <device/pci.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02006#include <device/pci_ops.h>
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +01007#include <device/pci_ids.h>
Naresh G Solanki3c6377f2017-07-03 21:57:11 +05308#include <elog.h>
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +01009#include <smbios.h>
10#include <string.h>
Duncan Laurie5c026442016-05-11 14:05:07 -070011#include "chip.h"
Karthikeyan Ramasubramanianfd5d7882019-05-29 15:09:42 -060012#include "drivers/wifi/generic_wifi.h"
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010013
Naresh G Solanki3c6377f2017-07-03 21:57:11 +053014#define PMCS_DR 0xcc
15#define PME_STS (1 << 15)
16
Julius Wernercd49cce2019-03-05 16:53:33 -080017#if CONFIG(GENERATE_SMBIOS_TABLES)
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010018static int smbios_write_wifi(struct device *dev, int *handle,
19 unsigned long *current)
20{
21 struct smbios_type_intel_wifi {
22 u8 type;
23 u8 length;
24 u16 handle;
25 u8 str;
Konstantin Aladyshevd0df1d72017-08-01 15:52:46 +030026 u8 eos[2];
Stefan Reinauer6a001132017-07-13 02:20:27 +020027 } __packed;
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010028
Duncan Laurie5c026442016-05-11 14:05:07 -070029 struct smbios_type_intel_wifi *t =
30 (struct smbios_type_intel_wifi *)*current;
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010031 int len = sizeof(struct smbios_type_intel_wifi);
32
33 memset(t, 0, sizeof(struct smbios_type_intel_wifi));
34 t->type = 0x85;
35 t->length = len - 2;
36 t->handle = *handle;
Duncan Laurie5c026442016-05-11 14:05:07 -070037 /*
38 * Intel wifi driver expects this string to be in the table 0x85
39 * with PCI IDs enumerated below.
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010040 */
41 t->str = smbios_add_string(t->eos, "KHOIHGIUCCHHII");
42
43 len = t->length + smbios_string_table_len(t->eos);
44 *current += len;
45 *handle += 1;
46 return len;
47}
Kyösti Mälkki828e73e2016-07-28 17:26:39 +030048#endif
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010049
Julius Wernercd49cce2019-03-05 16:53:33 -080050#if CONFIG(HAVE_ACPI_TABLES)
Furquan Shaikh7536a392020-04-24 21:59:21 -070051static void intel_wifi_fill_ssdt(const struct device *dev)
Duncan Laurie5c026442016-05-11 14:05:07 -070052{
53 struct drivers_intel_wifi_config *config = dev->chip_info;
Karthikeyan Ramasubramanianfd5d7882019-05-29 15:09:42 -060054 struct generic_wifi_config generic_config;
Duncan Laurie5c026442016-05-11 14:05:07 -070055
Karthikeyan Ramasubramanianfd5d7882019-05-29 15:09:42 -060056 if (config) {
57 generic_config.wake = config->wake;
58 /* By default, all intel wifi chips wake from S3 */
59 generic_config.maxsleep = 3;
Duncan Laurie5c026442016-05-11 14:05:07 -070060 }
Karthikeyan Ramasubramanianfd5d7882019-05-29 15:09:42 -060061 generic_wifi_fill_ssdt(dev, config ? &generic_config : NULL);
Duncan Laurie5c026442016-05-11 14:05:07 -070062}
63#endif
64
Naresh G Solanki3c6377f2017-07-03 21:57:11 +053065static void wifi_pci_dev_init(struct device *dev)
66{
67 pci_dev_init(dev);
68
Julius Wernercd49cce2019-03-05 16:53:33 -080069 if (CONFIG(ELOG)) {
Naresh G Solanki3c6377f2017-07-03 21:57:11 +053070 uint32_t val;
71 val = pci_read_config16(dev, PMCS_DR);
72 if (val & PME_STS)
73 elog_add_event_wake(ELOG_WAKE_SOURCE_PME_WIFI, 0);
Elyes HAOUAS88607a42018-10-05 10:36:45 +020074 }
Naresh G Solanki3c6377f2017-07-03 21:57:11 +053075}
76
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010077static struct pci_operations pci_ops = {
78 .set_subsystem = pci_dev_set_subsystem,
79};
80
81struct device_operations device_ops = {
Nico Huber68680dd2020-03-31 17:34:52 +020082 .read_resources = pci_dev_read_resources,
83 .set_resources = pci_dev_set_resources,
84 .enable_resources = pci_dev_enable_resources,
85 .init = wifi_pci_dev_init,
Julius Wernercd49cce2019-03-05 16:53:33 -080086#if CONFIG(GENERATE_SMBIOS_TABLES)
Nico Huber68680dd2020-03-31 17:34:52 +020087 .get_smbios_data = smbios_write_wifi,
Kyösti Mälkki828e73e2016-07-28 17:26:39 +030088#endif
Nico Huber68680dd2020-03-31 17:34:52 +020089 .ops_pci = &pci_ops,
Julius Wernercd49cce2019-03-05 16:53:33 -080090#if CONFIG(HAVE_ACPI_TABLES)
Nico Huber68680dd2020-03-31 17:34:52 +020091 .acpi_name = generic_wifi_acpi_name,
92 .acpi_fill_ssdt = intel_wifi_fill_ssdt,
Duncan Laurie5c026442016-05-11 14:05:07 -070093#endif
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010094};
95
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010096static const unsigned short pci_device_ids[] = {
Subrata Banikf9529832018-03-22 05:25:45 +053097 PCI_DEVICE_ID_1000_SERIES_WIFI,
98 PCI_DEVICE_ID_6005_SERIES_WIFI,
99 PCI_DEVICE_ID_6005_I_SERIES_WIFI,
100 PCI_DEVICE_ID_1030_SERIES_WIFI,
101 PCI_DEVICE_ID_6030_I_SERIES_WIFI,
102 PCI_DEVICE_ID_6030_SERIES_WIFI,
103 PCI_DEVICE_ID_6150_SERIES_WIFI,
104 PCI_DEVICE_ID_2030_SERIES_WIFI,
105 PCI_DEVICE_ID_2000_SERIES_WIFI,
106 PCI_DEVICE_ID_0135_SERIES_WIFI,
107 PCI_DEVICE_ID_0105_SERIES_WIFI,
108 PCI_DEVICE_ID_6035_SERIES_WIFI,
109 PCI_DEVICE_ID_5300_SERIES_WIFI,
110 PCI_DEVICE_ID_5100_SERIES_WIFI,
111 PCI_DEVICE_ID_6000_SERIES_WIFI,
112 PCI_DEVICE_ID_6000_I_SERIES_WIFI,
113 PCI_DEVICE_ID_5350_SERIES_WIFI,
114 PCI_DEVICE_ID_5150_SERIES_WIFI,
115 /* Wilkins Peak 2 */
116 PCI_DEVICE_ID_WP_7260_SERIES_1_WIFI,
117 PCI_DEVICE_ID_WP_7260_SERIES_2_WIFI,
118 /* Stone Peak 2 */
119 PCI_DEVICE_ID_SP_7265_SERIES_1_WIFI,
120 PCI_DEVICE_ID_SP_7265_SERIES_2_WIFI,
Subrata Banik4530af22018-09-28 22:43:10 +0530121 /* Stone Field Peak */
122 PCI_DEVICE_ID_SFP_8260_SERIES_1_WIFI,
123 PCI_DEVICE_ID_SFP_8260_SERIES_2_WIFI,
124 /* Windstorm Peak */
125 PCI_DEVICE_ID_WSP_8275_SERIES_1_WIFI,
Subrata Banikf9529832018-03-22 05:25:45 +0530126 /* Jefferson Peak */
127 PCI_DEVICE_ID_JP_9000_SERIES_1_WIFI,
128 PCI_DEVICE_ID_JP_9000_SERIES_2_WIFI,
129 PCI_DEVICE_ID_JP_9000_SERIES_3_WIFI,
Furquan Shaikh39130a42018-05-30 19:57:14 -0700130 /* Thunder Peak 2 */
131 PCI_DEVICE_ID_TP_9260_SERIES_WIFI,
Subrata Banikf9529832018-03-22 05:25:45 +0530132 /* Harrison Peak */
133 PCI_DEVICE_ID_HrP_9560_SERIES_1_WIFI,
134 PCI_DEVICE_ID_HrP_9560_SERIES_2_WIFI,
Subrata Banik71da5fe2019-02-19 12:11:26 +0530135 PCI_DEVICE_ID_HrP_9560_SERIES_3_WIFI,
Subrata Banik13f53602019-03-28 10:35:30 +0530136 PCI_DEVICE_ID_HrP_9560_SERIES_4_WIFI,
Subrata Banikb98c8962020-04-06 12:08:01 +0530137 PCI_DEVICE_ID_HrP_6SERIES_WIFI,
138 /* Cyclone Peak */
139 PCI_DEVICE_ID_CyP_6SERIES_WIFI,
140 /* Typhoon Peak */
141 PCI_DEVICE_ID_TyP_6SERIES_WIFI,
142 /* Garfiled Peak */
143 PCI_DEVICE_ID_GrP_6SERIES_1_WIFI,
144 PCI_DEVICE_ID_GrP_6SERIES_2_WIFI,
Duncan Laurie5c026442016-05-11 14:05:07 -0700145 0
146};
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +0100147
148static const struct pci_driver pch_intel_wifi __pci_driver = {
149 .ops = &device_ops,
150 .vendor = PCI_VENDOR_ID_INTEL,
151 .devices = pci_device_ids,
152};
Duncan Laurie5c026442016-05-11 14:05:07 -0700153
154static void intel_wifi_enable(struct device *dev)
155{
156 dev->ops = &device_ops;
157}
158
159struct chip_operations drivers_intel_wifi_ops = {
160 CHIP_NAME("Intel WiFi")
Elyes HAOUAS2aa3b162018-11-27 17:02:10 +0100161 .enable_dev = intel_wifi_enable
Duncan Laurie5c026442016-05-11 14:05:07 -0700162};