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