Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* mac89x0.c: A Crystal Semiconductor CS89[02]0 driver for linux. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) 	Written 1996 by Russell Nelson, with reference to skeleton.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 	written 1993-1994 by Donald Becker.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 	This software may be used and distributed according to the terms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 	of the GNU General Public License, incorporated herein by reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 	The author may be reached at nelson@crynwr.com, Crynwr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 	Software, 11 Grant St., Potsdam, NY 13676
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)   Changelog:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)   Mike Cruse        : mcruse@cti-ltd.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)                     : Changes for Linux 2.0 compatibility.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)                     : Added dev_id parameter in net_interrupt(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)                     : request_irq() and free_irq(). Just NULL for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)   Mike Cruse        : Added MOD_INC_USE_COUNT and MOD_DEC_USE_COUNT macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)                     : in net_open() and net_close() so kerneld would know
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)                     : that the module is in use and wouldn't eject the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)                     : driver prematurely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)   Mike Cruse        : Rewrote init_module() and cleanup_module using 8390.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)                     : as an example. Disabled autoprobing in init_module(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)                     : not a good thing to do to other devices while Linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)                     : is running from all accounts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)   Alan Cox          : Removed 1.2 support, added 2.1 extra counters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)   David Huggins-Daines <dhd@debian.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)   Split this off into mac89x0.c, and gutted it of all parts which are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)   not relevant to the existing CS8900 cards on the Macintosh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)   (i.e. basically the Daynaport CS and LC cards).  To be precise:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)     * Removed all the media-detection stuff, because these cards are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)     TP-only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)     * Lobotomized the ISA interrupt bogosity, because these cards use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)     a hardwired NuBus interrupt and a magic ISAIRQ value in the card.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)     * Basically eliminated everything not relevant to getting the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)     cards minimally functioning on the Macintosh.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)   I might add that these cards are badly designed even from the Mac
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)   standpoint, in that Dayna, in their infinite wisdom, used NuBus slot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)   I/O space and NuBus interrupts for these cards, but neglected to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)   provide anything even remotely resembling a NuBus ROM.  Therefore we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)   have to probe for them in a brain-damaged ISA-like fashion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)   Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 11/01/2001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)   check kmalloc and release the allocated memory on failure in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)   mac89x0_probe and in init_module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)   use local_irq_{save,restore}(flags) in net_get_stat, not just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)   local_irq_{dis,en}able()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) static const char version[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) "cs89x0.c:v1.02 11/26/96 Russell Nelson <nelson@crynwr.com>\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)   Sources:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	Crynwr packet driver epktisa.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	Crystal Semiconductor data sheets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) #include <linux/nubus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #include <asm/hwtest.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #include <asm/macints.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) #include "cs89x0.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) static int debug = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) module_param(debug, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) MODULE_PARM_DESC(debug, "debug message level");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* Information that need to be kept for each board. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct net_local {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	int msg_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	int chip_type;		/* one of: CS8900, CS8920, CS8920M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	char chip_revision;	/* revision letter of the chip ('A'...) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	int send_cmd;		/* the propercommand used to send a packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	int rx_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	int curr_rx_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)         int send_underrun;      /* keep track of how many underruns in a row we get */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* Index to functions, as function prototypes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static int net_open(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static irqreturn_t net_interrupt(int irq, void *dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static void set_multicast_list(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static void net_rx(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int net_close(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static struct net_device_stats *net_get_stats(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static int set_mac_address(struct net_device *dev, void *addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* For reading/writing registers ISA-style */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) readreg_io(struct net_device *dev, int portno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	nubus_writew(swab16(portno), dev->base_addr + ADD_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	return swab16(nubus_readw(dev->base_addr + DATA_PORT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) writereg_io(struct net_device *dev, int portno, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	nubus_writew(swab16(portno), dev->base_addr + ADD_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	nubus_writew(swab16(value), dev->base_addr + DATA_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* These are for reading/writing registers in shared memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) readreg(struct net_device *dev, int portno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	return swab16(nubus_readw(dev->mem_start + portno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) writereg(struct net_device *dev, int portno, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	nubus_writew(swab16(value), dev->mem_start + portno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static const struct net_device_ops mac89x0_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	.ndo_open		= net_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	.ndo_stop		= net_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	.ndo_start_xmit		= net_send_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	.ndo_get_stats		= net_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	.ndo_set_rx_mode	= set_multicast_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	.ndo_set_mac_address	= set_mac_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	.ndo_validate_addr	= eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* Probe for the CS8900 card in slot E.  We won't bother looking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)    anywhere else until we have a really good reason to do so. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static int mac89x0_device_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	struct net_local *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	int i, slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	unsigned rev_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	unsigned long ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	unsigned short sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	int err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	struct nubus_rsrc *fres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	dev = alloc_etherdev(sizeof(struct net_local));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	/* We might have to parameterize this later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	slot = 0xE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	/* Get out now if there's a real NuBus card in slot E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	for_each_func_rsrc(fres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		if (fres->board->slot == slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	/* The pseudo-ISA bits always live at offset 0x300 (gee,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)            wonder why...) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	ioaddr = (unsigned long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		nubus_slot_addr(slot) | (((slot&0xf) << 20) + DEFAULTIOBASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		int card_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		card_present = (hwreg_present((void *)ioaddr + 4) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 				hwreg_present((void *)ioaddr + DATA_PORT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		if (!card_present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	nubus_writew(0, ioaddr + ADD_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	sig = nubus_readw(ioaddr + DATA_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	if (sig != swab16(CHIP_EISA_ID_SIG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	SET_NETDEV_DEV(dev, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	/* Initialize the net_device structure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	lp->msg_enable = netif_msg_init(debug, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	/* Fill in the 'dev' fields. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	dev->base_addr = ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	dev->mem_start = (unsigned long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		nubus_slot_addr(slot) | (((slot&0xf) << 20) + MMIOBASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	dev->mem_end = dev->mem_start + 0x1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	/* Turn on shared memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	writereg_io(dev, PP_BusCTL, MEMORY_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	/* get the chip type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	rev_type = readreg(dev, PRODUCT_ID_ADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	lp->chip_type = rev_type &~ REVISON_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	/* Check the chip type and revision in order to set the correct send command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	CS8920 revision C and CS8900 revision F can use the faster send. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	lp->send_cmd = TX_AFTER_381;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	if (lp->chip_type == CS8900 && lp->chip_revision >= 'F')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		lp->send_cmd = TX_NOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	if (lp->chip_type != CS8900 && lp->chip_revision >= 'C')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		lp->send_cmd = TX_NOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	netif_dbg(lp, drv, dev, "%s", version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	pr_info("cs89%c0%s rev %c found at %#8lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		lp->chip_type == CS8900 ? '0' : '2',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		lp->chip_type == CS8920M ? "M" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		lp->chip_revision, dev->base_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	/* Try to read the MAC address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	if ((readreg(dev, PP_SelfST) & (EEPROM_PRESENT | EEPROM_OK)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		pr_info("No EEPROM, giving up now.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)         } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)                 for (i = 0; i < ETH_ALEN; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			/* Big-endian (why??!) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			unsigned short s = readreg(dev, PP_IA + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)                         dev->dev_addr[i] = s >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)                         dev->dev_addr[i+1] = s & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)                 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	dev->irq = SLOT2IRQ(slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	/* print the IRQ and ethernet address. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	pr_info("MAC %pM, IRQ %d\n", dev->dev_addr, dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	dev->netdev_ops		= &mac89x0_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	err = register_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	platform_set_drvdata(pdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	nubus_writew(0, dev->base_addr + ADD_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* Open/initialize the board.  This is called (in the current kernel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)    sometime after booting when the 'ifconfig' program is run.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)    This routine should set everything up anew at each open, even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)    registers that "should" only need to be set once at boot, so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)    there is non-reboot way to recover if something goes wrong.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) net_open(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	struct net_local *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	/* Disable the interrupt for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) & ~ENABLE_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	/* Grab the interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	if (request_irq(dev->irq, net_interrupt, 0, "cs89x0", dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	/* Set up the IRQ - Apparently magic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	if (lp->chip_type == CS8900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		writereg(dev, PP_CS8900_ISAINT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		writereg(dev, PP_CS8920_ISAINT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	/* set the Ethernet address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	for (i=0; i < ETH_ALEN/2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	/* Turn on both receive and transmit operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	/* Receive only error free packets addressed to this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	lp->rx_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	writereg(dev, PP_RxCTL, DEF_RX_ACCEPT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	lp->curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	writereg(dev, PP_RxCFG, lp->curr_rx_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	writereg(dev, PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	       TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	writereg(dev, PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		 TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	/* now that we've got our act together, enable everything */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) | ENABLE_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	netif_start_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static netdev_tx_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) net_send_packet(struct sk_buff *skb, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	struct net_local *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	netif_dbg(lp, tx_queued, dev, "sent %d byte packet of type %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		  skb->len, skb->data[ETH_ALEN + ETH_ALEN] << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		  skb->data[ETH_ALEN + ETH_ALEN + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	/* keep the upload from being interrupted, since we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	   ask the chip to start transmitting before the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	   whole packet has been completely uploaded. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	/* initiate a transmit sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	writereg(dev, PP_TxCMD, lp->send_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	writereg(dev, PP_TxLength, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	/* Test to see if the chip has allocated memory for the packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		/* Gasp!  It hasn't.  But that shouldn't happen since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		   we're waiting for TxOk, so return 1 and requeue this packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		return NETDEV_TX_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	/* Write the contents of the packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	skb_copy_from_linear_data(skb, (void *)(dev->mem_start + PP_TxFrame),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 				  skb->len+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	dev_kfree_skb (skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /* The typical workload of the driver:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)    Handle the network interface interrupts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static irqreturn_t net_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	struct net_device *dev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	struct net_local *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	int ioaddr, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	ioaddr = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	/* we MUST read all the events out of the ISQ, otherwise we'll never
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)            get interrupted again.  As a consequence, we can't have any limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)            on the number of times we loop in the interrupt handler.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)            hardware guarantees that eventually we'll run out of events.  Of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)            course, if you're on a slow machine, and packets are arriving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)            faster than you can read them off, you're screwed.  Hasta la
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)            vista, baby!  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	while ((status = swab16(nubus_readw(dev->base_addr + ISQ_PORT)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		netif_dbg(lp, intr, dev, "status=%04x\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		switch(status & ISQ_EVENT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		case ISQ_RECEIVER_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 			/* Got a packet(s). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 			net_rx(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		case ISQ_TRANSMITTER_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 			dev->stats.tx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 			netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 			if ((status & TX_OK) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 				dev->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 			if (status & TX_LOST_CRS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 				dev->stats.tx_carrier_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 			if (status & TX_SQE_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 				dev->stats.tx_heartbeat_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 			if (status & TX_LATE_COL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 				dev->stats.tx_window_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 			if (status & TX_16_COL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 				dev->stats.tx_aborted_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		case ISQ_BUFFER_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			if (status & READY_FOR_TX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 				/* we tried to transmit a packet earlier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)                                    but inexplicably ran out of buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)                                    That shouldn't happen since we only ever
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)                                    load one packet.  Shrug.  Do the right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)                                    thing anyway. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 				netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 			if (status & TX_UNDERRUN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 				netif_dbg(lp, tx_err, dev, "transmit underrun\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)                                 lp->send_underrun++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)                                 if (lp->send_underrun == 3) lp->send_cmd = TX_AFTER_381;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)                                 else if (lp->send_underrun == 6) lp->send_cmd = TX_AFTER_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)                         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		case ISQ_RX_MISS_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 			dev->stats.rx_missed_errors += (status >> 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		case ISQ_TX_COL_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 			dev->stats.collisions += (status >> 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* We have a good packet(s), get it/them out of the buffers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) net_rx(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	struct net_local *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	int status, length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	status = readreg(dev, PP_RxStatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	if ((status & RX_OK) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		dev->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		if (status & RX_RUNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 				dev->stats.rx_length_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		if (status & RX_EXTRA_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 				dev->stats.rx_length_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		if ((status & RX_CRC_ERROR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		    !(status & (RX_EXTRA_DATA|RX_RUNT)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 			/* per str 172 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 			dev->stats.rx_crc_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		if (status & RX_DRIBBLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 				dev->stats.rx_frame_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	length = readreg(dev, PP_RxLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	/* Malloc up new buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	skb = alloc_skb(length, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	if (skb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		dev->stats.rx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	skb_put(skb, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	skb_copy_to_linear_data(skb, (void *)(dev->mem_start + PP_RxFrame),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 				length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	netif_dbg(lp, rx_status, dev, "received %d byte packet of type %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		  length, skb->data[ETH_ALEN + ETH_ALEN] << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		  skb->data[ETH_ALEN + ETH_ALEN + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)         skb->protocol=eth_type_trans(skb,dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	dev->stats.rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	dev->stats.rx_bytes += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /* The inverse routine to net_open(). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) net_close(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	writereg(dev, PP_RxCFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	writereg(dev, PP_TxCFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	writereg(dev, PP_BufCFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	writereg(dev, PP_BusCTL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	free_irq(dev->irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	/* Update the statistics here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /* Get the current statistics.	This may be called with the card open or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)    closed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static struct net_device_stats *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) net_get_stats(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	/* Update the statistics from the device registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	dev->stats.rx_missed_errors += (readreg(dev, PP_RxMiss) >> 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	dev->stats.collisions += (readreg(dev, PP_TxCol) >> 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	return &dev->stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) static void set_multicast_list(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	struct net_local *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	if(dev->flags&IFF_PROMISC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		lp->rx_mode = RX_ALL_ACCEPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	} else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		/* The multicast-accept list is initialized to accept-all, and we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		   rely on higher-level filtering for now. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		lp->rx_mode = RX_MULTCAST_ACCEPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		lp->rx_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp->rx_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	/* in promiscuous mode, we accept errored packets, so we have to enable interrupts on them also */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	writereg(dev, PP_RxCFG, lp->curr_rx_cfg |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	     (lp->rx_mode == RX_ALL_ACCEPT? (RX_CRC_ERROR_ENBL|RX_RUNT_ENBL|RX_EXTRA_DATA_ENBL) : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static int set_mac_address(struct net_device *dev, void *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	struct sockaddr *saddr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	if (!is_valid_ether_addr(saddr->sa_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		return -EADDRNOTAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	netdev_info(dev, "Setting MAC address to %pM\n", dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	/* set the Ethernet address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	for (i=0; i < ETH_ALEN/2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static int mac89x0_device_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	struct net_device *dev = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	unregister_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	nubus_writew(0, dev->base_addr + ADD_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static struct platform_driver mac89x0_platform_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	.probe = mac89x0_device_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	.remove = mac89x0_device_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		.name = "mac89x0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) module_platform_driver(mac89x0_platform_driver);