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.

pcnet32.c 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161
  1. /*
  2. * Copyright (c) 2010 Andrei Faur <da3drus@gmail.com>
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. *
  19. */
  20. FILE_LICENCE ( GPL2_OR_LATER );
  21. #include <stdint.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <unistd.h>
  26. #include <assert.h>
  27. #include <byteswap.h>
  28. #include <errno.h>
  29. #include <ipxe/ethernet.h>
  30. #include <ipxe/if_ether.h>
  31. #include <ipxe/io.h>
  32. #include <ipxe/iobuf.h>
  33. #include <ipxe/malloc.h>
  34. #include <ipxe/netdevice.h>
  35. #include <ipxe/pci.h>
  36. #include <ipxe/timer.h>
  37. #include <mii.h>
  38. #include "pcnet32.h"
  39. static u16 pcnet32_wio_read_csr ( unsigned long addr, int index )
  40. {
  41. outw ( index, addr + PCNET32_WIO_RAP );
  42. return inw ( addr + PCNET32_WIO_RDP );
  43. }
  44. static void pcnet32_wio_write_csr ( unsigned long addr, int index, u16 val )
  45. {
  46. outw ( index, addr + PCNET32_WIO_RAP );
  47. outw ( val, addr + PCNET32_WIO_RDP );
  48. }
  49. static u16 pcnet32_wio_read_bcr ( unsigned long addr, int index )
  50. {
  51. outw ( index, addr + PCNET32_WIO_RAP );
  52. return inw ( addr + PCNET32_WIO_BDP );
  53. }
  54. static void pcnet32_wio_write_bcr ( unsigned long addr, int index, u16 val )
  55. {
  56. outw ( index, addr + PCNET32_WIO_RAP );
  57. outw ( val, addr + PCNET32_WIO_BDP );
  58. }
  59. static u16 pcnet32_wio_read_rap ( unsigned long addr )
  60. {
  61. return inw ( addr + PCNET32_WIO_RAP );
  62. }
  63. static void pcnet32_wio_write_rap ( unsigned long addr , u16 val )
  64. {
  65. outw ( val, addr + PCNET32_WIO_RAP );
  66. }
  67. static void pcnet32_wio_reset ( unsigned long addr )
  68. {
  69. inw ( addr + PCNET32_WIO_RESET );
  70. }
  71. static int pcnet32_wio_check ( unsigned long addr )
  72. {
  73. outw ( 88, addr + PCNET32_WIO_RAP );
  74. return ( inw ( addr + PCNET32_WIO_RAP ) == 88 );
  75. }
  76. static struct pcnet32_access pcnet32_wio = {
  77. .read_csr = pcnet32_wio_read_csr,
  78. .write_csr = pcnet32_wio_write_csr,
  79. .read_bcr = pcnet32_wio_read_bcr,
  80. .write_bcr = pcnet32_wio_write_bcr,
  81. .read_rap = pcnet32_wio_read_rap,
  82. .write_rap = pcnet32_wio_write_rap,
  83. .reset = pcnet32_wio_reset,
  84. };
  85. static u16 pcnet32_dwio_read_csr ( unsigned long addr, int index )
  86. {
  87. outl ( index, addr + PCNET32_DWIO_RAP );
  88. return ( inl ( addr + PCNET32_DWIO_RDP ) & 0xffff );
  89. }
  90. static void pcnet32_dwio_write_csr ( unsigned long addr, int index, u16 val )
  91. {
  92. outl ( index, addr + PCNET32_DWIO_RAP );
  93. outl ( val, addr + PCNET32_DWIO_RDP );
  94. }
  95. static u16 pcnet32_dwio_read_bcr ( unsigned long addr, int index )
  96. {
  97. outl ( index, addr + PCNET32_DWIO_RAP );
  98. return ( inl ( addr + PCNET32_DWIO_BDP ) & 0xffff );
  99. }
  100. static void pcnet32_dwio_write_bcr ( unsigned long addr, int index, u16 val )
  101. {
  102. outl ( index, addr + PCNET32_DWIO_RAP );
  103. outl ( val, addr + PCNET32_DWIO_BDP );
  104. }
  105. static u16 pcnet32_dwio_read_rap ( unsigned long addr )
  106. {
  107. return ( inl ( addr + PCNET32_DWIO_RAP ) & 0xffff );
  108. }
  109. static void pcnet32_dwio_write_rap ( unsigned long addr , u16 val )
  110. {
  111. outl ( val, addr + PCNET32_DWIO_RAP );
  112. }
  113. static void pcnet32_dwio_reset ( unsigned long addr )
  114. {
  115. inl ( addr + PCNET32_DWIO_RESET );
  116. }
  117. static int pcnet32_dwio_check ( unsigned long addr )
  118. {
  119. outl ( 88, addr + PCNET32_DWIO_RAP );
  120. return ( ( inl ( addr + PCNET32_DWIO_RAP ) & 0xffff ) == 88 );
  121. }
  122. static struct pcnet32_access pcnet32_dwio = {
  123. .read_csr = pcnet32_dwio_read_csr,
  124. .write_csr = pcnet32_dwio_write_csr,
  125. .read_bcr = pcnet32_dwio_read_bcr,
  126. .write_bcr = pcnet32_dwio_write_bcr,
  127. .read_rap = pcnet32_dwio_read_rap,
  128. .write_rap = pcnet32_dwio_write_rap,
  129. .reset = pcnet32_dwio_reset,
  130. };
  131. static int
  132. pcnet32_mdio_read ( struct net_device *netdev, int phy, int reg )
  133. {
  134. struct pcnet32_private *priv = netdev->priv;
  135. unsigned long ioaddr = priv->pci_dev->ioaddr;
  136. u16 val_out;
  137. if ( ! priv->mii )
  138. return 0;
  139. /* First, select PHY chip and the register we want to read */
  140. priv->a->write_bcr ( ioaddr, 33,
  141. ( ( phy & 0x1f ) << 5 ) | ( reg & 0x1f ) );
  142. /* Read the selected register's value */
  143. val_out = priv->a->read_bcr ( ioaddr, 34 );
  144. return val_out;
  145. }
  146. static void
  147. __unused pcnet32_mdio_write ( struct net_device *netdev, int phy, int reg, int val )
  148. {
  149. struct pcnet32_private *priv = netdev->priv;
  150. unsigned long ioaddr = priv->pci_dev->ioaddr;
  151. if ( ! priv->mii )
  152. return;
  153. /* First, select PHY chip and the register we want to write to */
  154. priv->a->write_bcr ( ioaddr, 33,
  155. ( ( phy & 0x1f ) << 5 ) | ( reg & 0x1f ) );
  156. /* Write val to the selected register */
  157. priv->a->write_bcr ( ioaddr, 34, val );
  158. }
  159. /**
  160. * pcnet32_refill_rx_ring - Allocates iobufs for every Rx descriptor
  161. * that doesn't have one and isn't in use by the hardware
  162. *
  163. * @v priv Driver private structure
  164. */
  165. static void
  166. pcnet32_refill_rx_ring ( struct pcnet32_private *priv )
  167. {
  168. struct pcnet32_rx_desc *rx_curr_desc;
  169. u16 status;
  170. int i;
  171. DBGP ( "pcnet32_refill_rx_ring\n" );
  172. for ( i = 0; i < RX_RING_SIZE; i++ ) {
  173. rx_curr_desc = priv->rx_base + i;
  174. status = le16_to_cpu ( rx_curr_desc->status );
  175. /* Don't touch descriptors owned by the hardware */
  176. if ( status & DescOwn )
  177. continue;
  178. /* Descriptors with iobufs still need to be processed */
  179. if ( priv->rx_iobuf[i] != NULL )
  180. continue;
  181. /* If alloc_iob fails, try again later (next poll) */
  182. if ( ! ( priv->rx_iobuf[i] = alloc_iob ( PKT_BUF_SIZE ) ) ) {
  183. DBG ( "Refill rx ring failed\n" );
  184. break;
  185. }
  186. rx_curr_desc->base =
  187. cpu_to_le32 ( virt_to_bus ( priv->rx_iobuf[i]->data ) );
  188. rx_curr_desc->buf_length = cpu_to_le16 ( -PKT_BUF_SIZE );
  189. rx_curr_desc->msg_length = rx_curr_desc->reserved = 0;
  190. /* Owner changes after the other status fields are set */
  191. wmb();
  192. rx_curr_desc->status = cpu_to_le16 ( DescOwn );
  193. }
  194. }
  195. /**
  196. * pcnet32_setup_rx_resources - allocate Rx resources (Descriptors)
  197. *
  198. * @v priv Driver private structure
  199. *
  200. * @ret rc Returns 0 on success, negative on failure
  201. */
  202. static int
  203. pcnet32_setup_rx_resources ( struct pcnet32_private *priv )
  204. {
  205. DBGP ( "pcnet32_setup_rx_resources\n" );
  206. priv->rx_base = malloc_dma ( RX_RING_BYTES, RX_RING_ALIGN );
  207. DBG ( "priv->rx_base = %#08lx\n", virt_to_bus ( priv->rx_base ) );
  208. if ( ! priv->rx_base ) {
  209. return -ENOMEM;
  210. }
  211. memset ( priv->rx_base, 0, RX_RING_BYTES );
  212. pcnet32_refill_rx_ring ( priv );
  213. priv->rx_curr = 0;
  214. return 0;
  215. }
  216. static void
  217. pcnet32_free_rx_resources ( struct pcnet32_private *priv )
  218. {
  219. int i;
  220. DBGP ( "pcnet32_free_rx_resources\n" );
  221. free_dma ( priv->rx_base, RX_RING_BYTES );
  222. for ( i = 0; i < RX_RING_SIZE; i++ ) {
  223. free_iob ( priv->rx_iobuf[i] );
  224. priv->rx_iobuf[i] = NULL;
  225. }
  226. }
  227. /**
  228. * pcnet32_setup_tx_resources - allocate Tx resources (Descriptors)
  229. *
  230. * @v priv Driver private structure
  231. *
  232. * @ret rc Returns 0 on success, negative on failure
  233. */
  234. static int
  235. pcnet32_setup_tx_resources ( struct pcnet32_private *priv )
  236. {
  237. DBGP ( "pcnet32_setup_tx_resources\n" );
  238. priv->tx_base = malloc_dma ( TX_RING_BYTES, TX_RING_ALIGN );
  239. if ( ! priv->tx_base ) {
  240. return -ENOMEM;
  241. }
  242. memset ( priv->tx_base, 0, TX_RING_BYTES );
  243. DBG ( "priv->tx_base = %#08lx\n", virt_to_bus ( priv->tx_base ) );
  244. priv->tx_curr = 0;
  245. priv->tx_fill_ctr = 0;
  246. priv->tx_tail = 0;
  247. return 0;
  248. }
  249. static void
  250. pcnet32_free_tx_resources ( struct pcnet32_private *priv )
  251. {
  252. DBGP ( "pcnet32_free_tx_resources\n" );
  253. free_dma ( priv->tx_base, TX_RING_BYTES );
  254. }
  255. static int
  256. pcnet32_chip_detect ( struct pcnet32_private *priv )
  257. {
  258. int fdx, mii, fset;
  259. int media;
  260. int rc;
  261. unsigned long ioaddr;
  262. struct pcnet32_access *a;
  263. int chip_version;
  264. char *chipname;
  265. ioaddr = priv->pci_dev->ioaddr;
  266. a = priv->a;
  267. chip_version = a->read_csr ( ioaddr, 88 )
  268. | ( a->read_csr ( ioaddr, 89 ) << 16 );
  269. rc = -ENODEV;
  270. DBG ( "PCnet chip version is 0x%X\n", chip_version );
  271. if ( ( chip_version & 0xfff ) != 0x003 )
  272. goto err_unsupported;
  273. fdx = mii = fset = 0;
  274. chip_version = ( chip_version >> 12 ) & 0xffff;
  275. switch (chip_version) {
  276. case 0x2420:
  277. chipname = "PCnet/PCI 79C970";
  278. break;
  279. case 0x2430:
  280. /* 970 gives the wrong chip id back */
  281. chipname = "PCnet/PCI 79C970";
  282. break;
  283. case 0x2621:
  284. chipname = "PCnet/PCI II 79C970A";
  285. fdx = 1;
  286. break;
  287. case 0x2623:
  288. chipname = "PCnet/FAST 79C971";
  289. fdx = 1;
  290. mii = 1;
  291. fset = 1;
  292. break;
  293. case 0x2624:
  294. chipname = "PCnet/FAST+ 79C972";
  295. fdx = 1;
  296. mii = 1;
  297. fset = 1;
  298. break;
  299. case 0x2625:
  300. chipname = "PCnet/FAST III 79C973";
  301. fdx = 1;
  302. mii = 1;
  303. break;
  304. case 0x2626:
  305. chipname = "PCnet/Home 79C978";
  306. fdx = 1;
  307. /*
  308. * This is based on specs published at www.amd.com. This section
  309. * assumes that a NIC with a 79C978 wants to go into 1Mb HomePNA
  310. * mode. The 79C978 can also go into standard ethernet, and
  311. * there probably should be some sort of module option to select
  312. * the mode by which the card should operate
  313. */
  314. /* switch to home wiring mode */
  315. media = a->read_bcr(ioaddr, 49);
  316. DBG ( "media reset to %#x.\n", media );
  317. a->write_bcr(ioaddr, 49, media);
  318. break;
  319. case 0x2627:
  320. chipname = "PCnet/FAST III 79C975";
  321. fdx = 1;
  322. mii = 1;
  323. break;
  324. case 0x2628:
  325. chipname = "PCnet/PRO 79C976";
  326. fdx = 1;
  327. mii = 1;
  328. break;
  329. default:
  330. chipname = "UNKNOWN";
  331. DBG ( "PCnet version %#x, no PCnet32 chip.\n", chip_version );
  332. goto err_unsupported;
  333. }
  334. DBG ( "PCnet chipname %s\n", chipname );
  335. /*
  336. * On selected chips turn on the BCR18:NOUFLO bit. This stops transmit
  337. * starting until the packet is loaded. Strike one for reliability, lose
  338. * one for latency - although on PCI this isn't a big loss. Older chips
  339. * have FIFO's smaller than a packet, so you can't do this.
  340. * Turn on BCR18:BurstRdEn and BCR18:BurstWrEn.
  341. */
  342. if (fset) {
  343. a->write_bcr ( ioaddr, 18,
  344. ( a->read_bcr ( ioaddr, 18 ) | 0x0860 ) );
  345. a->write_csr ( ioaddr, 80, 0x0c00 );
  346. }
  347. priv->full_duplex = fdx;
  348. priv->mii = mii;
  349. return 0;
  350. err_unsupported:
  351. return rc;
  352. }
  353. /**
  354. * pcnet32_set_ops - Determines the ops used to access the registers
  355. *
  356. * @v priv Driver private structure
  357. *
  358. * @ret rc Returns 0 on success, negative on failure
  359. */
  360. static int
  361. pcnet32_set_ops ( struct pcnet32_private *priv )
  362. {
  363. int rc;
  364. unsigned long ioaddr;
  365. ioaddr = priv->pci_dev->ioaddr;
  366. /* Check if CSR0 has its default value and perform a write / read
  367. in the RAP register to see if it works. Based on these results
  368. determine what mode the NIC is in (WIO / DWIO)
  369. */
  370. rc = -ENODEV;
  371. if ( pcnet32_wio_read_csr ( ioaddr, 0 ) == 4 &&
  372. pcnet32_wio_check ( ioaddr ) ) {
  373. priv->a = &pcnet32_wio;
  374. } else {
  375. pcnet32_dwio_reset ( ioaddr );
  376. if ( pcnet32_dwio_read_csr ( ioaddr, 0 ) == 4 &&
  377. pcnet32_dwio_check ( ioaddr ) ) {
  378. priv->a = &pcnet32_dwio;
  379. } else {
  380. goto err_unsupported;
  381. }
  382. }
  383. return 0;
  384. err_unsupported:
  385. return rc;
  386. }
  387. /**
  388. * pcnet32_setup_init_block - setup the NICs initialization block
  389. *
  390. * @v priv Driver private structure
  391. *
  392. * @ret rc Returns 0 on success, negative on failure
  393. */
  394. static void
  395. pcnet32_setup_init_block ( struct pcnet32_private *priv )
  396. {
  397. int i;
  398. /* Configure the network port based on what we've established so far */
  399. priv->init_block.mode =
  400. cpu_to_le16 ( ( priv->options & PCNET32_PORT_PORTSEL ) << 7 );
  401. /* Setup RLEN and TLEN fields */
  402. priv->init_block.tlen_rlen =
  403. cpu_to_le16 ( ( PCNET32_LOG_RX_BUFFERS << 4 ) |
  404. ( PCNET32_LOG_TX_BUFFERS << 12 ) );
  405. /* Fill in physical address */
  406. for ( i = 0; i < ETH_ALEN; i++)
  407. priv->init_block.phys_addr[i] = priv->netdev->hw_addr[i];
  408. /* No multicasting scheme, accept everything */
  409. priv->init_block.filter[0] = 0xffffffff;
  410. priv->init_block.filter[1] = 0xffffffff;
  411. priv->init_block.rx_ring =
  412. cpu_to_le32 ( virt_to_bus ( priv->rx_base ) );
  413. priv->init_block.tx_ring =
  414. cpu_to_le32 ( virt_to_bus ( priv->tx_base ) );
  415. /* Make sure all changes are visible */
  416. wmb();
  417. }
  418. /**
  419. * pcnet32_setup_probe_phy - go through all PHYs and see which one is present
  420. *
  421. * @v priv Driver private structure
  422. */
  423. static void
  424. pcnet32_setup_probe_phy ( struct pcnet32_private *priv )
  425. {
  426. unsigned long ioaddr = priv->pci_dev->ioaddr;
  427. unsigned int phycount = 0;
  428. int phy_id;
  429. int i;
  430. if ( priv->mii ) {
  431. phy_id = ( ( priv->a->read_bcr ( ioaddr, 33 ) ) >> 5 ) & 0x1f;
  432. for ( i = 0; i < PCNET32_MAX_PHYS; i++ ) {
  433. unsigned short id1, id2;
  434. id1 = pcnet32_mdio_read ( priv->netdev, i, MII_PHYSID1 );
  435. if ( id1 == 0xffff )
  436. continue;
  437. id2 = pcnet32_mdio_read ( priv->netdev, i, MII_PHYSID2 );
  438. if ( id2 == 0xffff )
  439. continue;
  440. if ( i == 31 && ( ( priv->chip_version + 1 ) & 0xfffe ) == 0x2624 )
  441. continue;
  442. phycount++;
  443. phy_id = i;
  444. }
  445. priv->a->write_bcr ( ioaddr, 33, phy_id << 5 );
  446. if ( phycount > 1 )
  447. priv->options |= PCNET32_PORT_MII;
  448. }
  449. }
  450. /**
  451. * pcnet32_setup_mac_addr - check for inconsistency between CSR12-14
  452. * and PROM addresses
  453. *
  454. * @v priv Driver private structure
  455. */
  456. static int
  457. pcnet32_setup_mac_addr ( struct pcnet32_private *priv )
  458. {
  459. int i;
  460. u8 promaddr[ETH_ALEN];
  461. unsigned long ioaddr = priv->pci_dev->ioaddr;
  462. /* In most chips, after a chip reset, the ethernet address is read from
  463. * the station address PROM at the base address and programmed into the
  464. * "Physical Address Registers" CSR12-14.
  465. * As a precautionary measure, we read the PROM values and complain if
  466. * they disagree with the CSRs. If they miscompare, and the PROM addr
  467. * is valid, then the PROM addr is used.
  468. */
  469. for ( i = 0; i < 3; i++ ) {
  470. unsigned int val;
  471. val = priv->a->read_csr ( ioaddr, i + 12 ) & 0x0ffff;
  472. /* There may be endianness issues here. */
  473. priv->netdev->hw_addr[2 * i] = val & 0x0ff;
  474. priv->netdev->hw_addr[2 * i + 1] = ( val >> 8 ) & 0x0ff;
  475. }
  476. for ( i = 0; i < ETH_ALEN; i++ )
  477. promaddr[i] = inb ( ioaddr + i );
  478. if ( memcmp ( promaddr, priv->netdev->hw_addr, ETH_ALEN ) ||
  479. ! is_valid_ether_addr ( priv->netdev->hw_addr ) ) {
  480. if ( is_valid_ether_addr ( promaddr ) ) {
  481. DBG ( "CSR address is invalid, using PROM addr\n" );
  482. memcpy ( priv->netdev->hw_addr, promaddr, ETH_ALEN );
  483. }
  484. }
  485. /* If ethernet address is not valid, return error */
  486. if ( ! is_valid_ether_addr ( priv->netdev->hw_addr ) )
  487. return -EADDRNOTAVAIL;
  488. return 0;
  489. }
  490. /**
  491. * pcnet32_setup_if_duplex - Sets the NICs used interface and duplex mode
  492. *
  493. * @v priv Driver private structure
  494. */
  495. static void
  496. pcnet32_setup_if_duplex ( struct pcnet32_private *priv )
  497. {
  498. unsigned long ioaddr = priv->pci_dev->ioaddr;
  499. u16 val;
  500. /* Set/Reset autoselect bit */
  501. val = priv->a->read_bcr ( ioaddr, 2 ) & ~2;
  502. if ( priv->options & PCNET32_PORT_ASEL )
  503. val |= 2;
  504. priv->a->write_bcr ( ioaddr, 2, val );
  505. /* Handle full duplex setting */
  506. if ( priv->full_duplex ) {
  507. val = priv->a->read_bcr ( ioaddr, 9 ) & ~3;
  508. if ( priv->options & PCNET32_PORT_FD ) {
  509. val |= 1;
  510. if ( priv->options == ( PCNET32_PORT_FD | PCNET32_PORT_AUI ) )
  511. val |= 2;
  512. } else if ( priv->options & PCNET32_PORT_ASEL ) {
  513. /* Workaround of xSeries 250, on for 79C975 only */
  514. if ( priv->chip_version == 0x2627 )
  515. val |= 3;
  516. }
  517. priv->a->write_bcr ( ioaddr, 9, val );
  518. }
  519. /* Set/Reset GPSI bit in test register */
  520. val = priv->a->read_csr ( ioaddr, 124 ) & ~0x10;
  521. if ( ( priv->options & PCNET32_PORT_PORTSEL ) == PCNET32_PORT_GPSI )
  522. val |= 0x10;
  523. priv->a->write_bcr ( ioaddr, 124, val );
  524. /* Allied Telesyn AT are 100Mbit only and do not negotiate */
  525. u16 subsys_vend_id, subsys_dev_id;
  526. pci_read_config_word ( priv->pci_dev,
  527. PCI_SUBSYSTEM_VENDOR_ID,
  528. &subsys_vend_id );
  529. pci_read_config_word ( priv->pci_dev,
  530. PCI_SUBSYSTEM_ID,
  531. &subsys_dev_id );
  532. if ( subsys_vend_id == PCI_VENDOR_ID_AT &&
  533. ( ( subsys_dev_id == PCI_SUBDEVICE_ID_AT_2700FX ) ||
  534. ( subsys_dev_id == PCI_SUBDEVICE_ID_AT_2701FX ) ) ) {
  535. priv->options = PCNET32_PORT_FD | PCNET32_PORT_100;
  536. }
  537. if ( priv->mii && ! ( priv->options & PCNET32_PORT_ASEL ) ) {
  538. /* Disable Auto Negotiation, set 10Mbps, HD */
  539. val = priv->a->read_bcr ( ioaddr, 32 ) & ~0x38;
  540. if ( priv->options & PCNET32_PORT_FD )
  541. val |= 0x10;
  542. if ( priv->options & PCNET32_PORT_100 )
  543. val |= 0x08;
  544. priv->a->write_bcr ( ioaddr, 32, val );
  545. } else if ( priv->options & PCNET32_PORT_ASEL ) {
  546. /* 79C970 chips do not have the BCR32 register */
  547. if ( ( priv->chip_version != 0x2420 ) &&
  548. ( priv->chip_version != 0x2621 ) ) {
  549. /* Enable Auto Negotiation, setup, disable FD */
  550. val = priv->a->read_bcr ( ioaddr, 32 ) & ~0x98;
  551. val |= 0x20;
  552. priv->a->write_bcr ( ioaddr, 32, val );
  553. }
  554. }
  555. }
  556. /**
  557. * pcnet32_hw_start - Starts up the NIC
  558. *
  559. * @v priv Driver private structure
  560. */
  561. static void
  562. pcnet32_hw_start ( struct pcnet32_private *priv )
  563. {
  564. unsigned long ioaddr = priv->pci_dev->ioaddr;
  565. int i;
  566. /* Begin initialization procedure */
  567. priv->a->write_csr ( ioaddr, 0, Init );
  568. /* Wait for the initialization to be done */
  569. i = 0;
  570. while ( i++ < 100 )
  571. if ( priv->a->read_csr ( ioaddr, 0 ) & InitDone )
  572. break;
  573. /* Start the chip */
  574. priv->a->write_csr ( ioaddr, 0, Strt );
  575. }
  576. /**
  577. * open - Called when a network interface is made active
  578. *
  579. * @v netdev Network device
  580. * @ret rc Return status code, 0 on success, negative value on failure
  581. **/
  582. static int
  583. pcnet32_open ( struct net_device *netdev )
  584. {
  585. struct pcnet32_private *priv = netdev_priv ( netdev );
  586. unsigned long ioaddr = priv->pci_dev->ioaddr;
  587. int rc;
  588. u16 val;
  589. /* Setup TX and RX descriptors */
  590. if ( ( rc = pcnet32_setup_tx_resources ( priv ) ) != 0 ) {
  591. DBG ( "Error setting up TX resources\n" );
  592. goto err_setup_tx;
  593. }
  594. if ( ( rc = pcnet32_setup_rx_resources ( priv ) ) != 0 ) {
  595. DBG ( "Error setting up RX resources\n" );
  596. goto err_setup_rx;
  597. }
  598. /* Reset the chip */
  599. priv->a->reset ( ioaddr );
  600. /* Switch pcnet32 to 32bit mode */
  601. priv->a->write_bcr ( ioaddr, 20, PCNET32_SWSTYLE_PCNET32 );
  602. /* Setup the interface and duplex mode */
  603. pcnet32_setup_if_duplex ( priv );
  604. /* Disable interrupts */
  605. val = priv->a->read_csr ( ioaddr, 3 );
  606. val |= BablMask | MissFrameMask | RxIntMask | TxIntMask | InitDoneMask;
  607. priv->a->write_csr ( ioaddr, 3, val );
  608. /* Setup initialization block */
  609. pcnet32_setup_init_block ( priv );
  610. /* Fill in the address of the initialization block */
  611. priv->a->write_csr ( ioaddr, 1,
  612. ( virt_to_bus ( &priv->init_block ) ) & 0xffff );
  613. priv->a->write_csr ( ioaddr, 2,
  614. ( virt_to_bus ( &priv->init_block ) ) >> 16 );
  615. /* Enable Auto-Pad, disable interrupts */
  616. priv->a->write_csr ( ioaddr, 4, 0x0915 );
  617. pcnet32_hw_start ( priv );
  618. return 0;
  619. err_setup_rx:
  620. pcnet32_free_tx_resources ( priv );
  621. err_setup_tx:
  622. priv->a->reset( priv->pci_dev->ioaddr );
  623. return rc;
  624. }
  625. /**
  626. * transmit - Transmit a packet
  627. *
  628. * @v netdev Network device
  629. * @v iobuf I/O buffer
  630. *
  631. * @ret rc Returns 0 on success, negative on failure
  632. */
  633. static int
  634. pcnet32_transmit ( struct net_device *netdev, struct io_buffer *iobuf )
  635. {
  636. struct pcnet32_private *priv = netdev_priv ( netdev );
  637. unsigned long ioaddr = priv->pci_dev->ioaddr;
  638. uint32_t tx_len = iob_len ( iobuf );
  639. struct pcnet32_tx_desc *tx_curr_desc;
  640. DBGP ( "pcnet32_transmit\n" );
  641. if ( priv->tx_fill_ctr == TX_RING_SIZE ) {
  642. DBG ( "Tx overflow\n" );
  643. return -ENOTSUP;
  644. }
  645. priv->tx_iobuf[priv->tx_curr] = iobuf;
  646. tx_curr_desc = priv->tx_base + priv->tx_curr;
  647. /* Configure current descriptor to transmit packet */
  648. tx_curr_desc->length = cpu_to_le16 ( -tx_len );
  649. tx_curr_desc->misc = 0x00000000;
  650. tx_curr_desc->base = cpu_to_le32 ( virt_to_bus ( iobuf->data ) );
  651. /* Owner changes after the other status fields are set */
  652. wmb();
  653. tx_curr_desc->status =
  654. cpu_to_le16 ( DescOwn | StartOfPacket | EndOfPacket );
  655. /* Trigger an immediate send poll */
  656. priv->a->write_csr ( ioaddr, 0,
  657. ( priv->irq_enabled ? IntEnable : 0 ) | TxDemand );
  658. /* Point to the next free descriptor */
  659. priv->tx_curr = ( priv->tx_curr + 1 ) % TX_RING_SIZE;
  660. /* Increment number of tx descriptors in use */
  661. priv->tx_fill_ctr++;
  662. return 0;
  663. }
  664. /**
  665. * pcnet32_process_tx_packets - Checks for successfully sent packets,
  666. * reports them to iPXE with netdev_tx_complete()
  667. *
  668. * @v netdev Network device
  669. */
  670. static void
  671. pcnet32_process_tx_packets ( struct net_device *netdev )
  672. {
  673. struct pcnet32_private *priv = netdev_priv ( netdev );
  674. struct pcnet32_tx_desc *tx_curr_desc;
  675. DBGP ( "pcnet32_process_tx_packets\n" );
  676. while ( priv->tx_tail != priv->tx_curr ) {
  677. tx_curr_desc = priv->tx_base + priv->tx_tail;
  678. u16 status = le16_to_cpu ( tx_curr_desc->status );
  679. DBG ( "Before OWN bit check, status: %#08x\n", status );
  680. /* Skip this descriptor if hardware still owns it */
  681. if ( status & DescOwn )
  682. break;
  683. DBG ( "Transmitted packet.\n" );
  684. DBG ( "priv->tx_fill_ctr= %d\n", priv->tx_fill_ctr );
  685. DBG ( "priv->tx_tail = %d\n", priv->tx_tail );
  686. DBG ( "priv->tx_curr = %d\n", priv->tx_curr );
  687. DBG ( "tx_curr_desc = %#08lx\n", virt_to_bus ( tx_curr_desc ) );
  688. /* This packet is ready for completion */
  689. netdev_tx_complete ( netdev, priv->tx_iobuf[priv->tx_tail]);
  690. /* Clear the descriptor */
  691. memset ( tx_curr_desc, 0, sizeof(*tx_curr_desc) );
  692. /* Reduce the number of tx descriptors in use */
  693. priv->tx_fill_ctr--;
  694. /* Go to next available descriptor */
  695. priv->tx_tail = ( priv->tx_tail + 1 ) % TX_RING_SIZE;
  696. }
  697. }
  698. /**
  699. * pcnet32_process_rx_packets - Checks for received packets, reports them
  700. * to iPXE with netdev_rx() or netdev_rx_err() if there was an error receiving
  701. * the packet
  702. *
  703. * @v netdev Network device
  704. */
  705. static void
  706. pcnet32_process_rx_packets ( struct net_device *netdev )
  707. {
  708. struct pcnet32_private *priv = netdev_priv ( netdev );
  709. struct pcnet32_rx_desc *rx_curr_desc;
  710. u16 status;
  711. u32 len;
  712. int i;
  713. DBGP ( "pcnet32_process_rx_packets\n" );
  714. for ( i = 0; i < RX_RING_SIZE; i++ ) {
  715. rx_curr_desc = priv->rx_base + priv->rx_curr;
  716. status = le16_to_cpu ( rx_curr_desc->status );
  717. rmb();
  718. DBG ( "Before OWN bit check, status: %#08x\n", status );
  719. /* Skip this descriptor if hardware still owns it */
  720. if ( status & DescOwn )
  721. break;
  722. /* We own the descriptor, but it has not been refilled yet */
  723. if ( priv->rx_iobuf[priv->rx_curr] == NULL )
  724. break;
  725. DBG ( "Received packet.\n" );
  726. DBG ( "priv->rx_curr = %d\n", priv->rx_curr );
  727. DBG ( "rx_len = %d\n",
  728. ( le32_to_cpu ( rx_curr_desc->msg_length ) & 0xfff ) - 4 );
  729. DBG ( "rx_curr_desc = %#08lx\n",
  730. virt_to_bus ( rx_curr_desc ) );
  731. /* Check ERR bit */
  732. if ( status & 0x4000 ) {
  733. netdev_rx_err ( netdev, priv->rx_iobuf[priv->rx_curr],
  734. -EINVAL );
  735. DBG ( "Corrupted packet received!\n");
  736. } else {
  737. /* Adjust size of the iobuf to reflect received data */
  738. len = ( le32_to_cpu ( rx_curr_desc->msg_length ) & 0xfff ) - 4;
  739. iob_put ( priv->rx_iobuf[priv->rx_curr], len );
  740. /* Add this packet to the receive queue */
  741. netdev_rx ( netdev, priv->rx_iobuf[priv->rx_curr] );
  742. }
  743. /* Invalidate iobuf and descriptor */
  744. priv->rx_iobuf[priv->rx_curr] = NULL;
  745. memset ( rx_curr_desc, 0, sizeof(*rx_curr_desc) );
  746. /* Point to the next free descriptor */
  747. priv->rx_curr = ( priv->rx_curr + 1 ) % RX_RING_SIZE;
  748. }
  749. /* Allocate new iobufs where needed */
  750. pcnet32_refill_rx_ring ( priv );
  751. }
  752. /**
  753. * poll - Poll for received packets
  754. *
  755. * @v netdev Network device
  756. */
  757. static void
  758. pcnet32_poll ( struct net_device *netdev )
  759. {
  760. struct pcnet32_private *priv = netdev_priv ( netdev );
  761. unsigned long ioaddr = priv->pci_dev->ioaddr;
  762. u16 status;
  763. DBGP ( "pcnet32_poll\n" );
  764. status = priv->a->read_csr ( ioaddr, 0 );
  765. /* Clear interrupts */
  766. priv->a->write_csr ( ioaddr, 0, status );
  767. DBG ( "pcnet32_poll: mask = %#04x, status = %#04x\n",
  768. priv->a->read_csr ( ioaddr, 3 ), status );
  769. /* Return when RINT or TINT are not set */
  770. if ( ( status & 0x0500 ) == 0x0000 )
  771. return;
  772. /* Process transmitted packets */
  773. pcnet32_process_tx_packets ( netdev );
  774. /* Process received packets */
  775. pcnet32_process_rx_packets ( netdev );
  776. }
  777. /**
  778. * close - Disable network interface
  779. *
  780. * @v netdev network interface device structure
  781. **/
  782. static void
  783. pcnet32_close ( struct net_device *netdev )
  784. {
  785. struct pcnet32_private *priv = netdev_priv ( netdev );
  786. unsigned long ioaddr = priv->pci_dev->ioaddr;
  787. DBGP ( "pcnet32_close\n" );
  788. /* Reset the chip */
  789. pcnet32_wio_reset ( ioaddr );
  790. /* Stop the PCNET32 - it occasionally polls memory if we don't */
  791. priv->a->write_csr ( ioaddr, 0, Stop );
  792. /* Switch back to 16bit mode to avoid problems with dumb
  793. * DOS packet driver after a warm reboot */
  794. priv->a->write_bcr ( ioaddr, 20, PCNET32_SWSTYLE_LANCE );
  795. pcnet32_free_rx_resources ( priv );
  796. pcnet32_free_tx_resources ( priv );
  797. }
  798. static void pcnet32_irq_enable ( struct pcnet32_private *priv )
  799. {
  800. unsigned long ioaddr = priv->pci_dev->ioaddr;
  801. u16 val;
  802. DBGP ( "pcnet32_irq_enable\n" );
  803. /* Enable TINT and RINT masks */
  804. val = priv->a->read_csr ( ioaddr, 3 );
  805. val &= ~( RxIntMask | TxIntMask );
  806. priv->a->write_csr ( ioaddr, 3, val );
  807. /* Enable interrupts */
  808. priv->a->write_csr ( ioaddr, 0, IntEnable );
  809. priv->irq_enabled = 1;
  810. }
  811. static void pcnet32_irq_disable ( struct pcnet32_private *priv )
  812. {
  813. unsigned long ioaddr = priv->pci_dev->ioaddr;
  814. DBGP ( "pcnet32_irq_disable\n" );
  815. priv->a->write_csr ( ioaddr, 0, 0x0000 );
  816. priv->irq_enabled = 0;
  817. }
  818. /**
  819. * irq - enable or disable interrupts
  820. *
  821. * @v netdev network adapter
  822. * @v action requested interrupt action
  823. **/
  824. static void
  825. pcnet32_irq ( struct net_device *netdev, int action )
  826. {
  827. struct pcnet32_private *priv = netdev_priv ( netdev );
  828. DBGP ( "pcnet32_irq\n" );
  829. switch ( action ) {
  830. case 0:
  831. pcnet32_irq_disable ( priv );
  832. break;
  833. default:
  834. pcnet32_irq_enable ( priv );
  835. break;
  836. }
  837. }
  838. static struct net_device_operations pcnet32_operations = {
  839. .open = pcnet32_open,
  840. .transmit = pcnet32_transmit,
  841. .poll = pcnet32_poll,
  842. .close = pcnet32_close,
  843. .irq = pcnet32_irq,
  844. };
  845. /**
  846. * probe - Initial configuration of NIC
  847. *
  848. * @v pdev PCI device
  849. * @v ent PCI IDs
  850. *
  851. * @ret rc Return status code
  852. **/
  853. static int
  854. pcnet32_probe ( struct pci_device *pdev )
  855. {
  856. struct net_device *netdev;
  857. struct pcnet32_private *priv;
  858. unsigned long ioaddr;
  859. int rc;
  860. DBGP ( "pcnet32_probe\n" );
  861. DBG ( "Found %s, vendor = %#04x, device = %#04x\n",
  862. pdev->id->name, pdev->id->vendor, pdev->id->device );
  863. /* Allocate our private data */
  864. netdev = alloc_etherdev ( sizeof ( *priv ) );
  865. if ( ! netdev ) {
  866. rc = -ENOMEM;
  867. goto err_alloc_etherdev;
  868. }
  869. /* Link our operations to the netdev struct */
  870. netdev_init ( netdev, &pcnet32_operations );
  871. /* Link the PCI device to the netdev struct */
  872. pci_set_drvdata ( pdev, netdev );
  873. netdev->dev = &pdev->dev;
  874. /* Get a reference to our private data */
  875. priv = netdev_priv ( netdev );
  876. /* We'll need these set up for the rest of the routines */
  877. priv->pci_dev = pdev;
  878. priv->netdev = netdev;
  879. ioaddr = pdev->ioaddr;
  880. /* Only use irqs under UNDI */
  881. priv->irq_enabled = 0;
  882. /* Reset the chip */
  883. pcnet32_wio_reset ( ioaddr );
  884. if ( ( rc = pcnet32_set_ops ( priv ) ) != 0 ) {
  885. DBG ( "Setting driver operations failed\n");
  886. goto err_set_ops;
  887. }
  888. if ( ( rc = pcnet32_chip_detect ( priv ) ) != 0 ) {
  889. DBG ( "pcnet32_chip_detect failed\n" );
  890. goto err_chip_detect;
  891. }
  892. /* Enter bus mastering mode */
  893. adjust_pci_device ( pdev );
  894. /* Verify and get MAC address */
  895. if ( ( rc = pcnet32_setup_mac_addr ( priv ) ) != 0 ) {
  896. DBG ( "Setting MAC address failed\n" );
  897. goto err_mac_addr;
  898. }
  899. DBG ( "IO Addr 0x%lX, MAC Addr %s\n", ioaddr,
  900. eth_ntoa ( netdev->hw_addr ) );
  901. priv->options = PCNET32_PORT_ASEL;
  902. /* Detect special T1/E1 WAN card by checking for MAC address */
  903. if ( netdev->hw_addr[0] == 0x00 &&
  904. netdev->hw_addr[1] == 0xE0 &&
  905. netdev->hw_addr[2] == 0x75 )
  906. priv->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
  907. /* Probe the PHY so we can check link state and speed */
  908. pcnet32_setup_probe_phy ( priv );
  909. if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
  910. DBG ( "Error registering netdev\n" );
  911. goto err_register;
  912. }
  913. netdev_link_up ( netdev );
  914. return 0;
  915. err_register:
  916. netdev_put ( netdev );
  917. err_chip_detect:
  918. err_set_ops:
  919. err_alloc_etherdev:
  920. err_mac_addr:
  921. return rc;
  922. }
  923. /**
  924. * remove - Device Removal Routine
  925. *
  926. * @v pdev PCI device information struct
  927. **/
  928. static void
  929. pcnet32_remove ( struct pci_device *pdev )
  930. {
  931. struct net_device *netdev = pci_get_drvdata ( pdev );
  932. unsigned long ioaddr = pdev->ioaddr;
  933. DBGP ( "pcnet32_remove\n" );
  934. /* Reset the chip */
  935. pcnet32_wio_reset ( ioaddr );
  936. unregister_netdev ( netdev );
  937. netdev_nullify ( netdev );
  938. netdev_put ( netdev );
  939. }
  940. static struct pci_device_id pcnet32_nics[] = {
  941. PCI_ROM(0x1022, 0x2000, "pcnet32", "AMD PCnet/PCI", 0),
  942. PCI_ROM(0x1022, 0x2625, "pcnetfastiii", "AMD PCNet FAST III", 0),
  943. PCI_ROM(0x1022, 0x2001, "amdhomepna", "AMD PCnet/HomePNA", 0),
  944. };
  945. struct pci_driver pcnet32_driver __pci_driver = {
  946. .ids = pcnet32_nics,
  947. .id_count = ARRAY_SIZE ( pcnet32_nics ),
  948. .probe = pcnet32_probe,
  949. .remove = pcnet32_remove,
  950. };