Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2964db0f authored by Finn Thain's avatar Finn Thain Committed by Linus Torvalds
Browse files

m68k: Mac DP8390 update



Fix the support for C/NET nubus ethernet cards etc. Sync up the DP8390 driver
with the latest code in the mac68k repo.

Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Signed-off-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent f8779588
Loading
Loading
Loading
Loading
+175 −70
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@
/* 2001-05-15: support for Cabletron ported from old daynaport driver
 * and fixed access to Sonic Sys card which masquerades as a Farallon
 * by rayk@knightsmanor.org */
/* 2002-12-30: Try to support more cards, some clues from NetBSD driver */
/* 2003-12-26: Make sure Asante cards always work. */

#include <linux/module.h>
#include <linux/kernel.h>
@@ -61,25 +63,21 @@ static char version[] =
#define DAYNA_8390_BASE		0x80000
#define DAYNA_8390_MEM		0x00000

#define KINETICS_8390_BASE	0x80000
#define KINETICS_8390_MEM	0x00000

#define CABLETRON_8390_BASE	0x90000
#define CABLETRON_8390_MEM	0x00000

#define INTERLAN_8390_BASE	0xE0000
#define INTERLAN_8390_MEM	0xD0000

enum mac8390_type {
	MAC8390_NONE = -1,
	MAC8390_APPLE,
	MAC8390_ASANTE,
	MAC8390_FARALLON,  /* Apple, Asante, and Farallon are all compatible */
	MAC8390_FARALLON,
	MAC8390_CABLETRON,
	MAC8390_DAYNA,
	MAC8390_INTERLAN,
	MAC8390_KINETICS,
	MAC8390_FOCUS,
	MAC8390_SONICSYS,
	MAC8390_DAYNA2,
	MAC8390_DAYNA3,
};

static const char * cardname[] = {
@@ -90,10 +88,6 @@ static const char * cardname[] = {
	"dayna",
	"interlan",
	"kinetics",
	"focus",
	"sonic systems",
	"dayna2",
	"dayna_lc",
};

static int word16[] = {
@@ -104,10 +98,6 @@ static int word16[] = {
	0, /* dayna */
	1, /* interlan */
	0, /* kinetics */
	1, /* focus (??) */
	1, /* sonic systems  */
	1, /* dayna2 */
	1, /* dayna-lc */
};

/* on which cards do we use NuBus resources? */
@@ -119,10 +109,12 @@ static int useresources[] = {
	0, /* dayna */
	0, /* interlan */
	0, /* kinetics */
	0, /* focus (??) */
	1, /* sonic systems */
	1, /* dayna2 */
	1, /* dayna-lc */
};

enum mac8390_access {
	ACCESS_UNKNOWN = 0,
	ACCESS_32,
	ACCESS_16,
};

extern enum mac8390_type mac8390_ident(struct nubus_dev * dev);
@@ -134,8 +126,9 @@ static int mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev,
static int mac8390_open(struct net_device * dev);
static int mac8390_close(struct net_device * dev);
static void mac8390_no_reset(struct net_device *dev);
static void interlan_reset(struct net_device *dev);

/* Sane (32-bit chunk memory read/write) - Apple/Asante/Farallon do this*/
/* Sane (32-bit chunk memory read/write) - Some Farallon and Apple do this*/
static void sane_get_8390_hdr(struct net_device *dev,
			      struct e8390_pkt_hdr *hdr, int ring_page);
static void sane_block_input(struct net_device * dev, int count,
@@ -172,23 +165,93 @@ static void word_memcpy_fromcard(void *tp, const void *fp, int count);

enum mac8390_type __init mac8390_ident(struct nubus_dev * dev)
{
	if (dev->dr_sw == NUBUS_DRSW_ASANTE)
	switch (dev->dr_sw) {
		case NUBUS_DRSW_3COM:
			switch (dev->dr_hw) {
				case NUBUS_DRHW_APPLE_SONIC_NB:
				case NUBUS_DRHW_APPLE_SONIC_LC:
				case NUBUS_DRHW_SONNET:
					return MAC8390_NONE;
					break;
				default:
					return MAC8390_APPLE;
					break;
			}
			break;

		case NUBUS_DRSW_APPLE:
			switch (dev->dr_hw) {
				case NUBUS_DRHW_ASANTE_LC:
					return MAC8390_NONE;
					break;
				case NUBUS_DRHW_CABLETRON:
					return MAC8390_CABLETRON;
					break;
				default:
					return MAC8390_APPLE;
					break;
			}
			break;

		case NUBUS_DRSW_ASANTE:
			return MAC8390_ASANTE;
	if (dev->dr_sw == NUBUS_DRSW_FARALLON)
			break;

		case NUBUS_DRSW_TECHWORKS:
		case NUBUS_DRSW_DAYNA2:
		case NUBUS_DRSW_DAYNA_LC:
			if (dev->dr_hw == NUBUS_DRHW_CABLETRON)
				return MAC8390_CABLETRON;
			else
				return MAC8390_APPLE;
			break;

		case NUBUS_DRSW_FARALLON:
			return MAC8390_FARALLON;
	if (dev->dr_sw == NUBUS_DRSW_KINETICS)
			break;

		case NUBUS_DRSW_KINETICS:
			switch (dev->dr_hw) {
				case NUBUS_DRHW_INTERLAN:
					return MAC8390_INTERLAN;
					break;
				default:
					return MAC8390_KINETICS;
	if (dev->dr_sw == NUBUS_DRSW_DAYNA)
					break;
			}
			break;

		case NUBUS_DRSW_DAYNA:
			// These correspond to Dayna Sonic cards
			// which use the macsonic driver
			if (dev->dr_hw == NUBUS_DRHW_SMC9194 ||
				dev->dr_hw == NUBUS_DRHW_INTERLAN )
				return MAC8390_NONE;
			else
				return MAC8390_DAYNA;
	if (dev->dr_sw == NUBUS_DRSW_DAYNA2)
		return MAC8390_DAYNA2;
	if (dev->dr_sw == NUBUS_DRSW_DAYNA_LC)
		return MAC8390_DAYNA3;
	if (dev->dr_hw == NUBUS_DRHW_CABLETRON)
		return MAC8390_CABLETRON;
			break;
	}
	return MAC8390_NONE;
}

enum mac8390_access __init mac8390_testio(volatile unsigned long membase)
{
	unsigned long outdata = 0xA5A0B5B0;
	unsigned long indata =  0x00000000;
	/* Try writing 32 bits */
	memcpy((char *)membase, (char *)&outdata, 4);
	/* Now compare them */
	if (memcmp((char *)&outdata, (char *)membase, 4) == 0)
		return ACCESS_32;
	/* Write 16 bit output */
	word_memcpy_tocard((char *)membase, (char *)&outdata, 4);
	/* Now read it back */
	word_memcpy_fromcard((char *)&indata, (char *)membase, 4);
	if (outdata == indata)
		return ACCESS_16;
	return ACCESS_UNKNOWN;
}

int __init mac8390_memsize(unsigned long membase)
{
	unsigned long flags;
@@ -287,14 +350,6 @@ struct net_device * __init mac8390_probe(int unit)
			continue;
		} else {
			nubus_get_rsrc_mem(dev->dev_addr, &ent, 6);
			/* Some Sonic Sys cards masquerade as Farallon */
			if (cardtype == MAC8390_FARALLON &&
					dev->dev_addr[0] == 0x0 &&
					dev->dev_addr[1] == 0x40 &&
					dev->dev_addr[2] == 0x10) {
				/* This is really Sonic Sys card */
				cardtype = MAC8390_SONICSYS;
			}
		}

		if (useresources[cardtype] == 1) {
@@ -334,6 +389,17 @@ struct net_device * __init mac8390_probe(int unit)
						dev->mem_start +
						mac8390_memsize(dev->mem_start);
					break;
				case MAC8390_INTERLAN:
					dev->base_addr =
						(int)(ndev->board->slot_addr +
						INTERLAN_8390_BASE);
					dev->mem_start =
						(int)(ndev->board->slot_addr +
						INTERLAN_8390_MEM);
					dev->mem_end =
						dev->mem_start +
						mac8390_memsize(dev->mem_start);
					break;
				case MAC8390_CABLETRON:
					dev->base_addr =
						(int)(ndev->board->slot_addr +
@@ -357,7 +423,7 @@ struct net_device * __init mac8390_probe(int unit)
				default:
					printk(KERN_ERR "Card type %s is"
					       " unsupported, sorry\n",
					       cardname[cardtype]);
					       ndev->board->name);
					continue;
			}
		}
@@ -438,7 +504,7 @@ static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * nd
		24,    26,     28,     30
	};

	int access_bitmode;
	int access_bitmode = 0;

	/* Now fill in our stuff */
	dev->open = &mac8390_open;
@@ -468,22 +534,25 @@ static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * nd

	/* Fill in model-specific information and functions */
	switch(type) {
	case MAC8390_SONICSYS:
	case MAC8390_FARALLON:
	case MAC8390_APPLE:
		switch(mac8390_testio(dev->mem_start)) {
			case ACCESS_UNKNOWN:
				printk("Don't know how to access card memory!\n");
				return -ENODEV;
				break;

			case ACCESS_16:
				/* 16 bit card, register map is reversed */
				ei_status.reset_8390 = &mac8390_no_reset;
				ei_status.block_input = &slow_sane_block_input;
				ei_status.block_output = &slow_sane_block_output;
				ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
				ei_status.reg_offset = back4_offsets;
		access_bitmode = 0;
				break;
	case MAC8390_FARALLON:
	case MAC8390_APPLE:
	case MAC8390_ASANTE:
	case MAC8390_DAYNA2:
	case MAC8390_DAYNA3:

			case ACCESS_32:
				/* 32 bit card, register map is reversed */
		/* sane */
				ei_status.reset_8390 = &mac8390_no_reset;
				ei_status.block_input = &sane_block_input;
				ei_status.block_output = &sane_block_output;
@@ -491,6 +560,21 @@ static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * nd
				ei_status.reg_offset = back4_offsets;
				access_bitmode = 1;
				break;
		}
		break;

	case MAC8390_ASANTE:
		/* Some Asante cards pass the 32 bit test
		 * but overwrite system memory when run at 32 bit.
		 * so we run them all at 16 bit.
		 */
		ei_status.reset_8390 = &mac8390_no_reset;
		ei_status.block_input = &slow_sane_block_input;
		ei_status.block_output = &slow_sane_block_output;
		ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
		ei_status.reg_offset = back4_offsets;
		break;

	case MAC8390_CABLETRON:
		/* 16 bit card, register map is short forward */
		ei_status.reset_8390 = &mac8390_no_reset;
@@ -498,21 +582,30 @@ static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * nd
		ei_status.block_output = &slow_sane_block_output;
		ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
		ei_status.reg_offset = fwrd2_offsets;
		access_bitmode = 0;
		break;

	case MAC8390_DAYNA:
	case MAC8390_KINETICS:
		/* 16 bit memory */
		/* 16 bit memory, register map is forward */
		/* dayna and similar */
		ei_status.reset_8390 = &mac8390_no_reset;
		ei_status.block_input = &dayna_block_input;
		ei_status.block_output = &dayna_block_output;
		ei_status.get_8390_hdr = &dayna_get_8390_hdr;
		ei_status.reg_offset = fwrd4_offsets;
		access_bitmode = 0;
		break;

	case MAC8390_INTERLAN:
		/* 16 bit memory, register map is forward */
		ei_status.reset_8390 = &interlan_reset;
		ei_status.block_input = &slow_sane_block_input;
		ei_status.block_output = &slow_sane_block_output;
		ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
	        ei_status.reg_offset = fwrd4_offsets;
	        break;

	default:
		printk(KERN_ERR "Card type %s is unsupported, sorry\n", cardname[type]);
		printk(KERN_ERR "Card type %s is unsupported, sorry\n", ndev->board->name);
		return -ENODEV;
	}

@@ -530,9 +623,9 @@ static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * nd
				printk(":");
		}
	}
	printk(" IRQ %d, shared memory at %#lx-%#lx,  %d-bit access.\n",
		   dev->irq, dev->mem_start, dev->mem_end-1,
		   access_bitmode?32:16);
	printk(" IRQ %d, %d KB shared memory at %#lx,  %d-bit access.\n",
		   dev->irq, (int)((dev->mem_end - dev->mem_start)/0x1000) * 4,
		   dev->mem_start, access_bitmode?32:16);
	return 0;
}

@@ -561,6 +654,18 @@ static void mac8390_no_reset(struct net_device *dev)
	return;
}

static void interlan_reset(struct net_device *dev)
{
	unsigned char *target=nubus_slot_addr(IRQ2SLOT(dev->irq));
	if (ei_debug > 1)
		printk("Need to reset the NS8390 t=%lu...", jiffies);
	ei_status.txing = 0;
	target[0xC0000] = 0;
	if (ei_debug > 1)
		printk("reset complete\n");
	return;
}

/* dayna_memcpy_fromio/dayna_memcpy_toio */
/* directly from daynaport.c by Alan Cox */
static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, int count)