📄 smc911x.h
字号:
/*------------------------------------------------------------------------ . smc911x.h - macros for SMSC's LAN911{5,6,7,8} single-chip Ethernet device. . . Copyright (C) 2005 Sensoria Corp. . Derived from the unified SMC91x driver by Nicolas Pitre . . This program is free software; you can redistribute it and/or modify . it under the terms of the GNU General Public License as published by . the Free Software Foundation; either version 2 of the License, or . (at your option) any later version. . . This program is distributed in the hope that it will be useful, . but WITHOUT ANY WARRANTY; without even the implied warranty of . MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the . GNU General Public License for more details. . . You should have received a copy of the GNU General Public License . along with this program; if not, write to the Free Software . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA . . Information contained in this file was obtained from the LAN9118 . manual from SMC. To get a copy, if you really want one, you can find . information under www.smsc.com. . . Authors . Dustin McIntire <dustin@sensoria.com> . ---------------------------------------------------------------------------*/#ifndef _SMC911X_H_#define _SMC911X_H_/* * Use the DMA feature on PXA chips */#ifdef CONFIG_ARCH_PXA #define SMC_USE_PXA_DMA 1 #define SMC_USE_16BIT 0 #define SMC_USE_32BIT 1 #define SMC_IRQ_SENSE IRQF_TRIGGER_FALLING#elif defined(CONFIG_SH_MAGIC_PANEL_R2) #define SMC_USE_SH_DMA 0 #define SMC_USE_16BIT 0 #define SMC_USE_32BIT 1 #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW#endif/* * Define the bus width specific IO macros */#if SMC_USE_16BIT#define SMC_inb(a, r) readb((a) + (r))#define SMC_inw(a, r) readw((a) + (r))#define SMC_inl(a, r) ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw(a+2, r)<<16))#define SMC_outb(v, a, r) writeb(v, (a) + (r))#define SMC_outw(v, a, r) writew(v, (a) + (r))#define SMC_outl(v, a, r) \ do{ \ writel(v & 0xFFFF, (a) + (r)); \ writel(v >> 16, (a) + (r) + 2); \ } while (0)#define SMC_insl(a, r, p, l) readsw((short*)((a) + (r)), p, l*2)#define SMC_outsl(a, r, p, l) writesw((short*)((a) + (r)), p, l*2)#elif SMC_USE_32BIT#define SMC_inb(a, r) readb((a) + (r))#define SMC_inw(a, r) readw((a) + (r))#define SMC_inl(a, r) readl((a) + (r))#define SMC_outb(v, a, r) writeb(v, (a) + (r))#define SMC_outl(v, a, r) writel(v, (a) + (r))#define SMC_insl(a, r, p, l) readsl((int*)((a) + (r)), p, l)#define SMC_outsl(a, r, p, l) writesl((int*)((a) + (r)), p, l)#endif /* SMC_USE_16BIT */#ifdef SMC_USE_PXA_DMA#define SMC_USE_DMA/* * Define the request and free functions * These are unfortunately architecture specific as no generic allocation * mechanism exits */#define SMC_DMA_REQUEST(dev, handler) \ pxa_request_dma(dev->name, DMA_PRIO_LOW, handler, dev)#define SMC_DMA_FREE(dev, dma) \ pxa_free_dma(dma)#define SMC_DMA_ACK_IRQ(dev, dma) \{ \ if (DCSR(dma) & DCSR_BUSERR) { \ printk("%s: DMA %d bus error!\n", dev->name, dma); \ } \ DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; \}/* * Use a DMA for RX and TX packets. */#include <linux/dma-mapping.h>#include <asm/dma.h>#include <asm/arch/pxa-regs.h>static dma_addr_t rx_dmabuf, tx_dmabuf;static int rx_dmalen, tx_dmalen;#ifdef SMC_insl#undef SMC_insl#define SMC_insl(a, r, p, l) \ smc_pxa_dma_insl(lp->dev, a, lp->physaddr, r, lp->rxdma, p, l)static inline voidsmc_pxa_dma_insl(struct device *dev, u_long ioaddr, u_long physaddr, int reg, int dma, u_char *buf, int len){ /* 64 bit alignment is required for memory to memory DMA */ if ((long)buf & 4) { *((u32 *)buf) = SMC_inl(ioaddr, reg); buf += 4; len--; } len *= 4; rx_dmabuf = dma_map_single(dev, buf, len, DMA_FROM_DEVICE); rx_dmalen = len; DCSR(dma) = DCSR_NODESC; DTADR(dma) = rx_dmabuf; DSADR(dma) = physaddr + reg; DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 | DCMD_WIDTH4 | DCMD_ENDIRQEN | (DCMD_LENGTH & rx_dmalen)); DCSR(dma) = DCSR_NODESC | DCSR_RUN;}#endif#ifdef SMC_insw#undef SMC_insw#define SMC_insw(a, r, p, l) \ smc_pxa_dma_insw(lp->dev, a, lp->physaddr, r, lp->rxdma, p, l)static inline voidsmc_pxa_dma_insw(struct device *dev, u_long ioaddr, u_long physaddr, int reg, int dma, u_char *buf, int len){ /* 64 bit alignment is required for memory to memory DMA */ while ((long)buf & 6) { *((u16 *)buf) = SMC_inw(ioaddr, reg); buf += 2; len--; } len *= 2; rx_dmabuf = dma_map_single(dev, buf, len, DMA_FROM_DEVICE); rx_dmalen = len; DCSR(dma) = DCSR_NODESC; DTADR(dma) = rx_dmabuf; DSADR(dma) = physaddr + reg; DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 | DCMD_WIDTH2 | DCMD_ENDIRQEN | (DCMD_LENGTH & rx_dmalen)); DCSR(dma) = DCSR_NODESC | DCSR_RUN;}#endif#ifdef SMC_outsl#undef SMC_outsl#define SMC_outsl(a, r, p, l) \ smc_pxa_dma_outsl(lp->dev, a, lp->physaddr, r, lp->txdma, p, l)static inline voidsmc_pxa_dma_outsl(struct device *dev, u_long ioaddr, u_long physaddr, int reg, int dma, u_char *buf, int len){ /* 64 bit alignment is required for memory to memory DMA */ if ((long)buf & 4) { SMC_outl(*((u32 *)buf), ioaddr, reg); buf += 4; len--; } len *= 4; tx_dmabuf = dma_map_single(dev, buf, len, DMA_TO_DEVICE); tx_dmalen = len; DCSR(dma) = DCSR_NODESC; DSADR(dma) = tx_dmabuf; DTADR(dma) = physaddr + reg; DCMD(dma) = (DCMD_INCSRCADDR | DCMD_BURST32 | DCMD_WIDTH4 | DCMD_ENDIRQEN | (DCMD_LENGTH & tx_dmalen)); DCSR(dma) = DCSR_NODESC | DCSR_RUN;}#endif#ifdef SMC_outsw#undef SMC_outsw#define SMC_outsw(a, r, p, l) \ smc_pxa_dma_outsw(lp->dev, a, lp->physaddr, r, lp->txdma, p, l)static inline voidsmc_pxa_dma_outsw(struct device *dev, u_long ioaddr, u_long physaddr, int reg, int dma, u_char *buf, int len){ /* 64 bit alignment is required for memory to memory DMA */ while ((long)buf & 6) { SMC_outw(*((u16 *)buf), ioaddr, reg); buf += 2; len--; } len *= 2; tx_dmabuf = dma_map_single(dev, buf, len, DMA_TO_DEVICE); tx_dmalen = len; DCSR(dma) = DCSR_NODESC; DSADR(dma) = tx_dmabuf; DTADR(dma) = physaddr + reg; DCMD(dma) = (DCMD_INCSRCADDR | DCMD_BURST32 | DCMD_WIDTH2 | DCMD_ENDIRQEN | (DCMD_LENGTH & tx_dmalen)); DCSR(dma) = DCSR_NODESC | DCSR_RUN;}#endif#endif /* SMC_USE_PXA_DMA *//* Chip Parameters and Register Definitions */#define SMC911X_TX_FIFO_LOW_THRESHOLD (1536*2)#define SMC911X_IO_EXTENT 0x100#define SMC911X_EEPROM_LEN 7/* Below are the register offsets and bit definitions * of the Lan911x memory space */#define RX_DATA_FIFO (0x00)#define TX_DATA_FIFO (0x20)#define TX_CMD_A_INT_ON_COMP_ (0x80000000)#define TX_CMD_A_INT_BUF_END_ALGN_ (0x03000000)#define TX_CMD_A_INT_4_BYTE_ALGN_ (0x00000000)#define TX_CMD_A_INT_16_BYTE_ALGN_ (0x01000000)#define TX_CMD_A_INT_32_BYTE_ALGN_ (0x02000000)#define TX_CMD_A_INT_DATA_OFFSET_ (0x001F0000)#define TX_CMD_A_INT_FIRST_SEG_ (0x00002000)#define TX_CMD_A_INT_LAST_SEG_ (0x00001000)#define TX_CMD_A_BUF_SIZE_ (0x000007FF)#define TX_CMD_B_PKT_TAG_ (0xFFFF0000)#define TX_CMD_B_ADD_CRC_DISABLE_ (0x00002000)#define TX_CMD_B_DISABLE_PADDING_ (0x00001000)#define TX_CMD_B_PKT_BYTE_LENGTH_ (0x000007FF)#define RX_STATUS_FIFO (0x40)#define RX_STS_PKT_LEN_ (0x3FFF0000)#define RX_STS_ES_ (0x00008000)#define RX_STS_BCST_ (0x00002000)#define RX_STS_LEN_ERR_ (0x00001000)#define RX_STS_RUNT_ERR_ (0x00000800)#define RX_STS_MCAST_ (0x00000400)#define RX_STS_TOO_LONG_ (0x00000080)#define RX_STS_COLL_ (0x00000040)#define RX_STS_ETH_TYPE_ (0x00000020)#define RX_STS_WDOG_TMT_ (0x00000010)#define RX_STS_MII_ERR_ (0x00000008)#define RX_STS_DRIBBLING_ (0x00000004)#define RX_STS_CRC_ERR_ (0x00000002)#define RX_STATUS_FIFO_PEEK (0x44)#define TX_STATUS_FIFO (0x48)#define TX_STS_TAG_ (0xFFFF0000)#define TX_STS_ES_ (0x00008000)#define TX_STS_LOC_ (0x00000800)#define TX_STS_NO_CARR_ (0x00000400)#define TX_STS_LATE_COLL_ (0x00000200)#define TX_STS_MANY_COLL_ (0x00000100)#define TX_STS_COLL_CNT_ (0x00000078)#define TX_STS_MANY_DEFER_ (0x00000004)#define TX_STS_UNDERRUN_ (0x00000002)#define TX_STS_DEFERRED_ (0x00000001)#define TX_STATUS_FIFO_PEEK (0x4C)#define ID_REV (0x50)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -