⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dc2114x.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * See file CREDITS for list of people who contributed to this * project. * * 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 */#include <common.h>#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) \	&& defined(CONFIG_TULIP)#include <malloc.h>#include <net.h>#include <pci.h>#undef DEBUG_SROM#undef DEBUG_SROM2#undef UPDATE_SROM/* PCI Registers. */#define PCI_CFDA_PSM		0x43#define CFRV_RN		0x000000f0	/* Revision Number */#define WAKEUP		0x00		/* Power Saving Wakeup */#define SLEEP		0x80		/* Power Saving Sleep Mode */#define DC2114x_BRK	0x0020		/* CFRV break between DC21142 & DC21143 *//* Ethernet chip registers. */#define DE4X5_BMR	0x000		/* Bus Mode Register */#define DE4X5_TPD	0x008		/* Transmit Poll Demand Reg */#define DE4X5_RRBA	0x018		/* RX Ring Base Address Reg */#define DE4X5_TRBA	0x020		/* TX Ring Base Address Reg */#define DE4X5_STS	0x028		/* Status Register */#define DE4X5_OMR	0x030		/* Operation Mode Register */#define DE4X5_SICR	0x068		/* SIA Connectivity Register */#define DE4X5_APROM	0x048		/* Ethernet Address PROM *//* Register bits. */#define BMR_SWR		0x00000001	/* Software Reset */#define STS_TS		0x00700000	/* Transmit Process State */#define STS_RS		0x000e0000	/* Receive Process State */#define OMR_ST		0x00002000	/* Start/Stop Transmission Command */#define OMR_SR		0x00000002	/* Start/Stop Receive */#define OMR_PS		0x00040000	/* Port Select */#define OMR_SDP		0x02000000	/* SD Polarity - MUST BE ASSERTED */#define OMR_PM		0x00000080	/* Pass All Multicast *//* Descriptor bits. */#define R_OWN		0x80000000	/* Own Bit */#define RD_RER		0x02000000	/* Receive End Of Ring */#define RD_LS		0x00000100	/* Last Descriptor */#define RD_ES		0x00008000	/* Error Summary */#define TD_TER		0x02000000	/* Transmit End Of Ring */#define T_OWN		0x80000000	/* Own Bit */#define TD_LS		0x40000000	/* Last Segment */#define TD_FS		0x20000000	/* First Segment */#define TD_ES		0x00008000	/* Error Summary */#define TD_SET		0x08000000	/* Setup Packet *//* The EEPROM commands include the alway-set leading bit. */#define SROM_WRITE_CMD	5#define SROM_READ_CMD	6#define SROM_ERASE_CMD	7#define SROM_HWADD	    0x0014	/* Hardware Address offset in SROM */#define SROM_RD		0x00004000	/* Read from Boot ROM */#define EE_DATA_WRITE	      0x04	/* EEPROM chip data in. */#define EE_WRITE_0	    0x4801#define EE_WRITE_1	    0x4805#define EE_DATA_READ	      0x08	/* EEPROM chip data out. */#define SROM_SR		0x00000800	/* Select Serial ROM when set */#define DT_IN		0x00000004	/* Serial Data In */#define DT_CLK		0x00000002	/* Serial ROM Clock */#define DT_CS		0x00000001	/* Serial ROM Chip Select */#define POLL_DEMAND	1#ifdef CONFIG_TULIP_FIX_DAVICOM#define RESET_DM9102(dev) {\    unsigned long i;\    i=INL(dev, 0x0);\    udelay(1000);\    OUTL(dev, i | BMR_SWR, DE4X5_BMR);\    udelay(1000);\}#else#define RESET_DE4X5(dev) {\    int i;\    i=INL(dev, DE4X5_BMR);\    udelay(1000);\    OUTL(dev, i | BMR_SWR, DE4X5_BMR);\    udelay(1000);\    OUTL(dev, i, DE4X5_BMR);\    udelay(1000);\    for (i=0;i<5;i++) {INL(dev, DE4X5_BMR); udelay(10000);}\    udelay(1000);\}#endif#define START_DE4X5(dev) {\    s32 omr; \    omr = INL(dev, DE4X5_OMR);\    omr |= OMR_ST | OMR_SR;\    OUTL(dev, omr, DE4X5_OMR);		/* Enable the TX and/or RX */\}#define STOP_DE4X5(dev) {\    s32 omr; \    omr = INL(dev, DE4X5_OMR);\    omr &= ~(OMR_ST|OMR_SR);\    OUTL(dev, omr, DE4X5_OMR);		/* Disable the TX and/or RX */ \}#define NUM_RX_DESC PKTBUFSRX#ifndef CONFIG_TULIP_FIX_DAVICOM	#define NUM_TX_DESC 1			/* Number of TX descriptors   */#else	#define NUM_TX_DESC 4#endif#define RX_BUFF_SZ  PKTSIZE_ALIGN#define TOUT_LOOP   1000000#define SETUP_FRAME_LEN 192#define ETH_ALEN	6struct de4x5_desc {	volatile s32 status;	u32 des1;	u32 buf;	u32 next;};static struct de4x5_desc rx_ring[NUM_RX_DESC] __attribute__ ((aligned(32))); /* RX descriptor ring         */static struct de4x5_desc tx_ring[NUM_TX_DESC] __attribute__ ((aligned(32))); /* TX descriptor ring         */static int rx_new;                             /* RX descriptor ring pointer */static int tx_new;                             /* TX descriptor ring pointer */static char rxRingSize;static char txRingSize;#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM)static void  sendto_srom(struct eth_device* dev, u_int command, u_long addr);static int   getfrom_srom(struct eth_device* dev, u_long addr);static int   do_eeprom_cmd(struct eth_device *dev, u_long ioaddr,int cmd,int cmd_len);static int   do_read_eeprom(struct eth_device *dev,u_long ioaddr,int location,int addr_len);#endif	/* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */#ifdef UPDATE_SROMstatic int   write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value);static void  update_srom(struct eth_device *dev, bd_t *bis);#endif#ifndef CONFIG_TULIP_FIX_DAVICOMstatic int   read_srom(struct eth_device *dev, u_long ioaddr, int index);static void  read_hw_addr(struct eth_device* dev, bd_t * bis);#endif	/* CONFIG_TULIP_FIX_DAVICOM */static void  send_setup_frame(struct eth_device* dev, bd_t * bis);static int   dc21x4x_init(struct eth_device* dev, bd_t* bis);static int   dc21x4x_send(struct eth_device* dev, volatile void *packet, int length);static int   dc21x4x_recv(struct eth_device* dev);static void  dc21x4x_halt(struct eth_device* dev);#ifdef CONFIG_TULIP_SELECT_MEDIAextern void  dc21x4x_select_media(struct eth_device* dev);#endif#if defined(CONFIG_E500)#define phys_to_bus(a) (a)#else#define phys_to_bus(a)	pci_phys_to_mem((pci_dev_t)dev->priv, a)#endifstatic int INL(struct eth_device* dev, u_long addr){	return le32_to_cpu(*(volatile u_long *)(addr + dev->iobase));}static void OUTL(struct eth_device* dev, int command, u_long addr){	*(volatile u_long *)(addr + dev->iobase) = cpu_to_le32(command);}static struct pci_device_id supported[] = {	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST },	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142 },#ifdef CONFIG_TULIP_FIX_DAVICOM	{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DAVICOM_DM9102A },#endif	{ }};int dc21x4x_initialize(bd_t *bis){	int             	idx=0;	int             	card_number = 0;	int             	cfrv;	unsigned char   	timer;	pci_dev_t		devbusfn;	unsigned int		iobase;	unsigned short		status;	struct eth_device* 	dev;	while(1) {		devbusfn =  pci_find_devices(supported, idx++);		if (devbusfn == -1) {			break;		}		/* Get the chip configuration revision register. */		pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv);#ifndef CONFIG_TULIP_FIX_DAVICOM		if ((cfrv & CFRV_RN) < DC2114x_BRK ) {			printf("Error: The chip is not DC21143.\n");			continue;		}#endif		pci_read_config_word(devbusfn, PCI_COMMAND, &status);		status |=#ifdef CONFIG_TULIP_USE_IO		  PCI_COMMAND_IO |#else		  PCI_COMMAND_MEMORY |#endif		  PCI_COMMAND_MASTER;		pci_write_config_word(devbusfn, PCI_COMMAND, status);		pci_read_config_word(devbusfn, PCI_COMMAND, &status);		if (!(status & PCI_COMMAND_IO)) {			printf("Error: Can not enable I/O access.\n");			continue;		}		if (!(status & PCI_COMMAND_IO)) {			printf("Error: Can not enable I/O access.\n");			continue;		}		if (!(status & PCI_COMMAND_MASTER)) {			printf("Error: Can not enable Bus Mastering.\n");			continue;		}		/* Check the latency timer for values >= 0x60. */		pci_read_config_byte(devbusfn, PCI_LATENCY_TIMER, &timer);		if (timer < 0x60) {			pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x60);		}#ifdef CONFIG_TULIP_USE_IO		/* read BAR for memory space access */		pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase);		iobase &= PCI_BASE_ADDRESS_IO_MASK;#else		/* read BAR for memory space access */		pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &iobase);		iobase &= PCI_BASE_ADDRESS_MEM_MASK;#endif		debug ("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase);		dev = (struct eth_device*) malloc(sizeof *dev);#ifdef CONFIG_TULIP_FIX_DAVICOM		sprintf(dev->name, "Davicom#%d", card_number);#else		sprintf(dev->name, "dc21x4x#%d", card_number);#endif#ifdef CONFIG_TULIP_USE_IO		dev->iobase = pci_io_to_phys(devbusfn, iobase);#else		dev->iobase = pci_mem_to_phys(devbusfn, iobase);#endif		dev->priv   = (void*) devbusfn;		dev->init   = dc21x4x_init;		dev->halt   = dc21x4x_halt;		dev->send   = dc21x4x_send;		dev->recv   = dc21x4x_recv;		/* Ensure we're not sleeping. */		pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP);		udelay(10 * 1000);#ifndef CONFIG_TULIP_FIX_DAVICOM		read_hw_addr(dev, bis);#endif		eth_register(dev);		card_number++;	}	return card_number;}static int dc21x4x_init(struct eth_device* dev, bd_t* bis){	int		i;	int		devbusfn = (int) dev->priv;	/* Ensure we're not sleeping. */	pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP);#ifdef CONFIG_TULIP_FIX_DAVICOM	RESET_DM9102(dev);#else	RESET_DE4X5(dev);#endif	if ((INL(dev, DE4X5_STS) & (STS_TS | STS_RS)) != 0) {		printf("Error: Cannot reset ethernet controller.\n");		return 0;	}#ifdef CONFIG_TULIP_SELECT_MEDIA	dc21x4x_select_media(dev);#else	OUTL(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR);#endif	for (i = 0; i < NUM_RX_DESC; i++) {		rx_ring[i].status = cpu_to_le32(R_OWN);		rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ);		rx_ring[i].buf = cpu_to_le32(phys_to_bus((u32) NetRxPackets[i]));#ifdef CONFIG_TULIP_FIX_DAVICOM		rx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &rx_ring[(i+1) % NUM_RX_DESC]));#else		rx_ring[i].next = 0;#endif	}	for (i=0; i < NUM_TX_DESC; i++) {		tx_ring[i].status = 0;		tx_ring[i].des1 = 0;		tx_ring[i].buf = 0;#ifdef CONFIG_TULIP_FIX_DAVICOM	tx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &tx_ring[(i+1) % NUM_TX_DESC]));#else		tx_ring[i].next = 0;#endif	}	rxRingSize = NUM_RX_DESC;	txRingSize = NUM_TX_DESC;	/* Write the end of list marker to the descriptor lists. */	rx_ring[rxRingSize - 1].des1 |= cpu_to_le32(RD_RER);	tx_ring[txRingSize - 1].des1 |= cpu_to_le32(TD_TER);	/* Tell the adapter where the TX/RX rings are located. */	OUTL(dev, phys_to_bus((u32) &rx_ring), DE4X5_RRBA);	OUTL(dev, phys_to_bus((u32) &tx_ring), DE4X5_TRBA);	START_DE4X5(dev);	tx_new = 0;	rx_new = 0;	send_setup_frame(dev, bis);	return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -