Second beta release of device driver for WD/SMC 80x3 and 3c503 ethernet boards
This commit is contained in:
+97
-30
@@ -16,7 +16,32 @@
|
|||||||
/*
|
/*
|
||||||
* Modification history
|
* Modification history
|
||||||
*
|
*
|
||||||
* $Log$
|
* $Log: if_ed.c,v $
|
||||||
|
* Revision 1.7 93/06/22 04:45:01 davidg
|
||||||
|
* (no additional changes) Second beta release
|
||||||
|
*
|
||||||
|
* Revision 1.6 93/06/22 04:40:35 davidg
|
||||||
|
* minor definition fix to ed_reset()
|
||||||
|
*
|
||||||
|
* Revision 1.5 93/06/22 04:37:39 davidg
|
||||||
|
* fixed some comments
|
||||||
|
*
|
||||||
|
* Revision 1.4 93/06/22 04:34:34 davidg
|
||||||
|
* added support to use the LLC0 'link-level control' flag
|
||||||
|
* to disable the tranceiver for AUI operation on 3Com boards.
|
||||||
|
* The default for this flag can be set in the kernel config
|
||||||
|
* file - 'flags 0x01' sets the flag (disables the tranceiver).
|
||||||
|
*
|
||||||
|
* Revision 1.3 93/06/17 03:57:28 davidg
|
||||||
|
* fixed some printf's
|
||||||
|
*
|
||||||
|
* Revision 1.2 93/06/17 03:26:49 davidg
|
||||||
|
* fixed 3c503 code to determine 8/16bit board
|
||||||
|
* changed attach printf to work with Interim-0.1.5 and NetBSD
|
||||||
|
*
|
||||||
|
* Revision 1.1 93/06/14 22:21:24 davidg
|
||||||
|
* Beta release of device driver for SMC/WD80x3 and 3C503 ethernet boards.
|
||||||
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -432,46 +457,45 @@ ed_probe(isa_dev)
|
|||||||
* Reset NIC and ASIC
|
* Reset NIC and ASIC
|
||||||
*/
|
*/
|
||||||
outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_RST);
|
outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_RST);
|
||||||
/*
|
|
||||||
* Verify that reset bit was set
|
|
||||||
*/
|
|
||||||
if ((inb(sc->asic_addr + ED_3COM_CR) & ED_3COM_CR_RST) == 0)
|
|
||||||
return (0);
|
|
||||||
/*
|
/*
|
||||||
* Wait for a while, then un-reset it
|
* Wait for a while, then un-reset it
|
||||||
*/
|
*/
|
||||||
DELAY(5000);
|
DELAY(5000);
|
||||||
outb(sc->asic_addr + ED_3COM_CR, 0);
|
outb(sc->asic_addr + ED_3COM_CR, 0);
|
||||||
|
|
||||||
/*
|
|
||||||
* Verify that the bit cleared
|
|
||||||
*/
|
|
||||||
if (inb(sc->asic_addr + ED_3COM_CR) & ED_3COM_CR_RST)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait a bit for the NIC to recover from the reset
|
* Wait a bit for the NIC to recover from the reset
|
||||||
*/
|
*/
|
||||||
DELAY(5000);
|
DELAY(5000);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 3Com ASIC defaults to rather strange settings for the CR after
|
||||||
|
* a reset - it's important to set it so that the NIC I/O
|
||||||
|
* registers are mapped. The above setting of it to '0' only
|
||||||
|
* resets the reset condition - the CR is *not* set to zeros.
|
||||||
|
*/
|
||||||
|
outb(sc->asic_addr + ED_3COM_CR, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine if this is an 8bit or 16bit board
|
* Determine if this is an 8bit or 16bit board
|
||||||
*/
|
*/
|
||||||
/* XXX - either this code is broken...or the hardware is... */
|
|
||||||
/* it always comes up 8bit */
|
|
||||||
/*
|
/*
|
||||||
* select page 0 registers
|
* select page 0 registers
|
||||||
*/
|
*/
|
||||||
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
|
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attempt to clear WTS bit. If it doesn't clear, then this is a
|
* Attempt to clear WTS bit. If it doesn't clear, then this is a
|
||||||
* 16bit board.
|
* 16bit board.
|
||||||
*/
|
*/
|
||||||
outb(sc->nic_addr + ED_P0_DCR, 0);
|
outb(sc->nic_addr + ED_P0_DCR, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* select page 2 registers
|
* select page 2 registers
|
||||||
*/
|
*/
|
||||||
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_2|ED_CR_RD2|ED_CR_STP);
|
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_2|ED_CR_RD2|ED_CR_STP);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The 3c503 forces the WTS bit to a one if this is a 16bit board
|
* The 3c503 forces the WTS bit to a one if this is a 16bit board
|
||||||
*/
|
*/
|
||||||
@@ -480,13 +504,10 @@ ed_probe(isa_dev)
|
|||||||
else
|
else
|
||||||
memwidth = 8;
|
memwidth = 8;
|
||||||
|
|
||||||
#if 0
|
|
||||||
printf(" (%dbit)",memwidth);
|
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* select page 0 registers
|
* select page 0 registers
|
||||||
*/
|
*/
|
||||||
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
|
outb(sc->nic_addr + ED_P2_CR, ED_CR_RD2|ED_CR_STP);
|
||||||
|
|
||||||
sc->txb_cnt = 1;
|
sc->txb_cnt = 1;
|
||||||
|
|
||||||
@@ -524,7 +545,7 @@ printf(" (%dbit)",memwidth);
|
|||||||
outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ5);
|
outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ5);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("ed0: Invalid irq configuration\n");
|
printf("ed%d: Invalid irq configuration\n", isa_dev->id_unit);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,13 +578,19 @@ printf(" (%dbit)",memwidth);
|
|||||||
sc->arpcom.ac_enaddr[i] = inb(sc->nic_addr + i);
|
sc->arpcom.ac_enaddr[i] = inb(sc->nic_addr + i);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unmap PROM - select NIC registers
|
* Unmap PROM - select NIC registers. Tranceiver remains disabled at
|
||||||
|
* this point. It's enabled in ed_init so that the attach code
|
||||||
|
* is given a chance to set the default based on a compile-time
|
||||||
|
* config option
|
||||||
*/
|
*/
|
||||||
outb(sc->asic_addr + ED_3COM_CR, 0);
|
outb(sc->asic_addr + ED_3COM_CR, 0);
|
||||||
|
|
||||||
/*
|
#if 0
|
||||||
* Zero memory and verify that it is clear
|
printf("Starting write\n");
|
||||||
*/
|
for (i = 0; i < 8192; ++i)
|
||||||
|
bzero(sc->smem_start, 8192);
|
||||||
|
printf("Done.\n");
|
||||||
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
{ char test_buf[1024];
|
{ char test_buf[1024];
|
||||||
printf("starting write\n");
|
printf("starting write\n");
|
||||||
@@ -576,6 +603,9 @@ printf("done.\n");
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Zero memory and verify that it is clear
|
||||||
|
*/
|
||||||
bzero(sc->smem_start, memsize);
|
bzero(sc->smem_start, memsize);
|
||||||
|
|
||||||
for (i = 0; i < memsize; ++i)
|
for (i = 0; i < memsize; ++i)
|
||||||
@@ -612,7 +642,6 @@ ed_attach(isa_dev)
|
|||||||
ifp->if_unit = isa_dev->id_unit;
|
ifp->if_unit = isa_dev->id_unit;
|
||||||
ifp->if_name = "ed" ;
|
ifp->if_name = "ed" ;
|
||||||
ifp->if_mtu = ETHERMTU;
|
ifp->if_mtu = ETHERMTU;
|
||||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS ;
|
|
||||||
ifp->if_init = ed_init;
|
ifp->if_init = ed_init;
|
||||||
ifp->if_output = ether_output;
|
ifp->if_output = ether_output;
|
||||||
ifp->if_start = ed_start;
|
ifp->if_start = ed_start;
|
||||||
@@ -620,6 +649,16 @@ ed_attach(isa_dev)
|
|||||||
ifp->if_reset = ed_reset;
|
ifp->if_reset = ed_reset;
|
||||||
ifp->if_watchdog = ed_watchdog;
|
ifp->if_watchdog = ed_watchdog;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set default state for LLC0 flag (used to disable the tranceiver
|
||||||
|
* for AUI operation), based on compile-time config option.
|
||||||
|
*/
|
||||||
|
if (isa_dev->id_flags & ED_FLAGS_DISABLE_TRANCEIVER)
|
||||||
|
ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS
|
||||||
|
| IFF_LLC0);
|
||||||
|
else
|
||||||
|
ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS);
|
||||||
|
|
||||||
if_attach(ifp);
|
if_attach(ifp);
|
||||||
|
|
||||||
#if NBPFILTER > 0
|
#if NBPFILTER > 0
|
||||||
@@ -635,11 +674,11 @@ ed_attach(isa_dev)
|
|||||||
ifa = ifa->ifa_next;
|
ifa = ifa->ifa_next;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we find an AF_LINK type entry, we well fill in the hardware addr
|
* If we find an AF_LINK type entry we fill in the hardware address
|
||||||
*/
|
*/
|
||||||
if ((ifa != 0) && (ifa->ifa_addr != 0)) {
|
if ((ifa != 0) && (ifa->ifa_addr != 0)) {
|
||||||
/*
|
/*
|
||||||
* Fill in the link level address for this interface
|
* Fill in the link-level address for this interface
|
||||||
*/
|
*/
|
||||||
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
|
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
|
||||||
sdl->sdl_type = IFT_ETHER;
|
sdl->sdl_type = IFT_ETHER;
|
||||||
@@ -651,15 +690,17 @@ ed_attach(isa_dev)
|
|||||||
/*
|
/*
|
||||||
* Print additional info when attached
|
* Print additional info when attached
|
||||||
*/
|
*/
|
||||||
printf(" enet %s type %s", ether_sprintf(sc->arpcom.ac_enaddr),
|
printf("ed%d: address %s, type %s (%dbit) %s\n", isa_dev->id_unit,
|
||||||
sc->type_str);
|
ether_sprintf(sc->arpcom.ac_enaddr), sc->type_str,
|
||||||
|
sc->memwidth, ((sc->vendor == ED_VENDOR_3COM) &&
|
||||||
|
(ifp->if_flags & IFF_LLC0)) ? "tranceiver disabled" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset interface.
|
* Reset interface.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ed_reset(unit, uban)
|
ed_reset(unit)
|
||||||
int unit;
|
int unit;
|
||||||
{
|
{
|
||||||
int s;
|
int s;
|
||||||
@@ -839,6 +880,16 @@ ed_init(unit)
|
|||||||
*/
|
*/
|
||||||
outb(sc->nic_addr + ED_P0_TCR, 0);
|
outb(sc->nic_addr + ED_P0_TCR, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this is a 3Com board, the tranceiver must be software enabled
|
||||||
|
* (there is no settable hardware default).
|
||||||
|
*/
|
||||||
|
if ((sc->vendor == ED_VENDOR_3COM) && (ifp->if_flags & IFF_LLC0)) {
|
||||||
|
outb(sc->asic_addr + ED_3COM_CR, 0);
|
||||||
|
} else {
|
||||||
|
outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_XSEL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set 'running' flag, and clear output active flag.
|
* Set 'running' flag, and clear output active flag.
|
||||||
*/
|
*/
|
||||||
@@ -1221,6 +1272,10 @@ edintr(unit)
|
|||||||
*/
|
*/
|
||||||
if (isr & ED_ISR_RXE) {
|
if (isr & ED_ISR_RXE) {
|
||||||
++sc->arpcom.ac_if.if_ierrors;
|
++sc->arpcom.ac_if.if_ierrors;
|
||||||
|
#ifdef ED_DEBUG
|
||||||
|
printf("ed%d: receive error %x\n", unit,
|
||||||
|
inb(sc->nic_addr + ED_P0_RSR));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1421,14 +1476,26 @@ ed_ioctl(ifp, command, data)
|
|||||||
*/
|
*/
|
||||||
outb(sc->nic_addr + ED_P0_RCR,
|
outb(sc->nic_addr + ED_P0_RCR,
|
||||||
ED_RCR_PRO|ED_RCR_AM|ED_RCR_AB);
|
ED_RCR_PRO|ED_RCR_AM|ED_RCR_AB);
|
||||||
} else
|
} else {
|
||||||
/*
|
/*
|
||||||
* XXX - for multicasts to work, we would need to
|
* XXX - for multicasts to work, we would need to
|
||||||
* rewrite the multicast hashing array with the
|
* rewrite the multicast hashing array with the
|
||||||
* proper hash (would have been destroyed above).
|
* proper hash (would have been destroyed above).
|
||||||
*/
|
*/
|
||||||
outb(sc->nic_addr + ED_P0_RCR, ED_RCR_AB);
|
outb(sc->nic_addr + ED_P0_RCR, ED_RCR_AB);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/*
|
||||||
|
* An unfortunate hack to provide the (required) software control
|
||||||
|
* of the tranceiver for 3Com boards. The LLC0 flag disables
|
||||||
|
* the tranceiver if set.
|
||||||
|
*/
|
||||||
|
if ((sc->vendor == ED_VENDOR_3COM) && (ifp->if_flags & IFF_LLC0)) {
|
||||||
|
outb(sc->asic_addr + ED_3COM_CR, 0);
|
||||||
|
} else {
|
||||||
|
outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_XSEL);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -546,6 +546,14 @@ struct ed_ring {
|
|||||||
#define ED_VENDOR_WD_SMC 0x00 /* Western Digital/SMC */
|
#define ED_VENDOR_WD_SMC 0x00 /* Western Digital/SMC */
|
||||||
#define ED_VENDOR_3COM 0x01 /* 3Com */
|
#define ED_VENDOR_3COM 0x01 /* 3Com */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compile-time config flags
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* this sets the default for enabling/disablng the tranceiver
|
||||||
|
*/
|
||||||
|
#define ED_FLAGS_DISABLE_TRANCEIVER 0x01
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definitions for Western digital/SMC WD80x3 series ASIC
|
* Definitions for Western digital/SMC WD80x3 series ASIC
|
||||||
*/
|
*/
|
||||||
|
|||||||
+97
-30
@@ -16,7 +16,32 @@
|
|||||||
/*
|
/*
|
||||||
* Modification history
|
* Modification history
|
||||||
*
|
*
|
||||||
* $Log$
|
* $Log: if_ed.c,v $
|
||||||
|
* Revision 1.7 93/06/22 04:45:01 davidg
|
||||||
|
* (no additional changes) Second beta release
|
||||||
|
*
|
||||||
|
* Revision 1.6 93/06/22 04:40:35 davidg
|
||||||
|
* minor definition fix to ed_reset()
|
||||||
|
*
|
||||||
|
* Revision 1.5 93/06/22 04:37:39 davidg
|
||||||
|
* fixed some comments
|
||||||
|
*
|
||||||
|
* Revision 1.4 93/06/22 04:34:34 davidg
|
||||||
|
* added support to use the LLC0 'link-level control' flag
|
||||||
|
* to disable the tranceiver for AUI operation on 3Com boards.
|
||||||
|
* The default for this flag can be set in the kernel config
|
||||||
|
* file - 'flags 0x01' sets the flag (disables the tranceiver).
|
||||||
|
*
|
||||||
|
* Revision 1.3 93/06/17 03:57:28 davidg
|
||||||
|
* fixed some printf's
|
||||||
|
*
|
||||||
|
* Revision 1.2 93/06/17 03:26:49 davidg
|
||||||
|
* fixed 3c503 code to determine 8/16bit board
|
||||||
|
* changed attach printf to work with Interim-0.1.5 and NetBSD
|
||||||
|
*
|
||||||
|
* Revision 1.1 93/06/14 22:21:24 davidg
|
||||||
|
* Beta release of device driver for SMC/WD80x3 and 3C503 ethernet boards.
|
||||||
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -432,46 +457,45 @@ ed_probe(isa_dev)
|
|||||||
* Reset NIC and ASIC
|
* Reset NIC and ASIC
|
||||||
*/
|
*/
|
||||||
outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_RST);
|
outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_RST);
|
||||||
/*
|
|
||||||
* Verify that reset bit was set
|
|
||||||
*/
|
|
||||||
if ((inb(sc->asic_addr + ED_3COM_CR) & ED_3COM_CR_RST) == 0)
|
|
||||||
return (0);
|
|
||||||
/*
|
/*
|
||||||
* Wait for a while, then un-reset it
|
* Wait for a while, then un-reset it
|
||||||
*/
|
*/
|
||||||
DELAY(5000);
|
DELAY(5000);
|
||||||
outb(sc->asic_addr + ED_3COM_CR, 0);
|
outb(sc->asic_addr + ED_3COM_CR, 0);
|
||||||
|
|
||||||
/*
|
|
||||||
* Verify that the bit cleared
|
|
||||||
*/
|
|
||||||
if (inb(sc->asic_addr + ED_3COM_CR) & ED_3COM_CR_RST)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait a bit for the NIC to recover from the reset
|
* Wait a bit for the NIC to recover from the reset
|
||||||
*/
|
*/
|
||||||
DELAY(5000);
|
DELAY(5000);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 3Com ASIC defaults to rather strange settings for the CR after
|
||||||
|
* a reset - it's important to set it so that the NIC I/O
|
||||||
|
* registers are mapped. The above setting of it to '0' only
|
||||||
|
* resets the reset condition - the CR is *not* set to zeros.
|
||||||
|
*/
|
||||||
|
outb(sc->asic_addr + ED_3COM_CR, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine if this is an 8bit or 16bit board
|
* Determine if this is an 8bit or 16bit board
|
||||||
*/
|
*/
|
||||||
/* XXX - either this code is broken...or the hardware is... */
|
|
||||||
/* it always comes up 8bit */
|
|
||||||
/*
|
/*
|
||||||
* select page 0 registers
|
* select page 0 registers
|
||||||
*/
|
*/
|
||||||
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
|
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attempt to clear WTS bit. If it doesn't clear, then this is a
|
* Attempt to clear WTS bit. If it doesn't clear, then this is a
|
||||||
* 16bit board.
|
* 16bit board.
|
||||||
*/
|
*/
|
||||||
outb(sc->nic_addr + ED_P0_DCR, 0);
|
outb(sc->nic_addr + ED_P0_DCR, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* select page 2 registers
|
* select page 2 registers
|
||||||
*/
|
*/
|
||||||
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_2|ED_CR_RD2|ED_CR_STP);
|
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_2|ED_CR_RD2|ED_CR_STP);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The 3c503 forces the WTS bit to a one if this is a 16bit board
|
* The 3c503 forces the WTS bit to a one if this is a 16bit board
|
||||||
*/
|
*/
|
||||||
@@ -480,13 +504,10 @@ ed_probe(isa_dev)
|
|||||||
else
|
else
|
||||||
memwidth = 8;
|
memwidth = 8;
|
||||||
|
|
||||||
#if 0
|
|
||||||
printf(" (%dbit)",memwidth);
|
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* select page 0 registers
|
* select page 0 registers
|
||||||
*/
|
*/
|
||||||
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
|
outb(sc->nic_addr + ED_P2_CR, ED_CR_RD2|ED_CR_STP);
|
||||||
|
|
||||||
sc->txb_cnt = 1;
|
sc->txb_cnt = 1;
|
||||||
|
|
||||||
@@ -524,7 +545,7 @@ printf(" (%dbit)",memwidth);
|
|||||||
outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ5);
|
outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ5);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("ed0: Invalid irq configuration\n");
|
printf("ed%d: Invalid irq configuration\n", isa_dev->id_unit);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,13 +578,19 @@ printf(" (%dbit)",memwidth);
|
|||||||
sc->arpcom.ac_enaddr[i] = inb(sc->nic_addr + i);
|
sc->arpcom.ac_enaddr[i] = inb(sc->nic_addr + i);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unmap PROM - select NIC registers
|
* Unmap PROM - select NIC registers. Tranceiver remains disabled at
|
||||||
|
* this point. It's enabled in ed_init so that the attach code
|
||||||
|
* is given a chance to set the default based on a compile-time
|
||||||
|
* config option
|
||||||
*/
|
*/
|
||||||
outb(sc->asic_addr + ED_3COM_CR, 0);
|
outb(sc->asic_addr + ED_3COM_CR, 0);
|
||||||
|
|
||||||
/*
|
#if 0
|
||||||
* Zero memory and verify that it is clear
|
printf("Starting write\n");
|
||||||
*/
|
for (i = 0; i < 8192; ++i)
|
||||||
|
bzero(sc->smem_start, 8192);
|
||||||
|
printf("Done.\n");
|
||||||
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
{ char test_buf[1024];
|
{ char test_buf[1024];
|
||||||
printf("starting write\n");
|
printf("starting write\n");
|
||||||
@@ -576,6 +603,9 @@ printf("done.\n");
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Zero memory and verify that it is clear
|
||||||
|
*/
|
||||||
bzero(sc->smem_start, memsize);
|
bzero(sc->smem_start, memsize);
|
||||||
|
|
||||||
for (i = 0; i < memsize; ++i)
|
for (i = 0; i < memsize; ++i)
|
||||||
@@ -612,7 +642,6 @@ ed_attach(isa_dev)
|
|||||||
ifp->if_unit = isa_dev->id_unit;
|
ifp->if_unit = isa_dev->id_unit;
|
||||||
ifp->if_name = "ed" ;
|
ifp->if_name = "ed" ;
|
||||||
ifp->if_mtu = ETHERMTU;
|
ifp->if_mtu = ETHERMTU;
|
||||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS ;
|
|
||||||
ifp->if_init = ed_init;
|
ifp->if_init = ed_init;
|
||||||
ifp->if_output = ether_output;
|
ifp->if_output = ether_output;
|
||||||
ifp->if_start = ed_start;
|
ifp->if_start = ed_start;
|
||||||
@@ -620,6 +649,16 @@ ed_attach(isa_dev)
|
|||||||
ifp->if_reset = ed_reset;
|
ifp->if_reset = ed_reset;
|
||||||
ifp->if_watchdog = ed_watchdog;
|
ifp->if_watchdog = ed_watchdog;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set default state for LLC0 flag (used to disable the tranceiver
|
||||||
|
* for AUI operation), based on compile-time config option.
|
||||||
|
*/
|
||||||
|
if (isa_dev->id_flags & ED_FLAGS_DISABLE_TRANCEIVER)
|
||||||
|
ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS
|
||||||
|
| IFF_LLC0);
|
||||||
|
else
|
||||||
|
ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS);
|
||||||
|
|
||||||
if_attach(ifp);
|
if_attach(ifp);
|
||||||
|
|
||||||
#if NBPFILTER > 0
|
#if NBPFILTER > 0
|
||||||
@@ -635,11 +674,11 @@ ed_attach(isa_dev)
|
|||||||
ifa = ifa->ifa_next;
|
ifa = ifa->ifa_next;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we find an AF_LINK type entry, we well fill in the hardware addr
|
* If we find an AF_LINK type entry we fill in the hardware address
|
||||||
*/
|
*/
|
||||||
if ((ifa != 0) && (ifa->ifa_addr != 0)) {
|
if ((ifa != 0) && (ifa->ifa_addr != 0)) {
|
||||||
/*
|
/*
|
||||||
* Fill in the link level address for this interface
|
* Fill in the link-level address for this interface
|
||||||
*/
|
*/
|
||||||
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
|
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
|
||||||
sdl->sdl_type = IFT_ETHER;
|
sdl->sdl_type = IFT_ETHER;
|
||||||
@@ -651,15 +690,17 @@ ed_attach(isa_dev)
|
|||||||
/*
|
/*
|
||||||
* Print additional info when attached
|
* Print additional info when attached
|
||||||
*/
|
*/
|
||||||
printf(" enet %s type %s", ether_sprintf(sc->arpcom.ac_enaddr),
|
printf("ed%d: address %s, type %s (%dbit) %s\n", isa_dev->id_unit,
|
||||||
sc->type_str);
|
ether_sprintf(sc->arpcom.ac_enaddr), sc->type_str,
|
||||||
|
sc->memwidth, ((sc->vendor == ED_VENDOR_3COM) &&
|
||||||
|
(ifp->if_flags & IFF_LLC0)) ? "tranceiver disabled" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset interface.
|
* Reset interface.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ed_reset(unit, uban)
|
ed_reset(unit)
|
||||||
int unit;
|
int unit;
|
||||||
{
|
{
|
||||||
int s;
|
int s;
|
||||||
@@ -839,6 +880,16 @@ ed_init(unit)
|
|||||||
*/
|
*/
|
||||||
outb(sc->nic_addr + ED_P0_TCR, 0);
|
outb(sc->nic_addr + ED_P0_TCR, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this is a 3Com board, the tranceiver must be software enabled
|
||||||
|
* (there is no settable hardware default).
|
||||||
|
*/
|
||||||
|
if ((sc->vendor == ED_VENDOR_3COM) && (ifp->if_flags & IFF_LLC0)) {
|
||||||
|
outb(sc->asic_addr + ED_3COM_CR, 0);
|
||||||
|
} else {
|
||||||
|
outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_XSEL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set 'running' flag, and clear output active flag.
|
* Set 'running' flag, and clear output active flag.
|
||||||
*/
|
*/
|
||||||
@@ -1221,6 +1272,10 @@ edintr(unit)
|
|||||||
*/
|
*/
|
||||||
if (isr & ED_ISR_RXE) {
|
if (isr & ED_ISR_RXE) {
|
||||||
++sc->arpcom.ac_if.if_ierrors;
|
++sc->arpcom.ac_if.if_ierrors;
|
||||||
|
#ifdef ED_DEBUG
|
||||||
|
printf("ed%d: receive error %x\n", unit,
|
||||||
|
inb(sc->nic_addr + ED_P0_RSR));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1421,14 +1476,26 @@ ed_ioctl(ifp, command, data)
|
|||||||
*/
|
*/
|
||||||
outb(sc->nic_addr + ED_P0_RCR,
|
outb(sc->nic_addr + ED_P0_RCR,
|
||||||
ED_RCR_PRO|ED_RCR_AM|ED_RCR_AB);
|
ED_RCR_PRO|ED_RCR_AM|ED_RCR_AB);
|
||||||
} else
|
} else {
|
||||||
/*
|
/*
|
||||||
* XXX - for multicasts to work, we would need to
|
* XXX - for multicasts to work, we would need to
|
||||||
* rewrite the multicast hashing array with the
|
* rewrite the multicast hashing array with the
|
||||||
* proper hash (would have been destroyed above).
|
* proper hash (would have been destroyed above).
|
||||||
*/
|
*/
|
||||||
outb(sc->nic_addr + ED_P0_RCR, ED_RCR_AB);
|
outb(sc->nic_addr + ED_P0_RCR, ED_RCR_AB);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/*
|
||||||
|
* An unfortunate hack to provide the (required) software control
|
||||||
|
* of the tranceiver for 3Com boards. The LLC0 flag disables
|
||||||
|
* the tranceiver if set.
|
||||||
|
*/
|
||||||
|
if ((sc->vendor == ED_VENDOR_3COM) && (ifp->if_flags & IFF_LLC0)) {
|
||||||
|
outb(sc->asic_addr + ED_3COM_CR, 0);
|
||||||
|
} else {
|
||||||
|
outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_XSEL);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -546,6 +546,14 @@ struct ed_ring {
|
|||||||
#define ED_VENDOR_WD_SMC 0x00 /* Western Digital/SMC */
|
#define ED_VENDOR_WD_SMC 0x00 /* Western Digital/SMC */
|
||||||
#define ED_VENDOR_3COM 0x01 /* 3Com */
|
#define ED_VENDOR_3COM 0x01 /* 3Com */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compile-time config flags
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* this sets the default for enabling/disablng the tranceiver
|
||||||
|
*/
|
||||||
|
#define ED_FLAGS_DISABLE_TRANCEIVER 0x01
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definitions for Western digital/SMC WD80x3 series ASIC
|
* Definitions for Western digital/SMC WD80x3 series ASIC
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user