xref: /aosp_15_r20/external/flashrom/nicintel_eeprom.c (revision 0d6140be3aa665ecc836e8907834fcd3e3b018fc)
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