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: Finn Thain <fthain@telegraphics.com.au> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
f877958879
commit
2964db0f59
1 changed files with 175 additions and 70 deletions
|
@ -14,6 +14,8 @@
|
||||||
/* 2001-05-15: support for Cabletron ported from old daynaport driver
|
/* 2001-05-15: support for Cabletron ported from old daynaport driver
|
||||||
* and fixed access to Sonic Sys card which masquerades as a Farallon
|
* and fixed access to Sonic Sys card which masquerades as a Farallon
|
||||||
* by rayk@knightsmanor.org */
|
* 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/module.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
@ -61,25 +63,21 @@ static char version[] =
|
||||||
#define DAYNA_8390_BASE 0x80000
|
#define DAYNA_8390_BASE 0x80000
|
||||||
#define DAYNA_8390_MEM 0x00000
|
#define DAYNA_8390_MEM 0x00000
|
||||||
|
|
||||||
#define KINETICS_8390_BASE 0x80000
|
|
||||||
#define KINETICS_8390_MEM 0x00000
|
|
||||||
|
|
||||||
#define CABLETRON_8390_BASE 0x90000
|
#define CABLETRON_8390_BASE 0x90000
|
||||||
#define CABLETRON_8390_MEM 0x00000
|
#define CABLETRON_8390_MEM 0x00000
|
||||||
|
|
||||||
|
#define INTERLAN_8390_BASE 0xE0000
|
||||||
|
#define INTERLAN_8390_MEM 0xD0000
|
||||||
|
|
||||||
enum mac8390_type {
|
enum mac8390_type {
|
||||||
MAC8390_NONE = -1,
|
MAC8390_NONE = -1,
|
||||||
MAC8390_APPLE,
|
MAC8390_APPLE,
|
||||||
MAC8390_ASANTE,
|
MAC8390_ASANTE,
|
||||||
MAC8390_FARALLON, /* Apple, Asante, and Farallon are all compatible */
|
MAC8390_FARALLON,
|
||||||
MAC8390_CABLETRON,
|
MAC8390_CABLETRON,
|
||||||
MAC8390_DAYNA,
|
MAC8390_DAYNA,
|
||||||
MAC8390_INTERLAN,
|
MAC8390_INTERLAN,
|
||||||
MAC8390_KINETICS,
|
MAC8390_KINETICS,
|
||||||
MAC8390_FOCUS,
|
|
||||||
MAC8390_SONICSYS,
|
|
||||||
MAC8390_DAYNA2,
|
|
||||||
MAC8390_DAYNA3,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char * cardname[] = {
|
static const char * cardname[] = {
|
||||||
|
@ -90,10 +88,6 @@ static const char * cardname[] = {
|
||||||
"dayna",
|
"dayna",
|
||||||
"interlan",
|
"interlan",
|
||||||
"kinetics",
|
"kinetics",
|
||||||
"focus",
|
|
||||||
"sonic systems",
|
|
||||||
"dayna2",
|
|
||||||
"dayna_lc",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int word16[] = {
|
static int word16[] = {
|
||||||
|
@ -104,10 +98,6 @@ static int word16[] = {
|
||||||
0, /* dayna */
|
0, /* dayna */
|
||||||
1, /* interlan */
|
1, /* interlan */
|
||||||
0, /* kinetics */
|
0, /* kinetics */
|
||||||
1, /* focus (??) */
|
|
||||||
1, /* sonic systems */
|
|
||||||
1, /* dayna2 */
|
|
||||||
1, /* dayna-lc */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* on which cards do we use NuBus resources? */
|
/* on which cards do we use NuBus resources? */
|
||||||
|
@ -119,10 +109,12 @@ static int useresources[] = {
|
||||||
0, /* dayna */
|
0, /* dayna */
|
||||||
0, /* interlan */
|
0, /* interlan */
|
||||||
0, /* kinetics */
|
0, /* kinetics */
|
||||||
0, /* focus (??) */
|
};
|
||||||
1, /* sonic systems */
|
|
||||||
1, /* dayna2 */
|
enum mac8390_access {
|
||||||
1, /* dayna-lc */
|
ACCESS_UNKNOWN = 0,
|
||||||
|
ACCESS_32,
|
||||||
|
ACCESS_16,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern enum mac8390_type mac8390_ident(struct nubus_dev * dev);
|
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_open(struct net_device * dev);
|
||||||
static int mac8390_close(struct net_device * dev);
|
static int mac8390_close(struct net_device * dev);
|
||||||
static void mac8390_no_reset(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,
|
static void sane_get_8390_hdr(struct net_device *dev,
|
||||||
struct e8390_pkt_hdr *hdr, int ring_page);
|
struct e8390_pkt_hdr *hdr, int ring_page);
|
||||||
static void sane_block_input(struct net_device * dev, int count,
|
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)
|
enum mac8390_type __init mac8390_ident(struct nubus_dev * dev)
|
||||||
{
|
{
|
||||||
if (dev->dr_sw == NUBUS_DRSW_ASANTE)
|
switch (dev->dr_sw) {
|
||||||
return MAC8390_ASANTE;
|
case NUBUS_DRSW_3COM:
|
||||||
if (dev->dr_sw == NUBUS_DRSW_FARALLON)
|
switch (dev->dr_hw) {
|
||||||
return MAC8390_FARALLON;
|
case NUBUS_DRHW_APPLE_SONIC_NB:
|
||||||
if (dev->dr_sw == NUBUS_DRSW_KINETICS)
|
case NUBUS_DRHW_APPLE_SONIC_LC:
|
||||||
return MAC8390_KINETICS;
|
case NUBUS_DRHW_SONNET:
|
||||||
if (dev->dr_sw == NUBUS_DRSW_DAYNA)
|
return MAC8390_NONE;
|
||||||
return MAC8390_DAYNA;
|
break;
|
||||||
if (dev->dr_sw == NUBUS_DRSW_DAYNA2)
|
default:
|
||||||
return MAC8390_DAYNA2;
|
return MAC8390_APPLE;
|
||||||
if (dev->dr_sw == NUBUS_DRSW_DAYNA_LC)
|
break;
|
||||||
return MAC8390_DAYNA3;
|
}
|
||||||
if (dev->dr_hw == NUBUS_DRHW_CABLETRON)
|
break;
|
||||||
return MAC8390_CABLETRON;
|
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NUBUS_DRSW_KINETICS:
|
||||||
|
switch (dev->dr_hw) {
|
||||||
|
case NUBUS_DRHW_INTERLAN:
|
||||||
|
return MAC8390_INTERLAN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return MAC8390_KINETICS;
|
||||||
|
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;
|
||||||
|
break;
|
||||||
|
}
|
||||||
return MAC8390_NONE;
|
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)
|
int __init mac8390_memsize(unsigned long membase)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -287,14 +350,6 @@ struct net_device * __init mac8390_probe(int unit)
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
nubus_get_rsrc_mem(dev->dev_addr, &ent, 6);
|
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) {
|
if (useresources[cardtype] == 1) {
|
||||||
|
@ -334,6 +389,17 @@ struct net_device * __init mac8390_probe(int unit)
|
||||||
dev->mem_start +
|
dev->mem_start +
|
||||||
mac8390_memsize(dev->mem_start);
|
mac8390_memsize(dev->mem_start);
|
||||||
break;
|
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:
|
case MAC8390_CABLETRON:
|
||||||
dev->base_addr =
|
dev->base_addr =
|
||||||
(int)(ndev->board->slot_addr +
|
(int)(ndev->board->slot_addr +
|
||||||
|
@ -356,8 +422,8 @@ struct net_device * __init mac8390_probe(int unit)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printk(KERN_ERR "Card type %s is"
|
printk(KERN_ERR "Card type %s is"
|
||||||
" unsupported, sorry\n",
|
" unsupported, sorry\n",
|
||||||
cardname[cardtype]);
|
ndev->board->name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -438,7 +504,7 @@ static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * nd
|
||||||
24, 26, 28, 30
|
24, 26, 28, 30
|
||||||
};
|
};
|
||||||
|
|
||||||
int access_bitmode;
|
int access_bitmode = 0;
|
||||||
|
|
||||||
/* Now fill in our stuff */
|
/* Now fill in our stuff */
|
||||||
dev->open = &mac8390_open;
|
dev->open = &mac8390_open;
|
||||||
|
@ -468,29 +534,47 @@ static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * nd
|
||||||
|
|
||||||
/* Fill in model-specific information and functions */
|
/* Fill in model-specific information and functions */
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case MAC8390_SONICSYS:
|
case MAC8390_FARALLON:
|
||||||
/* 16 bit card, register map is reversed */
|
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;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACCESS_32:
|
||||||
|
/* 32 bit card, register map is reversed */
|
||||||
|
ei_status.reset_8390 = &mac8390_no_reset;
|
||||||
|
ei_status.block_input = &sane_block_input;
|
||||||
|
ei_status.block_output = &sane_block_output;
|
||||||
|
ei_status.get_8390_hdr = &sane_get_8390_hdr;
|
||||||
|
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.reset_8390 = &mac8390_no_reset;
|
||||||
ei_status.block_input = &slow_sane_block_input;
|
ei_status.block_input = &slow_sane_block_input;
|
||||||
ei_status.block_output = &slow_sane_block_output;
|
ei_status.block_output = &slow_sane_block_output;
|
||||||
ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
|
ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
|
||||||
ei_status.reg_offset = back4_offsets;
|
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:
|
|
||||||
/* 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;
|
|
||||||
ei_status.get_8390_hdr = &sane_get_8390_hdr;
|
|
||||||
ei_status.reg_offset = back4_offsets;
|
|
||||||
access_bitmode = 1;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAC8390_CABLETRON:
|
case MAC8390_CABLETRON:
|
||||||
/* 16 bit card, register map is short forward */
|
/* 16 bit card, register map is short forward */
|
||||||
ei_status.reset_8390 = &mac8390_no_reset;
|
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.block_output = &slow_sane_block_output;
|
||||||
ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
|
ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
|
||||||
ei_status.reg_offset = fwrd2_offsets;
|
ei_status.reg_offset = fwrd2_offsets;
|
||||||
access_bitmode = 0;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAC8390_DAYNA:
|
case MAC8390_DAYNA:
|
||||||
case MAC8390_KINETICS:
|
case MAC8390_KINETICS:
|
||||||
/* 16 bit memory */
|
/* 16 bit memory, register map is forward */
|
||||||
/* dayna and similar */
|
/* dayna and similar */
|
||||||
ei_status.reset_8390 = &mac8390_no_reset;
|
ei_status.reset_8390 = &mac8390_no_reset;
|
||||||
ei_status.block_input = &dayna_block_input;
|
ei_status.block_input = &dayna_block_input;
|
||||||
ei_status.block_output = &dayna_block_output;
|
ei_status.block_output = &dayna_block_output;
|
||||||
ei_status.get_8390_hdr = &dayna_get_8390_hdr;
|
ei_status.get_8390_hdr = &dayna_get_8390_hdr;
|
||||||
ei_status.reg_offset = fwrd4_offsets;
|
ei_status.reg_offset = fwrd4_offsets;
|
||||||
access_bitmode = 0;
|
|
||||||
break;
|
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:
|
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;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,9 +623,9 @@ static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * nd
|
||||||
printk(":");
|
printk(":");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printk(" IRQ %d, shared memory at %#lx-%#lx, %d-bit access.\n",
|
printk(" IRQ %d, %d KB shared memory at %#lx, %d-bit access.\n",
|
||||||
dev->irq, dev->mem_start, dev->mem_end-1,
|
dev->irq, (int)((dev->mem_end - dev->mem_start)/0x1000) * 4,
|
||||||
access_bitmode?32:16);
|
dev->mem_start, access_bitmode?32:16);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -561,6 +654,18 @@ static void mac8390_no_reset(struct net_device *dev)
|
||||||
return;
|
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 */
|
/* dayna_memcpy_fromio/dayna_memcpy_toio */
|
||||||
/* directly from daynaport.c by Alan Cox */
|
/* directly from daynaport.c by Alan Cox */
|
||||||
static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, int count)
|
static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, int count)
|
||||||
|
|
Loading…
Reference in a new issue