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

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162
  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,
  346. ( a->read_csr ( ioaddr, 80 ) & 0x0C00) | 0x0C00 );
  347. }
  348. priv->full_duplex = fdx;
  349. priv->mii = mii;
  350. return 0;
  351. err_unsupported:
  352. return rc;
  353. }
  354. /**
  355. * pcnet32_set_ops - Determines the ops used to access the registers
  356. *
  357. * @v priv Driver private structure
  358. *
  359. * @ret rc Returns 0 on success, negative on failure
  360. */
  361. static int
  362. pcnet32_set_ops ( struct pcnet32_private *priv )
  363. {
  364. int rc;
  365. unsigned long ioaddr;
  366. ioaddr = priv->pci_dev->ioaddr;
  367. /* Check if CSR0 has its default value and perform a write / read
  368. in the RAP register to see if it works. Based on these results
  369. determine what mode the NIC is in (WIO / DWIO)
  370. */
  371. rc = -ENODEV;
  372. if ( pcnet32_wio_read_csr ( ioaddr, 0 ) == 4 &&
  373. pcnet32_wio_check ( ioaddr ) ) {
  374. priv->a = &pcnet32_wio;
  375. } else {
  376. pcnet32_dwio_reset ( ioaddr );
  377. if ( pcnet32_dwio_read_csr ( ioaddr, 0 ) == 4 &&
  378. pcnet32_dwio_check ( ioaddr ) ) {
  379. priv->a = &pcnet32_dwio;
  380. } else {
  381. goto err_unsupported;
  382. }
  383. }
  384. return 0;
  385. err_unsupported:
  386. return rc;
  387. }
  388. /**
  389. * pcnet32_setup_init_block - setup the NICs initialization block
  390. *
  391. * @v priv Driver private structure
  392. *
  393. * @ret rc Returns 0 on success, negative on failure
  394. */
  395. static void
  396. pcnet32_setup_init_block ( struct pcnet32_private *priv )
  397. {
  398. int i;
  399. /* Configure the network port based on what we've established so far */
  400. priv->init_block.mode =
  401. cpu_to_le16 ( ( priv->options & PCNET32_PORT_PORTSEL ) << 7 );
  402. /* Setup RLEN and TLEN fields */
  403. priv->init_block.tlen_rlen =
  404. cpu_to_le16 ( ( PCNET32_LOG_RX_BUFFERS << 4 ) |
  405. ( PCNET32_LOG_TX_BUFFERS << 12 ) );
  406. /* Fill in physical address */
  407. for ( i = 0; i < ETH_ALEN; i++)
  408. priv->init_block.phys_addr[i] = priv->netdev->hw_addr[i];
  409. /* No multicasting scheme, accept everything */
  410. priv->init_block.filter[0] = 0xffffffff;
  411. priv->init_block.filter[1] = 0xffffffff;
  412. priv->init_block.rx_ring =
  413. cpu_to_le32 ( virt_to_bus ( priv->rx_base ) );
  414. priv->init_block.tx_ring =
  415. cpu_to_le32 ( virt_to_bus ( priv->tx_base ) );
  416. /* Make sure all changes are visible */
  417. wmb();
  418. }
  419. /**
  420. * pcnet32_setup_probe_phy - go through all PHYs and see which one is present
  421. *
  422. * @v priv Driver private structure
  423. */
  424. static void
  425. pcnet32_setup_probe_phy ( struct pcnet32_private *priv )
  426. {
  427. unsigned long ioaddr = priv->pci_dev->ioaddr;
  428. unsigned int phycount = 0;
  429. int phy_id;
  430. int i;
  431. if ( priv->mii ) {
  432. phy_id = ( ( priv->a->read_bcr ( ioaddr, 33 ) ) >> 5 ) & 0x1f;
  433. for ( i = 0; i < PCNET32_MAX_PHYS; i++ ) {
  434. unsigned short id1, id2;
  435. id1 = pcnet32_mdio_read ( priv->netdev, i, MII_PHYSID1 );
  436. if ( id1 == 0xffff )
  437. continue;
  438. id2 = pcnet32_mdio_read ( priv->netdev, i, MII_PHYSID2 );
  439. if ( id2 == 0xffff )
  440. continue;
  441. if ( i == 31 && ( ( priv->chip_version + 1 ) & 0xfffe ) == 0x2624 )
  442. continue;
  443. phycount++;
  444. phy_id = i;
  445. }
  446. priv->a->write_bcr ( ioaddr, 33, phy_id << 5 );
  447. if ( phycount > 1 )
  448. priv->options |= PCNET32_PORT_MII;
  449. }
  450. }
  451. /**
  452. * pcnet32_setup_mac_addr - check for inconsistency between CSR12-14
  453. * and PROM addresses
  454. *
  455. * @v priv Driver private structure
  456. */
  457. static int
  458. pcnet32_setup_mac_addr ( struct pcnet32_private *priv )
  459. {
  460. int i;
  461. u8 promaddr[ETH_ALEN];
  462. unsigned long ioaddr = priv->pci_dev->ioaddr;
  463. /* In most chips, after a chip reset, the ethernet address is read from
  464. * the station address PROM at the base address and programmed into the
  465. * "Physical Address Registers" CSR12-14.
  466. * As a precautionary measure, we read the PROM values and complain if
  467. * they disagree with the CSRs. If they miscompare, and the PROM addr
  468. * is valid, then the PROM addr is used.
  469. */
  470. for ( i = 0; i < 3; i++ ) {
  471. unsigned int val;
  472. val = priv->a->read_csr ( ioaddr, i + 12 ) & 0x0ffff;
  473. /* There may be endianness issues here. */
  474. priv->netdev->hw_addr[2 * i] = val & 0x0ff;
  475. priv->netdev->hw_addr[2 * i + 1] = ( val >> 8 ) & 0x0ff;
  476. }
  477. for ( i = 0; i < ETH_ALEN; i++ )
  478. promaddr[i] = inb ( ioaddr + i );
  479. if ( memcmp ( promaddr, priv->netdev->hw_addr, ETH_ALEN ) ||
  480. ! is_valid_ether_addr ( priv->netdev->hw_addr ) ) {
  481. if ( is_valid_ether_addr ( promaddr ) ) {
  482. DBG ( "CSR address is invalid, using PROM addr\n" );
  483. memcpy ( priv->netdev->hw_addr, promaddr, ETH_ALEN );
  484. }
  485. }
  486. /* If ethernet address is not valid, return error */
  487. if ( ! is_valid_ether_addr ( priv->netdev->hw_addr ) )
  488. return -EADDRNOTAVAIL;
  489. return 0;
  490. }
  491. /**
  492. * pcnet32_setup_if_duplex - Sets the NICs used interface and duplex mode
  493. *
  494. * @v priv Driver private structure
  495. */
  496. static void
  497. pcnet32_setup_if_duplex ( struct pcnet32_private *priv )
  498. {
  499. unsigned long ioaddr = priv->pci_dev->ioaddr;
  500. u16 val;
  501. /* Set/Reset autoselect bit */
  502. val = priv->a->read_bcr ( ioaddr, 2 ) & ~2;
  503. if ( priv->options & PCNET32_PORT_ASEL )
  504. val |= 2;
  505. priv->a->write_bcr ( ioaddr, 2, val );
  506. /* Handle full duplex setting */
  507. if ( priv->full_duplex ) {
  508. val = priv->a->read_bcr ( ioaddr, 9 ) & ~3;
  509. if ( priv->options & PCNET32_PORT_FD ) {
  510. val |= 1;
  511. if ( priv->options == ( PCNET32_PORT_FD | PCNET32_PORT_AUI ) )
  512. val |= 2;
  513. } else if ( priv->options & PCNET32_PORT_ASEL ) {
  514. /* Workaround of xSeries 250, on for 79C975 only */
  515. if ( priv->chip_version == 0x2627 )
  516. val |= 3;
  517. }
  518. priv->a->write_bcr ( ioaddr, 9, val );
  519. }
  520. /* Set/Reset GPSI bit in test register */
  521. val = priv->a->read_csr ( ioaddr, 124 ) & ~0x10;
  522. if ( ( priv->options & PCNET32_PORT_PORTSEL ) == PCNET32_PORT_GPSI )
  523. val |= 0x10;
  524. priv->a->write_bcr ( ioaddr, 124, val );
  525. /* Allied Telesyn AT are 100Mbit only and do not negotiate */
  526. u16 subsys_vend_id, subsys_dev_id;
  527. pci_read_config_word ( priv->pci_dev,
  528. PCI_SUBSYSTEM_VENDOR_ID,
  529. &subsys_vend_id );
  530. pci_read_config_word ( priv->pci_dev,
  531. PCI_SUBSYSTEM_ID,
  532. &subsys_dev_id );
  533. if ( subsys_vend_id == PCI_VENDOR_ID_AT &&
  534. ( ( subsys_dev_id == PCI_SUBDEVICE_ID_AT_2700FX ) ||
  535. ( subsys_dev_id == PCI_SUBDEVICE_ID_AT_2701FX ) ) ) {
  536. priv->options = PCNET32_PORT_FD | PCNET32_PORT_100;
  537. }
  538. if ( priv->mii && ! ( priv->options & PCNET32_PORT_ASEL ) ) {
  539. /* Disable Auto Negotiation, set 10Mbps, HD */
  540. val = priv->a->read_bcr ( ioaddr, 32 ) & ~0x38;
  541. if ( priv->options & PCNET32_PORT_FD )
  542. val |= 0x10;
  543. if ( priv->options & PCNET32_PORT_100 )
  544. val |= 0x08;
  545. priv->a->write_bcr ( ioaddr, 32, val );
  546. } else if ( priv->options & PCNET32_PORT_ASEL ) {
  547. /* 79C970 chips do not have the BCR32 register */
  548. if ( ( priv->chip_version != 0x2420 ) &&
  549. ( priv->chip_version != 0x2621 ) ) {
  550. /* Enable Auto Negotiation, setup, disable FD */
  551. val = priv->a->read_bcr ( ioaddr, 32 ) & ~0x98;
  552. val |= 0x20;
  553. priv->a->write_bcr ( ioaddr, 32, val );
  554. }
  555. }
  556. }
  557. /**
  558. * pcnet32_hw_start - Starts up the NIC
  559. *
  560. * @v priv Driver private structure
  561. */
  562. static void
  563. pcnet32_hw_start ( struct pcnet32_private *priv )
  564. {
  565. unsigned long ioaddr = priv->pci_dev->ioaddr;
  566. int i;
  567. /* Begin initialization procedure */
  568. priv->a->write_csr ( ioaddr, 0, Init );
  569. /* Wait for the initialization to be done */
  570. i = 0;
  571. while ( i++ < 100 )
  572. if ( priv->a->read_csr ( ioaddr, 0 ) & InitDone )
  573. break;
  574. /* Start the chip */
  575. priv->a->write_csr ( ioaddr, 0, Strt );
  576. }
  577. /**
  578. * open - Called when a network interface is made active
  579. *
  580. * @v netdev Network device
  581. * @ret rc Return status code, 0 on success, negative value on failure
  582. **/
  583. static int
  584. pcnet32_open ( struct net_device *netdev )
  585. {
  586. struct pcnet32_private *priv = netdev_priv ( netdev );
  587. unsigned long ioaddr = priv->pci_dev->ioaddr;
  588. int rc;
  589. u16 val;
  590. /* Setup TX and RX descriptors */
  591. if ( ( rc = pcnet32_setup_tx_resources ( priv ) ) != 0 ) {
  592. DBG ( "Error setting up TX resources\n" );
  593. goto err_setup_tx;
  594. }
  595. if ( ( rc = pcnet32_setup_rx_resources ( priv ) ) != 0 ) {
  596. DBG ( "Error setting up RX resources\n" );
  597. goto err_setup_rx;
  598. }
  599. /* Reset the chip */
  600. priv->a->reset ( ioaddr );
  601. /* Switch pcnet32 to 32bit mode */
  602. priv->a->write_bcr ( ioaddr, 20, PCNET32_SWSTYLE_PCNET32 );
  603. /* Setup the interface and duplex mode */
  604. pcnet32_setup_if_duplex ( priv );
  605. /* Disable interrupts */
  606. val = priv->a->read_csr ( ioaddr, 3 );
  607. val |= BablMask | MissFrameMask | RxIntMask | TxIntMask | InitDoneMask;
  608. priv->a->write_csr ( ioaddr, 3, val );
  609. /* Setup initialization block */
  610. pcnet32_setup_init_block ( priv );
  611. /* Fill in the address of the initialization block */
  612. priv->a->write_csr ( ioaddr, 1,
  613. ( virt_to_bus ( &priv->init_block ) ) & 0xffff );
  614. priv->a->write_csr ( ioaddr, 2,
  615. ( virt_to_bus ( &priv->init_block ) ) >> 16 );
  616. /* Enable Auto-Pad, disable interrupts */
  617. priv->a->write_csr ( ioaddr, 4, 0x0915 );
  618. pcnet32_hw_start ( priv );
  619. return 0;
  620. err_setup_rx:
  621. pcnet32_free_tx_resources ( priv );
  622. err_setup_tx:
  623. priv->a->reset( priv->pci_dev->ioaddr );
  624. return rc;
  625. }
  626. /**
  627. * transmit - Transmit a packet
  628. *
  629. * @v netdev Network device
  630. * @v iobuf I/O buffer
  631. *
  632. * @ret rc Returns 0 on success, negative on failure
  633. */
  634. static int
  635. pcnet32_transmit ( struct net_device *netdev, struct io_buffer *iobuf )
  636. {
  637. struct pcnet32_private *priv = netdev_priv ( netdev );
  638. unsigned long ioaddr = priv->pci_dev->ioaddr;
  639. uint32_t tx_len = iob_len ( iobuf );
  640. struct pcnet32_tx_desc *tx_curr_desc;
  641. DBGP ( "pcnet32_transmit\n" );
  642. if ( priv->tx_fill_ctr == TX_RING_SIZE ) {
  643. DBG ( "Tx overflow\n" );
  644. return -ENOTSUP;
  645. }
  646. priv->tx_iobuf[priv->tx_curr] = iobuf;
  647. tx_curr_desc = priv->tx_base + priv->tx_curr;
  648. /* Configure current descriptor to transmit packet */
  649. tx_curr_desc->length = cpu_to_le16 ( -tx_len );
  650. tx_curr_desc->misc = 0x00000000;
  651. tx_curr_desc->base = cpu_to_le32 ( virt_to_bus ( iobuf->data ) );
  652. /* Owner changes after the other status fields are set */
  653. wmb();
  654. tx_curr_desc->status =
  655. cpu_to_le16 ( DescOwn | StartOfPacket | EndOfPacket );
  656. /* Trigger an immediate send poll */
  657. priv->a->write_csr ( ioaddr, 0,
  658. ( priv->irq_enabled ? IntEnable : 0 ) | TxDemand );
  659. /* Point to the next free descriptor */
  660. priv->tx_curr = ( priv->tx_curr + 1 ) % TX_RING_SIZE;
  661. /* Increment number of tx descriptors in use */
  662. priv->tx_fill_ctr++;
  663. return 0;
  664. }
  665. /**
  666. * pcnet32_process_tx_packets - Checks for successfully sent packets,
  667. * reports them to iPXE with netdev_tx_complete()
  668. *
  669. * @v netdev Network device
  670. */
  671. static void
  672. pcnet32_process_tx_packets ( struct net_device *netdev )
  673. {
  674. struct pcnet32_private *priv = netdev_priv ( netdev );
  675. struct pcnet32_tx_desc *tx_curr_desc;
  676. DBGP ( "pcnet32_process_tx_packets\n" );
  677. while ( priv->tx_tail != priv->tx_curr ) {
  678. tx_curr_desc = priv->tx_base + priv->tx_tail;
  679. u16 status = le16_to_cpu ( tx_curr_desc->status );
  680. DBG ( "Before OWN bit check, status: %#08x\n", status );
  681. /* Skip this descriptor if hardware still owns it */
  682. if ( status & DescOwn )
  683. break;
  684. DBG ( "Transmitted packet.\n" );
  685. DBG ( "priv->tx_fill_ctr= %d\n", priv->tx_fill_ctr );
  686. DBG ( "priv->tx_tail = %d\n", priv->tx_tail );
  687. DBG ( "priv->tx_curr = %d\n", priv->tx_curr );
  688. DBG ( "tx_curr_desc = %#08lx\n", virt_to_bus ( tx_curr_desc ) );
  689. /* This packet is ready for completion */
  690. netdev_tx_complete ( netdev, priv->tx_iobuf[priv->tx_tail]);
  691. /* Clear the descriptor */
  692. memset ( tx_curr_desc, 0, sizeof(*tx_curr_desc) );
  693. /* Reduce the number of tx descriptors in use */
  694. priv->tx_fill_ctr--;
  695. /* Go to next available descriptor */
  696. priv->tx_tail = ( priv->tx_tail + 1 ) % TX_RING_SIZE;
  697. }
  698. }
  699. /**
  700. * pcnet32_process_rx_packets - Checks for received packets, reports them
  701. * to iPXE with netdev_rx() or netdev_rx_err() if there was an error receiving
  702. * the packet
  703. *
  704. * @v netdev Network device
  705. */
  706. static void
  707. pcnet32_process_rx_packets ( struct net_device *netdev )
  708. {
  709. struct pcnet32_private *priv = netdev_priv ( netdev );
  710. struct pcnet32_rx_desc *rx_curr_desc;
  711. u16 status;
  712. u32 len;
  713. int i;
  714. DBGP ( "pcnet32_process_rx_packets\n" );
  715. for ( i = 0; i < RX_RING_SIZE; i++ ) {
  716. rx_curr_desc = priv->rx_base + priv->rx_curr;
  717. status = le16_to_cpu ( rx_curr_desc->status );
  718. rmb();
  719. DBG ( "Before OWN bit check, status: %#08x\n", status );
  720. /* Skip this descriptor if hardware still owns it */
  721. if ( status & DescOwn )
  722. break;
  723. /* We own the descriptor, but it has not been refilled yet */
  724. if ( priv->rx_iobuf[priv->rx_curr] == NULL )
  725. break;
  726. DBG ( "Received packet.\n" );
  727. DBG ( "priv->rx_curr = %d\n", priv->rx_curr );
  728. DBG ( "rx_len = %d\n",
  729. ( le32_to_cpu ( rx_curr_desc->msg_length ) & 0xfff ) - 4 );
  730. DBG ( "rx_curr_desc = %#08lx\n",
  731. virt_to_bus ( rx_curr_desc ) );
  732. /* Check ERR bit */
  733. if ( status & 0x4000 ) {
  734. netdev_rx_err ( netdev, priv->rx_iobuf[priv->rx_curr],
  735. -EINVAL );
  736. DBG ( "Corrupted packet received!\n");
  737. } else {
  738. /* Adjust size of the iobuf to reflect received data */
  739. len = ( le32_to_cpu ( rx_curr_desc->msg_length ) & 0xfff ) - 4;
  740. iob_put ( priv->rx_iobuf[priv->rx_curr], len );
  741. /* Add this packet to the receive queue */
  742. netdev_rx ( netdev, priv->rx_iobuf[priv->rx_curr] );
  743. }
  744. /* Invalidate iobuf and descriptor */
  745. priv->rx_iobuf[priv->rx_curr] = NULL;
  746. memset ( rx_curr_desc, 0, sizeof(*rx_curr_desc) );
  747. /* Point to the next free descriptor */
  748. priv->rx_curr = ( priv->rx_curr + 1 ) % RX_RING_SIZE;
  749. }
  750. /* Allocate new iobufs where needed */
  751. pcnet32_refill_rx_ring ( priv );
  752. }
  753. /**
  754. * poll - Poll for received packets
  755. *
  756. * @v netdev Network device
  757. */
  758. static void
  759. pcnet32_poll ( struct net_device *netdev )
  760. {
  761. struct pcnet32_private *priv = netdev_priv ( netdev );
  762. unsigned long ioaddr = priv->pci_dev->ioaddr;
  763. u16 status;
  764. DBGP ( "pcnet32_poll\n" );
  765. status = priv->a->read_csr ( ioaddr, 0 );
  766. /* Clear interrupts */
  767. priv->a->write_csr ( ioaddr, 0, status );
  768. DBG ( "pcnet32_poll: mask = %#04x, status = %#04x\n",
  769. priv->a->read_csr ( ioaddr, 3 ), status );
  770. /* Return when RINT or TINT are not set */
  771. if ( ( status & 0x0500 ) == 0x0000 )
  772. return;
  773. /* Process transmitted packets */
  774. pcnet32_process_tx_packets ( netdev );
  775. /* Process received packets */
  776. pcnet32_process_rx_packets ( netdev );
  777. }
  778. /**
  779. * close - Disable network interface
  780. *
  781. * @v netdev network interface device structure
  782. **/
  783. static void
  784. pcnet32_close ( struct net_device *netdev )
  785. {
  786. struct pcnet32_private *priv = netdev_priv ( netdev );
  787. unsigned long ioaddr = priv->pci_dev->ioaddr;
  788. DBGP ( "pcnet32_close\n" );
  789. /* Reset the chip */
  790. pcnet32_wio_reset ( ioaddr );
  791. /* Stop the PCNET32 - it occasionally polls memory if we don't */
  792. priv->a->write_csr ( ioaddr, 0, Stop );
  793. /* Switch back to 16bit mode to avoid problems with dumb
  794. * DOS packet driver after a warm reboot */
  795. priv->a->write_bcr ( ioaddr, 20, PCNET32_SWSTYLE_LANCE );
  796. pcnet32_free_rx_resources ( priv );
  797. pcnet32_free_tx_resources ( priv );
  798. }
  799. static void pcnet32_irq_enable ( struct pcnet32_private *priv )
  800. {
  801. unsigned long ioaddr = priv->pci_dev->ioaddr;
  802. u16 val;
  803. DBGP ( "pcnet32_irq_enable\n" );
  804. /* Enable TINT and RINT masks */
  805. val = priv->a->read_csr ( ioaddr, 3 );
  806. val &= ~( RxIntMask | TxIntMask );
  807. priv->a->write_csr ( ioaddr, 3, val );
  808. /* Enable interrupts */
  809. priv->a->write_csr ( ioaddr, 0, IntEnable );
  810. priv->irq_enabled = 1;
  811. }
  812. static void pcnet32_irq_disable ( struct pcnet32_private *priv )
  813. {
  814. unsigned long ioaddr = priv->pci_dev->ioaddr;
  815. DBGP ( "pcnet32_irq_disable\n" );
  816. priv->a->write_csr ( ioaddr, 0, 0x0000 );
  817. priv->irq_enabled = 0;
  818. }
  819. /**
  820. * irq - enable or disable interrupts
  821. *
  822. * @v netdev network adapter
  823. * @v action requested interrupt action
  824. **/
  825. static void
  826. pcnet32_irq ( struct net_device *netdev, int action )
  827. {
  828. struct pcnet32_private *priv = netdev_priv ( netdev );
  829. DBGP ( "pcnet32_irq\n" );
  830. switch ( action ) {
  831. case 0:
  832. pcnet32_irq_disable ( priv );
  833. break;
  834. default:
  835. pcnet32_irq_enable ( priv );
  836. break;
  837. }
  838. }
  839. static struct net_device_operations pcnet32_operations = {
  840. .open = pcnet32_open,
  841. .transmit = pcnet32_transmit,
  842. .poll = pcnet32_poll,
  843. .close = pcnet32_close,
  844. .irq = pcnet32_irq,
  845. };
  846. /**
  847. * probe - Initial configuration of NIC
  848. *
  849. * @v pdev PCI device
  850. * @v ent PCI IDs
  851. *
  852. * @ret rc Return status code
  853. **/
  854. static int
  855. pcnet32_probe ( struct pci_device *pdev )
  856. {
  857. struct net_device *netdev;
  858. struct pcnet32_private *priv;
  859. unsigned long ioaddr;
  860. int rc;
  861. DBGP ( "pcnet32_probe\n" );
  862. DBG ( "Found %s, vendor = %#04x, device = %#04x\n",
  863. pdev->id->name, pdev->id->vendor, pdev->id->device );
  864. /* Allocate our private data */
  865. netdev = alloc_etherdev ( sizeof ( *priv ) );
  866. if ( ! netdev ) {
  867. rc = -ENOMEM;
  868. goto err_alloc_etherdev;
  869. }
  870. /* Link our operations to the netdev struct */
  871. netdev_init ( netdev, &pcnet32_operations );
  872. /* Link the PCI device to the netdev struct */
  873. pci_set_drvdata ( pdev, netdev );
  874. netdev->dev = &pdev->dev;
  875. /* Get a reference to our private data */
  876. priv = netdev_priv ( netdev );
  877. /* We'll need these set up for the rest of the routines */
  878. priv->pci_dev = pdev;
  879. priv->netdev = netdev;
  880. ioaddr = pdev->ioaddr;
  881. /* Only use irqs under UNDI */
  882. priv->irq_enabled = 0;
  883. /* Reset the chip */
  884. pcnet32_wio_reset ( ioaddr );
  885. if ( ( rc = pcnet32_set_ops ( priv ) ) != 0 ) {
  886. DBG ( "Setting driver operations failed\n");
  887. goto err_set_ops;
  888. }
  889. if ( ( rc = pcnet32_chip_detect ( priv ) ) != 0 ) {
  890. DBG ( "pcnet32_chip_detect failed\n" );
  891. goto err_chip_detect;
  892. }
  893. /* Enter bus mastering mode */
  894. adjust_pci_device ( pdev );
  895. /* Verify and get MAC address */
  896. if ( ( rc = pcnet32_setup_mac_addr ( priv ) ) != 0 ) {
  897. DBG ( "Setting MAC address failed\n" );
  898. goto err_mac_addr;
  899. }
  900. DBG ( "IO Addr 0x%lX, MAC Addr %s\n", ioaddr,
  901. eth_ntoa ( netdev->hw_addr ) );
  902. priv->options = PCNET32_PORT_ASEL;
  903. /* Detect special T1/E1 WAN card by checking for MAC address */
  904. if ( netdev->hw_addr[0] == 0x00 &&
  905. netdev->hw_addr[1] == 0xE0 &&
  906. netdev->hw_addr[2] == 0x75 )
  907. priv->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
  908. /* Probe the PHY so we can check link state and speed */
  909. pcnet32_setup_probe_phy ( priv );
  910. if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
  911. DBG ( "Error registering netdev\n" );
  912. goto err_register;
  913. }
  914. netdev_link_up ( netdev );
  915. return 0;
  916. err_register:
  917. netdev_put ( netdev );
  918. err_chip_detect:
  919. err_set_ops:
  920. err_alloc_etherdev:
  921. err_mac_addr:
  922. return rc;
  923. }
  924. /**
  925. * remove - Device Removal Routine
  926. *
  927. * @v pdev PCI device information struct
  928. **/
  929. static void
  930. pcnet32_remove ( struct pci_device *pdev )
  931. {
  932. struct net_device *netdev = pci_get_drvdata ( pdev );
  933. unsigned long ioaddr = pdev->ioaddr;
  934. DBGP ( "pcnet32_remove\n" );
  935. /* Reset the chip */
  936. pcnet32_wio_reset ( ioaddr );
  937. unregister_netdev ( netdev );
  938. netdev_nullify ( netdev );
  939. netdev_put ( netdev );
  940. }
  941. static struct pci_device_id pcnet32_nics[] = {
  942. PCI_ROM(0x1022, 0x2000, "pcnet32", "AMD PCnet/PCI", 0),
  943. PCI_ROM(0x1022, 0x2625, "pcnetfastiii", "AMD PCNet FAST III", 0),
  944. PCI_ROM(0x1022, 0x2001, "amdhomepna", "AMD PCnet/HomePNA", 0),
  945. };
  946. struct pci_driver pcnet32_driver __pci_driver = {
  947. .ids = pcnet32_nics,
  948. .id_count = ARRAY_SIZE ( pcnet32_nics ),
  949. .probe = pcnet32_probe,
  950. .remove = pcnet32_remove,
  951. };