1 /*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2010 Carl-Daniel Hailfinger
5 * Copyright (C) 2010 Idwer Vollering
6 *
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 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17 /*
18 * Datasheets:
19 * PCI/PCI-X Family of Gigabit Ethernet Controllers Software Developer's Manual
20 * 82540EP/EM, 82541xx, 82544GC/EI, 82545GM/EM, 82546GB/EB, and 82547xx
21 * http://www.intel.com/content/www/us/en/ethernet-controllers/pci-pci-x-family-gbe-controllers-software-dev-manual.html
22 *
23 * PCIe GbE Controllers Open Source Software Developer's Manual
24 * http://www.intel.com/content/www/us/en/ethernet-controllers/pcie-gbe-controllers-open-source-manual.html
25 *
26 * Intel 82574 Gigabit Ethernet Controller Family Datasheet
27 * http://www.intel.com/content/www/us/en/ethernet-controllers/82574l-gbe-controller-datasheet.html
28 *
29 * Intel 82599 10 GbE Controller Datasheet (331520)
30 * http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82599-10-gbe-controller-datasheet.pdf
31 */
32
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include "flash.h"
36 #include "programmer.h"
37 #include "hwaccess_physmap.h"
38 #include "platform/pci.h"
39
40 #define PCI_VENDOR_ID_INTEL 0x8086
41 #define MEMMAP_SIZE getpagesize()
42
43 /* EEPROM/Flash Control & Data Register */
44 #define EECD 0x10
45 /* Flash Access Register */
46 #define FLA 0x1c
47
48 /*
49 * Register bits of EECD.
50 * Table 13-6
51 *
52 * Bit 04, 05: FWE (Flash Write Enable Control)
53 * 00b = not allowed (on some cards this sends an erase command if bit 31 (FL_ER) of FLA is set)
54 * 01b = flash writes disabled
55 * 10b = flash writes enabled
56 * 11b = not allowed
57 */
58 #define FLASH_WRITES_DISABLED 0x10 /* FWE: 10000b */
59 #define FLASH_WRITES_ENABLED 0x20 /* FWE: 100000b */
60
61 /* Flash Access register bits
62 * Table 13-9
63 */
64 #define FL_SCK 0
65 #define FL_CS 1
66 #define FL_SI 2
67 #define FL_SO 3
68 #define FL_REQ 4
69 #define FL_GNT 5
70 #define FL_LOCKED 6
71 #define FL_ABORT 7
72 #define FL_CLR_ERR 8
73 /* Currently unused */
74 // #define FL_BUSY 30
75 // #define FL_ER 31
76
77 struct nicintel_spi_data {
78 uint8_t *spibar;
79 };
80
81 static const struct dev_entry nics_intel_spi[] = {
82 {PCI_VENDOR_ID_INTEL, 0x105e, OK, "Intel", "82571EB Gigabit Ethernet Controller"},
83 {PCI_VENDOR_ID_INTEL, 0x1076, OK, "Intel", "82541GI Gigabit Ethernet Controller"},
84 {PCI_VENDOR_ID_INTEL, 0x107c, OK, "Intel", "82541PI Gigabit Ethernet Controller"},
85 {PCI_VENDOR_ID_INTEL, 0x10b9, OK, "Intel", "82572EI Gigabit Ethernet Controller"},
86 {PCI_VENDOR_ID_INTEL, 0x10d3, OK, "Intel", "82574L Gigabit Ethernet Controller"},
87
88 {PCI_VENDOR_ID_INTEL, 0x10d8, NT, "Intel", "82599 10 Gigabit Unprogrammed Network Controller"},
89 {PCI_VENDOR_ID_INTEL, 0x10f7, NT, "Intel", "82599 10 Gigabit KX4 Dual Port Network Controller"},
90 {PCI_VENDOR_ID_INTEL, 0x10f8, NT, "Intel", "82599 10 Gigabit Dual Port Backplane Controller"},
91 {PCI_VENDOR_ID_INTEL, 0x10f9, NT, "Intel", "82599 10 Gigabit CX4 Dual Port Network Controller"},
92 {PCI_VENDOR_ID_INTEL, 0x10fb, NT, "Intel", "82599 10-Gigabit SFI/SFP+ Network Controller"},
93 {PCI_VENDOR_ID_INTEL, 0x10fc, OK, "Intel", "82599 10 Gigabit XAUI/BX4 Dual Port Network Controller"},
94 {PCI_VENDOR_ID_INTEL, 0x1517, NT, "Intel", "82599 10 Gigabit KR Network Controller"},
95 {PCI_VENDOR_ID_INTEL, 0x151c, NT, "Intel", "82599 10 Gigabit TN Network Controller"},
96 {PCI_VENDOR_ID_INTEL, 0x1529, NT, "Intel", "82599 10 Gigabit Dual Port Network Controller with FCoE"},
97 {PCI_VENDOR_ID_INTEL, 0x152a, NT, "Intel", "82599 10 Gigabit Dual Port Backplane Controller with FCoE"},
98 {PCI_VENDOR_ID_INTEL, 0x1557, NT, "Intel", "82599 10 Gigabit SFI Network Controller"},
99
100 {PCI_VENDOR_ID_INTEL, 0x1531, OK, "Intel", "I210 Gigabit Network Connection Unprogrammed"},
101 {PCI_VENDOR_ID_INTEL, 0x1532, NT, "Intel", "I211 Gigabit Network Connection Unprogrammed"},
102 {PCI_VENDOR_ID_INTEL, 0x1533, NT, "Intel", "I210 Gigabit Network Connection"},
103 {PCI_VENDOR_ID_INTEL, 0x1536, NT, "Intel", "I210 Gigabit Network Connection SERDES Fiber"},
104 {PCI_VENDOR_ID_INTEL, 0x1537, NT, "Intel", "I210 Gigabit Network Connection SERDES Backplane"},
105 {PCI_VENDOR_ID_INTEL, 0x1538, NT, "Intel", "I210 Gigabit Network Connection SGMII"},
106 {PCI_VENDOR_ID_INTEL, 0x1539, NT, "Intel", "I211 Gigabit Network Connection"},
107
108 {0},
109 };
110
nicintel_request_spibus(void * spi_data)111 static void nicintel_request_spibus(void *spi_data)
112 {
113 struct nicintel_spi_data *data = spi_data;
114 uint32_t tmp;
115
116 tmp = pci_mmio_readl(data->spibar + FLA);
117 tmp |= BIT(FL_REQ);
118 pci_mmio_writel(tmp, data->spibar + FLA);
119
120 /* Wait until we are allowed to use the SPI bus. */
121 while (!(pci_mmio_readl(data->spibar + FLA) & BIT(FL_GNT))) ;
122 }
123
nicintel_release_spibus(void * spi_data)124 static void nicintel_release_spibus(void *spi_data)
125 {
126 struct nicintel_spi_data *data = spi_data;
127 uint32_t tmp;
128
129 tmp = pci_mmio_readl(data->spibar + FLA);
130 tmp &= ~BIT(FL_REQ);
131 pci_mmio_writel(tmp, data->spibar + FLA);
132 }
133
nicintel_bitbang_set_cs(int val,void * spi_data)134 static void nicintel_bitbang_set_cs(int val, void *spi_data)
135 {
136 struct nicintel_spi_data *data = spi_data;
137 uint32_t tmp;
138
139 tmp = pci_mmio_readl(data->spibar + FLA);
140 tmp &= ~BIT(FL_CS);
141 tmp |= (val << FL_CS);
142 pci_mmio_writel(tmp, data->spibar + FLA);
143 }
144
nicintel_bitbang_set_sck(int val,void * spi_data)145 static void nicintel_bitbang_set_sck(int val, void *spi_data)
146 {
147 struct nicintel_spi_data *data = spi_data;
148 uint32_t tmp;
149
150 tmp = pci_mmio_readl(data->spibar + FLA);
151 tmp &= ~BIT(FL_SCK);
152 tmp |= (val << FL_SCK);
153 pci_mmio_writel(tmp, data->spibar + FLA);
154 }
155
nicintel_bitbang_set_mosi(int val,void * spi_data)156 static void nicintel_bitbang_set_mosi(int val, void *spi_data)
157 {
158 struct nicintel_spi_data *data = spi_data;
159 uint32_t tmp;
160
161 tmp = pci_mmio_readl(data->spibar + FLA);
162 tmp &= ~BIT(FL_SI);
163 tmp |= (val << FL_SI);
164 pci_mmio_writel(tmp, data->spibar + FLA);
165 }
166
nicintel_bitbang_set_sck_set_mosi(int sck,int mosi,void * spi_data)167 static void nicintel_bitbang_set_sck_set_mosi(int sck, int mosi, void *spi_data)
168 {
169 struct nicintel_spi_data *data = spi_data;
170 uint32_t tmp;
171
172 tmp = pci_mmio_readl(data->spibar + FLA);
173 tmp &= ~BIT(FL_SCK);
174 tmp &= ~BIT(FL_SI);
175 tmp |= (sck << FL_SCK);
176 tmp |= (mosi << FL_SI);
177 pci_mmio_writel(tmp, data->spibar + FLA);
178 }
179
nicintel_bitbang_get_miso(void * spi_data)180 static int nicintel_bitbang_get_miso(void *spi_data)
181 {
182 struct nicintel_spi_data *data = spi_data;
183 uint32_t tmp;
184
185 tmp = pci_mmio_readl(data->spibar + FLA);
186 tmp = (tmp >> FL_SO) & 0x1;
187 return tmp;
188 }
189
nicintel_bitbang_set_sck_get_miso(int sck,void * spi_data)190 static int nicintel_bitbang_set_sck_get_miso(int sck, void *spi_data)
191 {
192 struct nicintel_spi_data *data = spi_data;
193 uint32_t tmp;
194
195 tmp = pci_mmio_readl(data->spibar + FLA);
196 tmp &= ~BIT(FL_SCK);
197 tmp |= (sck << FL_SCK);
198 pci_mmio_writel(tmp, data->spibar + FLA);
199 return (tmp >> FL_SO) & 0x1;
200 }
201
202 static const struct bitbang_spi_master bitbang_spi_master_nicintel = {
203 .set_cs = nicintel_bitbang_set_cs,
204 .set_sck = nicintel_bitbang_set_sck,
205 .set_mosi = nicintel_bitbang_set_mosi,
206 .set_sck_set_mosi = nicintel_bitbang_set_sck_set_mosi,
207 .set_sck_get_miso = nicintel_bitbang_set_sck_get_miso,
208 .get_miso = nicintel_bitbang_get_miso,
209 .request_bus = nicintel_request_spibus,
210 .release_bus = nicintel_release_spibus,
211 .half_period = 1,
212 };
213
nicintel_spi_shutdown(void * spi_data)214 static int nicintel_spi_shutdown(void *spi_data)
215 {
216 struct nicintel_spi_data *data = spi_data;
217 uint32_t tmp;
218
219 /* Disable writes manually. See the comment about EECD in nicintel_spi_init() for details. */
220 tmp = pci_mmio_readl(data->spibar + EECD);
221 tmp &= ~FLASH_WRITES_ENABLED;
222 tmp |= FLASH_WRITES_DISABLED;
223 pci_mmio_writel(tmp, data->spibar + EECD);
224
225 free(data);
226 return 0;
227 }
228
nicintel_spi_82599_enable_flash(struct nicintel_spi_data * data)229 static int nicintel_spi_82599_enable_flash(struct nicintel_spi_data *data)
230 {
231 uint32_t tmp;
232
233 /* Automatic restore of EECD on shutdown is not possible because EECD
234 * does not only contain FLASH_WRITES_DISABLED|FLASH_WRITES_ENABLED,
235 * but other bits with side effects as well. Those other bits must be
236 * left untouched.
237 */
238 tmp = pci_mmio_readl(data->spibar + EECD);
239 tmp &= ~FLASH_WRITES_DISABLED;
240 tmp |= FLASH_WRITES_ENABLED;
241 pci_mmio_writel(tmp, data->spibar + EECD);
242
243 /* test if FWE is really set to allow writes */
244 tmp = pci_mmio_readl(data->spibar + EECD);
245 if ( (tmp & FLASH_WRITES_DISABLED) || !(tmp & FLASH_WRITES_ENABLED) ) {
246 msg_perr("Enabling flash write access failed.\n");
247 return 1;
248 }
249
250 if (register_shutdown(nicintel_spi_shutdown, data))
251 return 1;
252
253 return 0;
254 }
255
nicintel_spi_i210_shutdown(void * data)256 static int nicintel_spi_i210_shutdown(void *data)
257 {
258 free(data);
259 return 0;
260 }
261
nicintel_spi_i210_enable_flash(struct nicintel_spi_data * data)262 static int nicintel_spi_i210_enable_flash(struct nicintel_spi_data *data)
263 {
264 uint32_t tmp;
265
266 tmp = pci_mmio_readl(data->spibar + FLA);
267 if (tmp & BIT(FL_LOCKED)) {
268 msg_perr("Flash is in Secure Mode. Abort.\n");
269 return 1;
270 }
271
272 if (tmp & BIT(FL_ABORT)) {
273 tmp |= BIT(FL_CLR_ERR);
274 pci_mmio_writel(tmp, data->spibar + FLA);
275 tmp = pci_mmio_readl(data->spibar + FLA);
276 if (!(tmp & BIT(FL_ABORT))) {
277 msg_perr("Unable to clear Flash Access Error. Abort\n");
278 return 1;
279 }
280 }
281
282 if (register_shutdown(nicintel_spi_i210_shutdown, data))
283 return 1;
284
285 return 0;
286 }
287
nicintel_spi_init(const struct programmer_cfg * cfg)288 static int nicintel_spi_init(const struct programmer_cfg *cfg)
289 {
290 struct pci_dev *dev = NULL;
291
292 dev = pcidev_init(cfg, nics_intel_spi, PCI_BASE_ADDRESS_0);
293 if (!dev)
294 return 1;
295
296 uint32_t io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0);
297 if (!io_base_addr)
298 return 1;
299
300 struct nicintel_spi_data *data = calloc(1, sizeof(*data));
301 if (!data) {
302 msg_perr("Unable to allocate space for SPI master data\n");
303 return 1;
304 }
305
306 if ((dev->device_id & 0xfff0) == 0x1530) {
307 data->spibar = rphysmap("Intel I210 Gigabit w/ SPI flash", io_base_addr + 0x12000,
308 MEMMAP_SIZE);
309 if (!data->spibar || nicintel_spi_i210_enable_flash(data)) {
310 free(data);
311 return 1;
312 }
313 } else if (dev->device_id < 0x10d8) {
314 data->spibar = rphysmap("Intel Gigabit NIC w/ SPI flash", io_base_addr,
315 MEMMAP_SIZE);
316 if (!data->spibar || nicintel_spi_82599_enable_flash(data)) {
317 free(data);
318 return 1;
319 }
320 } else {
321 data->spibar = rphysmap("Intel 10 Gigabit NIC w/ SPI flash", io_base_addr + 0x10000,
322 MEMMAP_SIZE);
323 if (!data->spibar || nicintel_spi_82599_enable_flash(data)) {
324 free(data);
325 return 1;
326 }
327 }
328
329 if (register_spi_bitbang_master(&bitbang_spi_master_nicintel, data))
330 return 1; /* shutdown function does cleanup */
331
332 return 0;
333 }
334
335 const struct programmer_entry programmer_nicintel_spi = {
336 .name = "nicintel_spi",
337 .type = PCI,
338 .devs.dev = nics_intel_spi,
339 .init = nicintel_spi_init,
340 };
341