3c574, 3c515 bitfields abuse
wn3_config is shared by these cards; the way we deal with it is both bad C (union abuse) and broken on big-endian. For 3c515 it's less serious (ISA cards are quite rare outside of little-endian boxen), but 3c574 is a pcmcia one and that'd better be endian-independent... Fix is the same in both cases. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
c15561f0e5
commit
b665982409
2 changed files with 48 additions and 43 deletions
|
@ -243,14 +243,16 @@ enum eeprom_offset {
|
||||||
enum Window3 { /* Window 3: MAC/config bits. */
|
enum Window3 { /* Window 3: MAC/config bits. */
|
||||||
Wn3_Config = 0, Wn3_MAC_Ctrl = 6, Wn3_Options = 8,
|
Wn3_Config = 0, Wn3_MAC_Ctrl = 6, Wn3_Options = 8,
|
||||||
};
|
};
|
||||||
union wn3_config {
|
enum wn3_config {
|
||||||
int i;
|
Ram_size = 7,
|
||||||
struct w3_config_fields {
|
Ram_width = 8,
|
||||||
unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2;
|
Ram_speed = 0x30,
|
||||||
int pad8:8;
|
Rom_size = 0xc0,
|
||||||
unsigned int ram_split:2, pad18:2, xcvr:3, pad21:1, autoselect:1;
|
Ram_split_shift = 16,
|
||||||
int pad24:7;
|
Ram_split = 3 << Ram_split_shift,
|
||||||
} u;
|
Xcvr_shift = 20,
|
||||||
|
Xcvr = 7 << Xcvr_shift,
|
||||||
|
Autoselect = 0x1000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Window4 {
|
enum Window4 {
|
||||||
|
@ -614,7 +616,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
|
||||||
/* Read the station address from the EEPROM. */
|
/* Read the station address from the EEPROM. */
|
||||||
EL3WINDOW(0);
|
EL3WINDOW(0);
|
||||||
for (i = 0; i < 0x18; i++) {
|
for (i = 0; i < 0x18; i++) {
|
||||||
short *phys_addr = (short *) dev->dev_addr;
|
__be16 *phys_addr = (__be16 *) dev->dev_addr;
|
||||||
int timer;
|
int timer;
|
||||||
outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd);
|
outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd);
|
||||||
/* Pause for at least 162 us. for the read to take place. */
|
/* Pause for at least 162 us. for the read to take place. */
|
||||||
|
@ -646,22 +648,22 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
|
||||||
|
|
||||||
{
|
{
|
||||||
char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" };
|
char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" };
|
||||||
union wn3_config config;
|
__u32 config;
|
||||||
EL3WINDOW(3);
|
EL3WINDOW(3);
|
||||||
vp->available_media = inw(ioaddr + Wn3_Options);
|
vp->available_media = inw(ioaddr + Wn3_Options);
|
||||||
config.i = inl(ioaddr + Wn3_Config);
|
config = inl(ioaddr + Wn3_Config);
|
||||||
if (corkscrew_debug > 1)
|
if (corkscrew_debug > 1)
|
||||||
printk(KERN_INFO " Internal config register is %4.4x, transceivers %#x.\n",
|
printk(KERN_INFO " Internal config register is %4.4x, transceivers %#x.\n",
|
||||||
config.i, inw(ioaddr + Wn3_Options));
|
config, inw(ioaddr + Wn3_Options));
|
||||||
printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
|
printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
|
||||||
8 << config.u.ram_size,
|
8 << config & Ram_size,
|
||||||
config.u.ram_width ? "word" : "byte",
|
config & Ram_width ? "word" : "byte",
|
||||||
ram_split[config.u.ram_split],
|
ram_split[(config & Ram_split) >> Ram_split_shift],
|
||||||
config.u.autoselect ? "autoselect/" : "",
|
config & Autoselect ? "autoselect/" : "",
|
||||||
media_tbl[config.u.xcvr].name);
|
media_tbl[(config & Xcvr) >> Xcvr_shift].name);
|
||||||
dev->if_port = config.u.xcvr;
|
vp->default_media = (config & Xcvr) >> Xcvr_shift;
|
||||||
vp->default_media = config.u.xcvr;
|
vp->autoselect = config & Autoselect ? 1 : 0;
|
||||||
vp->autoselect = config.u.autoselect;
|
dev->if_port = vp->default_media;
|
||||||
}
|
}
|
||||||
if (vp->media_override != 7) {
|
if (vp->media_override != 7) {
|
||||||
printk(KERN_INFO " Media override to transceiver type %d (%s).\n",
|
printk(KERN_INFO " Media override to transceiver type %d (%s).\n",
|
||||||
|
@ -694,14 +696,14 @@ static int corkscrew_open(struct net_device *dev)
|
||||||
{
|
{
|
||||||
int ioaddr = dev->base_addr;
|
int ioaddr = dev->base_addr;
|
||||||
struct corkscrew_private *vp = netdev_priv(dev);
|
struct corkscrew_private *vp = netdev_priv(dev);
|
||||||
union wn3_config config;
|
__u32 config;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Before initializing select the active media port. */
|
/* Before initializing select the active media port. */
|
||||||
EL3WINDOW(3);
|
EL3WINDOW(3);
|
||||||
if (vp->full_duplex)
|
if (vp->full_duplex)
|
||||||
outb(0x20, ioaddr + Wn3_MAC_Ctrl); /* Set the full-duplex bit. */
|
outb(0x20, ioaddr + Wn3_MAC_Ctrl); /* Set the full-duplex bit. */
|
||||||
config.i = inl(ioaddr + Wn3_Config);
|
config = inl(ioaddr + Wn3_Config);
|
||||||
|
|
||||||
if (vp->media_override != 7) {
|
if (vp->media_override != 7) {
|
||||||
if (corkscrew_debug > 1)
|
if (corkscrew_debug > 1)
|
||||||
|
@ -727,12 +729,12 @@ static int corkscrew_open(struct net_device *dev)
|
||||||
} else
|
} else
|
||||||
dev->if_port = vp->default_media;
|
dev->if_port = vp->default_media;
|
||||||
|
|
||||||
config.u.xcvr = dev->if_port;
|
config = (config & ~Xcvr) | (dev->if_port << Xcvr_shift);
|
||||||
outl(config.i, ioaddr + Wn3_Config);
|
outl(config, ioaddr + Wn3_Config);
|
||||||
|
|
||||||
if (corkscrew_debug > 1) {
|
if (corkscrew_debug > 1) {
|
||||||
printk("%s: corkscrew_open() InternalConfig %8.8x.\n",
|
printk("%s: corkscrew_open() InternalConfig %8.8x.\n",
|
||||||
dev->name, config.i);
|
dev->name, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
outw(TxReset, ioaddr + EL3_CMD);
|
outw(TxReset, ioaddr + EL3_CMD);
|
||||||
|
@ -901,7 +903,7 @@ static void corkscrew_timer(unsigned long data)
|
||||||
ok = 1;
|
ok = 1;
|
||||||
}
|
}
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
union wn3_config config;
|
__u32 config;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
dev->if_port =
|
dev->if_port =
|
||||||
|
@ -928,9 +930,9 @@ static void corkscrew_timer(unsigned long data)
|
||||||
ioaddr + Wn4_Media);
|
ioaddr + Wn4_Media);
|
||||||
|
|
||||||
EL3WINDOW(3);
|
EL3WINDOW(3);
|
||||||
config.i = inl(ioaddr + Wn3_Config);
|
config = inl(ioaddr + Wn3_Config);
|
||||||
config.u.xcvr = dev->if_port;
|
config = (config & ~Xcvr) | (dev->if_port << Xcvr_shift);
|
||||||
outl(config.i, ioaddr + Wn3_Config);
|
outl(config, ioaddr + Wn3_Config);
|
||||||
|
|
||||||
outw(dev->if_port == 3 ? StartCoax : StopCoax,
|
outw(dev->if_port == 3 ? StartCoax : StopCoax,
|
||||||
ioaddr + EL3_CMD);
|
ioaddr + EL3_CMD);
|
||||||
|
|
|
@ -187,14 +187,16 @@ enum Window1 {
|
||||||
enum Window3 { /* Window 3: MAC/config bits. */
|
enum Window3 { /* Window 3: MAC/config bits. */
|
||||||
Wn3_Config=0, Wn3_MAC_Ctrl=6, Wn3_Options=8,
|
Wn3_Config=0, Wn3_MAC_Ctrl=6, Wn3_Options=8,
|
||||||
};
|
};
|
||||||
union wn3_config {
|
enum wn3_config {
|
||||||
int i;
|
Ram_size = 7,
|
||||||
struct w3_config_fields {
|
Ram_width = 8,
|
||||||
unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2;
|
Ram_speed = 0x30,
|
||||||
int pad8:8;
|
Rom_size = 0xc0,
|
||||||
unsigned int ram_split:2, pad18:2, xcvr:3, pad21:1, autoselect:1;
|
Ram_split_shift = 16,
|
||||||
int pad24:7;
|
Ram_split = 3 << Ram_split_shift,
|
||||||
} u;
|
Xcvr_shift = 20,
|
||||||
|
Xcvr = 7 << Xcvr_shift,
|
||||||
|
Autoselect = 0x1000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Window4 { /* Window 4: Xcvr/media bits. */
|
enum Window4 { /* Window 4: Xcvr/media bits. */
|
||||||
|
@ -342,7 +344,7 @@ static int tc574_config(struct pcmcia_device *link)
|
||||||
kio_addr_t ioaddr;
|
kio_addr_t ioaddr;
|
||||||
__be16 *phys_addr;
|
__be16 *phys_addr;
|
||||||
char *cardname;
|
char *cardname;
|
||||||
union wn3_config config;
|
__u32 config;
|
||||||
DECLARE_MAC_BUF(mac);
|
DECLARE_MAC_BUF(mac);
|
||||||
|
|
||||||
phys_addr = (__be16 *)dev->dev_addr;
|
phys_addr = (__be16 *)dev->dev_addr;
|
||||||
|
@ -401,9 +403,9 @@ static int tc574_config(struct pcmcia_device *link)
|
||||||
outw(0<<11, ioaddr + RunnerRdCtrl);
|
outw(0<<11, ioaddr + RunnerRdCtrl);
|
||||||
printk(KERN_INFO " ASIC rev %d,", mcr>>3);
|
printk(KERN_INFO " ASIC rev %d,", mcr>>3);
|
||||||
EL3WINDOW(3);
|
EL3WINDOW(3);
|
||||||
config.i = inl(ioaddr + Wn3_Config);
|
config = inl(ioaddr + Wn3_Config);
|
||||||
lp->default_media = config.u.xcvr;
|
lp->default_media = (config & Xcvr) >> Xcvr_shift;
|
||||||
lp->autoselect = config.u.autoselect;
|
lp->autoselect = config & Autoselect ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_timer(&lp->media);
|
init_timer(&lp->media);
|
||||||
|
@ -464,8 +466,9 @@ static int tc574_config(struct pcmcia_device *link)
|
||||||
dev->name, cardname, dev->base_addr, dev->irq,
|
dev->name, cardname, dev->base_addr, dev->irq,
|
||||||
print_mac(mac, dev->dev_addr));
|
print_mac(mac, dev->dev_addr));
|
||||||
printk(" %dK FIFO split %s Rx:Tx, %sMII interface.\n",
|
printk(" %dK FIFO split %s Rx:Tx, %sMII interface.\n",
|
||||||
8 << config.u.ram_size, ram_split[config.u.ram_split],
|
8 << config & Ram_size,
|
||||||
config.u.autoselect ? "autoselect " : "");
|
ram_split[(config & Ram_split) >> Ram_split_shift],
|
||||||
|
config & Autoselect ? "autoselect " : "");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue