1 /* -*- Mode:C; c-basic-offset:4; -*- */
2
3 /*
4 natsemi.c: An Etherboot driver for the NatSemi DP8381x series.
5
6 Copyright (C) 2001 Entity Cyber, Inc.
7
8 This development of this Etherboot driver was funded by
9
10 Sicom Systems: http://www.sicompos.com/
11
12 Author: Marty Connor (mdc@thinguin.org)
13 Adapted from a Linux driver which was written by Donald Becker
14
15 This software may be used and distributed according to the terms
16 of the GNU Public License (GPL), incorporated herein by reference.
17
18 Original Copyright Notice:
19
20 Written/copyright 1999-2001 by Donald Becker.
21
22 This software may be used and distributed according to the terms of
23 the GNU General Public License (GPL), incorporated herein by reference.
24 Drivers based on or derived from this code fall under the GPL and must
25 retain the authorship, copyright and license notice. This file is not
26 a complete program and may only be used when the entire operating
27 system is licensed under the GPL. License for under other terms may be
28 available. Contact the original author for details.
29
30 The original author may be reached as becker@scyld.com, or at
31 Scyld Computing Corporation
32 410 Severn Ave., Suite 210
33 Annapolis MD 21403
34
35 Support information and updates available at
36 http://www.scyld.com/network/netsemi.html
37
38 References:
39
40 http://www.scyld.com/expert/100mbps.html
41 http://www.scyld.com/expert/NWay.html
42 Datasheet is available from:
43 http://www.national.com/pf/DP/DP83815.html
44
45 */
46
47 /* Revision History */
48
49 /*
50 13 Dec 2003 timlegge 1.1 Enabled Multicast Support
51 29 May 2001 mdc 1.0
52 Initial Release. Tested with Netgear FA311 and FA312 boards
53 */
54 /* Includes */
55
56 #include "etherboot.h"
57 #include "nic.h"
58 #include "pci.h"
59
60 /* defines */
61
62 #define OWN 0x80000000
63 #define DSIZE 0x00000FFF
64 #define CRC_SIZE 4
65
66 /* Time in ticks before concluding the transmitter is hung. */
67 #define TX_TIMEOUT (4*TICKS_PER_SEC)
68
69 #define TX_BUF_SIZE 1536
70 #define RX_BUF_SIZE 1536
71
72 #define NUM_RX_DESC 4 /* Number of Rx descriptor registers. */
73
74 typedef uint8_t u8;
75 typedef int8_t s8;
76 typedef uint16_t u16;
77 typedef int16_t s16;
78 typedef uint32_t u32;
79 typedef int32_t s32;
80
81 /* helpful macroes if on a big_endian machine for changing byte order.
82 not strictly needed on Intel */
83 #define get_unaligned(ptr) (*(ptr))
84 #define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
85 #define get_u16(ptr) (*(u16 *)(ptr))
86 #define virt_to_le32desc(addr) virt_to_bus(addr)
87
88 enum pcistuff {
89 PCI_USES_IO = 0x01,
90 PCI_USES_MEM = 0x02,
91 PCI_USES_MASTER = 0x04,
92 PCI_ADDR0 = 0x08,
93 PCI_ADDR1 = 0x10,
94 };
95
96 /* MMIO operations required */
97 #define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1)
98
99 /* Offsets to the device registers.
100 Unlike software-only systems, device drivers interact with complex hardware.
101 It's not useful to define symbolic names for every register bit in the
102 device.
103 */
104 enum register_offsets {
105 ChipCmd = 0x00,
106 ChipConfig = 0x04,
107 EECtrl = 0x08,
108 PCIBusCfg = 0x0C,
109 IntrStatus = 0x10,
110 IntrMask = 0x14,
111 IntrEnable = 0x18,
112 TxRingPtr = 0x20,
113 TxConfig = 0x24,
114 RxRingPtr = 0x30,
115 RxConfig = 0x34,
116 ClkRun = 0x3C,
117 WOLCmd = 0x40,
118 PauseCmd = 0x44,
119 RxFilterAddr = 0x48,
120 RxFilterData = 0x4C,
121 BootRomAddr = 0x50,
122 BootRomData = 0x54,
123 SiliconRev = 0x58,
124 StatsCtrl = 0x5C,
125 StatsData = 0x60,
126 RxPktErrs = 0x60,
127 RxMissed = 0x68,
128 RxCRCErrs = 0x64,
129 PCIPM = 0x44,
130 PhyStatus = 0xC0,
131 MIntrCtrl = 0xC4,
132 MIntrStatus = 0xC8,
133
134 /* These are from the spec, around page 78... on a separate table. */
135 PGSEL = 0xCC,
136 PMDCSR = 0xE4,
137 TSTDAT = 0xFC,
138 DSPCFG = 0xF4,
139 SDCFG = 0x8C
140 };
141
142 /* Bit in ChipCmd. */
143 enum ChipCmdBits {
144 ChipReset = 0x100,
145 RxReset = 0x20,
146 TxReset = 0x10,
147 RxOff = 0x08,
148 RxOn = 0x04,
149 TxOff = 0x02,
150 TxOn = 0x01
151 };
152
153 /* Bits in the RxMode register. */
154 enum rx_mode_bits {
155 AcceptErr = 0x20,
156 AcceptRunt = 0x10,
157 AcceptBroadcast = 0xC0000000,
158 AcceptMulticast = 0x00200000,
159 AcceptAllMulticast = 0x20000000,
160 AcceptAllPhys = 0x10000000,
161 AcceptMyPhys = 0x08000000,
162 RxFilterEnable = 0x80000000
163 };
164
165 typedef struct _BufferDesc {
166 u32 link;
167 volatile u32 cmdsts;
168 u32 bufptr;
169 u32 software_use;
170 } BufferDesc;
171
172 /* Bits in network_desc.status */
173 enum desc_status_bits {
174 DescOwn = 0x80000000,
175 DescMore = 0x40000000,
176 DescIntr = 0x20000000,
177 DescNoCRC = 0x10000000,
178 DescPktOK = 0x08000000,
179 RxTooLong = 0x00400000
180 };
181
182 /* Globals */
183
184 static int natsemi_debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */
185
186 const char *nic_name;
187
188 static u32 SavedClkRun;
189
190
191 static unsigned short vendor, dev_id;
192 static unsigned long ioaddr;
193
194 static unsigned int cur_rx;
195
196 static unsigned int advertising;
197
198 static unsigned int rx_config;
199 static unsigned int tx_config;
200
201 /* Note: transmit and receive buffers and descriptors must be
202 longword aligned
203 */
204
205 static BufferDesc txd __attribute__ ((aligned(4)));
206 static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(4)));
207
208 static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(4)));
209 static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE] __attribute__ ((aligned(4)));
210
211 /* Function Prototypes */
212
213 static int natsemi_probe(struct dev *dev, struct pci_device *pci);
214 static int eeprom_read(long addr, int location);
215 static int mdio_read(int phy_id, int location);
216 static void natsemi_init(struct nic *nic);
217 static void natsemi_reset(struct nic *nic);
218 static void natsemi_init_rxfilter(struct nic *nic);
219 static void natsemi_init_txd(struct nic *nic);
220 static void natsemi_init_rxd(struct nic *nic);
221 static void natsemi_set_rx_mode(struct nic *nic);
222 static void natsemi_check_duplex(struct nic *nic);
223 static void natsemi_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p);
224 static int natsemi_poll(struct nic *nic, int retrieve);
225 static void natsemi_disable(struct dev *dev);
226 static void natsemi_irq(struct nic *nic, irq_action_t action);
227
228 /*
229 * Function: natsemi_probe
230 *
231 * Description: Retrieves the MAC address of the card, and sets up some
232 * globals required by other routines, and initializes the NIC, making it
233 * ready to send and receive packets.
234 *
235 * Side effects:
236 * leaves the ioaddress of the natsemi chip in the variable ioaddr.
237 * leaves the natsemi initialized, and ready to recieve packets.
238 *
239 * Returns: struct nic *: pointer to NIC data structure
240 */
241
242 static int
natsemi_probe(struct dev * dev,struct pci_device * pci)243 natsemi_probe(struct dev *dev, struct pci_device *pci)
244 {
245 struct nic *nic = (struct nic *)dev;
246 int i;
247 int prev_eedata;
248 u32 tmp;
249
250 if (pci->ioaddr == 0)
251 return 0;
252
253 adjust_pci_device(pci);
254
255 /* initialize some commonly used globals */
256
257 nic->irqno = 0;
258 nic->ioaddr = pci->ioaddr & ~3;
259
260 ioaddr = pci->ioaddr & ~3;
261 vendor = pci->vendor;
262 dev_id = pci->dev_id;
263 nic_name = pci->name;
264
265 /* natsemi has a non-standard PM control register
266 * in PCI config space. Some boards apparently need
267 * to be brought to D0 in this manner.
268 */
269 pcibios_read_config_dword(pci->bus, pci->devfn, PCIPM, &tmp);
270 if (tmp & (0x03|0x100)) {
271 /* D0 state, disable PME assertion */
272 u32 newtmp = tmp & ~(0x03|0x100);
273 pcibios_write_config_dword(pci->bus, pci->devfn, PCIPM, newtmp);
274 }
275
276 /* get MAC address */
277
278 prev_eedata = eeprom_read(ioaddr, 6);
279 for (i = 0; i < 3; i++) {
280 int eedata = eeprom_read(ioaddr, i + 7);
281 nic->node_addr[i*2] = (eedata << 1) + (prev_eedata >> 15);
282 nic->node_addr[i*2+1] = eedata >> 7;
283 prev_eedata = eedata;
284 }
285
286 printf("\nnatsemi_probe: MAC addr %! at ioaddr %#hX\n",
287 nic->node_addr, ioaddr);
288 printf("natsemi_probe: Vendor:%#hX Device:%#hX\n", vendor, dev_id);
289
290 /* Reset the chip to erase any previous misconfiguration. */
291 outl(ChipReset, ioaddr + ChipCmd);
292
293 advertising = mdio_read(1, 4);
294 {
295 u32 chip_config = inl(ioaddr + ChipConfig);
296 printf("%s: Transceiver default autoneg. %s "
297 "10%s %s duplex.\n",
298 nic_name,
299 chip_config & 0x2000 ? "enabled, advertise" : "disabled, force",
300 chip_config & 0x4000 ? "0" : "",
301 chip_config & 0x8000 ? "full" : "half");
302 }
303 printf("%s: Transceiver status %hX advertising %hX\n",
304 nic_name, (int)inl(ioaddr + 0x84), advertising);
305
306 /* Disable PME:
307 * The PME bit is initialized from the EEPROM contents.
308 * PCI cards probably have PME disabled, but motherboard
309 * implementations may have PME set to enable WakeOnLan.
310 * With PME set the chip will scan incoming packets but
311 * nothing will be written to memory. */
312 SavedClkRun = inl(ioaddr + ClkRun);
313 outl(SavedClkRun & ~0x100, ioaddr + ClkRun);
314
315 /* initialize device */
316 natsemi_init(nic);
317
318 dev->disable = natsemi_disable;
319 nic->poll = natsemi_poll;
320 nic->transmit = natsemi_transmit;
321 nic->irq = natsemi_irq;
322
323 return 1;
324 }
325
326 /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
327 The EEPROM code is for the common 93c06/46 EEPROMs with 6 bit addresses.
328 */
329
330 /* Delay between EEPROM clock transitions.
331 No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
332 a delay. */
333 #define eeprom_delay(ee_addr) inl(ee_addr)
334
335 enum EEPROM_Ctrl_Bits {
336 EE_ShiftClk = 0x04,
337 EE_DataIn = 0x01,
338 EE_ChipSelect = 0x08,
339 EE_DataOut = 0x02
340 };
341
342 #define EE_Write0 (EE_ChipSelect)
343 #define EE_Write1 (EE_ChipSelect | EE_DataIn)
344
345 /* The EEPROM commands include the alway-set leading bit. */
346 enum EEPROM_Cmds {
347 EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
348 };
349
eeprom_read(long addr,int location)350 static int eeprom_read(long addr, int location)
351 {
352 int i;
353 int retval = 0;
354 int ee_addr = addr + EECtrl;
355 int read_cmd = location | EE_ReadCmd;
356 outl(EE_Write0, ee_addr);
357
358 /* Shift the read command bits out. */
359 for (i = 10; i >= 0; i--) {
360 short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
361 outl(dataval, ee_addr);
362 eeprom_delay(ee_addr);
363 outl(dataval | EE_ShiftClk, ee_addr);
364 eeprom_delay(ee_addr);
365 }
366 outl(EE_ChipSelect, ee_addr);
367 eeprom_delay(ee_addr);
368
369 for (i = 0; i < 16; i++) {
370 outl(EE_ChipSelect | EE_ShiftClk, ee_addr);
371 eeprom_delay(ee_addr);
372 retval |= (inl(ee_addr) & EE_DataOut) ? 1 << i : 0;
373 outl(EE_ChipSelect, ee_addr);
374 eeprom_delay(ee_addr);
375 }
376
377 /* Terminate the EEPROM access. */
378 outl(EE_Write0, ee_addr);
379 outl(0, ee_addr);
380
381 return retval;
382 }
383
384 /* MII transceiver control section.
385 The 83815 series has an internal transceiver, and we present the
386 management registers as if they were MII connected. */
387
mdio_read(int phy_id,int location)388 static int mdio_read(int phy_id, int location)
389 {
390 if (phy_id == 1 && location < 32)
391 return inl(ioaddr + 0x80 + (location<<2)) & 0xffff;
392 else
393 return 0xffff;
394 }
395
396 /* Function: natsemi_init
397 *
398 * Description: resets the ethernet controller chip and configures
399 * registers and data structures required for sending and receiving packets.
400 *
401 * Arguments: struct nic *nic: NIC data structure
402 *
403 * returns: void.
404 */
405
406 static void
natsemi_init(struct nic * nic)407 natsemi_init(struct nic *nic)
408 {
409 natsemi_reset(nic);
410
411 /* Disable PME:
412 * The PME bit is initialized from the EEPROM contents.
413 * PCI cards probably have PME disabled, but motherboard
414 * implementations may have PME set to enable WakeOnLan.
415 * With PME set the chip will scan incoming packets but
416 * nothing will be written to memory. */
417 outl(SavedClkRun & ~0x100, ioaddr + ClkRun);
418
419 natsemi_init_rxfilter(nic);
420
421 natsemi_init_txd(nic);
422 natsemi_init_rxd(nic);
423
424 /* Initialize other registers. */
425 /* Configure the PCI bus bursts and FIFO thresholds. */
426 /* Configure for standard, in-spec Ethernet. */
427 if (inl(ioaddr + ChipConfig) & 0x20000000) { /* Full duplex */
428 tx_config = 0xD0801002;
429 rx_config = 0x10000020;
430 } else {
431 tx_config = 0x10801002;
432 rx_config = 0x0020;
433 }
434 outl(tx_config, ioaddr + TxConfig);
435 outl(rx_config, ioaddr + RxConfig);
436
437 natsemi_check_duplex(nic);
438 natsemi_set_rx_mode(nic);
439
440 outl(RxOn, ioaddr + ChipCmd);
441 }
442
443 /*
444 * Function: natsemi_reset
445 *
446 * Description: soft resets the controller chip
447 *
448 * Arguments: struct nic *nic: NIC data structure
449 *
450 * Returns: void.
451 */
452 static void
natsemi_reset(struct nic * nic __unused)453 natsemi_reset(struct nic *nic __unused)
454 {
455 outl(ChipReset, ioaddr + ChipCmd);
456
457 /* On page 78 of the spec, they recommend some settings for "optimum
458 performance" to be done in sequence. These settings optimize some
459 of the 100Mbit autodetection circuitry. Also, we only want to do
460 this for rev C of the chip.
461 */
462 if (inl(ioaddr + SiliconRev) == 0x302) {
463 outw(0x0001, ioaddr + PGSEL);
464 outw(0x189C, ioaddr + PMDCSR);
465 outw(0x0000, ioaddr + TSTDAT);
466 outw(0x5040, ioaddr + DSPCFG);
467 outw(0x008C, ioaddr + SDCFG);
468 }
469 /* Disable interrupts using the mask. */
470 outl(0, ioaddr + IntrMask);
471 outl(0, ioaddr + IntrEnable);
472 }
473
474 /* Function: natsemi_init_rxfilter
475 *
476 * Description: sets receive filter address to our MAC address
477 *
478 * Arguments: struct nic *nic: NIC data structure
479 *
480 * returns: void.
481 */
482
483 static void
natsemi_init_rxfilter(struct nic * nic)484 natsemi_init_rxfilter(struct nic *nic)
485 {
486 int i;
487
488 for (i = 0; i < ETH_ALEN; i += 2) {
489 outl(i, ioaddr + RxFilterAddr);
490 outw(nic->node_addr[i] + (nic->node_addr[i+1] << 8), ioaddr + RxFilterData);
491 }
492 }
493
494 /*
495 * Function: natsemi_init_txd
496 *
497 * Description: initializes the Tx descriptor
498 *
499 * Arguments: struct nic *nic: NIC data structure
500 *
501 * returns: void.
502 */
503
504 static void
natsemi_init_txd(struct nic * nic __unused)505 natsemi_init_txd(struct nic *nic __unused)
506 {
507 txd.link = (u32) 0;
508 txd.cmdsts = (u32) 0;
509 txd.bufptr = virt_to_bus(&txb[0]);
510
511 /* load Transmit Descriptor Register */
512 outl(virt_to_bus(&txd), ioaddr + TxRingPtr);
513 if (natsemi_debug > 1)
514 printf("natsemi_init_txd: TX descriptor register loaded with: %X\n",
515 inl(ioaddr + TxRingPtr));
516 }
517
518 /* Function: natsemi_init_rxd
519 *
520 * Description: initializes the Rx descriptor ring
521 *
522 * Arguments: struct nic *nic: NIC data structure
523 *
524 * Returns: void.
525 */
526
527 static void
natsemi_init_rxd(struct nic * nic __unused)528 natsemi_init_rxd(struct nic *nic __unused)
529 {
530 int i;
531
532 cur_rx = 0;
533
534 /* init RX descriptor */
535 for (i = 0; i < NUM_RX_DESC; i++) {
536 rxd[i].link = virt_to_bus((i+1 < NUM_RX_DESC) ? &rxd[i+1] : &rxd[0]);
537 rxd[i].cmdsts = (u32) RX_BUF_SIZE;
538 rxd[i].bufptr = virt_to_bus(&rxb[i*RX_BUF_SIZE]);
539 if (natsemi_debug > 1)
540 printf("natsemi_init_rxd: rxd[%d]=%X link=%X cmdsts=%X bufptr=%X\n",
541 i, &rxd[i], rxd[i].link, rxd[i].cmdsts, rxd[i].bufptr);
542 }
543
544 /* load Receive Descriptor Register */
545 outl(virt_to_bus(&rxd[0]), ioaddr + RxRingPtr);
546
547 if (natsemi_debug > 1)
548 printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n",
549 inl(ioaddr + RxRingPtr));
550 }
551
552 /* Function: natsemi_set_rx_mode
553 *
554 * Description:
555 * sets the receive mode to accept all broadcast packets and packets
556 * with our MAC address, and reject all multicast packets.
557 *
558 * Arguments: struct nic *nic: NIC data structure
559 *
560 * Returns: void.
561 */
562
natsemi_set_rx_mode(struct nic * nic __unused)563 static void natsemi_set_rx_mode(struct nic *nic __unused)
564 {
565 u32 rx_mode = RxFilterEnable | AcceptBroadcast |
566 AcceptAllMulticast | AcceptMyPhys;
567
568 outl(rx_mode, ioaddr + RxFilterAddr);
569 }
570
natsemi_check_duplex(struct nic * nic __unused)571 static void natsemi_check_duplex(struct nic *nic __unused)
572 {
573 int duplex = inl(ioaddr + ChipConfig) & 0x20000000 ? 1 : 0;
574
575 if (natsemi_debug)
576 printf("%s: Setting %s-duplex based on negotiated link"
577 " capability.\n", nic_name,
578 duplex ? "full" : "half");
579 if (duplex) {
580 rx_config |= 0x10000000;
581 tx_config |= 0xC0000000;
582 } else {
583 rx_config &= ~0x10000000;
584 tx_config &= ~0xC0000000;
585 }
586 outl(tx_config, ioaddr + TxConfig);
587 outl(rx_config, ioaddr + RxConfig);
588 }
589
590 /* Function: natsemi_transmit
591 *
592 * Description: transmits a packet and waits for completion or timeout.
593 *
594 * Arguments: char d[6]: destination ethernet address.
595 * unsigned short t: ethernet protocol type.
596 * unsigned short s: size of the data-part of the packet.
597 * char *p: the data for the packet.
598 *
599 * Returns: void.
600 */
601
602 static void
natsemi_transmit(struct nic * nic,const char * d,unsigned int t,unsigned int s,const char * p)603 natsemi_transmit(struct nic *nic,
604 const char *d, /* Destination */
605 unsigned int t, /* Type */
606 unsigned int s, /* size */
607 const char *p) /* Packet */
608 {
609 u32 to, nstype;
610 u32 tx_status;
611
612 /* Stop the transmitter */
613 outl(TxOff, ioaddr + ChipCmd);
614
615 /* load Transmit Descriptor Register */
616 outl(virt_to_bus(&txd), ioaddr + TxRingPtr);
617 if (natsemi_debug > 1)
618 printf("natsemi_transmit: TX descriptor register loaded with: %X\n",
619 inl(ioaddr + TxRingPtr));
620
621 memcpy(txb, d, ETH_ALEN);
622 memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
623 nstype = htons(t);
624 memcpy(txb + 2 * ETH_ALEN, (char*)&nstype, 2);
625 memcpy(txb + ETH_HLEN, p, s);
626
627 s += ETH_HLEN;
628 s &= DSIZE;
629
630 if (natsemi_debug > 1)
631 printf("natsemi_transmit: sending %d bytes ethtype %hX\n", (int) s, t);
632
633 /* pad to minimum packet size */
634 while (s < ETH_ZLEN)
635 txb[s++] = '\0';
636
637 /* set the transmit buffer descriptor and enable Transmit State Machine */
638 txd.bufptr = virt_to_bus(&txb[0]);
639 txd.cmdsts = (u32) OWN | s;
640
641 /* restart the transmitter */
642 outl(TxOn, ioaddr + ChipCmd);
643
644 if (natsemi_debug > 1)
645 printf("natsemi_transmit: Queued Tx packet size %d.\n", (int) s);
646
647 to = currticks() + TX_TIMEOUT;
648
649 while ((((volatile u32) tx_status=txd.cmdsts) & OWN) && (currticks() < to))
650 /* wait */ ;
651
652 if (currticks() >= to) {
653 printf("natsemi_transmit: TX Timeout! Tx status %X.\n", tx_status);
654 }
655
656 if (!(tx_status & 0x08000000)) {
657 printf("natsemi_transmit: Transmit error, Tx status %X.\n", tx_status);
658 }
659 }
660
661 /* Function: natsemi_poll
662 *
663 * Description: checks for a received packet and returns it if found.
664 *
665 * Arguments: struct nic *nic: NIC data structure
666 *
667 * Returns: 1 if packet was received.
668 * 0 if no packet was received.
669 *
670 * Side effects:
671 * Returns (copies) the packet to the array nic->packet.
672 * Returns the length of the packet in nic->packetlen.
673 */
674
675 static int
natsemi_poll(struct nic * nic,int retrieve)676 natsemi_poll(struct nic *nic, int retrieve)
677 {
678 u32 rx_status = rxd[cur_rx].cmdsts;
679 int retstat = 0;
680
681 if (natsemi_debug > 2)
682 printf("natsemi_poll: cur_rx:%d, status:%X\n", cur_rx, rx_status);
683
684 if (!(rx_status & OWN))
685 return retstat;
686
687 if ( ! retrieve ) return 1;
688
689 if (natsemi_debug > 1)
690 printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n",
691 cur_rx, rx_status);
692
693 nic->packetlen = (rx_status & DSIZE) - CRC_SIZE;
694
695 if ((rx_status & (DescMore|DescPktOK|RxTooLong)) != DescPktOK) {
696 /* corrupted packet received */
697 printf("natsemi_poll: Corrupted packet received, buffer status = %X\n",
698 rx_status);
699 retstat = 0;
700 } else {
701 /* give packet to higher level routine */
702 memcpy(nic->packet, (rxb + cur_rx*RX_BUF_SIZE), nic->packetlen);
703 retstat = 1;
704 }
705
706 /* return the descriptor and buffer to receive ring */
707 rxd[cur_rx].cmdsts = RX_BUF_SIZE;
708 rxd[cur_rx].bufptr = virt_to_bus(&rxb[cur_rx*RX_BUF_SIZE]);
709
710 if (++cur_rx == NUM_RX_DESC)
711 cur_rx = 0;
712
713 /* re-enable the potentially idle receive state machine */
714 outl(RxOn, ioaddr + ChipCmd);
715
716 return retstat;
717 }
718
719 /* Function: natsemi_disable
720 *
721 * Description: Turns off interrupts and stops Tx and Rx engines
722 *
723 * Arguments: struct nic *nic: NIC data structure
724 *
725 * Returns: void.
726 */
727
728 static void
natsemi_disable(struct dev * dev)729 natsemi_disable(struct dev *dev)
730 {
731 struct nic *nic = (struct nic *)dev;
732 /* merge reset and disable */
733 natsemi_init(nic);
734
735 /* Disable interrupts using the mask. */
736 outl(0, ioaddr + IntrMask);
737 outl(0, ioaddr + IntrEnable);
738
739 /* Stop the chip's Tx and Rx processes. */
740 outl(RxOff | TxOff, ioaddr + ChipCmd);
741
742 /* Restore PME enable bit */
743 outl(SavedClkRun, ioaddr + ClkRun);
744 }
745
746 /* Function: natsemi_irq
747 *
748 * Description: Enable, Disable, or Force interrupts
749 *
750 * Arguments: struct nic *nic: NIC data structure
751 * irq_action_t action: requested action to perform
752 *
753 * Returns: void.
754 */
755
756 static void
natsemi_irq(struct nic * nic __unused,irq_action_t action __unused)757 natsemi_irq(struct nic *nic __unused, irq_action_t action __unused)
758 {
759 switch ( action ) {
760 case DISABLE :
761 break;
762 case ENABLE :
763 break;
764 case FORCE :
765 break;
766 }
767 }
768
769 static struct pci_id natsemi_nics[] = {
770 PCI_ROM(0x100b, 0x0020, "dp83815", "DP83815"),
771 };
772
773 struct pci_driver natsemi_driver = {
774 .type = NIC_DRIVER,
775 .name = "NATSEMI",
776 .probe = natsemi_probe,
777 .ids = natsemi_nics,
778 .id_count = sizeof(natsemi_nics)/sizeof(natsemi_nics[0]),
779 .class = 0,
780 };
781