^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* $Id: sunlance.c,v 1.112 2002/01/15 06:48:55 davem Exp $
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * lance.c: Linux/Sparc/Lance driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written 1995, 1996 by Miguel de Icaza
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Sources:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * The Linux depca driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * The Linux lance driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * The Linux skeleton driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * The NetBSD Sparc/Lance driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Theo de Raadt (deraadt@openbsd.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * NCR92C990 Lan Controller manual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * 1.4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Added support to run with a ledma on the Sun4m
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * 1.5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Added multiple card detection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * 4/17/96: Burst sizes and tpe selection on sun4m by Eddie C. Dost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * (ecd@skynet.be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * 5/15/96: auto carrier detection on sun4m by Eddie C. Dost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * (ecd@skynet.be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * 5/17/96: lebuffer on scsi/ether cards now work David S. Miller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * (davem@caip.rutgers.edu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * 5/29/96: override option 'tpe-link-test?', if it is 'false', as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * this disables auto carrier detection on sun4m. Eddie C. Dost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * (ecd@skynet.be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * 1.7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * 6/26/96: Bug fix for multiple ledmas, miguel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * 1.8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * Stole multicast code from depca.c, fixed lance_tx.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * 1.9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * 8/21/96: Fixed the multicast code (Pedro Roque)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * 8/28/96: Send fake packet in lance_open() if auto_select is true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * so we can detect the carrier loss condition in time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * Eddie C. Dost (ecd@skynet.be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * 9/15/96: Align rx_buf so that eth_copy_and_sum() won't cause an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * MNA trap during chksum_partial_copy(). (ecd@skynet.be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * 11/17/96: Handle LE_C0_MERR in lance_interrupt(). (ecd@skynet.be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * 12/22/96: Don't loop forever in lance_rx() on incomplete packets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * This was the sun4c killer. Shit, stupid bug.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * (ecd@skynet.be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * 1.10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * 1/26/97: Modularize driver. (ecd@skynet.be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * 1.11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * 12/27/97: Added sun4d support. (jj@sunsite.mff.cuni.cz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * 1.12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * 11/3/99: Fixed SMP race in lance_start_xmit found by davem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * Anton Blanchard (anton@progsoc.uts.edu.au)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * 2.00: 11/9/99: Massive overhaul and port to new SBUS driver interfaces.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * David S. Miller (davem@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * 2.01:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * 11/08/01: Use library crc32 functions (Matt_Domsch@dell.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #undef DEBUG_DRIVER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static char lancestr[] = "LANCE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #include <linux/socket.h> /* Used for the temporal inet entries and routing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #include <linux/route.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #include <asm/byteorder.h> /* Used by the checksum routines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #include <asm/idprom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #include <asm/prom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #include <asm/auxio.h> /* For tpe-link-test? setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define DRV_NAME "sunlance"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define DRV_RELDATE "8/24/03"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define DRV_AUTHOR "Miguel de Icaza (miguel@nuclecu.unam.mx)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) MODULE_AUTHOR(DRV_AUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) MODULE_DESCRIPTION("Sun Lance ethernet driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* Define: 2^4 Tx buffers and 2^4 Rx buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #ifndef LANCE_LOG_TX_BUFFERS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define LANCE_LOG_TX_BUFFERS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define LANCE_LOG_RX_BUFFERS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define LE_CSR0 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define LE_CSR1 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define LE_CSR2 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define LE_CSR3 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define LE_MO_PROM 0x8000 /* Enable promiscuous mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define LE_C0_ERR 0x8000 /* Error: set if BAB, SQE, MISS or ME is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define LE_C0_BABL 0x4000 /* BAB: Babble: tx timeout. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define LE_C0_CERR 0x2000 /* SQE: Signal quality error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define LE_C0_MISS 0x1000 /* MISS: Missed a packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define LE_C0_MERR 0x0800 /* ME: Memory error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define LE_C0_RINT 0x0400 /* Received interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define LE_C0_TINT 0x0200 /* Transmitter Interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define LE_C0_IDON 0x0100 /* IFIN: Init finished. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define LE_C0_INTR 0x0080 /* Interrupt or error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define LE_C0_INEA 0x0040 /* Interrupt enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define LE_C0_RXON 0x0020 /* Receiver on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define LE_C0_TXON 0x0010 /* Transmitter on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define LE_C0_TDMD 0x0008 /* Transmitter demand */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define LE_C0_STOP 0x0004 /* Stop the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define LE_C0_STRT 0x0002 /* Start the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define LE_C0_INIT 0x0001 /* Init the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define LE_C3_BSWP 0x4 /* SWAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define LE_C3_ACON 0x2 /* ALE Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define LE_C3_BCON 0x1 /* Byte control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* Receive message descriptor 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define LE_R1_OWN 0x80 /* Who owns the entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define LE_R1_ERR 0x40 /* Error: if FRA, OFL, CRC or BUF is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define LE_R1_FRA 0x20 /* FRA: Frame error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define LE_R1_OFL 0x10 /* OFL: Frame overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define LE_R1_CRC 0x08 /* CRC error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define LE_R1_BUF 0x04 /* BUF: Buffer error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define LE_R1_SOP 0x02 /* Start of packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define LE_R1_EOP 0x01 /* End of packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define LE_R1_POK 0x03 /* Packet is complete: SOP + EOP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define LE_T1_OWN 0x80 /* Lance owns the packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define LE_T1_ERR 0x40 /* Error summary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define LE_T1_EMORE 0x10 /* Error: more than one retry needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define LE_T1_EONE 0x08 /* Error: one retry needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define LE_T1_EDEF 0x04 /* Error: deferred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define LE_T1_SOP 0x02 /* Start of packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define LE_T1_EOP 0x01 /* End of packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define LE_T1_POK 0x03 /* Packet is complete: SOP + EOP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define LE_T3_BUF 0x8000 /* Buffer error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define LE_T3_UFL 0x4000 /* Error underflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define LE_T3_LCOL 0x1000 /* Error late collision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define LE_T3_CLOS 0x0800 /* Error carrier loss */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define LE_T3_RTY 0x0400 /* Error retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define LE_T3_TDR 0x03ff /* Time Domain Reflectometry counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define TX_RING_SIZE (1 << (LANCE_LOG_TX_BUFFERS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define TX_RING_LEN_BITS ((LANCE_LOG_TX_BUFFERS) << 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define TX_NEXT(__x) (((__x)+1) & TX_RING_MOD_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define RX_RING_SIZE (1 << (LANCE_LOG_RX_BUFFERS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define RX_NEXT(__x) (((__x)+1) & RX_RING_MOD_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #define PKT_BUF_SZ 1544
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #define RX_BUFF_SIZE PKT_BUF_SZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define TX_BUFF_SIZE PKT_BUF_SZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct lance_rx_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) u16 rmd0; /* low address of packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) u8 rmd1_bits; /* descriptor bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) u8 rmd1_hadr; /* high address of packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) s16 length; /* This length is 2s complement (negative)!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * Buffer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) u16 mblength; /* This is the actual number of bytes received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct lance_tx_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) u16 tmd0; /* low address of packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u8 tmd1_bits; /* descriptor bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u8 tmd1_hadr; /* high address of packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) s16 length; /* Length is 2s complement (negative)! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u16 misc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /* The LANCE initialization block, described in databook. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /* On the Sparc, this block should be on a DMA region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct lance_init_block {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) u16 mode; /* Pre-set mode (reg. 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) u8 phys_addr[6]; /* Physical ethernet address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u32 filter[2]; /* Multicast filter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* Receive and transmit ring base, along with extra bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) u16 rx_ptr; /* receive descriptor addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) u16 rx_len; /* receive len and high addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) u16 tx_ptr; /* transmit descriptor addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) u16 tx_len; /* transmit len and high addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /* The Tx and Rx ring entries must aligned on 8-byte boundaries. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct lance_rx_desc brx_ring[RX_RING_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct lance_tx_desc btx_ring[TX_RING_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) u8 tx_buf [TX_RING_SIZE][TX_BUFF_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) u8 pad[2]; /* align rx_buf for copy_and_sum(). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) u8 rx_buf [RX_RING_SIZE][RX_BUFF_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) #define libdesc_offset(rt, elem) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ((__u32)(((unsigned long)(&(((struct lance_init_block *)0)->rt[elem])))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #define libbuff_offset(rt, elem) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) ((__u32)(((unsigned long)(&(((struct lance_init_block *)0)->rt[elem][0])))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct lance_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) void __iomem *lregs; /* Lance RAP/RDP regs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) void __iomem *dregs; /* DMA controller regs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct lance_init_block __iomem *init_block_iomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct lance_init_block *init_block_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) int rx_new, tx_new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int rx_old, tx_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct platform_device *ledma; /* If set this points to ledma */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) char tpe; /* cable-selection is TPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) char auto_select; /* cable-selection by carrier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) char burst_sizes; /* ledma SBus burst sizes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) char pio_buffer; /* init block in PIO space? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) unsigned short busmaster_regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) void (*init_ring)(struct net_device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) void (*rx)(struct net_device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) void (*tx)(struct net_device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) dma_addr_t init_block_dvma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct net_device *dev; /* Backpointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct platform_device *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct platform_device *lebuffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct timer_list multicast_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) #define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) lp->tx_old+TX_RING_MOD_MASK-lp->tx_new:\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) lp->tx_old - lp->tx_new-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* Lance registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) #define RDP 0x00UL /* register data port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) #define RAP 0x02UL /* register address port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #define LANCE_REG_SIZE 0x04UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) #define STOP_LANCE(__lp) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) do { void __iomem *__base = (__lp)->lregs; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) sbus_writew(LE_CSR0, __base + RAP); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) sbus_writew(LE_C0_STOP, __base + RDP); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) int sparc_lance_debug = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /* The Lance uses 24 bit addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* On the Sun4c the DVMA will provide the remaining bytes for us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* On the Sun4m we have to instruct the ledma to provide them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* Even worse, on scsi/ether SBUS cards, the init block and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * transmit/receive buffers are addresses as offsets from absolute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * zero on the lebuffer PIO area. -DaveM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) #define LANCE_ADDR(x) ((long)(x) & ~0xff000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /* Load the CSR registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static void load_csrs(struct lance_private *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) u32 leptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (lp->pio_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) leptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) leptr = LANCE_ADDR(lp->init_block_dvma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) sbus_writew(LE_CSR1, lp->lregs + RAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) sbus_writew(leptr & 0xffff, lp->lregs + RDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) sbus_writew(LE_CSR2, lp->lregs + RAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) sbus_writew(leptr >> 16, lp->lregs + RDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) sbus_writew(LE_CSR3, lp->lregs + RAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) sbus_writew(lp->busmaster_regval, lp->lregs + RDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* Point back to csr0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) sbus_writew(LE_CSR0, lp->lregs + RAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* Setup the Lance Rx and Tx rings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static void lance_init_ring_dvma(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct lance_init_block *ib = lp->init_block_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) dma_addr_t aib = lp->init_block_dvma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) __u32 leptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* Lock out other processes while setting up hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) lp->rx_new = lp->tx_new = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) lp->rx_old = lp->tx_old = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /* Copy the ethernet address to the lance init block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * Note that on the sparc you need to swap the ethernet address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) ib->phys_addr [0] = dev->dev_addr [1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ib->phys_addr [1] = dev->dev_addr [0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) ib->phys_addr [2] = dev->dev_addr [3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) ib->phys_addr [3] = dev->dev_addr [2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ib->phys_addr [4] = dev->dev_addr [5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ib->phys_addr [5] = dev->dev_addr [4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* Setup the Tx ring entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) for (i = 0; i < TX_RING_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) leptr = LANCE_ADDR(aib + libbuff_offset(tx_buf, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) ib->btx_ring [i].tmd0 = leptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ib->btx_ring [i].tmd1_hadr = leptr >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) ib->btx_ring [i].tmd1_bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ib->btx_ring [i].length = 0xf000; /* The ones required by tmd2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ib->btx_ring [i].misc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /* Setup the Rx ring entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) for (i = 0; i < RX_RING_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) leptr = LANCE_ADDR(aib + libbuff_offset(rx_buf, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ib->brx_ring [i].rmd0 = leptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ib->brx_ring [i].rmd1_hadr = leptr >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ib->brx_ring [i].rmd1_bits = LE_R1_OWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) ib->brx_ring [i].length = -RX_BUFF_SIZE | 0xf000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) ib->brx_ring [i].mblength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* Setup the initialization block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* Setup rx descriptor pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) leptr = LANCE_ADDR(aib + libdesc_offset(brx_ring, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ib->rx_len = (LANCE_LOG_RX_BUFFERS << 13) | (leptr >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ib->rx_ptr = leptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* Setup tx descriptor pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) leptr = LANCE_ADDR(aib + libdesc_offset(btx_ring, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) ib->tx_len = (LANCE_LOG_TX_BUFFERS << 13) | (leptr >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) ib->tx_ptr = leptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static void lance_init_ring_pio(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct lance_init_block __iomem *ib = lp->init_block_iomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) u32 leptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* Lock out other processes while setting up hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) lp->rx_new = lp->tx_new = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) lp->rx_old = lp->tx_old = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /* Copy the ethernet address to the lance init block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * Note that on the sparc you need to swap the ethernet address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) sbus_writeb(dev->dev_addr[1], &ib->phys_addr[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) sbus_writeb(dev->dev_addr[0], &ib->phys_addr[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) sbus_writeb(dev->dev_addr[3], &ib->phys_addr[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) sbus_writeb(dev->dev_addr[2], &ib->phys_addr[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) sbus_writeb(dev->dev_addr[5], &ib->phys_addr[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) sbus_writeb(dev->dev_addr[4], &ib->phys_addr[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /* Setup the Tx ring entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) for (i = 0; i < TX_RING_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) leptr = libbuff_offset(tx_buf, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) sbus_writew(leptr, &ib->btx_ring [i].tmd0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) sbus_writeb(leptr >> 16,&ib->btx_ring [i].tmd1_hadr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) sbus_writeb(0, &ib->btx_ring [i].tmd1_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /* The ones required by tmd2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) sbus_writew(0xf000, &ib->btx_ring [i].length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) sbus_writew(0, &ib->btx_ring [i].misc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /* Setup the Rx ring entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) for (i = 0; i < RX_RING_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) leptr = libbuff_offset(rx_buf, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) sbus_writew(leptr, &ib->brx_ring [i].rmd0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) sbus_writeb(leptr >> 16,&ib->brx_ring [i].rmd1_hadr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) sbus_writeb(LE_R1_OWN, &ib->brx_ring [i].rmd1_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) sbus_writew(-RX_BUFF_SIZE|0xf000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) &ib->brx_ring [i].length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) sbus_writew(0, &ib->brx_ring [i].mblength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* Setup the initialization block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* Setup rx descriptor pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) leptr = libdesc_offset(brx_ring, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) sbus_writew((LANCE_LOG_RX_BUFFERS << 13) | (leptr >> 16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) &ib->rx_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) sbus_writew(leptr, &ib->rx_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* Setup tx descriptor pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) leptr = libdesc_offset(btx_ring, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) sbus_writew((LANCE_LOG_TX_BUFFERS << 13) | (leptr >> 16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) &ib->tx_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) sbus_writew(leptr, &ib->tx_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static void init_restart_ledma(struct lance_private *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) u32 csr = sbus_readl(lp->dregs + DMA_CSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (!(csr & DMA_HNDL_ERROR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /* E-Cache draining */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) while (sbus_readl(lp->dregs + DMA_CSR) & DMA_FIFO_ISDRAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) csr = sbus_readl(lp->dregs + DMA_CSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) csr &= ~DMA_E_BURSTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (lp->burst_sizes & DMA_BURST32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) csr |= DMA_E_BURST32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) csr |= DMA_E_BURST16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) csr |= (DMA_DSBL_RD_DRN | DMA_DSBL_WR_INV | DMA_FIFO_INV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (lp->tpe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) csr |= DMA_EN_ENETAUI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) csr &= ~DMA_EN_ENETAUI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) udelay(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) sbus_writel(csr, lp->dregs + DMA_CSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) udelay(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static int init_restart_lance(struct lance_private *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) u16 regval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (lp->dregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) init_restart_ledma(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) sbus_writew(LE_CSR0, lp->lregs + RAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) sbus_writew(LE_C0_INIT, lp->lregs + RDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /* Wait for the lance to complete initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) for (i = 0; i < 100; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) regval = sbus_readw(lp->lregs + RDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (regval & (LE_C0_ERR | LE_C0_IDON))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (i == 100 || (regval & LE_C0_ERR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) printk(KERN_ERR "LANCE unopened after %d ticks, csr0=%4.4x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) i, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (lp->dregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) printk("dcsr=%8.8x\n", sbus_readl(lp->dregs + DMA_CSR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) /* Clear IDON by writing a "1", enable interrupts and start lance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) sbus_writew(LE_C0_IDON, lp->lregs + RDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) sbus_writew(LE_C0_INEA | LE_C0_STRT, lp->lregs + RDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (lp->dregs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) u32 csr = sbus_readl(lp->dregs + DMA_CSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) csr |= DMA_INT_ENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) sbus_writel(csr, lp->dregs + DMA_CSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) static void lance_rx_dvma(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) struct lance_init_block *ib = lp->init_block_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) struct lance_rx_desc *rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) u8 bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) int len, entry = lp->rx_new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) for (rd = &ib->brx_ring [entry];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) !((bits = rd->rmd1_bits) & LE_R1_OWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) rd = &ib->brx_ring [entry]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /* We got an incomplete frame? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if ((bits & LE_R1_POK) != LE_R1_POK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) dev->stats.rx_over_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) dev->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) } else if (bits & LE_R1_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* Count only the end frame as a rx error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * not the beginning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (bits & LE_R1_BUF) dev->stats.rx_fifo_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (bits & LE_R1_CRC) dev->stats.rx_crc_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (bits & LE_R1_OFL) dev->stats.rx_over_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (bits & LE_R1_FRA) dev->stats.rx_frame_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (bits & LE_R1_EOP) dev->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) len = (rd->mblength & 0xfff) - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) skb = netdev_alloc_skb(dev, len + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (skb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) dev->stats.rx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) rd->mblength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) rd->rmd1_bits = LE_R1_OWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) lp->rx_new = RX_NEXT(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) dev->stats.rx_bytes += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) skb_reserve(skb, 2); /* 16 byte align */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) skb_put(skb, len); /* make room */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) skb_copy_to_linear_data(skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) (unsigned char *)&(ib->rx_buf [entry][0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) skb->protocol = eth_type_trans(skb, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) dev->stats.rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) /* Return the packet to the pool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) rd->mblength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) rd->rmd1_bits = LE_R1_OWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) entry = RX_NEXT(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) lp->rx_new = entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) static void lance_tx_dvma(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct lance_init_block *ib = lp->init_block_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) spin_lock(&lp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) j = lp->tx_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) for (i = j; i != lp->tx_new; i = j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) struct lance_tx_desc *td = &ib->btx_ring [i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) u8 bits = td->tmd1_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /* If we hit a packet not owned by us, stop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (bits & LE_T1_OWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (bits & LE_T1_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) u16 status = td->misc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) dev->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (status & LE_T3_RTY) dev->stats.tx_aborted_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (status & LE_T3_LCOL) dev->stats.tx_window_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (status & LE_T3_CLOS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) dev->stats.tx_carrier_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (lp->auto_select) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) lp->tpe = 1 - lp->tpe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) printk(KERN_NOTICE "%s: Carrier Lost, trying %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) dev->name, lp->tpe?"TPE":"AUI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) STOP_LANCE(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) lp->init_ring(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) load_csrs(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) init_restart_lance(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) /* Buffer errors and underflows turn off the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * transmitter, restart the adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (status & (LE_T3_BUF|LE_T3_UFL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) dev->stats.tx_fifo_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) printk(KERN_ERR "%s: Tx: ERR_BUF|ERR_UFL, restarting\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) STOP_LANCE(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) lp->init_ring(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) load_csrs(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) init_restart_lance(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) } else if ((bits & LE_T1_POK) == LE_T1_POK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * So we don't count the packet more than once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) td->tmd1_bits = bits & ~(LE_T1_POK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) /* One collision before packet was sent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (bits & LE_T1_EONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) dev->stats.collisions++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) /* More than one collision, be optimistic. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (bits & LE_T1_EMORE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) dev->stats.collisions += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) dev->stats.tx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) j = TX_NEXT(j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) lp->tx_old = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (netif_queue_stopped(dev) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) TX_BUFFS_AVAIL > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) spin_unlock(&lp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static void lance_piocopy_to_skb(struct sk_buff *skb, void __iomem *piobuf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) u16 *p16 = (u16 *) skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) u32 *p32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) u8 *p8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) void __iomem *pbuf = piobuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) /* We know here that both src and dest are on a 16bit boundary. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) *p16++ = sbus_readw(pbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) p32 = (u32 *) p16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) pbuf += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) len -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) while (len >= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) *p32++ = sbus_readl(pbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) pbuf += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) len -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) p8 = (u8 *) p32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (len >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) p16 = (u16 *) p32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) *p16++ = sbus_readw(pbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) pbuf += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) len -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) p8 = (u8 *) p16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (len >= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) *p8 = sbus_readb(pbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) static void lance_rx_pio(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct lance_init_block __iomem *ib = lp->init_block_iomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) struct lance_rx_desc __iomem *rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) unsigned char bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) int len, entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) entry = lp->rx_new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) for (rd = &ib->brx_ring [entry];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) !((bits = sbus_readb(&rd->rmd1_bits)) & LE_R1_OWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) rd = &ib->brx_ring [entry]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /* We got an incomplete frame? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if ((bits & LE_R1_POK) != LE_R1_POK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) dev->stats.rx_over_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) dev->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) } else if (bits & LE_R1_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /* Count only the end frame as a rx error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * not the beginning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (bits & LE_R1_BUF) dev->stats.rx_fifo_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (bits & LE_R1_CRC) dev->stats.rx_crc_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (bits & LE_R1_OFL) dev->stats.rx_over_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (bits & LE_R1_FRA) dev->stats.rx_frame_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (bits & LE_R1_EOP) dev->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) len = (sbus_readw(&rd->mblength) & 0xfff) - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) skb = netdev_alloc_skb(dev, len + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (skb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) dev->stats.rx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) sbus_writew(0, &rd->mblength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) sbus_writeb(LE_R1_OWN, &rd->rmd1_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) lp->rx_new = RX_NEXT(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) dev->stats.rx_bytes += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) skb_reserve (skb, 2); /* 16 byte align */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) skb_put(skb, len); /* make room */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) lance_piocopy_to_skb(skb, &(ib->rx_buf[entry][0]), len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) skb->protocol = eth_type_trans(skb, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) dev->stats.rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /* Return the packet to the pool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) sbus_writew(0, &rd->mblength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) sbus_writeb(LE_R1_OWN, &rd->rmd1_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) entry = RX_NEXT(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) lp->rx_new = entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static void lance_tx_pio(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) struct lance_init_block __iomem *ib = lp->init_block_iomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) spin_lock(&lp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) j = lp->tx_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) for (i = j; i != lp->tx_new; i = j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct lance_tx_desc __iomem *td = &ib->btx_ring [i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) u8 bits = sbus_readb(&td->tmd1_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /* If we hit a packet not owned by us, stop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (bits & LE_T1_OWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (bits & LE_T1_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) u16 status = sbus_readw(&td->misc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) dev->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (status & LE_T3_RTY) dev->stats.tx_aborted_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (status & LE_T3_LCOL) dev->stats.tx_window_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (status & LE_T3_CLOS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) dev->stats.tx_carrier_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (lp->auto_select) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) lp->tpe = 1 - lp->tpe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) printk(KERN_NOTICE "%s: Carrier Lost, trying %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) dev->name, lp->tpe?"TPE":"AUI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) STOP_LANCE(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) lp->init_ring(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) load_csrs(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) init_restart_lance(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /* Buffer errors and underflows turn off the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * transmitter, restart the adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (status & (LE_T3_BUF|LE_T3_UFL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) dev->stats.tx_fifo_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) printk(KERN_ERR "%s: Tx: ERR_BUF|ERR_UFL, restarting\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) STOP_LANCE(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) lp->init_ring(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) load_csrs(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) init_restart_lance(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) } else if ((bits & LE_T1_POK) == LE_T1_POK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) * So we don't count the packet more than once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) sbus_writeb(bits & ~(LE_T1_POK), &td->tmd1_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* One collision before packet was sent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (bits & LE_T1_EONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) dev->stats.collisions++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) /* More than one collision, be optimistic. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (bits & LE_T1_EMORE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) dev->stats.collisions += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) dev->stats.tx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) j = TX_NEXT(j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) lp->tx_old = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (netif_queue_stopped(dev) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) TX_BUFFS_AVAIL > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) spin_unlock(&lp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) static irqreturn_t lance_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) struct net_device *dev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) int csr0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) sbus_writew(LE_CSR0, lp->lregs + RAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) csr0 = sbus_readw(lp->lregs + RDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) /* Acknowledge all the interrupt sources ASAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) sbus_writew(csr0 & (LE_C0_INTR | LE_C0_TINT | LE_C0_RINT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) lp->lregs + RDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if ((csr0 & LE_C0_ERR) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /* Clear the error condition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) sbus_writew((LE_C0_BABL | LE_C0_ERR | LE_C0_MISS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) LE_C0_CERR | LE_C0_MERR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) lp->lregs + RDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (csr0 & LE_C0_RINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) lp->rx(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (csr0 & LE_C0_TINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) lp->tx(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (csr0 & LE_C0_BABL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) dev->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (csr0 & LE_C0_MISS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) dev->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (csr0 & LE_C0_MERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (lp->dregs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) u32 addr = sbus_readl(lp->dregs + DMA_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) printk(KERN_ERR "%s: Memory error, status %04x, addr %06x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) dev->name, csr0, addr & 0xffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) printk(KERN_ERR "%s: Memory error, status %04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) dev->name, csr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) sbus_writew(LE_C0_STOP, lp->lregs + RDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (lp->dregs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) u32 dma_csr = sbus_readl(lp->dregs + DMA_CSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) dma_csr |= DMA_FIFO_INV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) sbus_writel(dma_csr, lp->dregs + DMA_CSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) lp->init_ring(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) load_csrs(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) init_restart_lance(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) sbus_writew(LE_C0_INEA, lp->lregs + RDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /* Build a fake network packet and send it to ourselves. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) static void build_fake_packet(struct lance_private *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct net_device *dev = lp->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) int i, entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) entry = lp->tx_new & TX_RING_MOD_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (lp->pio_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) struct lance_init_block __iomem *ib = lp->init_block_iomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) u16 __iomem *packet = (u16 __iomem *) &(ib->tx_buf[entry][0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) struct ethhdr __iomem *eth = (struct ethhdr __iomem *) packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) for (i = 0; i < (ETH_ZLEN / sizeof(u16)); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) sbus_writew(0, &packet[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) for (i = 0; i < 6; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) sbus_writeb(dev->dev_addr[i], ð->h_dest[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) sbus_writeb(dev->dev_addr[i], ð->h_source[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) sbus_writew((-ETH_ZLEN) | 0xf000, &ib->btx_ring[entry].length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) sbus_writew(0, &ib->btx_ring[entry].misc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) sbus_writeb(LE_T1_POK|LE_T1_OWN, &ib->btx_ring[entry].tmd1_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct lance_init_block *ib = lp->init_block_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) u16 *packet = (u16 *) &(ib->tx_buf[entry][0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) struct ethhdr *eth = (struct ethhdr *) packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) memset(packet, 0, ETH_ZLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) for (i = 0; i < 6; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) eth->h_dest[i] = dev->dev_addr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) eth->h_source[i] = dev->dev_addr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) ib->btx_ring[entry].length = (-ETH_ZLEN) | 0xf000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) ib->btx_ring[entry].misc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) ib->btx_ring[entry].tmd1_bits = (LE_T1_POK|LE_T1_OWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) lp->tx_new = TX_NEXT(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) static int lance_open(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) STOP_LANCE(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (request_irq(dev->irq, lance_interrupt, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) lancestr, (void *) dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) printk(KERN_ERR "Lance: Can't get irq %d\n", dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) /* On the 4m, setup the ledma to provide the upper bits for buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (lp->dregs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) u32 regval = lp->init_block_dvma & 0xff000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) sbus_writel(regval, lp->dregs + DMA_TEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) /* Set mode and clear multicast filter only at device open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) * so that lance_init_ring() called at any error will not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) * forget multicast filters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) * BTW it is common bug in all lance drivers! --ANK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (lp->pio_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) struct lance_init_block __iomem *ib = lp->init_block_iomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) sbus_writew(0, &ib->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) sbus_writel(0, &ib->filter[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) sbus_writel(0, &ib->filter[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) struct lance_init_block *ib = lp->init_block_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) ib->mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) ib->filter [0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ib->filter [1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) lp->init_ring(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) load_csrs(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) netif_start_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) status = init_restart_lance(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (!status && lp->auto_select) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) build_fake_packet(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) sbus_writew(LE_C0_INEA | LE_C0_TDMD, lp->lregs + RDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) static int lance_close(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) del_timer_sync(&lp->multicast_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) STOP_LANCE(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) free_irq(dev->irq, (void *) dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) static int lance_reset(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) STOP_LANCE(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) /* On the 4m, reset the dma too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (lp->dregs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) u32 csr, addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) printk(KERN_ERR "resetting ledma\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) csr = sbus_readl(lp->dregs + DMA_CSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) sbus_writel(csr | DMA_RST_ENET, lp->dregs + DMA_CSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) udelay(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) sbus_writel(csr & ~DMA_RST_ENET, lp->dregs + DMA_CSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) addr = lp->init_block_dvma & 0xff000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) sbus_writel(addr, lp->dregs + DMA_TEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) lp->init_ring(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) load_csrs(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) netif_trans_update(dev); /* prevent tx timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) status = init_restart_lance(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) static void lance_piocopy_from_skb(void __iomem *dest, unsigned char *src, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) void __iomem *piobuf = dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) u32 *p32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) u16 *p16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) u8 *p8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) switch ((unsigned long)src & 0x3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) p32 = (u32 *) src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) while (len >= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) sbus_writel(*p32, piobuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) p32++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) piobuf += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) len -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) src = (char *) p32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) p8 = (u8 *) src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) while (len >= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) val = p8[0] << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) val |= p8[1] << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) val |= p8[2] << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) val |= p8[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) sbus_writel(val, piobuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) p8 += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) piobuf += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) len -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) src = (char *) p8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) p16 = (u16 *) src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) while (len >= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) u32 val = p16[0]<<16 | p16[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) sbus_writel(val, piobuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) p16 += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) piobuf += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) len -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) src = (char *) p16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (len >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) u16 val = src[0] << 8 | src[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) sbus_writew(val, piobuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) src += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) piobuf += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) len -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (len >= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) sbus_writeb(src[0], piobuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) static void lance_piozero(void __iomem *dest, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) void __iomem *piobuf = dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if ((unsigned long)piobuf & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) sbus_writeb(0, piobuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) piobuf += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) len -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (len == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) sbus_writeb(0, piobuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if ((unsigned long)piobuf & 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) sbus_writew(0, piobuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) piobuf += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) len -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) while (len >= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) sbus_writel(0, piobuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) piobuf += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) len -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) if (len >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) sbus_writew(0, piobuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) piobuf += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) len -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (len >= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) sbus_writeb(0, piobuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) static void lance_tx_timeout(struct net_device *dev, unsigned int txqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) printk(KERN_ERR "%s: transmit timed out, status %04x, reset\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) dev->name, sbus_readw(lp->lregs + RDP));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) lance_reset(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) static netdev_tx_t lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) int entry, skblen, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) skblen = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) spin_lock_irq(&lp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) dev->stats.tx_bytes += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) entry = lp->tx_new & TX_RING_MOD_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (lp->pio_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) struct lance_init_block __iomem *ib = lp->init_block_iomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) sbus_writew((-len) | 0xf000, &ib->btx_ring[entry].length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) sbus_writew(0, &ib->btx_ring[entry].misc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) lance_piocopy_from_skb(&ib->tx_buf[entry][0], skb->data, skblen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (len != skblen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) lance_piozero(&ib->tx_buf[entry][skblen], len - skblen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) sbus_writeb(LE_T1_POK | LE_T1_OWN, &ib->btx_ring[entry].tmd1_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) struct lance_init_block *ib = lp->init_block_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) ib->btx_ring [entry].length = (-len) | 0xf000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) ib->btx_ring [entry].misc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) skb_copy_from_linear_data(skb, &ib->tx_buf [entry][0], skblen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) if (len != skblen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) memset((char *) &ib->tx_buf [entry][skblen], 0, len - skblen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) ib->btx_ring [entry].tmd1_bits = (LE_T1_POK | LE_T1_OWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) lp->tx_new = TX_NEXT(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (TX_BUFFS_AVAIL <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) /* Kick the lance: transmit now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) sbus_writew(LE_C0_INEA | LE_C0_TDMD, lp->lregs + RDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) /* Read back CSR to invalidate the E-Cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) * This is needed, because DMA_DSBL_WR_INV is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (lp->dregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) sbus_readw(lp->lregs + RDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) spin_unlock_irq(&lp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) /* taken from the depca driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static void lance_load_multicast(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) struct netdev_hw_addr *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) u32 crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) /* set all multicast bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (dev->flags & IFF_ALLMULTI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) val = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (lp->pio_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) struct lance_init_block __iomem *ib = lp->init_block_iomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) sbus_writel(val, &ib->filter[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) sbus_writel(val, &ib->filter[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) struct lance_init_block *ib = lp->init_block_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) ib->filter [0] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) ib->filter [1] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (dev->flags & IFF_ALLMULTI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) /* Add addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) netdev_for_each_mc_addr(ha, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) crc = ether_crc_le(6, ha->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) crc = crc >> 26;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (lp->pio_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) struct lance_init_block __iomem *ib = lp->init_block_iomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) u16 __iomem *mcast_table = (u16 __iomem *) &ib->filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) u16 tmp = sbus_readw(&mcast_table[crc>>4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) tmp |= 1 << (crc & 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) sbus_writew(tmp, &mcast_table[crc>>4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) struct lance_init_block *ib = lp->init_block_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) u16 *mcast_table = (u16 *) &ib->filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) mcast_table [crc >> 4] |= 1 << (crc & 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) static void lance_set_multicast(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) struct lance_init_block *ib_mem = lp->init_block_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) struct lance_init_block __iomem *ib_iomem = lp->init_block_iomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) u16 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (!netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (lp->tx_old != lp->tx_new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) mod_timer(&lp->multicast_timer, jiffies + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) STOP_LANCE(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) lp->init_ring(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) if (lp->pio_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) mode = sbus_readw(&ib_iomem->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) mode = ib_mem->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (dev->flags & IFF_PROMISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) mode |= LE_MO_PROM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (lp->pio_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) sbus_writew(mode, &ib_iomem->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) ib_mem->mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) mode &= ~LE_MO_PROM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (lp->pio_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) sbus_writew(mode, &ib_iomem->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) ib_mem->mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) lance_load_multicast(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) load_csrs(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) init_restart_lance(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) static void lance_set_multicast_retry(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) struct lance_private *lp = from_timer(lp, t, multicast_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) struct net_device *dev = lp->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) lance_set_multicast(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) static void lance_free_hwresources(struct lance_private *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) if (lp->lregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) of_iounmap(&lp->op->resource[0], lp->lregs, LANCE_REG_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if (lp->dregs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) struct platform_device *ledma = lp->ledma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) of_iounmap(&ledma->resource[0], lp->dregs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) resource_size(&ledma->resource[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (lp->init_block_iomem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) of_iounmap(&lp->lebuffer->resource[0], lp->init_block_iomem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) sizeof(struct lance_init_block));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) } else if (lp->init_block_mem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) dma_free_coherent(&lp->op->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) sizeof(struct lance_init_block),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) lp->init_block_mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) lp->init_block_dvma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) /* Ethtool support... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) static void sparc_lance_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) strlcpy(info->driver, "sunlance", sizeof(info->driver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) static const struct ethtool_ops sparc_lance_ethtool_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) .get_drvinfo = sparc_lance_get_drvinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) .get_link = ethtool_op_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) static const struct net_device_ops sparc_lance_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) .ndo_open = lance_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) .ndo_stop = lance_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) .ndo_start_xmit = lance_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) .ndo_set_rx_mode = lance_set_multicast,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) .ndo_tx_timeout = lance_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) .ndo_set_mac_address = eth_mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) .ndo_validate_addr = eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) static int sparc_lance_probe_one(struct platform_device *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) struct platform_device *ledma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) struct platform_device *lebuffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) struct device_node *dp = op->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) struct lance_private *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) dev = alloc_etherdev(sizeof(struct lance_private) + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) spin_lock_init(&lp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) /* Copy the IDPROM ethernet address to the device structure, later we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) * will copy the address in the device structure to the lance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) * initialization block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) for (i = 0; i < 6; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) dev->dev_addr[i] = idprom->id_ethaddr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) /* Get the IO region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) lp->lregs = of_ioremap(&op->resource[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) LANCE_REG_SIZE, lancestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) if (!lp->lregs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) printk(KERN_ERR "SunLance: Cannot map registers.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) lp->ledma = ledma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) if (lp->ledma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) lp->dregs = of_ioremap(&ledma->resource[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) resource_size(&ledma->resource[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) "ledma");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (!lp->dregs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) printk(KERN_ERR "SunLance: Cannot map "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) "ledma registers.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) lp->op = op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) lp->lebuffer = lebuffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) if (lebuffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) /* sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (lebuffer->resource[0].start & 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) printk(KERN_ERR "SunLance: ERROR: Rx and Tx rings not on even boundary.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) lp->init_block_iomem =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) of_ioremap(&lebuffer->resource[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) sizeof(struct lance_init_block), "lebuffer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) if (!lp->init_block_iomem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) printk(KERN_ERR "SunLance: Cannot map PIO buffer.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) lp->init_block_dvma = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) lp->pio_buffer = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) lp->init_ring = lance_init_ring_pio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) lp->rx = lance_rx_pio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) lp->tx = lance_tx_pio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) lp->init_block_mem =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) dma_alloc_coherent(&op->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) sizeof(struct lance_init_block),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) &lp->init_block_dvma, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) if (!lp->init_block_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) lp->pio_buffer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) lp->init_ring = lance_init_ring_dvma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) lp->rx = lance_rx_dvma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) lp->tx = lance_tx_dvma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) lp->busmaster_regval = of_getintprop_default(dp, "busmaster-regval",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) (LE_C3_BSWP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) LE_C3_ACON |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) LE_C3_BCON));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) lp->name = lancestr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) lp->burst_sizes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) if (lp->ledma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) struct device_node *ledma_dp = ledma->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) struct device_node *sbus_dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) unsigned int sbmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) const char *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) u32 csr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) /* Find burst-size property for ledma */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) lp->burst_sizes = of_getintprop_default(ledma_dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) "burst-sizes", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) /* ledma may be capable of fast bursts, but sbus may not. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) sbus_dp = ledma_dp->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) sbmask = of_getintprop_default(sbus_dp, "burst-sizes",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) DMA_BURSTBITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) lp->burst_sizes &= sbmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) /* Get the cable-selection property */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) prop = of_get_property(ledma_dp, "cable-selection", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) if (!prop || prop[0] == '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) struct device_node *nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) printk(KERN_INFO "SunLance: using "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) "auto-carrier-detection.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) nd = of_find_node_by_path("/options");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) if (!nd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) goto no_link_test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) prop = of_get_property(nd, "tpe-link-test?", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) goto node_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) if (strcmp(prop, "true")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) printk(KERN_NOTICE "SunLance: warning: overriding option "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) "'tpe-link-test?'\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) printk(KERN_NOTICE "SunLance: warning: mail any problems "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) "to ecd@skynet.be\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) auxio_set_lte(AUXIO_LTE_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) node_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) of_node_put(nd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) no_link_test:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) lp->auto_select = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) lp->tpe = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) } else if (!strcmp(prop, "aui")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) lp->auto_select = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) lp->tpe = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) lp->auto_select = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) lp->tpe = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) /* Reset ledma */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) csr = sbus_readl(lp->dregs + DMA_CSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) sbus_writel(csr | DMA_RST_ENET, lp->dregs + DMA_CSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) udelay(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) sbus_writel(csr & ~DMA_RST_ENET, lp->dregs + DMA_CSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) lp->dregs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) lp->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) SET_NETDEV_DEV(dev, &op->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) dev->watchdog_timeo = 5*HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) dev->ethtool_ops = &sparc_lance_ethtool_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) dev->netdev_ops = &sparc_lance_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) dev->irq = op->archdata.irqs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) /* We cannot sleep if the chip is busy during a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) * multicast list update event, because such events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) * can occur from interrupts (ex. IPv6). So we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) * use a timer to try again later when necessary. -DaveM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) timer_setup(&lp->multicast_timer, lance_set_multicast_retry, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) if (register_netdev(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) printk(KERN_ERR "SunLance: Cannot register device.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) platform_set_drvdata(op, lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) printk(KERN_INFO "%s: LANCE %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) dev->name, dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) lance_free_hwresources(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) static int sunlance_sbus_probe(struct platform_device *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) struct platform_device *parent = to_platform_device(op->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) struct device_node *parent_dp = parent->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) if (of_node_name_eq(parent_dp, "ledma")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) err = sparc_lance_probe_one(op, parent, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) } else if (of_node_name_eq(parent_dp, "lebuffer")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) err = sparc_lance_probe_one(op, NULL, parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) err = sparc_lance_probe_one(op, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) static int sunlance_sbus_remove(struct platform_device *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) struct lance_private *lp = platform_get_drvdata(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) struct net_device *net_dev = lp->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) unregister_netdev(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) lance_free_hwresources(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) free_netdev(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) static const struct of_device_id sunlance_sbus_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) .name = "le",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) MODULE_DEVICE_TABLE(of, sunlance_sbus_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) static struct platform_driver sunlance_sbus_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) .name = "sunlance",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) .of_match_table = sunlance_sbus_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) .probe = sunlance_sbus_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) .remove = sunlance_sbus_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) module_platform_driver(sunlance_sbus_driver);