blob: 926905c26b1b6db06e3c8aa0f42fd529d5de3ea8 [file] [log] [blame]
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +01001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2014 Vladimir Serbinenko
Pratik Prajapati7fd1e4b2017-08-11 14:06:57 -07005 * Copyright (C) 2018 Intel Corp.
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +01006 *
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.
11 *
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.
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010016 */
17
18#include <console/console.h>
19#include <device/device.h>
20#include <device/pci.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020021#include <device/pci_ops.h>
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010022#include <device/pci_ids.h>
Naresh G Solanki3c6377f2017-07-03 21:57:11 +053023#include <elog.h>
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010024#include <smbios.h>
25#include <string.h>
Duncan Laurie5c026442016-05-11 14:05:07 -070026#include "chip.h"
Karthikeyan Ramasubramanianfd5d7882019-05-29 15:09:42 -060027#include "drivers/wifi/generic_wifi.h"
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010028
Naresh G Solanki3c6377f2017-07-03 21:57:11 +053029#define PMCS_DR 0xcc
30#define PME_STS (1 << 15)
31
Julius Wernercd49cce2019-03-05 16:53:33 -080032#if CONFIG(GENERATE_SMBIOS_TABLES)
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010033static int smbios_write_wifi(struct device *dev, int *handle,
34 unsigned long *current)
35{
36 struct smbios_type_intel_wifi {
37 u8 type;
38 u8 length;
39 u16 handle;
40 u8 str;
Konstantin Aladyshevd0df1d72017-08-01 15:52:46 +030041 u8 eos[2];
Stefan Reinauer6a001132017-07-13 02:20:27 +020042 } __packed;
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010043
Duncan Laurie5c026442016-05-11 14:05:07 -070044 struct smbios_type_intel_wifi *t =
45 (struct smbios_type_intel_wifi *)*current;
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010046 int len = sizeof(struct smbios_type_intel_wifi);
47
48 memset(t, 0, sizeof(struct smbios_type_intel_wifi));
49 t->type = 0x85;
50 t->length = len - 2;
51 t->handle = *handle;
Duncan Laurie5c026442016-05-11 14:05:07 -070052 /*
53 * Intel wifi driver expects this string to be in the table 0x85
54 * with PCI IDs enumerated below.
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010055 */
56 t->str = smbios_add_string(t->eos, "KHOIHGIUCCHHII");
57
58 len = t->length + smbios_string_table_len(t->eos);
59 *current += len;
60 *handle += 1;
61 return len;
62}
Kyösti Mälkki828e73e2016-07-28 17:26:39 +030063#endif
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010064
Julius Wernercd49cce2019-03-05 16:53:33 -080065#if CONFIG(HAVE_ACPI_TABLES)
Duncan Laurie5c026442016-05-11 14:05:07 -070066static void intel_wifi_fill_ssdt(struct device *dev)
67{
68 struct drivers_intel_wifi_config *config = dev->chip_info;
Karthikeyan Ramasubramanianfd5d7882019-05-29 15:09:42 -060069 struct generic_wifi_config generic_config;
Duncan Laurie5c026442016-05-11 14:05:07 -070070
Karthikeyan Ramasubramanianfd5d7882019-05-29 15:09:42 -060071 if (config) {
72 generic_config.wake = config->wake;
73 /* By default, all intel wifi chips wake from S3 */
74 generic_config.maxsleep = 3;
Duncan Laurie5c026442016-05-11 14:05:07 -070075 }
Karthikeyan Ramasubramanianfd5d7882019-05-29 15:09:42 -060076 generic_wifi_fill_ssdt(dev, config ? &generic_config : NULL);
Duncan Laurie5c026442016-05-11 14:05:07 -070077}
78#endif
79
Naresh G Solanki3c6377f2017-07-03 21:57:11 +053080static void wifi_pci_dev_init(struct device *dev)
81{
82 pci_dev_init(dev);
83
Julius Wernercd49cce2019-03-05 16:53:33 -080084 if (CONFIG(ELOG)) {
Naresh G Solanki3c6377f2017-07-03 21:57:11 +053085 uint32_t val;
86 val = pci_read_config16(dev, PMCS_DR);
87 if (val & PME_STS)
88 elog_add_event_wake(ELOG_WAKE_SOURCE_PME_WIFI, 0);
Elyes HAOUAS88607a42018-10-05 10:36:45 +020089 }
Naresh G Solanki3c6377f2017-07-03 21:57:11 +053090}
91
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +010092static struct pci_operations pci_ops = {
93 .set_subsystem = pci_dev_set_subsystem,
94};
95
96struct device_operations device_ops = {
Duncan Laurie5c026442016-05-11 14:05:07 -070097 .read_resources = pci_dev_read_resources,
98 .set_resources = pci_dev_set_resources,
99 .enable_resources = pci_dev_enable_resources,
Naresh G Solanki3c6377f2017-07-03 21:57:11 +0530100 .init = wifi_pci_dev_init,
Julius Wernercd49cce2019-03-05 16:53:33 -0800101#if CONFIG(GENERATE_SMBIOS_TABLES)
Duncan Laurie5c026442016-05-11 14:05:07 -0700102 .get_smbios_data = smbios_write_wifi,
Kyösti Mälkki828e73e2016-07-28 17:26:39 +0300103#endif
Duncan Laurie5c026442016-05-11 14:05:07 -0700104 .ops_pci = &pci_ops,
Julius Wernercd49cce2019-03-05 16:53:33 -0800105#if CONFIG(HAVE_ACPI_TABLES)
Karthikeyan Ramasubramanianfd5d7882019-05-29 15:09:42 -0600106 .acpi_name = generic_wifi_acpi_name,
Elyes HAOUAS2aa3b162018-11-27 17:02:10 +0100107 .acpi_fill_ssdt_generator = intel_wifi_fill_ssdt,
Duncan Laurie5c026442016-05-11 14:05:07 -0700108#endif
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +0100109};
110
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +0100111static const unsigned short pci_device_ids[] = {
Subrata Banikf9529832018-03-22 05:25:45 +0530112 PCI_DEVICE_ID_1000_SERIES_WIFI,
113 PCI_DEVICE_ID_6005_SERIES_WIFI,
114 PCI_DEVICE_ID_6005_I_SERIES_WIFI,
115 PCI_DEVICE_ID_1030_SERIES_WIFI,
116 PCI_DEVICE_ID_6030_I_SERIES_WIFI,
117 PCI_DEVICE_ID_6030_SERIES_WIFI,
118 PCI_DEVICE_ID_6150_SERIES_WIFI,
119 PCI_DEVICE_ID_2030_SERIES_WIFI,
120 PCI_DEVICE_ID_2000_SERIES_WIFI,
121 PCI_DEVICE_ID_0135_SERIES_WIFI,
122 PCI_DEVICE_ID_0105_SERIES_WIFI,
123 PCI_DEVICE_ID_6035_SERIES_WIFI,
124 PCI_DEVICE_ID_5300_SERIES_WIFI,
125 PCI_DEVICE_ID_5100_SERIES_WIFI,
126 PCI_DEVICE_ID_6000_SERIES_WIFI,
127 PCI_DEVICE_ID_6000_I_SERIES_WIFI,
128 PCI_DEVICE_ID_5350_SERIES_WIFI,
129 PCI_DEVICE_ID_5150_SERIES_WIFI,
130 /* Wilkins Peak 2 */
131 PCI_DEVICE_ID_WP_7260_SERIES_1_WIFI,
132 PCI_DEVICE_ID_WP_7260_SERIES_2_WIFI,
133 /* Stone Peak 2 */
134 PCI_DEVICE_ID_SP_7265_SERIES_1_WIFI,
135 PCI_DEVICE_ID_SP_7265_SERIES_2_WIFI,
Subrata Banik4530af22018-09-28 22:43:10 +0530136 /* Stone Field Peak */
137 PCI_DEVICE_ID_SFP_8260_SERIES_1_WIFI,
138 PCI_DEVICE_ID_SFP_8260_SERIES_2_WIFI,
139 /* Windstorm Peak */
140 PCI_DEVICE_ID_WSP_8275_SERIES_1_WIFI,
Subrata Banikf9529832018-03-22 05:25:45 +0530141 /* Jefferson Peak */
142 PCI_DEVICE_ID_JP_9000_SERIES_1_WIFI,
143 PCI_DEVICE_ID_JP_9000_SERIES_2_WIFI,
144 PCI_DEVICE_ID_JP_9000_SERIES_3_WIFI,
Furquan Shaikh39130a42018-05-30 19:57:14 -0700145 /* Thunder Peak 2 */
146 PCI_DEVICE_ID_TP_9260_SERIES_WIFI,
Subrata Banikf9529832018-03-22 05:25:45 +0530147 /* Harrison Peak */
148 PCI_DEVICE_ID_HrP_9560_SERIES_1_WIFI,
149 PCI_DEVICE_ID_HrP_9560_SERIES_2_WIFI,
Subrata Banik71da5fe2019-02-19 12:11:26 +0530150 PCI_DEVICE_ID_HrP_9560_SERIES_3_WIFI,
Subrata Banik13f53602019-03-28 10:35:30 +0530151 PCI_DEVICE_ID_HrP_9560_SERIES_4_WIFI,
Duncan Laurie5c026442016-05-11 14:05:07 -0700152 0
153};
Vladimir Serbinenko41f55b72014-10-31 09:10:16 +0100154
155static const struct pci_driver pch_intel_wifi __pci_driver = {
156 .ops = &device_ops,
157 .vendor = PCI_VENDOR_ID_INTEL,
158 .devices = pci_device_ids,
159};
Duncan Laurie5c026442016-05-11 14:05:07 -0700160
161static void intel_wifi_enable(struct device *dev)
162{
163 dev->ops = &device_ops;
164}
165
166struct chip_operations drivers_intel_wifi_ops = {
167 CHIP_NAME("Intel WiFi")
Elyes HAOUAS2aa3b162018-11-27 17:02:10 +0100168 .enable_dev = intel_wifi_enable
Duncan Laurie5c026442016-05-11 14:05:07 -0700169};