/* * Allocate DP-Ram and memory buffers. We need to allocate a transmit and * receive buffer descriptors from dual port ram, and a character * buffer area from host mem. If we are allocating for the console we need * to do it from bootmem */ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) { int dpmemsz, memsz; u8 *dp_mem; unsigned long dp_offset; u8 *mem_addr; dma_addr_t dma_addr = 0; pr_debug("CPM uart[%d]:allocbuf\n", pinfo->port.line); dpmemsz = sizeof(cbd_t) * (pinfo->rx_nrfifos + pinfo->tx_nrfifos); dp_offset = cpm_dpalloc(dpmemsz, 8); if (IS_ERR_VALUE(dp_offset)) { printk(KERN_ERR "cpm_uart_cpm1.c: could not allocate buffer descriptors\n"); return -ENOMEM; } dp_mem = cpm_dpram_addr(dp_offset); memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); if (is_con) { /* was hostalloc but changed cause it blows away the */ /* large tlb mapping when pinning the kernel area */ mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8)); dma_addr = (u32)cpm_dpram_phys(mem_addr); } else mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr, GFP_KERNEL); if (mem_addr == NULL) { cpm_dpfree(dp_offset); printk(KERN_ERR "cpm_uart_cpm1.c: could not allocate coherent memory\n"); return -ENOMEM; } pinfo->dp_addr = dp_offset; pinfo->mem_addr = mem_addr; /* virtual address*/ pinfo->dma_addr = dma_addr; /* physical address*/ pinfo->mem_size = memsz; pinfo->rx_buf = mem_addr; pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); pinfo->rx_bd_base = (volatile cbd_t *)dp_mem; pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; return 0; }
int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) { int dpmemsz, memsz; u8 *dp_mem; unsigned long dp_offset; u8 *mem_addr; dma_addr_t dma_addr = 0; pr_debug("CPM uart[%d]:allocbuf\n", pinfo->port.line); dpmemsz = sizeof(cbd_t) * (pinfo->rx_nrfifos + pinfo->tx_nrfifos); dp_offset = cpm_dpalloc(dpmemsz, 8); if (IS_ERR_VALUE(dp_offset)) { printk(KERN_ERR "cpm_uart_cpm1.c: could not allocate buffer descriptors\n"); return -ENOMEM; } dp_mem = cpm_dpram_addr(dp_offset); memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); if (is_con) { mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8)); dma_addr = (u32)cpm_dpram_phys(mem_addr); } else mem_addr = dma_alloc_coherent(pinfo->port.dev, memsz, &dma_addr, GFP_KERNEL); if (mem_addr == NULL) { cpm_dpfree(dp_offset); printk(KERN_ERR "cpm_uart_cpm1.c: could not allocate coherent memory\n"); return -ENOMEM; } pinfo->dp_addr = dp_offset; pinfo->mem_addr = mem_addr; pinfo->dma_addr = dma_addr; pinfo->mem_size = memsz; pinfo->rx_buf = mem_addr; pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); pinfo->rx_bd_base = (cbd_t __iomem __force *)dp_mem; pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; return 0; }
static void rpx_iic_init(struct i2c_algo_8xx_data *data) { volatile cpm8xx_t *cp; volatile immap_t *immap; cp = cpmp; /* Get pointer to Communication Processor */ immap = (immap_t *)IMAP_ADDR; /* and to internal registers */ data->iip = (iic_t *)&cp->cp_dparam[PROFF_IIC]; /* Check for and use a microcode relocation patch. */ if ((data->reloc = data->iip->iic_rpbase)) data->iip = (iic_t *)&cp->cp_dpmem[data->iip->iic_rpbase]; data->i2c = (i2c8xx_t *)&(immap->im_i2c); data->cp = cp; /* Initialize Port B IIC pins. */ cp->cp_pbpar |= 0x00000030; cp->cp_pbdir |= 0x00000030; cp->cp_pbodr |= 0x00000030; /* Allocate space for two transmit and two receive buffer * descriptors in the DP ram. */ data->dp_addr = cpm_dpalloc(sizeof(cbd_t) * 4, 8); /* ptr to i2c area */ data->i2c = (i2c8xx_t *)&(((immap_t *)IMAP_ADDR)->im_i2c); }
void idma_pci9_init(void) { uint dpram_offset; volatile idma_t *pram; volatile im_idma_t *idma_reg; volatile cpm2_map_t *immap = cpm2_immr; /* allocate IDMA dpram */ dpram_offset = cpm_dpalloc(sizeof(idma_dpram_t), 64); idma_dpram = cpm_dpram_addr(dpram_offset); /* initialize the IDMA parameter RAM */ memset((void *)idma_dpram, 0, sizeof(idma_dpram_t)); pram = &idma_dpram->pram; pram->ibase = dpram_offset + IDMA_BD_OFFSET; pram->dpr_buf = dpram_offset + IDMA_XFER_BUF_OFFSET; pram->ss_max = 32; pram->dts = 32; /* initialize the IDMA_BASE pointer to the IDMA parameter RAM */ *((ushort *) &immap->im_dprambase[PROFF_IDMA]) = dpram_offset; /* initialize the IDMA registers */ idma_reg = (volatile im_idma_t *) &immap->im_sdma.sdma_idsr1; idma_reg[IDMA_CHAN].idmr = 0; /* mask all IDMA interrupts */ idma_reg[IDMA_CHAN].idsr = 0xff; /* clear all event flags */ printk("<4>Using IDMA%d for MPC8260 device erratum PCI 9 workaround\n", IDMA_CHAN + 1); return; }
/* * Allocate DP-Ram and memory buffers. We need to allocate a transmit and * receive buffer descriptors from dual port ram, and a character * buffer area from host mem. If we are allocating for the console we need * to do it from bootmem */ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) { int dpmemsz, memsz; u8 *dp_mem; unsigned long dp_offset; u8 *mem_addr; dma_addr_t dma_addr = 0; pr_debug("CPM uart[%d]:allocbuf\n", pinfo->port.line); dpmemsz = sizeof(cbd_t) * (pinfo->rx_nrfifos + pinfo->tx_nrfifos); dp_offset = cpm_dpalloc(dpmemsz, 8); if (IS_ERR_VALUE(dp_offset)) { printk(KERN_ERR "cpm_uart_cpm.c: could not allocate buffer descriptors\n"); return -ENOMEM; } dp_mem = cpm_dpram_addr(dp_offset); memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); if (is_con) { /* KGDB hits this before bootmem is setup */ if (init_bootmem_done) { mem_addr = alloc_bootmem(memsz); dma_addr = virt_to_bus(mem_addr); } else { dma_addr = (dma_addr_t)lmb_alloc(memsz, 8); mem_addr = __va(dma_addr); } } else mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr, GFP_KERNEL); if (mem_addr == NULL) { cpm_dpfree(dp_offset); printk(KERN_ERR "cpm_uart_cpm.c: could not allocate coherent memory\n"); return -ENOMEM; } pinfo->dp_addr = dp_offset; pinfo->mem_addr = mem_addr; pinfo->dma_addr = dma_addr; pinfo->mem_size = memsz; pinfo->rx_buf = mem_addr; pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); pinfo->rx_bd_base = (volatile cbd_t *)dp_mem; pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; return 0; }
static int allocate_bd(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); const struct fs_platform_info *fpi = fep->fpi; fep->ring_mem_addr = cpm_dpalloc((fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t), 8); if (IS_ERR_VALUE(fep->ring_mem_addr)) return -ENOMEM; fep->ring_base = (void __iomem __force*) cpm_dpram_addr(fep->ring_mem_addr); return 0; }
/* * Allocate DP-Ram and memory buffers. We need to allocate a transmit and * receive buffer descriptors from dual port ram, and a character * buffer area from host mem. If we are allocating for the console we need * to do it from bootmem */ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) { int dpmemsz, memsz; u8 *dp_mem; uint dp_offset; u8 *mem_addr; dma_addr_t dma_addr = 0; pr_debug("CPM uart[%d]:allocbuf\n", pinfo->port.line); dpmemsz = sizeof(cbd_t) * (pinfo->rx_nrfifos + pinfo->tx_nrfifos); dp_offset = cpm_dpalloc(dpmemsz, 8); if (IS_DPERR(dp_offset)) { printk(KERN_ERR "cpm_uart_cpm.c: could not allocate buffer descriptors\n"); return -ENOMEM; } dp_mem = cpm_dpram_addr(dp_offset); memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); if (is_con) mem_addr = alloc_bootmem(memsz); else mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr, GFP_KERNEL); if (mem_addr == NULL) { cpm_dpfree(dp_offset); printk(KERN_ERR "cpm_uart_cpm.c: could not allocate coherent memory\n"); return -ENOMEM; } pinfo->dp_addr = dp_offset; pinfo->mem_addr = mem_addr; pinfo->dma_addr = dma_addr; pinfo->rx_buf = mem_addr; pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); pinfo->rx_bd_base = (volatile cbd_t *)dp_mem; pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; return 0; }
void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, struct device_node *np) { void __iomem *pram; unsigned long offset; struct resource res; unsigned long len; /* Don't remap parameter RAM if it has already been initialized * during console setup. */ if (IS_SMC(port) && port->smcup) return port->smcup; else if (!IS_SMC(port) && port->sccup) return port->sccup; if (of_address_to_resource(np, 1, &res)) return NULL; len = 1 + res.end - res.start; pram = ioremap(res.start, len); if (!pram) return NULL; if (!IS_SMC(port)) return pram; if (len != 2) { printk(KERN_WARNING "cpm_uart[%d]: device tree references " "SMC pram, using boot loader/wrapper pram mapping. " "Please fix your device tree to reference the pram " "base register instead.\n", port->port.line); return pram; } offset = cpm_dpalloc(PROFF_SMC_SIZE, 64); out_be16(pram, offset); iounmap(pram); return cpm_muram_addr(offset); }
static int do_pd_setup(struct fs_enet_private *fep) { struct of_device *ofdev = to_of_device(fep->dev); struct fs_platform_info *fpi = fep->fpi; int ret = -EINVAL; fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); if (fep->interrupt == NO_IRQ) goto out; fep->fcc.fccp = of_iomap(ofdev->node, 0); if (!fep->fcc.fccp) goto out; fep->fcc.ep = of_iomap(ofdev->node, 1); if (!fep->fcc.ep) goto out_fccp; fep->fcc.fcccp = of_iomap(ofdev->node, 2); if (!fep->fcc.fcccp) goto out_ep; fep->fcc.mem = (void __iomem *)cpm2_immr; fpi->dpram_offset = cpm_dpalloc(128, 8); if (IS_ERR_VALUE(fpi->dpram_offset)) { ret = fpi->dpram_offset; goto out_fcccp; } return 0; out_fcccp: iounmap(fep->fcc.fcccp); out_ep: iounmap(fep->fcc.ep); out_fccp: iounmap(fep->fcc.fccp); out: return ret; }
/* Initialize the CPM Ethernet on SCC. If EPPC-Bug loaded us, or performed * some other network I/O, a whole bunch of this has already been set up. * It is no big deal if we do it again, we just have to disable the * transmit and receive to make sure we don't catch the CPM with some * inconsistent control information. */ static int __init scc_enet_init(void) { struct net_device *dev; struct scc_enet_private *cep; int i, j, k, err; uint dp_offset; unsigned char *eap, *ba; dma_addr_t mem_addr; bd_t *bd; volatile cbd_t *bdp; volatile cpm8xx_t *cp; volatile scc_t *sccp; volatile scc_enet_t *ep; volatile immap_t *immap; cp = cpmp; /* Get pointer to Communication Processor */ immap = (immap_t *)(mfspr(IMMR) & 0xFFFF0000); /* and to internal registers */ bd = (bd_t *)__res; dev = alloc_etherdev(sizeof(*cep)); if (!dev) return -ENOMEM; cep = dev->priv; spin_lock_init(&cep->lock); /* Get pointer to SCC area in parameter RAM. */ ep = (scc_enet_t *)(&cp->cp_dparam[PROFF_ENET]); /* And another to the SCC register area. */ sccp = (volatile scc_t *)(&cp->cp_scc[SCC_ENET]); cep->sccp = (scc_t *)sccp; /* Keep the pointer handy */ /* Disable receive and transmit in case EPPC-Bug started it. */ sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); /* Cookbook style from the MPC860 manual..... * Not all of this is necessary if EPPC-Bug has initialized * the network. * So far we are lucky, all board configurations use the same * pins, or at least the same I/O Port for these functions..... * It can't last though...... */ #if (defined(PA_ENET_RXD) && defined(PA_ENET_TXD)) /* Configure port A pins for Txd and Rxd. */ immap->im_ioport.iop_papar |= (PA_ENET_RXD | PA_ENET_TXD); immap->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD); immap->im_ioport.iop_paodr &= ~PA_ENET_TXD; #elif (defined(PB_ENET_RXD) && defined(PB_ENET_TXD)) /* Configure port B pins for Txd and Rxd. */ immap->im_cpm.cp_pbpar |= (PB_ENET_RXD | PB_ENET_TXD); immap->im_cpm.cp_pbdir &= ~(PB_ENET_RXD | PB_ENET_TXD); immap->im_cpm.cp_pbodr &= ~PB_ENET_TXD; #else #error Exactly ONE pair of PA_ENET_[RT]XD, PB_ENET_[RT]XD must be defined #endif #if defined(PC_ENET_LBK) /* Configure port C pins to disable External Loopback */ immap->im_ioport.iop_pcpar &= ~PC_ENET_LBK; immap->im_ioport.iop_pcdir |= PC_ENET_LBK; immap->im_ioport.iop_pcso &= ~PC_ENET_LBK; immap->im_ioport.iop_pcdat &= ~PC_ENET_LBK; /* Disable Loopback */ #endif /* PC_ENET_LBK */ #ifdef PE_ENET_TCLK /* Configure port E for TCLK and RCLK. */ cp->cp_pepar |= (PE_ENET_TCLK | PE_ENET_RCLK); cp->cp_pedir &= ~(PE_ENET_TCLK | PE_ENET_RCLK); cp->cp_peso &= ~(PE_ENET_TCLK | PE_ENET_RCLK); #else /* Configure port A for TCLK and RCLK. */ immap->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK); immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK); #endif /* Configure port C pins to enable CLSN and RENA. */ immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA); immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA); immap->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA); /* Configure Serial Interface clock routing. * First, clear all SCC bits to zero, then set the ones we want. */ cp->cp_sicr &= ~SICR_ENET_MASK; cp->cp_sicr |= SICR_ENET_CLKRT; /* Manual says set SDDR, but I can't find anything with that * name. I think it is a misprint, and should be SDCR. This * has already been set by the communication processor initialization. */ /* Allocate space for the buffer descriptors in the DP ram. * These are relative offsets in the DP ram address space. * Initialize base addresses for the buffer descriptors. */ dp_offset = cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE, 8); ep->sen_genscc.scc_rbase = dp_offset; cep->rx_bd_base = cpm_dpram_addr(dp_offset); dp_offset = cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE, 8); ep->sen_genscc.scc_tbase = dp_offset; cep->tx_bd_base = cpm_dpram_addr(dp_offset); cep->dirty_tx = cep->cur_tx = cep->tx_bd_base; cep->cur_rx = cep->rx_bd_base; /* Issue init Rx BD command for SCC. * Manual says to perform an Init Rx parameters here. We have * to perform both Rx and Tx because the SCC may have been * already running. * In addition, we have to do it later because we don't yet have * all of the BD control/status set properly. cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_RX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); */ /* Initialize function code registers for big-endian. */ ep->sen_genscc.scc_rfcr = SCC_EB; ep->sen_genscc.scc_tfcr = SCC_EB; /* Set maximum bytes per receive buffer. * This appears to be an Ethernet frame size, not the buffer * fragment size. It must be a multiple of four. */ ep->sen_genscc.scc_mrblr = PKT_MAXBLR_SIZE; /* Set CRC preset and mask. */ ep->sen_cpres = 0xffffffff; ep->sen_cmask = 0xdebb20e3; ep->sen_crcec = 0; /* CRC Error counter */ ep->sen_alec = 0; /* alignment error counter */ ep->sen_disfc = 0; /* discard frame counter */ ep->sen_pads = 0x8888; /* Tx short frame pad character */ ep->sen_retlim = 15; /* Retry limit threshold */ ep->sen_maxflr = PKT_MAXBUF_SIZE; /* maximum frame length register */ ep->sen_minflr = PKT_MINBUF_SIZE; /* minimum frame length register */ ep->sen_maxd1 = PKT_MAXBLR_SIZE; /* maximum DMA1 length */ ep->sen_maxd2 = PKT_MAXBLR_SIZE; /* maximum DMA2 length */ /* Clear hash tables. */ ep->sen_gaddr1 = 0; ep->sen_gaddr2 = 0; ep->sen_gaddr3 = 0; ep->sen_gaddr4 = 0; ep->sen_iaddr1 = 0; ep->sen_iaddr2 = 0; ep->sen_iaddr3 = 0; ep->sen_iaddr4 = 0; /* Set Ethernet station address. */ eap = (unsigned char *)&(ep->sen_paddrh); for (i=5; i>=0; i--) *eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i]; ep->sen_pper = 0; /* 'cause the book says so */ ep->sen_taddrl = 0; /* temp address (LSB) */ ep->sen_taddrm = 0; ep->sen_taddrh = 0; /* temp address (MSB) */ /* Now allocate the host memory pages and initialize the * buffer descriptors. */ bdp = cep->tx_bd_base; for (i=0; i<TX_RING_SIZE; i++) { /* Initialize the BD for every fragment in the page. */ bdp->cbd_sc = 0; bdp->cbd_bufaddr = 0; bdp++; } /* Set the last buffer to wrap. */ bdp--; bdp->cbd_sc |= BD_SC_WRAP; bdp = cep->rx_bd_base; k = 0; for (i=0; i<CPM_ENET_RX_PAGES; i++) { /* Allocate a page. */ ba = (unsigned char *)dma_alloc_coherent(NULL, PAGE_SIZE, &mem_addr, GFP_KERNEL); /* BUG: no check for failure */ /* Initialize the BD for every fragment in the page. */ for (j=0; j<CPM_ENET_RX_FRPPG; j++) { bdp->cbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR; bdp->cbd_bufaddr = mem_addr; cep->rx_vaddr[k++] = ba; mem_addr += CPM_ENET_RX_FRSIZE; ba += CPM_ENET_RX_FRSIZE; bdp++; } } /* Set the last buffer to wrap. */ bdp--; bdp->cbd_sc |= BD_SC_WRAP; /* Let's re-initialize the channel now. We have to do it later * than the manual describes because we have just now finished * the BD initialization. */ cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); cep->skb_cur = cep->skb_dirty = 0; sccp->scc_scce = 0xffff; /* Clear any pending events */ /* Enable interrupts for transmit error, complete frame * received, and any transmit buffer we have also set the * interrupt flag. */ sccp->scc_sccm = (SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB); /* Install our interrupt handler. */ cpm_install_handler(CPMVEC_ENET, scc_enet_interrupt, dev); /* Set GSMR_H to enable all normal operating modes. * Set GSMR_L to enable Ethernet to MC68160. */ sccp->scc_gsmrh = 0; sccp->scc_gsmrl = (SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 | SCC_GSMRL_MODE_ENET); /* Set sync/delimiters. */ sccp->scc_dsr = 0xd555; /* Set processing mode. Use Ethernet CRC, catch broadcast, and * start frame search 22 bit times after RENA. */ sccp->scc_psmr = (SCC_PSMR_ENCRC | SCC_PSMR_NIB22); /* It is now OK to enable the Ethernet transmitter. * Unfortunately, there are board implementation differences here. */ #if (!defined (PB_ENET_TENA) && defined (PC_ENET_TENA) && !defined (PE_ENET_TENA)) immap->im_ioport.iop_pcpar |= PC_ENET_TENA; immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA; #elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && !defined (PE_ENET_TENA)) cp->cp_pbpar |= PB_ENET_TENA; cp->cp_pbdir |= PB_ENET_TENA; #elif ( !defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && defined (PE_ENET_TENA)) cp->cp_pepar |= PE_ENET_TENA; cp->cp_pedir &= ~PE_ENET_TENA; cp->cp_peso |= PE_ENET_TENA; #else #error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA, PE_ENET_TENA #endif #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) /* And while we are here, set the configuration to enable ethernet. */ *((volatile uint *)RPX_CSR_ADDR) &= ~BCSR0_ETHLPBK; *((volatile uint *)RPX_CSR_ADDR) |= (BCSR0_ETHEN | BCSR0_COLTESTDIS | BCSR0_FULLDPLXDIS); #endif #ifdef CONFIG_BSEIP /* BSE uses port B and C for PHY control. */ cp->cp_pbpar &= ~(PB_BSE_POWERUP | PB_BSE_FDXDIS); cp->cp_pbdir |= (PB_BSE_POWERUP | PB_BSE_FDXDIS); cp->cp_pbdat |= (PB_BSE_POWERUP | PB_BSE_FDXDIS); immap->im_ioport.iop_pcpar &= ~PC_BSE_LOOPBACK; immap->im_ioport.iop_pcdir |= PC_BSE_LOOPBACK; immap->im_ioport.iop_pcso &= ~PC_BSE_LOOPBACK; immap->im_ioport.iop_pcdat &= ~PC_BSE_LOOPBACK; #endif #ifdef CONFIG_FADS cp->cp_pbpar |= PB_ENET_TENA; cp->cp_pbdir |= PB_ENET_TENA; /* Enable the EEST PHY. */ *((volatile uint *)BCSR1) &= ~BCSR1_ETHEN; #endif #ifdef CONFIG_MPC885ADS /* Deassert PHY reset and enable the PHY. */ { volatile uint __iomem *bcsr = ioremap(BCSR_ADDR, BCSR_SIZE); uint tmp; tmp = in_be32(bcsr + 1 /* BCSR1 */); tmp |= BCSR1_ETHEN; out_be32(bcsr + 1, tmp); tmp = in_be32(bcsr + 4 /* BCSR4 */); tmp |= BCSR4_ETH10_RST; out_be32(bcsr + 4, tmp); iounmap(bcsr); } /* On MPC885ADS SCC ethernet PHY defaults to the full duplex mode * upon reset. SCC is set to half duplex by default. So this * inconsistency should be better fixed by the software. */ #endif dev->base_addr = (unsigned long)ep; #if 0 dev->name = "CPM_ENET"; #endif /* The CPM Ethernet specific entries in the device structure. */ dev->open = scc_enet_open; dev->hard_start_xmit = scc_enet_start_xmit; dev->tx_timeout = scc_enet_timeout; dev->watchdog_timeo = TX_TIMEOUT; dev->stop = scc_enet_close; dev->get_stats = scc_enet_get_stats; dev->set_multicast_list = set_multicast_list; err = register_netdev(dev); if (err) { free_netdev(dev); return err; } /* And last, enable the transmit and receive processing. */ sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); printk("%s: CPM ENET Version 0.2 on SCC%d, ", dev->name, SCC_ENET+1); for (i=0; i<5; i++) printk("%02x:", dev->dev_addr[i]); printk("%02x\n", dev->dev_addr[5]); return 0; }
/* Initialize the CPM Ethernet on SCC. */ static int __init scc_enet_init(void) { struct net_device *dev; struct scc_enet_private *cep; int i, j, err; uint dp_offset; unsigned char *eap; unsigned long mem_addr; bd_t *bd; volatile cbd_t *bdp; volatile cpm_cpm2_t *cp; volatile scc_t *sccp; volatile scc_enet_t *ep; volatile cpm2_map_t *immap; volatile iop_cpm2_t *io; cp = cpmp; /* Get pointer to Communication Processor */ immap = (cpm2_map_t *)CPM_MAP_ADDR; /* and to internal registers */ io = &immap->im_ioport; bd = (bd_t *)__res; /* Create an Ethernet device instance. */ dev = alloc_etherdev(sizeof(*cep)); if (!dev) return -ENOMEM; cep = dev->priv; spin_lock_init(&cep->lock); /* Get pointer to SCC area in parameter RAM. */ ep = (scc_enet_t *)(&immap->im_dprambase[PROFF_ENET]); /* And another to the SCC register area. */ sccp = (volatile scc_t *)(&immap->im_scc[SCC_ENET]); cep->sccp = (scc_t *)sccp; /* Keep the pointer handy */ /* Disable receive and transmit in case someone left it running. */ sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); /* Configure port C and D pins for SCC Ethernet. This * won't work for all SCC possibilities....it will be * board/port specific. */ io->iop_pparc |= (PC_ENET_RENA | PC_ENET_CLSN | PC_ENET_TXCLK | PC_ENET_RXCLK); io->iop_pdirc &= ~(PC_ENET_RENA | PC_ENET_CLSN | PC_ENET_TXCLK | PC_ENET_RXCLK); io->iop_psorc &= ~(PC_ENET_RENA | PC_ENET_TXCLK | PC_ENET_RXCLK); io->iop_psorc |= PC_ENET_CLSN; io->iop_ppard |= (PD_ENET_RXD | PD_ENET_TXD | PD_ENET_TENA); io->iop_pdird |= (PD_ENET_TXD | PD_ENET_TENA); io->iop_pdird &= ~PD_ENET_RXD; io->iop_psord |= PD_ENET_TXD; io->iop_psord &= ~(PD_ENET_RXD | PD_ENET_TENA); /* Configure Serial Interface clock routing. * First, clear all SCC bits to zero, then set the ones we want. */ immap->im_cpmux.cmx_scr &= ~CMX_CLK_MASK; immap->im_cpmux.cmx_scr |= CMX_CLK_ROUTE; /* Allocate space for the buffer descriptors in the DP ram. * These are relative offsets in the DP ram address space. * Initialize base addresses for the buffer descriptors. */ dp_offset = cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE, 8); ep->sen_genscc.scc_rbase = dp_offset; cep->rx_bd_base = (cbd_t *)cpm_dpram_addr(dp_offset); dp_offset = cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE, 8); ep->sen_genscc.scc_tbase = dp_offset; cep->tx_bd_base = (cbd_t *)cpm_dpram_addr(dp_offset); cep->dirty_tx = cep->cur_tx = cep->tx_bd_base; cep->cur_rx = cep->rx_bd_base; ep->sen_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; ep->sen_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB; /* Set maximum bytes per receive buffer. * This appears to be an Ethernet frame size, not the buffer * fragment size. It must be a multiple of four. */ ep->sen_genscc.scc_mrblr = PKT_MAXBLR_SIZE; /* Set CRC preset and mask. */ ep->sen_cpres = 0xffffffff; ep->sen_cmask = 0xdebb20e3; ep->sen_crcec = 0; /* CRC Error counter */ ep->sen_alec = 0; /* alignment error counter */ ep->sen_disfc = 0; /* discard frame counter */ ep->sen_pads = 0x8888; /* Tx short frame pad character */ ep->sen_retlim = 15; /* Retry limit threshold */ ep->sen_maxflr = PKT_MAXBUF_SIZE; /* maximum frame length register */ ep->sen_minflr = PKT_MINBUF_SIZE; /* minimum frame length register */ ep->sen_maxd1 = PKT_MAXBLR_SIZE; /* maximum DMA1 length */ ep->sen_maxd2 = PKT_MAXBLR_SIZE; /* maximum DMA2 length */ /* Clear hash tables. */ ep->sen_gaddr1 = 0; ep->sen_gaddr2 = 0; ep->sen_gaddr3 = 0; ep->sen_gaddr4 = 0; ep->sen_iaddr1 = 0; ep->sen_iaddr2 = 0; ep->sen_iaddr3 = 0; ep->sen_iaddr4 = 0; /* Set Ethernet station address. * * This is supplied in the board information structure, so we * copy that into the controller. */ eap = (unsigned char *)&(ep->sen_paddrh); for (i=5; i>=0; i--) *eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i]; ep->sen_pper = 0; /* 'cause the book says so */ ep->sen_taddrl = 0; /* temp address (LSB) */ ep->sen_taddrm = 0; ep->sen_taddrh = 0; /* temp address (MSB) */ /* Now allocate the host memory pages and initialize the * buffer descriptors. */ bdp = cep->tx_bd_base; for (i=0; i<TX_RING_SIZE; i++) { /* Initialize the BD for every fragment in the page. */ bdp->cbd_sc = 0; bdp->cbd_bufaddr = 0; bdp++; } /* Set the last buffer to wrap. */ bdp--; bdp->cbd_sc |= BD_SC_WRAP; bdp = cep->rx_bd_base; for (i=0; i<CPM_ENET_RX_PAGES; i++) { /* Allocate a page. */ mem_addr = __get_free_page(GFP_KERNEL); /* BUG: no check for failure */ /* Initialize the BD for every fragment in the page. */ for (j=0; j<CPM_ENET_RX_FRPPG; j++) { bdp->cbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR; bdp->cbd_bufaddr = __pa(mem_addr); mem_addr += CPM_ENET_RX_FRSIZE; bdp++; } } /* Set the last buffer to wrap. */ bdp--; bdp->cbd_sc |= BD_SC_WRAP; /* Let's re-initialize the channel now. We have to do it later * than the manual describes because we have just now finished * the BD initialization. */ cpmp->cp_cpcr = mk_cr_cmd(CPM_ENET_PAGE, CPM_ENET_BLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); cep->skb_cur = cep->skb_dirty = 0; sccp->scc_scce = 0xffff; /* Clear any pending events */ /* Enable interrupts for transmit error, complete frame * received, and any transmit buffer we have also set the * interrupt flag. */ sccp->scc_sccm = (SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB); /* Install our interrupt handler. */ request_irq(SIU_INT_ENET, scc_enet_interrupt, 0, "enet", dev); /* BUG: no check for failure */ /* Set GSMR_H to enable all normal operating modes. * Set GSMR_L to enable Ethernet to MC68160. */ sccp->scc_gsmrh = 0; sccp->scc_gsmrl = (SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 | SCC_GSMRL_MODE_ENET); /* Set sync/delimiters. */ sccp->scc_dsr = 0xd555; /* Set processing mode. Use Ethernet CRC, catch broadcast, and * start frame search 22 bit times after RENA. */ sccp->scc_psmr = (SCC_PSMR_ENCRC | SCC_PSMR_NIB22); /* It is now OK to enable the Ethernet transmitter. * Unfortunately, there are board implementation differences here. */ io->iop_pparc &= ~(PC_EST8260_ENET_LOOPBACK | PC_EST8260_ENET_SQE | PC_EST8260_ENET_NOTFD); io->iop_psorc &= ~(PC_EST8260_ENET_LOOPBACK | PC_EST8260_ENET_SQE | PC_EST8260_ENET_NOTFD); io->iop_pdirc |= (PC_EST8260_ENET_LOOPBACK | PC_EST8260_ENET_SQE | PC_EST8260_ENET_NOTFD); io->iop_pdatc &= ~(PC_EST8260_ENET_LOOPBACK | PC_EST8260_ENET_SQE); io->iop_pdatc |= PC_EST8260_ENET_NOTFD; dev->base_addr = (unsigned long)ep; /* The CPM Ethernet specific entries in the device structure. */ dev->open = scc_enet_open; dev->hard_start_xmit = scc_enet_start_xmit; dev->tx_timeout = scc_enet_timeout; dev->watchdog_timeo = TX_TIMEOUT; dev->stop = scc_enet_close; dev->get_stats = scc_enet_get_stats; dev->set_multicast_list = set_multicast_list; /* And last, enable the transmit and receive processing. */ sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); err = register_netdev(dev); if (err) { free_netdev(dev); return err; } printk("%s: SCC ENET Version 0.1, ", dev->name); for (i=0; i<5; i++) printk("%02x:", dev->dev_addr[i]); printk("%02x\n", dev->dev_addr[5]); return 0; }
static int do_pd_setup(struct fs_enet_private *fep) { #ifdef CONFIG_PPC_CPM_NEW_BINDING struct of_device *ofdev = to_of_device(fep->dev); struct fs_platform_info *fpi = fep->fpi; int ret = -EINVAL; fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); if (fep->interrupt == NO_IRQ) goto out; fep->fcc.fccp = of_iomap(ofdev->node, 0); if (!fep->fcc.fccp) goto out; fep->fcc.ep = of_iomap(ofdev->node, 1); if (!fep->fcc.ep) goto out_fccp; fep->fcc.fcccp = of_iomap(ofdev->node, 2); if (!fep->fcc.fcccp) goto out_ep; fep->fcc.mem = (void __iomem *)cpm2_immr; fpi->dpram_offset = cpm_dpalloc(128, 8); if (IS_ERR_VALUE(fpi->dpram_offset)) { ret = fpi->dpram_offset; goto out_fcccp; } return 0; out_fcccp: iounmap(fep->fcc.fcccp); out_ep: iounmap(fep->fcc.ep); out_fccp: iounmap(fep->fcc.fccp); out: return ret; #else struct platform_device *pdev = to_platform_device(fep->dev); struct resource *r; /* Fill out IRQ field */ fep->interrupt = platform_get_irq(pdev, 0); if (fep->interrupt < 0) return -EINVAL; /* Attach the memory for the FCC Parameter RAM */ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram"); fep->fcc.ep = ioremap(r->start, r->end - r->start + 1); if (fep->fcc.ep == NULL) return -EINVAL; r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_regs"); fep->fcc.fccp = ioremap(r->start, r->end - r->start + 1); if (fep->fcc.fccp == NULL) return -EINVAL; if (fep->fpi->fcc_regs_c) { fep->fcc.fcccp = (void __iomem *)fep->fpi->fcc_regs_c; } else { r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_regs_c"); fep->fcc.fcccp = ioremap(r->start, r->end - r->start + 1); } if (fep->fcc.fcccp == NULL) return -EINVAL; fep->fcc.mem = (void __iomem *)fep->fpi->mem_offset; if (fep->fcc.mem == NULL) return -EINVAL; return 0; #endif }