/* * Initialize the RC32434 ethernet controller. */ static int rc32434_init(struct net_device *dev) { struct rc32434_local *lp = (struct rc32434_local *)dev->priv; int i, j; /* Disable DMA */ rc32434_abort_tx(dev); rc32434_abort_rx(dev); /* reset ethernet logic */ __raw_writel(0, &lp->eth_regs->ethintfc); while((__raw_readl(&lp->eth_regs->ethintfc) & ETHINTFC_rip_m)) dev->trans_start = jiffies; /* Enable Ethernet Interface */ __raw_writel(ETHINTFC_en_m, &lp->eth_regs->ethintfc); #ifndef CONFIG_IDT_USE_NAPI tasklet_disable(lp->rx_tasklet); #endif tasklet_disable(lp->tx_tasklet); /* Initialize the transmit Descriptors */ for (i = 0; i < RC32434_NUM_TDS; i++) { lp->td_ring[i].control = DMAD_iof_m; lp->td_ring[i].devcs = ETHTX_fd_m | ETHTX_ld_m; lp->td_ring[i].ca = 0; lp->td_ring[i].link = 0; if (lp->tx_skb[i] != NULL) { dev_kfree_skb_any(lp->tx_skb[i]); lp->tx_skb[i] = NULL; } } lp->tx_next_done = lp->tx_chain_head = lp->tx_chain_tail = lp->tx_full = lp->tx_count = 0; lp-> tx_chain_status = empty; /* * Initialize the receive descriptors so that they * become a circular linked list, ie. let the last * descriptor point to the first again. */ for (i=0; i<RC32434_NUM_RDS; i++) { struct sk_buff *skb = lp->rx_skb[i]; if (lp->rx_skb[i] == NULL) { skb = dev_alloc_skb(RC32434_RBSIZE + 2); if (skb == NULL) { ERR("No memory in the system\n"); for (j = 0; j < RC32434_NUM_RDS; j ++) if (lp->rx_skb[j] != NULL) dev_kfree_skb_any(lp->rx_skb[j]); return 1; } else { skb->dev = dev; skb_reserve(skb, 2); lp->rx_skb[i] = skb; lp->rd_ring[i].ca = CPHYSADDR(skb->data); } } lp->rd_ring[i].control = DMAD_iod_m | DMA_COUNT(RC32434_RBSIZE); lp->rd_ring[i].devcs = 0; lp->rd_ring[i].ca = CPHYSADDR(skb->data); lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[i+1]); } /* loop back */ lp->rd_ring[RC32434_NUM_RDS-1].link = CPHYSADDR(&lp->rd_ring[0]); lp->rx_next_done = 0; lp->rd_ring[RC32434_NUM_RDS-1].control |= DMAD_cod_m; lp->rx_chain_head = 0; lp->rx_chain_tail = 0; lp->rx_chain_status = empty; __raw_writel(0, &lp->rx_dma_regs->dmas); /* Start Rx DMA */ rc32434_start_rx(lp, &lp->rd_ring[0]); /* Enable F E bit in Tx DMA */ __raw_writel(__raw_readl(&lp->tx_dma_regs->dmasm) & ~(DMASM_f_m | DMASM_e_m), &lp->tx_dma_regs->dmasm); /* Enable D H E bit in Rx DMA */ __raw_writel(__raw_readl(&lp->rx_dma_regs->dmasm) & ~(DMASM_d_m | DMASM_h_m | DMASM_e_m), &lp->rx_dma_regs->dmasm); /* Accept only packets destined for this Ethernet device address */ __raw_writel(ETHARC_ab_m, &lp->eth_regs->etharc); /* Set all Ether station address registers to their initial values */ __raw_writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal0); __raw_writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah0); __raw_writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal1); __raw_writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah1); __raw_writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal2); __raw_writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah2); __raw_writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal3); __raw_writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah3); /* Frame Length Checking, Pad Enable, CRC Enable, Full Duplex set */ __raw_writel(ETHMAC2_pe_m | ETHMAC2_cen_m | ETHMAC2_fd_m, &lp->eth_regs->ethmac2); //ETHMAC2_flc_m ETHMAC2_fd_m lp->duplex_mode /* Back to back inter-packet-gap */ __raw_writel(0x15, &lp->eth_regs->ethipgt); /* Non - Back to back inter-packet-gap */ __raw_writel(0x12, &lp->eth_regs->ethipgr); /* Management Clock Prescaler Divisor */ /* Clock independent setting */ __raw_writel(((idt_cpu_freq)/MII_CLOCK+1) & ~1, &lp->eth_regs->ethmcp); /* don't transmit until fifo contains 48b */ __raw_writel(48, &lp->eth_regs->ethfifott); __raw_writel(ETHMAC1_re_m, &lp->eth_regs->ethmac1); #ifndef CONFIG_IDT_USE_NAPI tasklet_enable(lp->rx_tasklet); #endif tasklet_enable(lp->tx_tasklet); netif_start_queue(dev); return 0; }
/* * Initialize the BANYAN ethernet controller. */ static int acacia_init(struct net_device *dev) { struct acacia_local *lp = (struct acacia_local *)dev->priv; int i; /* Disable DMA */ acacia_halt_tx(dev); acacia_halt_rx(dev); /* reset ethernet logic */ writel(0, &lp->eth_regs->ethintfc); i = readl(&lp->eth_regs->ethintfc); for(i = 0xfffff; i>0 ; i--) { if (!(readl(&lp->eth_regs->ethintfc) & ETHINTFC_rip_m)) break; } /* Enable Ethernet Interface */ writel(ETHINTFC_en_m, &lp->eth_regs->ethintfc); /* Fifo Tx Threshold level */ /* Accept only packets destined for this Ethernet device address */ /* cgg - and broadcasts */ writel(ETHARC_ab_m, &lp->eth_regs->etharc); /* Set all Ether station address registers to their initial values */ writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal0); writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah0); writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal1); writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah1); writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal2); writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah2); writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal3); writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah3); /* Input Ready threshold = 16, output Ready threshold = 16 */ #if 0 writel((0x10 << 16) + 16, &lp->eth_regs->ethfifost); #endif /* Frame Length Checking, Pad Enable, CRC Enable, Full Duplex set */ writel(ETHMAC2_flc_m | ETHMAC2_pe_m | ETHMAC2_cen_m | ETHMAC2_fd_m, &lp->eth_regs->ethmac2); /* Back to back inter-packet-gap */ writel(0x15, &lp->eth_regs->ethipgt); /* Non - Back to back inter-packet-gap */ writel(0x12, &lp->eth_regs->ethipgr); /* Management Clock Prescaler Divisor */ /* cgg - changed from clock independent setting: writel(40, &lp->eth_regs->ethmcp); */ writel(((IDT_BUS_FREQ * 1000 * 1000)/MII_CLOCK+1) & ~1, &lp->eth_regs->ethmcp); /* Clear Stat. Registers by reading them */ #if 0 tmp = readl(&lp->eth_regs->ethrbc); tmp = readl(&lp->eth_regs->ethrpc); tmp = readl(&lp->eth_regs->ethrupc); tmp = readl(&lp->eth_regs->ethrfc); tmp = readl(&lp->eth_regs->ethtbc); #endif /* don't transmit until fifo contains 48b */ writel(48, &lp->eth_regs->ethfifott); writel(ETHMAC1_re_m, &lp->eth_regs->ethmac1); /* Initialize the transmit Descriptors */ for (i = 0; i < ACACIA_NUM_TDS; i++) { lp->td_ring[i].control = DMAD_f_m; lp->td_ring[i].devcs = 0; lp->td_ring[i].ca = 0; lp->td_ring[i].link = 0; if (lp->tx_skb[i] != NULL) { /* free dangling skb */ dev_kfree_skb_any(lp->tx_skb[i]); lp->tx_skb[i] = NULL; } } lp->tx_next_in = lp->tx_next_out = lp->tx_count = 0; /* * Initialize the receive descriptors so that they * become a circular linked list, ie. let the last * descriptor point to the first again. */ for (i=0; i<ACACIA_NUM_RDS; i++) { lp->rd_ring[i].control = DMAD_iod_m | DMA_COUNT(ACACIA_RBSIZE); lp->rd_ring[i].devcs = 0; lp->rd_ring[i].ca = virt_to_phys(&lp->rba[i * ACACIA_RBSIZE]); lp->rd_ring[i].link = kseg1_to_phys(&lp->rd_ring[i+1]); } /* loop back */ lp->rd_ring[ACACIA_NUM_RDS-1].link = kseg1_to_phys(&lp->rd_ring[0]); lp->rx_next_out = 0; writel(0, &lp->rx_dma_regs->dmas); /* Start Rx DMA */ acacia_start_rx(lp, &lp->rd_ring[0]); writel(readl(&lp->tx_dma_regs->dmasm) & ~(DMAS_f_m | DMAS_e_m), &lp->tx_dma_regs->dmasm); writel(readl(&lp->rx_dma_regs->dmasm) & ~(DMAS_d_m | DMAS_h_m | DMAS_e_m), &lp->rx_dma_regs->dmasm); netif_start_queue(dev); return 0; }