nicintel_eeprom.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see http://www.gnu.org/licenses/.
  20. */
  21. /*
  22. * Datasheet: Intel 82580 Quad/Dual Gigabit Ethernet LAN Controller Datasheet
  23. * 3.3.1.4: General EEPROM Software Access
  24. * 4.7: Access to shared resources (FIXME: we should probably use this semaphore interface)
  25. * 7.4: Register Descriptions
  26. */
  27. #include <stdlib.h>
  28. #include <unistd.h>
  29. #include "flash.h"
  30. #include "spi.h"
  31. #include "programmer.h"
  32. #include "hwaccess.h"
  33. #define PCI_VENDOR_ID_INTEL 0x8086
  34. #define MEMMAP_SIZE (0x14 + 3) /* Only EEC and EERD are needed. */
  35. #define EEC 0x10 /* EEPROM/Flash Control Register */
  36. #define EERD 0x14 /* EEPROM Read Register */
  37. /* EPROM/Flash Control Register bits */
  38. #define EE_SCK 0
  39. #define EE_CS 1
  40. #define EE_SI 2
  41. #define EE_SO 3
  42. #define EE_REQ 6
  43. #define EE_GNT 7
  44. #define EE_PRES 8
  45. #define EE_SIZE 11
  46. #define EE_SIZE_MASK 0xf
  47. /* EEPROM Read Register bits */
  48. #define EERD_START 0
  49. #define EERD_DONE 1
  50. #define EERD_ADDR 2
  51. #define EERD_DATA 16
  52. #define BIT(x) (1<<x)
  53. #define EE_PAGE_MASK 0x3f
  54. static uint8_t *nicintel_eebar;
  55. static struct pci_dev *nicintel_pci;
  56. #define UNPROG_DEVICE 0x1509
  57. const struct dev_entry nics_intel_ee[] = {
  58. {PCI_VENDOR_ID_INTEL, 0x150e, OK, "Intel", "82580 Quad Gigabit Ethernet Controller (Copper)"},
  59. {PCI_VENDOR_ID_INTEL, 0x150f, NT , "Intel", "82580 Quad Gigabit Ethernet Controller (Fiber)"},
  60. {PCI_VENDOR_ID_INTEL, 0x1510, NT , "Intel", "82580 Quad Gigabit Ethernet Controller (Backplane)"},
  61. {PCI_VENDOR_ID_INTEL, 0x1511, NT , "Intel", "82580 Quad Gigabit Ethernet Controller (Ext. PHY)"},
  62. {PCI_VENDOR_ID_INTEL, 0x1511, NT , "Intel", "82580 Dual Gigabit Ethernet Controller (Copper)"},
  63. {PCI_VENDOR_ID_INTEL, UNPROG_DEVICE, OK, "Intel", "Unprogrammed 82580 Quad/Dual Gigabit Ethernet Controller"},
  64. {0},
  65. };
  66. static int nicintel_ee_probe(struct flashctx *flash)
  67. {
  68. if (nicintel_pci->device_id == UNPROG_DEVICE)
  69. flash->chip->total_size = 16; /* Fall back to minimum supported size. */
  70. else {
  71. uint32_t tmp = pci_mmio_readl(nicintel_eebar + EEC);
  72. tmp = ((tmp >> EE_SIZE) & EE_SIZE_MASK);
  73. switch (tmp) {
  74. case 7:
  75. flash->chip->total_size = 16;
  76. break;
  77. case 8:
  78. flash->chip->total_size = 32;
  79. break;
  80. default:
  81. msg_cerr("Unsupported chip size 0x%x\n", tmp);
  82. return 0;
  83. }
  84. }
  85. flash->chip->page_size = EE_PAGE_MASK + 1;
  86. flash->chip->tested = TEST_OK_PREW;
  87. flash->chip->gran = write_gran_1byte_implicit_erase;
  88. flash->chip->block_erasers->eraseblocks[0].size = (EE_PAGE_MASK + 1);
  89. flash->chip->block_erasers->eraseblocks[0].count = (flash->chip->total_size * 1024) / (EE_PAGE_MASK + 1);
  90. return 1;
  91. }
  92. static int nicintel_ee_read_word(unsigned int addr, uint16_t *data)
  93. {
  94. uint32_t tmp = BIT(EERD_START) | (addr << EERD_ADDR);
  95. pci_mmio_writel(tmp, nicintel_eebar + EERD);
  96. /* Poll done flag. 10.000.000 cycles seem to be enough. */
  97. uint32_t i;
  98. for (i = 0; i < 10000000; i++) {
  99. tmp = pci_mmio_readl(nicintel_eebar + EERD);
  100. if (tmp & BIT(EERD_DONE)) {
  101. *data = (tmp >> EERD_DATA) & 0xffff;
  102. return 0;
  103. }
  104. }
  105. return -1;
  106. }
  107. static int nicintel_ee_read(struct flashctx *flash, uint8_t *buf, unsigned int addr, unsigned int len)
  108. {
  109. uint16_t data;
  110. /* The NIC interface always reads 16 b words so we need to convert the address and handle odd address
  111. * explicitly at the start (and also at the end in the loop below). */
  112. if (addr & 1) {
  113. if (nicintel_ee_read_word(addr / 2, &data))
  114. return -1;
  115. *buf++ = data & 0xff;
  116. addr++;
  117. len--;
  118. }
  119. while (len > 0) {
  120. if (nicintel_ee_read_word(addr / 2, &data))
  121. return -1;
  122. *buf++ = data & 0xff;
  123. addr++;
  124. len--;
  125. if (len > 0) {
  126. *buf++ = (data >> 8) & 0xff;
  127. addr++;
  128. len--;
  129. }
  130. }
  131. return 0;
  132. }
  133. static int nicintel_ee_bitset(int reg, int bit, bool val)
  134. {
  135. uint32_t tmp;
  136. tmp = pci_mmio_readl(nicintel_eebar + reg);
  137. if (val)
  138. tmp |= BIT(bit);
  139. else
  140. tmp &= ~BIT(bit);
  141. pci_mmio_writel(tmp, nicintel_eebar + reg);
  142. return -1;
  143. }
  144. /* Shifts one byte out while receiving another one by bitbanging (denoted "direct access" in the datasheet). */
  145. static int nicintel_ee_bitbang(uint8_t mosi, uint8_t *miso)
  146. {
  147. uint8_t out = 0x0;
  148. int i;
  149. for (i = 7; i >= 0; i--) {
  150. nicintel_ee_bitset(EEC, EE_SI, mosi & BIT(i));
  151. nicintel_ee_bitset(EEC, EE_SCK, 1);
  152. if (miso != NULL) {
  153. uint32_t tmp = pci_mmio_readl(nicintel_eebar + EEC);
  154. if (tmp & BIT(EE_SO))
  155. out |= BIT(i);
  156. }
  157. nicintel_ee_bitset(EEC, EE_SCK, 0);
  158. }
  159. if (miso != NULL)
  160. *miso = out;
  161. return 0;
  162. }
  163. /* Polls the WIP bit of the status register of the attached EEPROM via bitbanging. */
  164. static int nicintel_ee_ready(void)
  165. {
  166. unsigned int i;
  167. for (i = 0; i < 1000; i++) {
  168. nicintel_ee_bitset(EEC, EE_CS, 0);
  169. nicintel_ee_bitbang(JEDEC_RDSR, NULL);
  170. uint8_t rdsr;
  171. nicintel_ee_bitbang(0x00, &rdsr);
  172. nicintel_ee_bitset(EEC, EE_CS, 1);
  173. programmer_delay(1);
  174. if (!(rdsr & SPI_SR_WIP)) {
  175. return 0;
  176. }
  177. }
  178. return -1;
  179. }
  180. /* Requests direct access to the SPI pins. */
  181. static int nicintel_ee_req(void)
  182. {
  183. uint32_t tmp;
  184. nicintel_ee_bitset(EEC, EE_REQ, 1);
  185. tmp = pci_mmio_readl(nicintel_eebar + EEC);
  186. if (!(tmp & BIT(EE_GNT))) {
  187. msg_perr("Enabling eeprom access failed.\n");
  188. return 1;
  189. }
  190. nicintel_ee_bitset(EEC, EE_SCK, 0);
  191. return 0;
  192. }
  193. static int nicintel_ee_write(struct flashctx *flash, const uint8_t *buf, unsigned int addr, unsigned int len)
  194. {
  195. if (nicintel_ee_req())
  196. return -1;
  197. int ret = -1;
  198. if (nicintel_ee_ready())
  199. goto out;
  200. while (len > 0) {
  201. /* WREN */
  202. nicintel_ee_bitset(EEC, EE_CS, 0);
  203. nicintel_ee_bitbang(JEDEC_WREN, NULL);
  204. nicintel_ee_bitset(EEC, EE_CS, 1);
  205. programmer_delay(1);
  206. /* data */
  207. nicintel_ee_bitset(EEC, EE_CS, 0);
  208. nicintel_ee_bitbang(JEDEC_BYTE_PROGRAM, NULL);
  209. nicintel_ee_bitbang((addr >> 8) & 0xff, NULL);
  210. nicintel_ee_bitbang(addr & 0xff, NULL);
  211. while (len > 0) {
  212. nicintel_ee_bitbang((buf) ? *buf++ : 0xff, NULL);
  213. len--;
  214. addr++;
  215. if (!(addr & EE_PAGE_MASK))
  216. break;
  217. }
  218. nicintel_ee_bitset(EEC, EE_CS, 1);
  219. programmer_delay(1);
  220. if (nicintel_ee_ready())
  221. goto out;
  222. }
  223. ret = 0;
  224. out:
  225. nicintel_ee_bitset(EEC, EE_REQ, 0); /* Give up direct access. */
  226. return ret;
  227. }
  228. static int nicintel_ee_erase(struct flashctx *flash, unsigned int addr, unsigned int len)
  229. {
  230. return nicintel_ee_write(flash, NULL, addr, len);
  231. }
  232. static const struct opaque_master opaque_master_nicintel_ee = {
  233. .probe = nicintel_ee_probe,
  234. .read = nicintel_ee_read,
  235. .write = nicintel_ee_write,
  236. .erase = nicintel_ee_erase,
  237. };
  238. static int nicintel_ee_shutdown(void *eecp)
  239. {
  240. uint32_t old_eec = *(uint32_t *)eecp;
  241. /* Request bitbanging and unselect the chip first to be safe. */
  242. if (nicintel_ee_req() || nicintel_ee_bitset(EEC, EE_CS, 1))
  243. return -1;
  244. /* Try to restore individual bits we care about. */
  245. int ret = nicintel_ee_bitset(EEC, EE_SCK, old_eec & BIT(EE_SCK));
  246. ret |= nicintel_ee_bitset(EEC, EE_SI, old_eec & BIT(EE_SI));
  247. ret |= nicintel_ee_bitset(EEC, EE_CS, old_eec & BIT(EE_CS));
  248. /* REQ will be cleared by hardware anyway after 2 seconds of inactivity on the SPI pins (3.3.2.1). */
  249. ret |= nicintel_ee_bitset(EEC, EE_REQ, old_eec & BIT(EE_REQ));
  250. free(eecp);
  251. return ret;
  252. }
  253. int nicintel_ee_init(void)
  254. {
  255. if (rget_io_perms())
  256. return 1;
  257. struct pci_dev *dev = pcidev_init(nics_intel_ee, PCI_BASE_ADDRESS_0);
  258. if (!dev)
  259. return 1;
  260. uint32_t io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0);
  261. if (!io_base_addr)
  262. return 1;
  263. nicintel_eebar = rphysmap("Intel Gigabit NIC w/ SPI EEPROM", io_base_addr, MEMMAP_SIZE);
  264. nicintel_pci = dev;
  265. if (dev->device_id != UNPROG_DEVICE) {
  266. uint32_t eec = pci_mmio_readl(nicintel_eebar + EEC);
  267. /* C.f. 3.3.1.5 for the detection mechanism (maybe? contradicting the EE_PRES definition),
  268. * and 3.3.1.7 for possible recovery. */
  269. if (!(eec & BIT(EE_PRES))) {
  270. msg_perr("Controller reports no EEPROM is present.\n");
  271. return 1;
  272. }
  273. uint32_t *eecp = malloc(sizeof(uint32_t));
  274. if (eecp == NULL)
  275. return 1;
  276. *eecp = eec;
  277. if (register_shutdown(nicintel_ee_shutdown, eecp))
  278. return 1;
  279. }
  280. return register_opaque_master(&opaque_master_nicintel_ee);
  281. }