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

📄 dm9000.c

📁 bootloader源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************** Copyright (c) 2001-2002  Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the Jasper DVD boot loader *//* * dm9000.c * * ethernet driver for DM9000 * * first revision by Ho Lee 11/05/2002 * EEPROM interface by Ho Lee 11/18/2002 */#include "config.h"#include "uart.h"#include "util.h"#include "quasar.h"#include "net.h"#include "specific.h"#ifdef SUPPORT_NETWORK#define DM9000_IGNOREID			0#define DM9000_RXDMA			0//// compatibility// typedef unsigned char u8;typedef unsigned short u16;typedef unsigned int u32;#define udelay(x)		DELAY(x)#define virt_to_phys(x)	((unsigned int)(x))// // constant defitions related DM9000 chipset//#define DM9000_ID		0x90000A46#define DM9000_REG00	0x00#define DM9000_REG05	0x30	/* SKIP_CRC/SKIP_LONG */#define DM9000_REG08	0x27#define DM9000_REG09	0x38#define DM9000_REG0A	0x08#define DM9000_REGFF	0x83	/* IMR */#define DM9000_PHY		0x40	/* PHY address 0x01 */#define DM9000_PKT_MAX	1536	/* Received packet max size */#define DM9000_PKT_RDY	0x01	/* Packet ready to receive */#define DM9000_MIN_IO	0x300#define DM9000_MAX_IO	0x370#define DM9000_INT_MII	0x00#define DM9000_EXT_MII	0x80#define DM9000_VID_L	0x28#define DM9000_VID_H	0x29#define DM9000_PID_L	0x2A#define DM9000_PID_H	0x2B#define DM9801_NOISE_FLOOR	0x08#define DM9802_NOISE_FLOOR	0x05enum DM9000_PHY_mode {	DM9000_10MHD = 0, DM9000_100MHD = 1, DM9000_10MFD = 4,	DM9000_100MFD = 5, DM9000_AUTO = 8, DM9000_1M_HPNA =0x10 };enum DM9000_NIC_TYPE {	FASTETHER_NIC = 0, HOMERUN_NIC = 1, LONGRUN_NIC = 2 };//// type definitions// typedef struct board_info {	u16 ioaddr;					/* Register I/O base address */	u16 io_data;				/* Data I/O address */	u16 irq;					/* IRQ */	u16 tx_pkt_cnt;	u16 queue_pkt_len;	u8 op_mode;					/* PHY operation mode */	u8 io_mode;					/* 0:word, 2:byte */	u8 link_failed;				/* Ever link failed */	u8 device_wait_reset;		/* device state */	u8 nic_type;				/* NIC type */} board_info_t;//// global variables// static board_info_t g_board_info;//// Basic I/O//static unsigned char __inline__ dmfe_inb(unsigned int addr){	return (unsigned char) (quasar_lbc_readl(addr) & 0x000000ff);}static unsigned short __inline__ dmfe_inw(unsigned int addr){	return (unsigned short) (quasar_lbc_readl(addr) & 0x0000ffff);}static void __inline__ dmfe_outb(unsigned int value, unsigned int addr){	quasar_lbc_writel(addr, value & 0x000000ff);}static void __inline__ dmfe_outw(unsigned int value, unsigned int addr){	quasar_lbc_writel(addr, value & 0x0000ffff);}static unsigned char ior(board_info_t *db, int reg){	dmfe_outb(reg, db->ioaddr);	return dmfe_inb(db->io_data);}static void iow(board_info_t *db, int reg, u8 value){	dmfe_outb(reg, db->ioaddr);	dmfe_outb(value, db->io_data);}// // Series I/O//#if !DM9000_RXDMAstatic void dmfe_insw(u16 *ptr, int len, int addr){	int i;		volatile unsigned int *pquasar = (volatile unsigned int *) QUASAR_MAP_AREA;	volatile unsigned int *paddr = pquasar + (QUASAR_LBC_READ_ADDR >> 2);	volatile unsigned int *pdata = pquasar + (QUASAR_LBC_READ_DATA >> 2);	volatile unsigned int *pstatus = pquasar + (QUASAR_LBC_STATUS >> 2);	#define RX_ONETIME									\		*paddr = addr; 									\		while (*pstatus & 0x01) 						\			; 											\		ptr[i] = *pdata;	for (i = 0; i < len; ++i) {		RX_ONETIME	}}#endifstatic void dmfe_outsw(u16 *ptr, int len, int addr){	int i;	volatile unsigned int *pquasar = (volatile unsigned int *) QUASAR_MAP_AREA;	volatile unsigned int *paddr = pquasar + (QUASAR_LBC_WRITE_ADDR >> 2);	volatile unsigned int *pdata = pquasar + (QUASAR_LBC_WRITE_DATA >> 2);	volatile unsigned int *pstatus = pquasar + (QUASAR_LBC_STATUS >> 2);	#define TX_ONETIME									\		*pdata = ptr[i];								\		while (*pstatus & 0x02)							\			;	*paddr = addr;	for (i = 0; i < len; ++i) {		TX_ONETIME	}}//// DMA//#if DM9000_RXDMAstatic void dmfe_start_rxdma(u16 *ptr, int len, int addr){	quasar_flush_cache_data_region((unsigned int) ptr, (unsigned int) ptr + (len << 1) + 8);	quasar_setup_q2h_dma(1, virt_to_phys(ptr), len << 1);	quasar_setup_lbc_readfifo(0, addr, len << 1);	do {		;	} while ((quasar_readl_reg(Q4_Q2H_int_status) & 0x08) == 0x08);}static void dmfe_cleanup_rxdma(void){	quasar_cleanup_lbc_fifo();}#endif//// Init & Main//int dmfe_probe(struct net_device *dev);static int dmfe_init(struct net_device *dev);static int dmfe_open(struct net_device *dev);static int dmfe_close(struct net_device *dev);static int dmfe_irq_pending(struct net_device *dev);static int dmfe_irq_clear(int irq_type, struct net_device *dev);static int dmfe_send_packet(struct sk_buff *skbuff, struct net_device *dev);static int dmfe_receive_packet(struct net_device *dev);static void dmfe_print_status(struct net_device *dev);static void identify_nic(board_info_t *db);static void program_dm9801(board_info_t *db, u16 HPNA_rev);static void program_dm9802(board_info_t *db);static void set_PHY_mode(board_info_t *db);static u16 phy_read(board_info_t *db, int reg);static void phy_write(board_info_t *db, int reg, u16 value);static unsigned short dmfe_eeprom_readw(struct net_device *dev, int reg);static void dmfe_eeprom_writew(struct net_device *dev, int reg, int data);int dmfe_probe(struct net_device *dev){	board_info_t *db = &g_board_info;	u32 id_val;	u16 iobase = DM9000_MIN_IO;	quasar_init();	quasar_init_irq();	do {		dmfe_outb(DM9000_VID_L, iobase);		id_val = dmfe_inb(iobase + 4);		dmfe_outb(DM9000_VID_H, iobase);		id_val |= dmfe_inb(iobase + 4) << 8;		dmfe_outb(DM9000_PID_L, iobase);		id_val |= dmfe_inb(iobase + 4) << 16;		dmfe_outb(DM9000_PID_H, iobase);		id_val |= dmfe_inb(iobase + 4) << 24;#if DM9000_IGNOREID		if (iobase == 0x300 && id_val != 0)			id_val = DM9000_ID;#endif		if (id_val == DM9000_ID) {			PrintFormat("Found DM9000 chipset at I/O address %x\n", iobase);			memset(db, 0, sizeof(*db));			dev->state = NETDEV_DOWN;			dev->priv = db;			dev->init = dmfe_init;			dev->open = dmfe_open;			dev->close = dmfe_close;			dev->irq_pending = dmfe_irq_pending;			dev->send_packet = dmfe_send_packet;			dev->receive_packet = dmfe_receive_packet;			dev->print_status = dmfe_print_status;			dev->eeprom_size = 128;			dev->eeprom_readw = dmfe_eeprom_readw;			dev->eeprom_writew = dmfe_eeprom_writew;						db->ioaddr = iobase;			db->io_data = iobase + 4;			// dev->irq = Q2H_LOC_IRQ;			/* Set Node Address : now do not read from EEPROM */			memset(dev->dev_addr, 0, MACADDR_LEN);			return 1;		}		iobase += 0x10;	} while (iobase <= DM9000_MAX_IO);	return 0;}int dmfe_init(struct net_device *dev){	int i;	board_info_t *db = (board_info_t *) dev->priv;	u8 reg0;	/* RESET device */	iow(db, 0, 1);	udelay(100);	/* delay 100us */	/* I/O mode */	db->io_mode = ior(db, 0xfe) >> 6; 	/* ISR bit7:6 keeps I/O mode */	/* NIC Type: FASTETHER, HOMERUN, LONGRUN */	identify_nic(db);		/* Set PHY */	db->op_mode = DM9000_AUTO;	set_PHY_mode(db);	/* Init needed register value */	reg0 = DM9000_REG00;	if ((db->nic_type != FASTETHER_NIC) && (db->op_mode & DM9000_1M_HPNA))		reg0 |= DM9000_EXT_MII;		/* User passed argument */	/* Program operating register */	iow(db, 0x00, reg0);	iow(db, 0x02, 0);	/* TX Polling clear */	iow(db, 0x08, 0x3f);	/* Less 3Kb, 200us */	iow(db, 0x09, DM9000_REG09);/* Flow Control : High/Low Water */	iow(db, 0x0a, DM9000_REG0A);/* Flow Control */	iow(db, 0x2f, 0);	/* Special Mode */	iow(db, 0x01, 0x2c);	/* clear TX status */	iow(db, 0xfe, 0x0f); 	/* Clear interrupt status */ 	/* Activate DM9000 */	iow(db, 0x05, DM9000_REG05 | 1);	/* RX enable */	iow(db, 0xff, DM9000_REGFF); 	/* Enable TX/RX interrupt mask */ 	/* Init Driver variable */	db->link_failed = 1;	db->tx_pkt_cnt = 0;	db->queue_pkt_len = 0;	/* Set node address */	for (i = 0; i < 6; ++i)		iow(db, 0x10 + i, dev->dev_addr[i]);	return 0;}int dmfe_open(struct net_device *dev){	quasar_enable_irq(0, 0);	dmfe_init(dev);	dev->state = NETDEV_UP;			return 0;}int dmfe_close(struct net_device *dev){	board_info_t *db = (board_info_t *) dev->priv;	quasar_disable_irq(0);		/* RESET devie */	phy_write(db, 0x00, 0x8000);	/* PHY RESET */	iow(db, 0x1f, 0x01);	/* Power-Down PHY */	iow(db, 0xff, 0x80);	/* Disable all interrupt */	iow(db, 0x05, 0x00);	/* Disable RX */	dev->state = NETDEV_DOWN;			return 0;}int dmfe_irq_pending(struct net_device *dev){	board_info_t *db = (board_info_t *) dev->priv;	int irq_stat, irq_pend = 0;	if (!quasar_irq_pending(0))		return 0;	irq_stat = ior(db, 0xfe);		if (irq_stat & 0x01)		irq_pend |= ETHIRQ_RX;	if (irq_stat & 0x02)		irq_pend |= ETHIRQ_TX;	return irq_pend;}int dmfe_irq_clear(int irq_type, struct net_device *dev){	board_info_t *db = (board_info_t *) dev->priv;	int irq_stat, irq_clear = 0;	irq_stat = ior(db, 0xfe);		if (irq_type & ETHIRQ_RX)		irq_clear |= (irq_stat | 0x01);	if (irq_type & ETHIRQ_TX)		irq_clear |= (irq_stat | 0x02);	iow(db, 0xfe, irq_clear);	if (quasar_irq_pending(0) && ((irq_stat & ~irq_clear) == 0))		quasar_clear_irq(0);	return 0;

⌨️ 快捷键说明

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