[go: nahoru, domu]

13c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO/*******************************************************************************
23c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  This is the driver for the MAC 10/100 on-chip Ethernet controller
33c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  currently tested on all the ST boards based on STb7109 and stx7200 SoCs.
43c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
53c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  DWC Ether MAC 10/100 Universal version 4.0 has been used for developing
63c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  this code.
73c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
856b106ae7b1f6b7cef4ef7e79a03b59cfc940923Giuseppe CAVALLARO  This contains the functions to handle the dma.
93c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
103c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  Copyright (C) 2007-2009  STMicroelectronics Ltd
113c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
123c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  This program is free software; you can redistribute it and/or modify it
133c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  under the terms and conditions of the GNU General Public License,
143c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  version 2, as published by the Free Software Foundation.
153c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
163c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  This program is distributed in the hope it will be useful, but WITHOUT
173c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
183c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
193c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  more details.
203c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
213c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  You should have received a copy of the GNU General Public License along with
223c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  this program; if not, write to the Free Software Foundation, Inc.,
233c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
243c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
253c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  The full GNU General Public License is included in this distribution in
263c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  the file called "COPYING".
273c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
283c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
293c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO*******************************************************************************/
303c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
31b7f080cfe223b3b7424872639d153695615a9255Alexey Dobriyan#include <asm/io.h>
323c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO#include "dwmac100.h"
333c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO#include "dwmac_dma.h"
343c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
35c24602ef86649376e9d71ea808cd877e414d340bGiuseppe CAVALLAROstatic int dwmac100_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb,
36c24602ef86649376e9d71ea808cd877e414d340bGiuseppe CAVALLARO			     int burst_len, u32 dma_tx, u32 dma_rx, int atds)
373c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO{
383c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	u32 value = readl(ioaddr + DMA_BUS_MODE);
39c629882ac73cab2cd41d9948caeed633fc570fc0Giuseppe CAVALLARO	int limit;
40c629882ac73cab2cd41d9948caeed633fc570fc0Giuseppe CAVALLARO
413c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	/* DMA SW reset */
423c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	value |= DMA_BUS_MODE_SFT_RESET;
433c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	writel(value, ioaddr + DMA_BUS_MODE);
44bbc1754639f771cd2b515fed39b977549b373034Francesco Virlinzi	limit = 10;
45c629882ac73cab2cd41d9948caeed633fc570fc0Giuseppe CAVALLARO	while (limit--) {
46c629882ac73cab2cd41d9948caeed633fc570fc0Giuseppe CAVALLARO		if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
47c629882ac73cab2cd41d9948caeed633fc570fc0Giuseppe CAVALLARO			break;
48bbc1754639f771cd2b515fed39b977549b373034Francesco Virlinzi		mdelay(10);
49c629882ac73cab2cd41d9948caeed633fc570fc0Giuseppe CAVALLARO	}
50c629882ac73cab2cd41d9948caeed633fc570fc0Giuseppe CAVALLARO	if (limit < 0)
51c629882ac73cab2cd41d9948caeed633fc570fc0Giuseppe CAVALLARO		return -EBUSY;
523c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
533c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	/* Enable Application Access by writing to DMA CSR0 */
543c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
55ceb694997e1b5d45627553ac7b1f88ff16cb9507Giuseppe CAVALLARO	       ioaddr + DMA_BUS_MODE);
563c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
573c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	/* Mask interrupts by writing to CSR7 */
583c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
593c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
60ceb694997e1b5d45627553ac7b1f88ff16cb9507Giuseppe CAVALLARO	/* RX/TX descriptor base addr lists must be written into
61ceb694997e1b5d45627553ac7b1f88ff16cb9507Giuseppe CAVALLARO	 * DMA CSR3 and CSR4, respectively
62ceb694997e1b5d45627553ac7b1f88ff16cb9507Giuseppe CAVALLARO	 */
633c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
643c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
653c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
663c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	return 0;
673c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO}
683c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
69ceb694997e1b5d45627553ac7b1f88ff16cb9507Giuseppe CAVALLARO/* Store and Forward capability is not used at all.
70ceb694997e1b5d45627553ac7b1f88ff16cb9507Giuseppe CAVALLARO *
71ceb694997e1b5d45627553ac7b1f88ff16cb9507Giuseppe CAVALLARO * The transmit threshold can be programmed by setting the TTC bits in the DMA
72ceb694997e1b5d45627553ac7b1f88ff16cb9507Giuseppe CAVALLARO * control register.
73ceb694997e1b5d45627553ac7b1f88ff16cb9507Giuseppe CAVALLARO */
74ad01b7d480a4a135f974afd5c617c417e0b0542fGiuseppe CAVALLAROstatic void dwmac100_dma_operation_mode(void __iomem *ioaddr, int txmode,
753c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO					int rxmode)
763c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO{
773c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	u32 csr6 = readl(ioaddr + DMA_CONTROL);
783c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
793c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	if (txmode <= 32)
803c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO		csr6 |= DMA_CONTROL_TTC_32;
813c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	else if (txmode <= 64)
823c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO		csr6 |= DMA_CONTROL_TTC_64;
833c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	else
843c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO		csr6 |= DMA_CONTROL_TTC_128;
853c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
863c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	writel(csr6, ioaddr + DMA_CONTROL);
873c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO}
883c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
89ad01b7d480a4a135f974afd5c617c417e0b0542fGiuseppe CAVALLAROstatic void dwmac100_dump_dma_regs(void __iomem *ioaddr)
903c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO{
913c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	int i;
923c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
9383d7af64ac9eaf4f4db7228677bc25f23c383790Giuseppe CAVALLARO	pr_debug("DWMAC 100 DMA CSR\n");
943c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	for (i = 0; i < 9; i++)
953c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO		pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i,
96ceb694997e1b5d45627553ac7b1f88ff16cb9507Giuseppe CAVALLARO			 (DMA_BUS_MODE + i * 4),
97ceb694997e1b5d45627553ac7b1f88ff16cb9507Giuseppe CAVALLARO			 readl(ioaddr + DMA_BUS_MODE + i * 4));
9883d7af64ac9eaf4f4db7228677bc25f23c383790Giuseppe CAVALLARO
9983d7af64ac9eaf4f4db7228677bc25f23c383790Giuseppe CAVALLARO	pr_debug("\tCSR20 (0x%x): 0x%08x, CSR21 (0x%x): 0x%08x\n",
10083d7af64ac9eaf4f4db7228677bc25f23c383790Giuseppe CAVALLARO		 DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR),
101ceb694997e1b5d45627553ac7b1f88ff16cb9507Giuseppe CAVALLARO		 DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR));
1023c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO}
1033c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
104ceb694997e1b5d45627553ac7b1f88ff16cb9507Giuseppe CAVALLARO/* DMA controller has two counters to track the number of the missed frames. */
1053c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLAROstatic void dwmac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
106ad01b7d480a4a135f974afd5c617c417e0b0542fGiuseppe CAVALLARO				       void __iomem *ioaddr)
1073c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO{
1083c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	struct net_device_stats *stats = (struct net_device_stats *)data;
1093c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
1103c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
1113c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	if (unlikely(csr8)) {
1123c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO		if (csr8 & DMA_MISSED_FRAME_OVE) {
1133c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO			stats->rx_over_errors += 0x800;
1143c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO			x->rx_overflow_cntr += 0x800;
1153c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO		} else {
1163c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO			unsigned int ove_cntr;
1173c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO			ove_cntr = ((csr8 & DMA_MISSED_FRAME_OVE_CNTR) >> 17);
1183c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO			stats->rx_over_errors += ove_cntr;
1193c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO			x->rx_overflow_cntr += ove_cntr;
1203c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO		}
1213c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
1223c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO		if (csr8 & DMA_MISSED_FRAME_OVE_M) {
1233c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO			stats->rx_missed_errors += 0xffff;
1243c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO			x->rx_missed_cntr += 0xffff;
1253c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO		} else {
1263c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO			unsigned int miss_f = (csr8 & DMA_MISSED_FRAME_M_CNTR);
1273c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO			stats->rx_missed_errors += miss_f;
1283c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO			x->rx_missed_cntr += miss_f;
1293c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO		}
1303c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	}
1313c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO}
1323c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO
133cadb7924b10b2a3117dafe14d6d6d28035ec4ddbstephen hemmingerconst struct stmmac_dma_ops dwmac100_dma_ops = {
1343c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	.init = dwmac100_dma_init,
1353c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	.dump_regs = dwmac100_dump_dma_regs,
1363c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	.dma_mode = dwmac100_dma_operation_mode,
1373c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	.dma_diagnostic_fr = dwmac100_dma_diagnostic_fr,
1383c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	.enable_dma_transmission = dwmac_enable_dma_transmission,
1393c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	.enable_dma_irq = dwmac_enable_dma_irq,
1403c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	.disable_dma_irq = dwmac_disable_dma_irq,
1413c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	.start_tx = dwmac_dma_start_tx,
1423c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	.stop_tx = dwmac_dma_stop_tx,
1433c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	.start_rx = dwmac_dma_start_rx,
1443c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	.stop_rx = dwmac_dma_stop_rx,
1453c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO	.dma_interrupt = dwmac_dma_interrupt,
1463c32be635c18ead00d460b7bdad1da52622ff40fGiuseppe CAVALLARO};
147