int mace68k_probe(struct net_device *unused) { int j; static int once=0; struct mace68k_data *mp; unsigned char *addr; struct net_device *dev; unsigned char checksum = 0; /* * There can be only one... */ if (once) return -ENODEV; once = 1; if (macintosh_config->ether_type != MAC_ETHER_MACE) return -ENODEV; printk("MACE ethernet should be present "); dev = init_etherdev(0, PRIV_BYTES); if(dev==NULL) { printk("no free memory.\n"); return -ENOMEM; } mp = (struct mace68k_data *) dev->priv; dev->base_addr = (u32)MACE_BASE; mp->mace = (volatile struct mace *) MACE_BASE; printk("at 0x%p", mp->mace); /* * 16K RX ring and 4K TX ring should do nicely */ mp->rx_ring=(void *)__get_free_pages(GFP_KERNEL, 2); mp->tx_ring=(void *)__get_free_page(GFP_KERNEL); printk("."); if(mp->tx_ring==NULL || mp->rx_ring==NULL) { if(mp->tx_ring) free_page((u32)mp->tx_ring); // if(mp->rx_ring) // __free_pages(mp->rx_ring,2); printk("\nNo memory for ring buffers.\n"); return -ENOMEM; } /* We want the receive data to be uncached. We dont care about the byte reading order */ printk("."); kernel_set_cachemode((void *)mp->rx_ring, 16384, IOMAP_NOCACHE_NONSER); printk("."); /* The transmit buffer needs to be write through */ kernel_set_cachemode((void *)mp->tx_ring, 4096, IOMAP_WRITETHROUGH); printk(" Ok\n"); dev->irq = IRQ_MAC_MACE; printk(KERN_INFO "%s: MACE at", dev->name); /* * The PROM contains 8 bytes which total 0xFF when XOR'd * together. Due to the usual peculiar apple brain damage * the bytes are spaced out in a strange boundary and the * bits are reversed. */ addr = (void *)MACE_PROM; for (j = 0; j < 6; ++j) { u8 v=bitrev(addr[j<<4]); checksum^=v; dev->dev_addr[j] = v; printk("%c%.2x", (j ? ':' : ' '), dev->dev_addr[j]); } for (; j < 8; ++j) { checksum^=bitrev(addr[j<<4]); } if(checksum!=0xFF) { printk(" (invalid checksum)\n"); return -ENODEV; } printk("\n"); memset(&mp->stats, 0, sizeof(mp->stats)); init_timer(&mp->tx_timeout); mp->timeout_active = 0; dev->open = mace68k_open; dev->stop = mace68k_close; dev->hard_start_xmit = mace68k_xmit_start; dev->get_stats = mace68k_stats; dev->set_multicast_list = mace68k_set_multicast; dev->set_mac_address = mace68k_set_address; ether_setup(dev); mp = (struct mace68k_data *) dev->priv; mp->maccc = ENXMT | ENRCV; mp->dma_intr = IRQ_MAC_MACE_DMA; psc_write_word(PSC_ENETWR_CTL, 0x9000); psc_write_word(PSC_ENETRD_CTL, 0x9000); psc_write_word(PSC_ENETWR_CTL, 0x0400); psc_write_word(PSC_ENETRD_CTL, 0x0400); /* apple's driver doesn't seem to do this */ /* except at driver shutdown time... */ #if 0 mace68k_dma_off(dev); #endif return 0; }
static int mace_open(struct net_device *dev) { struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; #if 0 int i; i = 200; while (--i) { mb->biucc = SWRST; if (mb->biucc & SWRST) { udelay(10); continue; } break; } if (!i) { printk(KERN_ERR "%s: software reset failed!!\n", dev->name); return -EAGAIN; } #endif mb->biucc = XMTSP_64; mb->fifocc = XMTFW_16 | RCVFW_64 | XMTFWU | RCVFWU | XMTBRST | RCVBRST; mb->xmtfc = AUTO_PAD_XMIT; mb->plscc = PORTSEL_AUI; /* mb->utr = RTRD; */ if (request_irq(dev->irq, mace_interrupt, 0, dev->name, dev)) { printk(KERN_ERR "%s: can't get irq %d\n", dev->name, dev->irq); return -EAGAIN; } if (request_irq(mp->dma_intr, mace_dma_intr, 0, dev->name, dev)) { printk(KERN_ERR "%s: can't get irq %d\n", dev->name, mp->dma_intr); free_irq(dev->irq, dev); return -EAGAIN; } /* Allocate the DMA ring buffers */ mp->rx_ring = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, N_RX_PAGES); mp->tx_ring = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, 0); if (mp->tx_ring==NULL || mp->rx_ring==NULL) { if (mp->rx_ring) free_pages((u32) mp->rx_ring, N_RX_PAGES); if (mp->tx_ring) free_pages((u32) mp->tx_ring, 0); free_irq(dev->irq, dev); free_irq(mp->dma_intr, dev); printk(KERN_ERR "%s: unable to allocate DMA buffers\n", dev->name); return -ENOMEM; } mp->rx_ring_phys = (unsigned char *) virt_to_bus((void *)mp->rx_ring); mp->tx_ring_phys = (unsigned char *) virt_to_bus((void *)mp->tx_ring); /* We want the Rx buffer to be uncached and the Tx buffer to be writethrough */ kernel_set_cachemode((void *)mp->rx_ring, N_RX_PAGES * PAGE_SIZE, IOMAP_NOCACHE_NONSER); kernel_set_cachemode((void *)mp->tx_ring, PAGE_SIZE, IOMAP_WRITETHROUGH); mace_dma_off(dev); /* Not sure what these do */ psc_write_word(PSC_ENETWR_CTL, 0x9000); psc_write_word(PSC_ENETRD_CTL, 0x9000); psc_write_word(PSC_ENETWR_CTL, 0x0400); psc_write_word(PSC_ENETRD_CTL, 0x0400); #if 0 /* load up the hardware address */ mb->iac = ADDRCHG | PHYADDR; while ((mb->iac & ADDRCHG) != 0); for (i = 0; i < 6; ++i) mb->padr = dev->dev_addr[i]; /* clear the multicast filter */ mb->iac = ADDRCHG | LOGADDR; while ((mb->iac & ADDRCHG) != 0); for (i = 0; i < 8; ++i) mb->ladrf = 0; mb->plscc = PORTSEL_GPSI + ENPLSIO; mb->maccc = ENXMT | ENRCV; mb->imr = RCVINT; #endif mace_rxdma_reset(dev); mace_txdma_reset(dev); return 0; }