patch-2.1.53 linux/drivers/net/3c509.c
Next file: linux/drivers/net/Config.in
Previous file: linux/arch/sparc64/solaris/systbl.S
Back to the patch index
Back to the overall index
- Lines: 178
- Date:
Thu Sep 4 13:25:28 1997
- Orig file:
v2.1.52/linux/drivers/net/3c509.c
- Orig date:
Tue May 13 22:41:08 1997
diff -u --recursive --new-file v2.1.52/linux/drivers/net/3c509.c linux/drivers/net/3c509.c
@@ -27,6 +27,7 @@
FIXES:
Alan Cox: Removed the 'Unexpected interrupt' bug.
Michael Meskes: Upgraded to Donald Becker's version 1.07.
+ Phil Blundell: Media selection support.
*/
static char *version = "3c509.c:1.07 6/15/95 becker@cesdis.gsfc.nasa.gov\n";
@@ -127,6 +128,7 @@
static struct net_device_stats *el3_get_stats(struct device *dev);
static int el3_rx(struct device *dev);
static int el3_close(struct device *dev);
+static int el3_set_config(struct device *dev, struct ifmap *map);
#ifdef HAVE_MULTICAST
static void set_multicast_list(struct device *dev);
#endif
@@ -136,9 +138,15 @@
__initfunc(int el3_probe(struct device *dev))
{
short lrs_state = 0xff, i;
- ushort ioaddr, irq, if_port;
+ ushort ioaddr, irq, port;
short *phys_addr = (short *)dev->dev_addr;
static int current_tag = 0;
+ static int el3_portmap[] = {
+ IF_PORT_10BASET,
+ IF_PORT_AUI,
+ IF_PORT_UNKNOWN,
+ IF_PORT_10BASE2
+ };
/* First check all slots of the EISA bus. The next slot address to
probe is kept in 'eisa_addr' to support multiple probe() calls. */
@@ -156,7 +164,7 @@
outw(SelectWindow | 0, ioaddr + 0xC80 + EL3_CMD);
irq = inw(ioaddr + WN0_IRQ) >> 12;
- if_port = inw(ioaddr + 6)>>14;
+ port = inw(ioaddr + 6)>>14;
for (i = 0; i < 3; i++)
phys_addr[i] = htons(read_eeprom(ioaddr, i));
@@ -179,7 +187,7 @@
if ((mca_adaptor_id(i) | 1) == 0x627c) {
ioaddr = mca_pos_base_addr(i);
irq = inw(ioaddr + WN0_IRQ) >> 12;
- if_port = inw(ioaddr + 6)>>14;
+ port = inw(ioaddr + 6)>>14;
for (i = 0; i < 3; i++)
phys_addr[i] = htons(read_eeprom(ioaddr, i));
@@ -245,7 +253,7 @@
{
unsigned short iobase = id_read_eeprom(8);
- if_port = iobase >> 14;
+ port = iobase >> 14;
ioaddr = 0x200 + ((iobase & 0x1f) << 4);
}
if (dev->irq > 1 && dev->irq < 16)
@@ -273,13 +281,13 @@
found:
dev->base_addr = ioaddr;
dev->irq = irq;
- dev->if_port = if_port;
+ dev->if_port = el3_portmap[port];
request_region(dev->base_addr, EL3_IO_EXTENT, "3c509");
{
- const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
+ static const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
printk("%s: 3c509 at %#3.3lx tag %d, %s port, address ",
- dev->name, dev->base_addr, current_tag, if_names[dev->if_port]);
+ dev->name, dev->base_addr, current_tag, if_names[port]);
}
/* Read in the station address. */
@@ -301,12 +309,14 @@
dev->hard_start_xmit = &el3_start_xmit;
dev->stop = &el3_close;
dev->get_stats = &el3_get_stats;
+ dev->set_config = &el3_set_config;
#ifdef HAVE_MULTICAST
dev->set_multicast_list = &set_multicast_list;
#endif
/* Fill in the generic fields of the device structure. */
ether_setup(dev);
+ dev->flags |= IFF_PORTSEL;
return 0;
}
@@ -345,6 +355,59 @@
static int
+el3_set_config(struct device *dev, struct ifmap *map)
+{
+ int ioaddr = dev->base_addr;
+ if (map->port != dev->if_port) {
+ switch (map->port) {
+ case IF_PORT_10BASE2:
+ case IF_PORT_10BASET:
+ case IF_PORT_AUI:
+ if (dev->start) {
+ if (dev->if_port == IF_PORT_10BASE2)
+ /* Turn off thinnet power. */
+ outw(StopCoax, ioaddr + EL3_CMD);
+ else if (dev->if_port == IF_PORT_10BASET) {
+ /* Disable link beat and jabber */
+ EL3WINDOW(4);
+ outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
+ EL3WINDOW(1);
+ }
+ }
+ printk(KERN_INFO "%s: %s port selected.\n", dev->name,
+ if_port_text[map->port]);
+ dev->if_port = map->port;
+ if (dev->start) {
+ if (dev->if_port == IF_PORT_10BASE2)
+ /* Start the thinnet transceiver. We should really wait 50ms...*/
+ outw(StartCoax, ioaddr + EL3_CMD);
+ else if (dev->if_port == IF_PORT_10BASET) {
+ /* 10baseT interface, enabled link beat and jabber check. */
+ EL3WINDOW(4);
+ outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
+ EL3WINDOW(1);
+ }
+ }
+ break;
+ default:
+ printk(KERN_ERR "%s: %s port not supported.\n", dev->name,
+ if_port_text[map->port]);
+ return -EINVAL;
+ }
+ }
+ if (map->irq != dev->irq) {
+ printk(KERN_ERR "%s: cannot change interrupt.\n", dev->name);
+ return -EINVAL;
+ }
+ if (map->base_addr != dev->base_addr) {
+ printk(KERN_ERR "%s: cannot change base address.\n", dev->name);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+
+static int
el3_open(struct device *dev)
{
int ioaddr = dev->base_addr;
@@ -376,10 +439,10 @@
for (i = 0; i < 6; i++)
outb(dev->dev_addr[i], ioaddr + i);
- if (dev->if_port == 3)
+ if (dev->if_port == IF_PORT_10BASE2)
/* Start the thinnet transceiver. We should really wait 50ms...*/
outw(StartCoax, ioaddr + EL3_CMD);
- else if (dev->if_port == 0) {
+ else if (dev->if_port == IF_PORT_10BASET) {
/* 10baseT interface, enabled link beat and jabber check. */
EL3WINDOW(4);
outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
@@ -731,10 +794,10 @@
outw(RxDisable, ioaddr + EL3_CMD);
outw(TxDisable, ioaddr + EL3_CMD);
- if (dev->if_port == 3)
+ if (dev->if_port == IF_PORT_10BASE2)
/* Turn off thinnet power. Green! */
outw(StopCoax, ioaddr + EL3_CMD);
- else if (dev->if_port == 0) {
+ else if (dev->if_port == IF_PORT_10BASET) {
/* Disable link beat and jabber, if_port may change ere next open(). */
EL3WINDOW(4);
outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov