1 /*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2013 Ricardo Ribalda - Qtechnology A/S
5 * Copyright (C) 2011, 2014 Stefan Tauner
6 *
7 * Based on nicinctel_spi.c and ichspi.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19 /*
20 * Datasheet: Intel 82580 Quad/Dual Gigabit Ethernet LAN Controller Datasheet
21 * 3.3.1.4: General EEPROM Software Access
22 * 4.7: Access to shared resources (FIXME: we should probably use this semaphore interface)
23 * 7.4: Register Descriptions
24 */
25 /*
26 * Datasheet: Intel Ethernet Controller I210: Datasheet
27 * 8.4.3: EEPROM-Mode Read Register
28 * 8.4.6: EEPROM-Mode Write Register
29 * Write process inspired on kernel e1000_i210.c
30 */
31
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include "flash.h"
35 #include "spi.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 0x1c /* Only EEC, EERD and EEWR are needed. */
42
43 #define EEC 0x10 /* EEPROM/Flash Control Register */
44 #define EERD 0x14 /* EEPROM Read Register */
45 #define EEWR 0x18 /* EEPROM Write Register */
46
47 /* EPROM/Flash Control Register bits */
48 #define EE_SCK 0
49 #define EE_CS 1
50 #define EE_SI 2
51 #define EE_SO 3
52 #define EE_REQ 6
53 #define EE_GNT 7
54 #define EE_PRES 8
55 #define EE_SIZE 11
56 #define EE_SIZE_MASK 0xf
57 #define EE_FLUPD 23
58 #define EE_FLUDONE 26
59
60 /* EEPROM Read Register bits */
61 #define EERD_START 0
62 #define EERD_DONE 1
63 #define EERD_ADDR 2
64 #define EERD_DATA 16
65
66 /* EEPROM Write Register bits */
67 #define EEWR_CMDV 0
68 #define EEWR_DONE 1
69 #define EEWR_ADDR 2
70 #define EEWR_DATA 16
71
72 #define EE_PAGE_MASK 0x3f
73
74 #define UNPROG_DEVICE 0x1509
75
76 struct nicintel_eeprom_data {
77 struct pci_dev *nicintel_pci;
78 uint8_t *nicintel_eebar;
79
80 /* Intel 82580 variable(s) */
81 uint32_t eec;
82
83 /* Intel I210 variable(s) */
84 bool done_i210_write;
85 };
86
87 /*
88 * Warning: is_i210() below makes assumptions on these PCI ids.
89 * It may have to be updated when this list is extended.
90 */
91 static const struct dev_entry nics_intel_ee[] = {
92 {PCI_VENDOR_ID_INTEL, 0x150e, OK, "Intel", "82580 Quad Gigabit Ethernet Controller (Copper)"},
93 {PCI_VENDOR_ID_INTEL, 0x150f, NT , "Intel", "82580 Quad Gigabit Ethernet Controller (Fiber)"},
94 {PCI_VENDOR_ID_INTEL, 0x1510, NT , "Intel", "82580 Quad Gigabit Ethernet Controller (Backplane)"},
95 {PCI_VENDOR_ID_INTEL, 0x1511, NT , "Intel", "82580 Quad Gigabit Ethernet Controller (Ext. PHY)"},
96 {PCI_VENDOR_ID_INTEL, 0x1511, NT , "Intel", "82580 Dual Gigabit Ethernet Controller (Copper)"},
97 {PCI_VENDOR_ID_INTEL, UNPROG_DEVICE, OK, "Intel", "Unprogrammed 82580 Quad/Dual Gigabit Ethernet Controller"},
98 {PCI_VENDOR_ID_INTEL, 0x1531, OK, "Intel", "I210 Gigabit Network Connection Unprogrammed"},
99 {PCI_VENDOR_ID_INTEL, 0x1532, NT, "Intel", "I211 Gigabit Network Connection Unprogrammed"},
100 {PCI_VENDOR_ID_INTEL, 0x1533, OK, "Intel", "I210 Gigabit Network Connection"},
101 {PCI_VENDOR_ID_INTEL, 0x1536, NT, "Intel", "I210 Gigabit Network Connection SERDES Fiber"},
102 {PCI_VENDOR_ID_INTEL, 0x1537, NT, "Intel", "I210 Gigabit Network Connection SERDES Backplane"},
103 {PCI_VENDOR_ID_INTEL, 0x1538, NT, "Intel", "I210 Gigabit Network Connection SGMII"},
104 {PCI_VENDOR_ID_INTEL, 0x1539, NT, "Intel", "I211 Gigabit Network Connection"},
105 {0},
106 };
107
is_i210(uint16_t device_id)108 static inline bool is_i210(uint16_t device_id)
109 {
110 return (device_id & 0xfff0) == 0x1530;
111 }
112
nicintel_ee_probe_i210(struct flashctx * flash)113 static int nicintel_ee_probe_i210(struct flashctx *flash)
114 {
115 /* Emulated eeprom has a fixed size of 4 KB */
116 flash->chip->total_size = 4;
117 flash->chip->page_size = flash->chip->total_size * 1024;
118 flash->chip->tested = TEST_OK_PREWB;
119 flash->chip->gran = WRITE_GRAN_1BYTE_IMPLICIT_ERASE;
120 flash->chip->block_erasers->eraseblocks[0].size = flash->chip->page_size;
121 flash->chip->block_erasers->eraseblocks[0].count = 1;
122
123 return 1;
124 }
125
nicintel_ee_probe_82580(struct flashctx * flash)126 static int nicintel_ee_probe_82580(struct flashctx *flash)
127 {
128 const struct nicintel_eeprom_data *data = flash->mst->opaque.data;
129
130 if (data->nicintel_pci->device_id == UNPROG_DEVICE)
131 flash->chip->total_size = 16; /* Fall back to minimum supported size. */
132 else {
133 uint32_t tmp = pci_mmio_readl(data->nicintel_eebar + EEC);
134 tmp = ((tmp >> EE_SIZE) & EE_SIZE_MASK);
135 switch (tmp) {
136 case 7:
137 flash->chip->total_size = 16;
138 break;
139 case 8:
140 flash->chip->total_size = 32;
141 break;
142 default:
143 msg_cerr("Unsupported chip size 0x%"PRIx32"\n", tmp);
144 return 0;
145 }
146 }
147
148 flash->chip->page_size = EE_PAGE_MASK + 1;
149 flash->chip->tested = TEST_OK_PREWB;
150 flash->chip->gran = WRITE_GRAN_1BYTE_IMPLICIT_ERASE;
151 flash->chip->block_erasers->eraseblocks[0].size = (EE_PAGE_MASK + 1);
152 flash->chip->block_erasers->eraseblocks[0].count = (flash->chip->total_size * 1024) / (EE_PAGE_MASK + 1);
153
154 return 1;
155 }
156
157 #define MAX_ATTEMPTS 10000000
nicintel_ee_read_word(uint8_t * eebar,unsigned int addr,uint16_t * data)158 static int nicintel_ee_read_word(uint8_t *eebar, unsigned int addr, uint16_t *data)
159 {
160 uint32_t tmp = BIT(EERD_START) | (addr << EERD_ADDR);
161 pci_mmio_writel(tmp, eebar + EERD);
162
163 /* Poll done flag. 10.000.000 cycles seem to be enough. */
164 uint32_t i;
165 for (i = 0; i < MAX_ATTEMPTS; i++) {
166 tmp = pci_mmio_readl(eebar + EERD);
167 if (tmp & BIT(EERD_DONE)) {
168 *data = (tmp >> EERD_DATA) & 0xffff;
169 return 0;
170 }
171 }
172
173 return -1;
174 }
175
nicintel_ee_read(struct flashctx * flash,uint8_t * buf,unsigned int addr,unsigned int len)176 static int nicintel_ee_read(struct flashctx *flash, uint8_t *buf, unsigned int addr, unsigned int len)
177 {
178 const struct nicintel_eeprom_data *opaque_data = flash->mst->opaque.data;
179 uint16_t data;
180
181 /* The NIC interface always reads 16 b words so we need to convert the address and handle odd address
182 * explicitly at the start (and also at the end in the loop below). */
183 if (addr & 1) {
184 if (nicintel_ee_read_word(opaque_data->nicintel_eebar, addr / 2, &data))
185 return -1;
186 *buf++ = data & 0xff;
187 addr++;
188 len--;
189 }
190
191 while (len > 0) {
192 if (nicintel_ee_read_word(opaque_data->nicintel_eebar, addr / 2, &data))
193 return -1;
194 *buf++ = data & 0xff;
195 addr++;
196 len--;
197 if (len > 0) {
198 *buf++ = (data >> 8) & 0xff;
199 addr++;
200 len--;
201 }
202 }
203
204 return 0;
205 }
206
nicintel_ee_write_word_i210(uint8_t * eebar,unsigned int addr,uint16_t data)207 static int nicintel_ee_write_word_i210(uint8_t *eebar, unsigned int addr, uint16_t data)
208 {
209 uint32_t eewr;
210
211 eewr = addr << EEWR_ADDR;
212 eewr |= data << EEWR_DATA;
213 eewr |= BIT(EEWR_CMDV);
214 pci_mmio_writel(eewr, eebar + EEWR);
215
216 default_delay(5);
217 int i;
218 for (i = 0; i < MAX_ATTEMPTS; i++)
219 if (pci_mmio_readl(eebar + EEWR) & BIT(EEWR_DONE))
220 return 0;
221 return -1;
222 }
223
nicintel_ee_write_i210(struct flashctx * flash,const uint8_t * buf,unsigned int addr,unsigned int len)224 static int nicintel_ee_write_i210(struct flashctx *flash, const uint8_t *buf,
225 unsigned int addr, unsigned int len)
226 {
227 struct nicintel_eeprom_data *opaque_data = flash->mst->opaque.data;
228 opaque_data->done_i210_write = true;
229
230 if (addr & 1) {
231 uint16_t data;
232
233 if (nicintel_ee_read_word(opaque_data->nicintel_eebar, addr / 2, &data)) {
234 msg_perr("Timeout reading heading byte\n");
235 return -1;
236 }
237
238 data &= 0xff;
239 data |= (buf ? (buf[0]) : 0xff) << 8;
240
241 if (nicintel_ee_write_word_i210(opaque_data->nicintel_eebar, addr / 2, data)) {
242 msg_perr("Timeout writing heading word\n");
243 return -1;
244 }
245
246 if (buf)
247 buf ++;
248 addr ++;
249 len --;
250 }
251
252 while (len > 0) {
253 uint16_t data;
254
255 if (len == 1) {
256 if (nicintel_ee_read_word(opaque_data->nicintel_eebar, addr / 2, &data)) {
257 msg_perr("Timeout reading tail byte\n");
258 return -1;
259 }
260
261 data &= 0xff00;
262 data |= buf ? (buf[0]) : 0xff;
263 } else {
264 if (buf)
265 data = buf[0] | (buf[1] << 8);
266 else
267 data = 0xffff;
268 }
269
270 if (nicintel_ee_write_word_i210(opaque_data->nicintel_eebar, addr / 2, data)) {
271 msg_perr("Timeout writing Shadow RAM\n");
272 return -1;
273 }
274
275 if (buf)
276 buf += 2;
277 if (len > 2)
278 len -= 2;
279 else
280 len = 0;
281 addr += 2;
282 }
283
284 return 0;
285 }
286
nicintel_ee_erase_i210(struct flashctx * flash,unsigned int addr,unsigned int len)287 static int nicintel_ee_erase_i210(struct flashctx *flash, unsigned int addr, unsigned int len)
288 {
289 return nicintel_ee_write_i210(flash, NULL, addr, len);
290 }
291
nicintel_ee_bitset(uint8_t * eebar,int reg,int bit,bool val)292 static int nicintel_ee_bitset(uint8_t *eebar, int reg, int bit, bool val)
293 {
294 uint32_t tmp;
295
296 tmp = pci_mmio_readl(eebar + reg);
297 if (val)
298 tmp |= BIT(bit);
299 else
300 tmp &= ~BIT(bit);
301 pci_mmio_writel(tmp, eebar + reg);
302
303 return -1;
304 }
305
306 /* Shifts one byte out while receiving another one by bitbanging (denoted "direct access" in the datasheet). */
nicintel_ee_bitbang(uint8_t * eebar,uint8_t mosi,uint8_t * miso)307 static int nicintel_ee_bitbang(uint8_t *eebar, uint8_t mosi, uint8_t *miso)
308 {
309 uint8_t out = 0x0;
310
311 int i;
312 for (i = 7; i >= 0; i--) {
313 nicintel_ee_bitset(eebar, EEC, EE_SI, mosi & BIT(i));
314 nicintel_ee_bitset(eebar, EEC, EE_SCK, 1);
315 if (miso != NULL) {
316 uint32_t tmp = pci_mmio_readl(eebar + EEC);
317 if (tmp & BIT(EE_SO))
318 out |= BIT(i);
319 }
320 nicintel_ee_bitset(eebar, EEC, EE_SCK, 0);
321 }
322
323 if (miso != NULL)
324 *miso = out;
325
326 return 0;
327 }
328
329 /* Polls the WIP bit of the status register of the attached EEPROM via bitbanging. */
nicintel_ee_ready(uint8_t * eebar)330 static int nicintel_ee_ready(uint8_t *eebar)
331 {
332 unsigned int i;
333 for (i = 0; i < 1000; i++) {
334 nicintel_ee_bitset(eebar, EEC, EE_CS, 0);
335
336 nicintel_ee_bitbang(eebar, JEDEC_RDSR, NULL);
337 uint8_t rdsr;
338 nicintel_ee_bitbang(eebar, 0x00, &rdsr);
339
340 nicintel_ee_bitset(eebar, EEC, EE_CS, 1);
341 default_delay(1);
342 if (!(rdsr & SPI_SR_WIP)) {
343 return 0;
344 }
345 }
346 return -1;
347 }
348
349 /* Requests direct access to the SPI pins. */
nicintel_ee_req(uint8_t * eebar)350 static int nicintel_ee_req(uint8_t *eebar)
351 {
352 uint32_t tmp;
353 nicintel_ee_bitset(eebar, EEC, EE_REQ, 1);
354
355 tmp = pci_mmio_readl(eebar + EEC);
356 if (!(tmp & BIT(EE_GNT))) {
357 msg_perr("Enabling eeprom access failed.\n");
358 return 1;
359 }
360
361 nicintel_ee_bitset(eebar, EEC, EE_SCK, 0);
362 return 0;
363 }
364
nicintel_ee_write_82580(struct flashctx * flash,const uint8_t * buf,unsigned int addr,unsigned int len)365 static int nicintel_ee_write_82580(struct flashctx *flash, const uint8_t *buf, unsigned int addr, unsigned int len)
366 {
367 const struct nicintel_eeprom_data *opaque_data = flash->mst->opaque.data;
368 uint8_t *eebar = opaque_data->nicintel_eebar;
369
370 if (nicintel_ee_req(eebar))
371 return -1;
372
373 int ret = -1;
374 if (nicintel_ee_ready(eebar))
375 goto out;
376
377 while (len > 0) {
378 /* WREN */
379 nicintel_ee_bitset(eebar, EEC, EE_CS, 0);
380 nicintel_ee_bitbang(eebar, JEDEC_WREN, NULL);
381 nicintel_ee_bitset(eebar, EEC, EE_CS, 1);
382 default_delay(1);
383
384 /* data */
385 nicintel_ee_bitset(eebar, EEC, EE_CS, 0);
386 nicintel_ee_bitbang(eebar, JEDEC_BYTE_PROGRAM, NULL);
387 nicintel_ee_bitbang(eebar, (addr >> 8) & 0xff, NULL);
388 nicintel_ee_bitbang(eebar, addr & 0xff, NULL);
389 while (len > 0) {
390 nicintel_ee_bitbang(eebar, (buf) ? *buf++ : 0xff, NULL);
391 len--;
392 addr++;
393 if (!(addr & EE_PAGE_MASK))
394 break;
395 }
396 nicintel_ee_bitset(eebar, EEC, EE_CS, 1);
397 default_delay(1);
398 if (nicintel_ee_ready(eebar))
399 goto out;
400 }
401 ret = 0;
402 out:
403 nicintel_ee_bitset(eebar, EEC, EE_REQ, 0); /* Give up direct access. */
404 return ret;
405 }
406
nicintel_ee_erase_82580(struct flashctx * flash,unsigned int addr,unsigned int len)407 static int nicintel_ee_erase_82580(struct flashctx *flash, unsigned int addr, unsigned int len)
408 {
409 return nicintel_ee_write_82580(flash, NULL, addr, len);
410 }
411
nicintel_ee_shutdown_i210(void * opaque_data)412 static int nicintel_ee_shutdown_i210(void *opaque_data)
413 {
414 struct nicintel_eeprom_data *data = opaque_data;
415 int ret = 0;
416
417 if (!data->done_i210_write)
418 goto out;
419
420 uint32_t flup = pci_mmio_readl(data->nicintel_eebar + EEC);
421
422 flup |= BIT(EE_FLUPD);
423 pci_mmio_writel(flup, data->nicintel_eebar + EEC);
424
425 int i;
426 for (i = 0; i < MAX_ATTEMPTS; i++)
427 if (pci_mmio_readl(data->nicintel_eebar + EEC) & BIT(EE_FLUDONE))
428 goto out;
429
430 ret = -1;
431 msg_perr("Flash update failed\n");
432
433 out:
434 free(data);
435 return ret;
436 }
437
nicintel_ee_shutdown_82580(void * opaque_data)438 static int nicintel_ee_shutdown_82580(void *opaque_data)
439 {
440 struct nicintel_eeprom_data *data = opaque_data;
441 uint8_t *eebar = data->nicintel_eebar;
442 int ret = 0;
443
444 if (data->nicintel_pci->device_id != UNPROG_DEVICE) {
445 uint32_t old_eec = data->eec;
446 /* Request bitbanging and unselect the chip first to be safe. */
447 if (nicintel_ee_req(eebar) || nicintel_ee_bitset(eebar, EEC, EE_CS, 1)) {
448 ret = -1;
449 goto out;
450 }
451
452 /* Try to restore individual bits we care about. */
453 ret = nicintel_ee_bitset(eebar, EEC, EE_SCK, old_eec & BIT(EE_SCK));
454 ret |= nicintel_ee_bitset(eebar, EEC, EE_SI, old_eec & BIT(EE_SI));
455 ret |= nicintel_ee_bitset(eebar, EEC, EE_CS, old_eec & BIT(EE_CS));
456 /* REQ will be cleared by hardware anyway after 2 seconds of inactivity
457 * on the SPI pins (3.3.2.1). */
458 ret |= nicintel_ee_bitset(eebar, EEC, EE_REQ, old_eec & BIT(EE_REQ));
459 }
460
461 out:
462 free(data);
463 return ret;
464 }
465
466 static const struct opaque_master opaque_master_nicintel_ee_82580 = {
467 .probe = nicintel_ee_probe_82580,
468 .read = nicintel_ee_read,
469 .write = nicintel_ee_write_82580,
470 .erase = nicintel_ee_erase_82580,
471 .shutdown = nicintel_ee_shutdown_82580,
472 };
473
474 static const struct opaque_master opaque_master_nicintel_ee_i210 = {
475 .probe = nicintel_ee_probe_i210,
476 .read = nicintel_ee_read,
477 .write = nicintel_ee_write_i210,
478 .erase = nicintel_ee_erase_i210,
479 .shutdown = nicintel_ee_shutdown_i210,
480 };
481
nicintel_ee_init(const struct programmer_cfg * cfg)482 static int nicintel_ee_init(const struct programmer_cfg *cfg)
483 {
484 const struct opaque_master *mst;
485 uint32_t eec = 0;
486 uint8_t *eebar;
487
488 struct pci_dev *dev = pcidev_init(cfg, nics_intel_ee, PCI_BASE_ADDRESS_0);
489 if (!dev)
490 return 1;
491
492 uint32_t io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0);
493 if (!io_base_addr)
494 return 1;
495
496 if (!is_i210(dev->device_id)) {
497 eebar = rphysmap("Intel Gigabit NIC w/ SPI EEPROM", io_base_addr, MEMMAP_SIZE);
498 if (!eebar)
499 return 1;
500
501 if (dev->device_id != UNPROG_DEVICE) {
502 eec = pci_mmio_readl(eebar + EEC);
503
504 /* C.f. 3.3.1.5 for the detection mechanism (maybe? contradicting
505 the EE_PRES definition),
506 and 3.3.1.7 for possible recovery. */
507 if (!(eec & BIT(EE_PRES))) {
508 msg_perr("Controller reports no EEPROM is present.\n");
509 return 1;
510 }
511 }
512
513 mst = &opaque_master_nicintel_ee_82580;
514 } else {
515 eebar = rphysmap("Intel i210 NIC w/ emulated EEPROM",
516 io_base_addr + 0x12000, MEMMAP_SIZE);
517 if (!eebar)
518 return 1;
519
520 mst = &opaque_master_nicintel_ee_i210;
521 }
522
523 struct nicintel_eeprom_data *data = calloc(1, sizeof(*data));
524 if (!data) {
525 msg_perr("Unable to allocate space for OPAQUE master data\n");
526 return 1;
527 }
528 data->nicintel_pci = dev;
529 data->nicintel_eebar = eebar;
530 data->eec = eec;
531 data->done_i210_write = false;
532
533 return register_opaque_master(mst, data);
534 }
535
536 const struct programmer_entry programmer_nicintel_eeprom = {
537 .name = "nicintel_eeprom",
538 .type = PCI,
539 .devs.dev = nics_intel_ee,
540 .init = nicintel_ee_init,
541 };
542