patch-2.4.18 linux/drivers/net/mace.c
Next file: linux/drivers/net/mii.c
Previous file: linux/drivers/net/irda/w83977af_ir.c
Back to the patch index
Back to the overall index
- Lines: 223
- Date:
Tue Jan 8 18:08:44 2002
- Orig file:
linux.orig/drivers/net/mace.c
- Orig date:
Mon Feb 18 20:18:39 2002
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/mace.c linux/drivers/net/mace.c
@@ -24,18 +24,18 @@
static struct net_device *mace_devs;
static int port_aaui = -1;
-MODULE_PARM(port_aaui, "i");
-MODULE_PARM_DESC(port_aaui, "MACE uses AAUI port (0-1)");
+#define N_RX_RING 8
+#define N_TX_RING 6
+#define MAX_TX_ACTIVE 1
+#define NCMDS_TX 1 /* dma commands per element in tx ring */
+#define RX_BUFLEN (ETH_FRAME_LEN + 8)
+#define TX_TIMEOUT HZ /* 1 second */
-#define N_RX_RING 8
-#define N_TX_RING 6
-#define MAX_TX_ACTIVE 1
-#define NCMDS_TX 1 /* dma commands per element in tx ring */
-#define RX_BUFLEN (ETH_FRAME_LEN + 8)
-#define TX_TIMEOUT HZ /* 1 second */
+/* Chip rev needs workaround on HW & multicast addr change */
+#define BROKEN_ADDRCHG_REV 0x0941
/* Bits in transmit DMA status */
-#define TX_DMA_ERR 0x80
+#define TX_DMA_ERR 0x80
struct mace_data {
volatile struct mace *mace;
@@ -59,6 +59,8 @@
struct timer_list tx_timeout;
int timeout_active;
int port_aaui;
+ int chipid;
+ struct device_node* of_node;
struct net_device *next_mace;
};
@@ -152,9 +154,25 @@
SET_MODULE_OWNER(dev);
mp = dev->priv;
+ mp->of_node = mace;
+
+ if (!request_OF_resource(mace, 0, " (mace)")) {
+ printk(KERN_ERR "MACE: can't request IO resource !\n");
+ goto err_out;
+ }
+ if (!request_OF_resource(mace, 1, " (mace tx dma)")) {
+ printk(KERN_ERR "MACE: can't request TX DMA resource !\n");
+ goto err_out;
+ }
+
+ if (!request_OF_resource(mace, 2, " (mace tx dma)")) {
+ printk(KERN_ERR "MACE: can't request RX DMA resource !\n");
+ goto err_out;
+ }
+
dev->base_addr = mace->addrs[0].address;
mp->mace = (volatile struct mace *)
- ioremap(mace->addrs[0].address, 0x1000);
+ ioremap(mace->addrs[0].address, 0x1000);
dev->irq = mace->intrs[0].line;
printk(KERN_INFO "%s: MACE at", dev->name);
@@ -163,8 +181,10 @@
dev->dev_addr[j] = rev? bitrev(addr[j]): addr[j];
printk("%c%.2x", (j? ':': ' '), dev->dev_addr[j]);
}
- printk(", chip revision %d.%d\n",
- in_8(&mp->mace->chipid_hi), in_8(&mp->mace->chipid_lo));
+ mp->chipid = (in_8(&mp->mace->chipid_hi) << 8) |
+ in_8(&mp->mace->chipid_lo);
+ printk(", chip revision %d.%d\n", mp->chipid >> 8, mp->chipid & 0xff);
+
mp = (struct mace_data *) dev->priv;
mp->maccc = ENXMT | ENRCV;
@@ -221,6 +241,16 @@
mp->next_mace = mace_devs;
mace_devs = dev;
+ return;
+
+err_out:
+ unregister_netdev(dev);
+ if (mp->of_node) {
+ release_OF_resource(mp->of_node, 0);
+ release_OF_resource(mp->of_node, 1);
+ release_OF_resource(mp->of_node, 2);
+ }
+ kfree(dev);
}
static void dbdma_reset(volatile struct dbdma_regs *dma)
@@ -273,14 +303,19 @@
__mace_set_address(dev, dev->dev_addr);
/* clear the multicast filter */
- out_8(&mb->iac, ADDRCHG | LOGADDR);
- while ((in_8(&mb->iac) & ADDRCHG) != 0)
- ;
- for (i = 0; i < 8; ++i) {
- out_8(&mb->ladrf, 0);
+ if (mp->chipid == BROKEN_ADDRCHG_REV)
+ out_8(&mb->iac, LOGADDR);
+ else {
+ out_8(&mb->iac, ADDRCHG | LOGADDR);
+ while ((in_8(&mb->iac) & ADDRCHG) != 0)
+ ;
}
+ for (i = 0; i < 8; ++i)
+ out_8(&mb->ladrf, 0);
+
/* done changing address */
- out_8(&mb->iac, 0);
+ if (mp->chipid != BROKEN_ADDRCHG_REV)
+ out_8(&mb->iac, 0);
if (mp->port_aaui)
out_8(&mb->plscc, PORTSEL_AUI + ENPLSIO);
@@ -290,16 +325,23 @@
static void __mace_set_address(struct net_device *dev, void *addr)
{
- volatile struct mace *mb = ((struct mace_data *) dev->priv)->mace;
+ struct mace_data *mp = (struct mace_data *) dev->priv;
+ volatile struct mace *mb = mp->mace;
unsigned char *p = addr;
int i;
/* load up the hardware address */
- out_8(&mb->iac, ADDRCHG | PHYADDR);
- while ((in_8(&mb->iac) & ADDRCHG) != 0)
- ;
+ if (mp->chipid == BROKEN_ADDRCHG_REV)
+ out_8(&mb->iac, PHYADDR);
+ else {
+ out_8(&mb->iac, ADDRCHG | PHYADDR);
+ while ((in_8(&mb->iac) & ADDRCHG) != 0)
+ ;
+ }
for (i = 0; i < 6; ++i)
out_8(&mb->padr, dev->dev_addr[i] = p[i]);
+ if (mp->chipid != BROKEN_ADDRCHG_REV)
+ out_8(&mb->iac, 0);
}
static int mace_set_address(struct net_device *dev, void *addr)
@@ -312,7 +354,6 @@
__mace_set_address(dev, addr);
- out_8(&mb->iac, 0);
/* note: setting ADDRCHG clears ENRCV */
out_8(&mb->maccc, mp->maccc);
@@ -557,12 +598,17 @@
printk("\n");
#endif
- out_8(&mb->iac, ADDRCHG | LOGADDR);
- while ((in_8(&mb->iac) & ADDRCHG) != 0)
- ;
- for (i = 0; i < 8; ++i) {
- out_8(&mb->ladrf, multicast_filter[i]);
+ if (mp->chipid == BROKEN_ADDRCHG_REV)
+ out_8(&mb->iac, LOGADDR);
+ else {
+ out_8(&mb->iac, ADDRCHG | LOGADDR);
+ while ((in_8(&mb->iac) & ADDRCHG) != 0)
+ ;
}
+ for (i = 0; i < 8; ++i)
+ out_8(&mb->ladrf, multicast_filter[i]);
+ if (mp->chipid != BROKEN_ADDRCHG_REV)
+ out_8(&mb->iac, 0);
}
/* reset maccc */
out_8(&mb->maccc, mp->maccc);
@@ -913,7 +959,10 @@
MODULE_AUTHOR("Paul Mackerras");
MODULE_DESCRIPTION("PowerMac MACE driver.");
+MODULE_PARM(port_aaui, "i");
+MODULE_PARM_DESC(port_aaui, "MACE uses AAUI port (0-1)");
MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
static void __exit mace_cleanup (void)
{
@@ -921,19 +970,23 @@
struct mace_data *mp;
while ((dev = mace_devs) != 0) {
- mp = (struct mace_data *) mace_devs->priv;
- mace_devs = mp->next_mace;
+ mp = (struct mace_data *) mace_devs->priv;
+ mace_devs = mp->next_mace;
- free_irq(dev->irq, dev);
- free_irq(mp->tx_dma_intr, dev);
- free_irq(mp->rx_dma_intr, dev);
+ unregister_netdev(dev);
+ free_irq(dev->irq, dev);
+ free_irq(mp->tx_dma_intr, dev);
+ free_irq(mp->rx_dma_intr, dev);
+
+ release_OF_resource(mp->of_node, 0);
+ release_OF_resource(mp->of_node, 1);
+ release_OF_resource(mp->of_node, 2);
- unregister_netdev(dev);
- kfree(dev);
+ kfree(dev);
}
if (dummy_buf != NULL) {
- kfree(dummy_buf);
- dummy_buf = NULL;
+ kfree(dummy_buf);
+ dummy_buf = NULL;
}
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)