You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. /* natsemi.c - gPXE driver for the NatSemi DP8381x series.
  2. */
  3. #include <stdint.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <io.h>
  7. #include <errno.h>
  8. #include <timer.h>
  9. #include <byteswap.h>
  10. #include <gpxe/pci.h>
  11. #include <gpxe/if_ether.h>
  12. #include <gpxe/ethernet.h>
  13. #include <gpxe/iobuf.h>
  14. #include <gpxe/netdevice.h>
  15. #include <gpxe/spi_bit.h>
  16. #include <gpxe/threewire.h>
  17. #include <gpxe/nvo.h>
  18. #define TX_RING_SIZE 4
  19. #define NUM_RX_DESC 4
  20. struct natsemi_tx {
  21. uint32_t link;
  22. uint32_t cmdsts;
  23. uint32_t bufptr;
  24. };
  25. struct natsemi_rx {
  26. uint32_t link;
  27. uint32_t cmdsts;
  28. uint32_t bufptr;
  29. };
  30. struct natsemi_nic {
  31. unsigned short ioaddr;
  32. unsigned short tx_cur;
  33. unsigned short tx_dirty;
  34. unsigned short rx_cur;
  35. struct natsemi_tx tx[TX_RING_SIZE];
  36. struct natsemi_rx rx[NUM_RX_DESC];
  37. /* need to add iobuf as we cannot free iobuf->data in close without this
  38. * alternatively substracting sizeof(head) and sizeof(list_head) can also
  39. * give the same.*/
  40. struct io_buffer *iobuf[NUM_RX_DESC];
  41. struct spi_bit_basher spibit;
  42. struct spi_device eeprom;
  43. struct nvo_block nvo;
  44. };
  45. /* Tuning Parameters */
  46. #define TX_FIFO_THRESH 256 /* In bytes, rounded down to 32 byte units. */
  47. #define RX_FIFO_THRESH 4 /* Rx buffer level before first PCI xfer. */
  48. #define RX_DMA_BURST 4 /* Maximum PCI burst, '4' is 256 bytes */
  49. #define TX_DMA_BURST 4 /* Calculate as 16<<val. */
  50. #define TX_IPG 3 /* This is the only valid value */
  51. //#define RX_BUF_LEN_IDX 0 /* */
  52. #define RX_BUF_LEN 8192 /*buffer size should be multiple of 32 */
  53. #define RX_BUF_PAD 4
  54. #define RX_BUF_SIZE 1536
  55. #define OWN 0x80000000
  56. #define DSIZE 0x00000FFF
  57. #define CRC_SIZE 4
  58. /* NATSEMI: Offsets to the device registers.
  59. Unlike software-only systems, device drivers interact with complex hardware.
  60. It's not useful to define symbolic names for every register bit in the
  61. device.
  62. */
  63. enum register_offsets {
  64. ChipCmd = 0x00,
  65. ChipConfig = 0x04,
  66. EECtrl = 0x08,
  67. PCIBusCfg = 0x0C,
  68. IntrStatus = 0x10,
  69. IntrMask = 0x14,
  70. IntrEnable = 0x18,
  71. TxRingPtr = 0x20,
  72. TxConfig = 0x24,
  73. RxRingPtr = 0x30,
  74. RxConfig = 0x34,
  75. ClkRun = 0x3C,
  76. WOLCmd = 0x40,
  77. PauseCmd = 0x44,
  78. RxFilterAddr = 0x48,
  79. RxFilterData = 0x4C,
  80. BootRomAddr = 0x50,
  81. BootRomData = 0x54,
  82. SiliconRev = 0x58,
  83. StatsCtrl = 0x5C,
  84. StatsData = 0x60,
  85. RxPktErrs = 0x60,
  86. RxMissed = 0x68,
  87. RxCRCErrs = 0x64,
  88. PCIPM = 0x44,
  89. PhyStatus = 0xC0,
  90. MIntrCtrl = 0xC4,
  91. MIntrStatus = 0xC8,
  92. /* These are from the spec, around page 78... on a separate table. */
  93. PGSEL = 0xCC,
  94. PMDCSR = 0xE4,
  95. TSTDAT = 0xFC,
  96. DSPCFG = 0xF4,
  97. SDCFG = 0x8C,
  98. BasicControl = 0x80,
  99. BasicStatus = 0x84
  100. };
  101. /* Bit in ChipCmd. */
  102. enum ChipCmdBits {
  103. ChipReset = 0x100,
  104. RxReset = 0x20,
  105. TxReset = 0x10,
  106. RxOff = 0x08,
  107. RxOn = 0x04,
  108. TxOff = 0x02,
  109. TxOn = 0x01
  110. };
  111. /* Bits in the RxMode register. */
  112. enum rx_mode_bits {
  113. AcceptErr = 0x20,
  114. AcceptRunt = 0x10,
  115. AcceptBroadcast = 0xC0000000,
  116. AcceptMulticast = 0x00200000,
  117. AcceptAllMulticast = 0x20000000,
  118. AcceptAllPhys = 0x10000000,
  119. AcceptMyPhys = 0x08000000,
  120. RxFilterEnable = 0x80000000
  121. };
  122. /* Bits in network_desc.status */
  123. enum desc_status_bits {
  124. DescOwn = 0x80000000,
  125. DescMore = 0x40000000,
  126. DescIntr = 0x20000000,
  127. DescNoCRC = 0x10000000,
  128. DescPktOK = 0x08000000,
  129. RxTooLong = 0x00400000
  130. };
  131. /* EEPROM access , values are devices specific*/
  132. //#define EE_M1 0x80 /* Mode select bit 1 */
  133. //#define EE_M0 0x40 /* Mode select bit 0 */
  134. #define EE_CS 0x08 /* EEPROM chip select */
  135. #define EE_SK 0x04 /* EEPROM shift clock */
  136. #define EE_DI 0x01 /* Data in */
  137. #define EE_DO 0x02 /* Data out */
  138. /* Offsets within EEPROM (these are word offsets) */
  139. #define EE_MAC 7
  140. #define EE_REG EECtrl
  141. static uint32_t SavedClkRun;
  142. static const uint8_t nat_ee_bits[] = {
  143. [SPI_BIT_SCLK] = EE_SK,
  144. [SPI_BIT_MOSI] = EE_DI,
  145. [SPI_BIT_MISO] = EE_DO,
  146. [SPI_BIT_SS(0)] = EE_CS,
  147. };
  148. static int nat_spi_read_bit ( struct bit_basher *basher,
  149. unsigned int bit_id ) {
  150. struct natsemi_nic *nat = container_of ( basher, struct natsemi_nic,
  151. spibit.basher );
  152. uint8_t mask = nat_ee_bits[bit_id];
  153. uint8_t eereg;
  154. eereg = inb ( nat->ioaddr + EE_REG);
  155. return ( eereg & mask );
  156. }
  157. static void nat_spi_write_bit ( struct bit_basher *basher,
  158. unsigned int bit_id, unsigned long data ) {
  159. struct natsemi_nic *nat = container_of ( basher, struct natsemi_nic,
  160. spibit.basher );
  161. uint8_t mask = nat_ee_bits[bit_id];
  162. uint8_t eereg;
  163. eereg = inb ( nat->ioaddr + EE_REG );
  164. eereg &= ~mask;
  165. eereg |= ( data & mask );
  166. outb ( eereg, nat->ioaddr + EE_REG);
  167. }
  168. static struct bit_basher_operations nat_basher_ops = {
  169. .read = nat_spi_read_bit,
  170. .write = nat_spi_write_bit,
  171. };
  172. /** Portion of EEPROM available for non-volatile stored options
  173. *
  174. * We use offset 0x40 (i.e. address 0x20), length 0x40. This block is
  175. * marked as VPD in the rtl8139 datasheets, so we use it only if we
  176. * detect that the card is not supporting VPD.
  177. */
  178. static struct nvo_fragment nat_nvo_fragments[] = {
  179. { 0x20, 0x40 },
  180. { 0, 0 }
  181. };
  182. /**
  183. * Set up for EEPROM access
  184. *
  185. * @v NAT NATSEMI NIC
  186. */
  187. void nat_init_eeprom ( struct natsemi_nic *nat ) {
  188. int ee9356;
  189. int vpd;
  190. // Initialise three-wire bus
  191. nat->spibit.basher.op = &nat_basher_ops;
  192. nat->spibit.bus.mode = SPI_MODE_THREEWIRE;
  193. init_spi_bit_basher ( &nat->spibit );
  194. DBG ( "EEPROM is an AT93C46\n" );
  195. init_at93c46 ( &nat->eeprom, 16 );
  196. nat->eeprom.bus = &nat->spibit.bus;
  197. // Initialise space for non-volatile options, if available
  198. //vpd = ( inw ( rtl->ioaddr + Config1 ) & VPDEnable );
  199. //if ( vpd ) {
  200. // DBG ( "EEPROM in use for VPD; cannot use for options\n" );
  201. //} else {
  202. // nat->nvo.nvs = &nat->eeprom.nvs;
  203. // nat->nvo.fragments = nat_nvo_fragments;
  204. // }
  205. }
  206. /**
  207. * Reset NIC
  208. *
  209. * @v NATSEMI NIC
  210. *
  211. * Issues a hardware reset and waits for the reset to complete.
  212. */
  213. static void nat_reset ( struct natsemi_nic *nat ) {
  214. int i;
  215. /* Reset chip */
  216. outl ( ChipReset, nat->ioaddr + ChipCmd );
  217. mdelay ( 10 );
  218. nat->tx_dirty=0;
  219. nat->tx_cur=0;
  220. for(i=0;i<TX_RING_SIZE;i++)
  221. {
  222. nat->tx[i].link=0;
  223. nat->tx[i].cmdsts=0;
  224. nat->tx[i].bufptr=0;
  225. }
  226. nat->rx_cur = 0;
  227. outl(virt_to_bus(&nat->tx[0]),nat->ioaddr+TxRingPtr);
  228. outl(virt_to_bus(&nat->rx[0]), nat->ioaddr + RxRingPtr);
  229. outl(TxOff|RxOff, nat->ioaddr + ChipCmd);
  230. /* Restore PME enable bit */
  231. outl(SavedClkRun, nat->ioaddr + ClkRun);
  232. }
  233. /**
  234. * Open NIC
  235. *
  236. * @v netdev Net device
  237. * @ret rc Return status code
  238. */
  239. static int nat_open ( struct net_device *netdev ) {
  240. struct natsemi_nic *nat = netdev->priv;
  241. //struct io_buffer *iobuf;
  242. int i;
  243. uint32_t tx_config,rx_config;
  244. /* Disable PME:
  245. * The PME bit is initialized from the EEPROM contents.
  246. * PCI cards probably have PME disabled, but motherboard
  247. * implementations may have PME set to enable WakeOnLan.
  248. * With PME set the chip will scan incoming packets but
  249. * nothing will be written to memory. */
  250. SavedClkRun = inl(nat->ioaddr + ClkRun);
  251. outl(SavedClkRun & ~0x100, nat->ioaddr + ClkRun);
  252. /* Program the MAC address TODO enable this comment */
  253. for ( i = 0 ; i < ETH_ALEN ; i+=2 )
  254. {
  255. outl(i,nat->ioaddr+RxFilterAddr);
  256. outw ( netdev->ll_addr[i] + (netdev->ll_addr[i+1]<<8), nat->ioaddr +RxFilterData);
  257. DBG("MAC address %d octet :%X %X\n",i,netdev->ll_addr[i],netdev->ll_addr[i+1]);
  258. }
  259. /*Set up the Tx Ring */
  260. nat->tx_cur=0;
  261. nat->tx_dirty=0;
  262. for (i=0;i<TX_RING_SIZE;i++)
  263. {
  264. nat->tx[i].link = virt_to_bus((i+1 < TX_RING_SIZE) ? &nat->tx[i+1] : &nat->tx[0]);
  265. nat->tx[i].cmdsts = 0;
  266. nat->tx[i].bufptr = 0;
  267. }
  268. /* Set up RX ring */
  269. nat->rx_cur=0;
  270. for (i=0;i<NUM_RX_DESC;i++)
  271. {
  272. nat->iobuf[i] = alloc_iob ( RX_BUF_SIZE );
  273. if (!nat->iobuf[i])
  274. return -ENOMEM;
  275. nat->rx[i].link = virt_to_bus((i+1 < NUM_RX_DESC) ? &nat->rx[i+1] : &nat->rx[0]);
  276. nat->rx[i].cmdsts = (uint32_t) RX_BUF_SIZE;
  277. nat->rx[i].bufptr = virt_to_bus(nat->iobuf[i]->data);
  278. }
  279. /* load Receive Descriptor Register */
  280. outl(virt_to_bus(&nat->rx[0]), nat->ioaddr + RxRingPtr);
  281. DBG("Natsemi Rx descriptor loaded with: %X\n",(unsigned int)inl(nat->ioaddr+RxRingPtr));
  282. /* setup Tx ring */
  283. outl(virt_to_bus(&nat->tx[0]),nat->ioaddr+TxRingPtr);
  284. DBG("Natsemi Tx descriptor loaded with: %X\n",(unsigned int)inl(nat->ioaddr+TxRingPtr));
  285. /* Enables RX */
  286. outl(RxFilterEnable|AcceptBroadcast|AcceptAllMulticast|AcceptMyPhys, nat->ioaddr+RxFilterAddr);
  287. /* Initialize other registers. */
  288. /* Configure the PCI bus bursts and FIFO thresholds. */
  289. /* Configure for standard, in-spec Ethernet. */
  290. if (inl(nat->ioaddr + ChipConfig) & 0x20000000) { /* Full duplex */
  291. tx_config = 0xD0801002;
  292. rx_config = 0x10000020;
  293. } else {
  294. tx_config = 0x10801002;
  295. rx_config = 0x0020;
  296. }
  297. outl(tx_config, nat->ioaddr + TxConfig);
  298. outl(rx_config, nat->ioaddr + RxConfig);
  299. /*start the receiver */
  300. outl(RxOn, nat->ioaddr + ChipCmd);
  301. return 0;
  302. }
  303. /**
  304. * Close NIC
  305. *
  306. * @v netdev Net device
  307. */
  308. static void nat_close ( struct net_device *netdev ) {
  309. struct natsemi_nic *nat = netdev->priv;
  310. int i;
  311. /* Reset the hardware to disable everything in one go */
  312. nat_reset ( nat );
  313. /* Free RX ring */
  314. for (i=0;i<NUM_RX_DESC;i++)
  315. {
  316. free_iob( nat->iobuf[i] );
  317. }
  318. }
  319. /**
  320. * Transmit packet
  321. *
  322. * @v netdev Network device
  323. * @v iobuf I/O buffer
  324. * @ret rc Return status code
  325. */
  326. static int nat_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
  327. struct natsemi_nic *nat = netdev->priv;
  328. /* check for space in TX ring */
  329. if (nat->tx[nat->tx_cur].cmdsts !=0)
  330. {
  331. printf ( "TX overflow\n" );
  332. return -ENOBUFS;
  333. }
  334. /* Pad and align packet */
  335. iob_pad ( iobuf, ETH_ZLEN );
  336. /* Add to TX ring */
  337. DBG ( "TX id %d at %lx+%x\n", nat->tx_cur,
  338. virt_to_bus ( iobuf->data ), iob_len ( iobuf ) );
  339. nat->tx[nat->tx_cur].bufptr = virt_to_bus(iobuf->data);
  340. nat->tx[nat->tx_cur].cmdsts= (uint32_t) iob_len(iobuf)|OWN;
  341. nat->tx_cur=(nat->tx_cur+1) % TX_RING_SIZE;
  342. /*start the transmitter */
  343. outl(TxOn, nat->ioaddr + ChipCmd);
  344. return 0;
  345. }
  346. /**
  347. * Poll for received packets
  348. *
  349. * @v netdev Network device
  350. * @v rx_quota Maximum number of packets to receive
  351. */
  352. static void nat_poll ( struct net_device *netdev, unsigned int rx_quota ) {
  353. struct natsemi_nic *nat = netdev->priv;
  354. uint32_t status;
  355. unsigned int rx_status;
  356. unsigned int rx_len;
  357. struct io_buffer *rx_iob;
  358. int i;
  359. /* check the status of packets given to card for transmission */
  360. for ( i = 0 ; i < TX_RING_SIZE ; i++ )
  361. {
  362. //status=(uint32_t)bus_to_virt(nat->tx[nat->tx_dirty].cmdsts);
  363. status=(uint32_t)nat->tx[nat->tx_dirty].cmdsts;
  364. /* check if current packet has been transmitted or not */
  365. if(status & OWN)
  366. break;
  367. /* Check if any errors in transmission */
  368. if (! (status & DescPktOK))
  369. {
  370. printf("Error in sending Packet with data: %s\n and status:%X\n",
  371. (char *)nat->tx[nat->tx_dirty].bufptr,(unsigned int)status);
  372. }
  373. else
  374. {
  375. DBG("Success in transmitting Packet with data: %s",
  376. (char *)nat->tx[nat->tx_dirty].bufptr);
  377. }
  378. /* setting cmdsts zero, indicating that it can be reused */
  379. nat->tx[nat->tx_dirty].cmdsts=0;
  380. nat->tx_dirty=(nat->tx_dirty +1) % TX_RING_SIZE;
  381. }
  382. //rx_status=(unsigned int)bus_to_virt(nat->rx[nat->rx_cur].cmdsts);
  383. rx_status=(unsigned int)nat->rx[nat->rx_cur].cmdsts;
  384. /* Handle received packets */
  385. while (rx_quota && (rx_status & OWN))
  386. {
  387. rx_len= (rx_status & DSIZE) - CRC_SIZE;
  388. /*check for the corrupt packet */
  389. if((rx_status & (DescMore|DescPktOK|RxTooLong)) != DescPktOK)
  390. {
  391. printf("natsemi_poll: Corrupted packet received, "
  392. "buffer status = %X ^ %X \n",rx_status,
  393. (unsigned int) nat->rx[nat->rx_cur].cmdsts);
  394. }
  395. else
  396. {
  397. rx_iob = alloc_iob(rx_len);
  398. if(!rx_iob)
  399. /* leave packet for next call to poll*/
  400. return;
  401. memcpy(iob_put(rx_iob,rx_len),
  402. nat->rx[nat->rx_cur].bufptr,rx_len);
  403. /* add to the receive queue. */
  404. netdev_rx(netdev,rx_iob);
  405. rx_quota--;
  406. }
  407. nat->rx[nat->rx_cur].cmdsts = RX_BUF_SIZE;
  408. nat->rx_cur=(nat->rx_cur+1) % NUM_RX_DESC;
  409. //rx_status=(unsigned int)bus_to_virt(nat->rx[nat->rx_cur].cmdsts);
  410. rx_status=(unsigned int)nat->rx[nat->rx_cur].cmdsts;
  411. }
  412. /* re-enable the potentially idle receive state machine */
  413. outl(RxOn, nat->ioaddr + ChipCmd);
  414. }
  415. /**
  416. * Probe PCI device
  417. *
  418. * @v pci PCI device
  419. * @v id PCI ID
  420. * @ret rc Return status code
  421. */
  422. static int nat_probe ( struct pci_device *pci,
  423. const struct pci_device_id *id __unused ) {
  424. struct net_device *netdev;
  425. struct natsemi_nic *nat = NULL;
  426. int registered_netdev = 0;
  427. int rc;
  428. uint32_t advertising;
  429. /* Fix up PCI device */
  430. adjust_pci_device ( pci );
  431. /* Allocate net device */
  432. netdev = alloc_etherdev ( sizeof ( *nat ) );
  433. if ( ! netdev ) {
  434. rc = -ENOMEM;
  435. goto err;
  436. }
  437. nat = netdev->priv;
  438. pci_set_drvdata ( pci, netdev );
  439. netdev->dev = &pci->dev;
  440. memset ( nat, 0, sizeof ( *nat ) );
  441. nat->ioaddr = pci->ioaddr;
  442. /* Reset the NIC, set up EEPROM access and read MAC address */
  443. nat_reset ( nat );
  444. nat_init_eeprom ( nat );
  445. nvs_read ( &nat->eeprom.nvs, EE_MAC, netdev->ll_addr, ETH_ALEN );
  446. uint8_t eetest[12];
  447. int i;
  448. nvs_read ( &nat->eeprom.nvs, 6, eetest,8 );
  449. for (i=0;i<8;i++)
  450. {
  451. printf("%d word : %X\n",i,eetest[i]);
  452. }
  453. /* mdio routine of etherboot-5.4.0 natsemi driver has been removed and
  454. * statement to read from MII transceiver control section is used directly
  455. */
  456. advertising = inl(nat->ioaddr + 0x80 + (4<<2)) & 0xffff;
  457. {
  458. uint32_t chip_config = inl(nat->ioaddr + ChipConfig);
  459. DBG("%s: Transceiver default autoneg. %s 10 %s %s duplex.\n",
  460. pci->driver_name,
  461. chip_config & 0x2000 ? "enabled, advertise" : "disabled, force",
  462. chip_config & 0x4000 ? "0" : "",
  463. chip_config & 0x8000 ? "full" : "half");
  464. }
  465. DBG("%s: Transceiver status %hX advertising %hX\n",pci->driver_name, (int)inl(nat->ioaddr + 0x84),(unsigned int) advertising);
  466. /* Point to NIC specific routines */
  467. netdev->open = nat_open;
  468. netdev->close = nat_close;
  469. netdev->transmit = nat_transmit;
  470. netdev->poll = nat_poll;
  471. /* Register network device */
  472. if ( ( rc = register_netdev ( netdev ) ) != 0 )
  473. goto err;
  474. registered_netdev = 1;
  475. /* Register non-volatile storagei
  476. * uncomment lines below in final version*/
  477. /*
  478. if ( rtl->nvo.nvs ) {
  479. if ( ( rc = nvo_register ( &rtl->nvo ) ) != 0 )
  480. goto err;
  481. }
  482. */
  483. return 0;
  484. err:
  485. /* Disable NIC */
  486. if ( nat )
  487. nat_reset ( nat );
  488. if ( registered_netdev )
  489. unregister_netdev ( netdev );
  490. /* Free net device */
  491. free_netdev ( netdev );
  492. return rc;
  493. }
  494. /**
  495. * Remove PCI device
  496. *
  497. * @v pci PCI device
  498. */
  499. static void nat_remove ( struct pci_device *pci ) {
  500. struct net_device *netdev = pci_get_drvdata ( pci );
  501. struct natsemi_nic *nat = netdev->priv;
  502. /* TODO
  503. if ( rtl->nvo.nvs )
  504. nvo_unregister ( &rtl->nvo );
  505. */
  506. unregister_netdev ( netdev );
  507. nat_reset ( nat );
  508. free_netdev ( netdev );
  509. }
  510. static struct pci_device_id natsemi_nics[] = {
  511. PCI_ROM(0x100b, 0x0020, "dp83815", "DP83815"),
  512. };
  513. struct pci_driver natsemi_driver __pci_driver = {
  514. .ids = natsemi_nics,
  515. .id_count = ( sizeof ( natsemi_nics ) / sizeof ( natsemi_nics[0] ) ),
  516. .probe = nat_probe,
  517. .remove = nat_remove,
  518. };