示例#1
0
文件: korina.c 项目: anchowee/linino
/*
 * 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; 
}
示例#2
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;
}