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

📄 dm9000.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
   A Davicom DM9000 ISA NIC fast Ethernet driver for Linux.
   Copyright (C) 1997  Sten Wang

   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.

  (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
*/
#include <windows.h>
#include <halether.h>
#include <oal.h>


#define DM9000_INFO		TRUE
#define DM9000_ERROR	TRUE
#define DM9000_DEBUG	FALSE
#define DM9000_MISS		TRUE

//------------------------------------------------------------------------------
// Types

enum DM9000_PHY_mode
{
	DM9000_10MHD = 0,
	DM9000_100MHD = 1,
	DM9000_10MFD = 4,
	DM9000_100MFD = 5,
	DM9000_AUTO = 8,
	DM9000_1M_HPNA = 0x10
};

#define DM9000_PHY_MODE	DM9000_AUTO

//------------------------------------------------------------------------------
// Defines 

#define CONFIG_DM9000_USE_32BIT

#define DM9000_ID		0x90000A46
#define DM9000_PKT_MAX		1536	/* Received packet max size */
#define DM9000_PKT_RDY		0x01	/* Packet ready to receive */

/* although the registers are 16 bit, they are 32-bit aligned.
 */

#define DM9000_NCR             0x00
#define DM9000_NSR             0x01
#define DM9000_TCR             0x02
#define DM9000_TSR1            0x03
#define DM9000_TSR2            0x04
#define DM9000_RCR             0x05
#define DM9000_RSR             0x06
#define DM9000_ROCR            0x07
#define DM9000_BPTR            0x08
#define DM9000_FCTR            0x09
#define DM9000_FCR             0x0A
#define DM9000_EPCR            0x0B
#define DM9000_EPAR            0x0C
#define DM9000_EPDRL           0x0D
#define DM9000_EPDRH           0x0E
#define DM9000_WCR             0x0F

#define DM9000_PAR             0x10
#define DM9000_MAR             0x16

#define DM9000_GPCR            0x1e
#define DM9000_GPR             0x1f
#define DM9000_TRPAL           0x22
#define DM9000_TRPAH           0x23
#define DM9000_RWPAL           0x24
#define DM9000_RWPAH           0x25

#define DM9000_VIDL            0x28
#define DM9000_VIDH            0x29
#define DM9000_PIDL            0x2A
#define DM9000_PIDH            0x2B

#define DM9000_CHIPR           0x2C
#define DM9000_SMCR            0x2F

#define DM9000_PHY             0x40

#define DM9000_MRCMDX          0xF0
#define DM9000_MRCMD           0xF2
#define DM9000_MRRL            0xF4
#define DM9000_MRRH            0xF5
#define DM9000_MWCMDX			0xF6
#define DM9000_MWCMD           0xF8
#define DM9000_MWRL            0xFA
#define DM9000_MWRH            0xFB
#define DM9000_TXPLL           0xFC
#define DM9000_TXPLH           0xFD
#define DM9000_ISR             0xFE
#define DM9000_IMR             0xFF

#define NCR_EXT_PHY		(1<<7)
#define NCR_WAKEEN		(1<<6)
#define NCR_FCOL		(1<<4)
#define NCR_FDX			(1<<3)
#define NCR_LBK			(3<<1)
#define NCR_RST			(1<<0)

#define NSR_SPEED		(1<<7)
#define NSR_LINKST		(1<<6)
#define NSR_WAKEST		(1<<5)
#define NSR_TX2END		(1<<3)
#define NSR_TX1END		(1<<2)
#define NSR_RXOV		(1<<1)

#define TCR_TJDIS		(1<<6)
#define TCR_EXCECM		(1<<5)
#define TCR_PAD_DIS2	(1<<4)
#define TCR_CRC_DIS2	(1<<3)
#define TCR_PAD_DIS1	(1<<2)
#define TCR_CRC_DIS1	(1<<1)
#define TCR_TXREQ		(1<<0)

#define TSR_TJTO		(1<<7)
#define TSR_LC			(1<<6)
#define TSR_NC			(1<<5)
#define TSR_LCOL		(1<<4)
#define TSR_COL			(1<<3)
#define TSR_EC			(1<<2)

#define RCR_WTDIS		(1<<6)
#define RCR_DIS_LONG	(1<<5)
#define RCR_DIS_CRC		(1<<4)
#define RCR_ALL			(1<<3)
#define RCR_RUNT		(1<<2)
#define RCR_PRMSC		(1<<1)
#define RCR_RXEN		(1<<0)

#define RSR_RF			(1<<7)
#define RSR_MF			(1<<6)
#define RSR_LCS			(1<<5)
#define RSR_RWTO		(1<<4)
#define RSR_PLE			(1<<3)
#define RSR_AE			(1<<2)
#define RSR_CE			(1<<1)
#define RSR_FOE			(1<<0)

#define FCTR_HWOT(ot)	(( ot & 0xf ) << 4 )
#define FCTR_LWOT(ot)	( ot & 0xf )

#define IMR_PAR			(1<<7)
#define IMR_ROOM		(1<<3)
#define IMR_ROM			(1<<2)
#define IMR_PTM			(1<<1)
#define IMR_PRM			(1<<0)

//------------------------------------------------------------------------------
// Local Variables 

static UINT32	DM9000_IO;
static UINT32	DM9000_DATA;

//------------------------------------------------------------------------------
// Local Functions 
typedef UINT32	u32;
typedef UINT16	u16;
typedef UINT8	u8;

#define DM9000_outb(d,r) ( *(volatile u8 *)r = d )
#define DM9000_outw(d,r) ( *(volatile u16 *)r = d )
#define DM9000_outl(d,r) ( *(volatile u32 *)r = d )
#define DM9000_inb(r) (*(volatile u8 *)r)
#define DM9000_inw(r) (*(volatile u16 *)r)
#define DM9000_inl(r) (*(volatile u32 *)r)

static u8 DM9000_ior(int reg)
{
	DM9000_outb(reg, DM9000_IO);
	return DM9000_inb(DM9000_DATA);
}

static void DM9000_iow(int reg, u8 value)
{
	DM9000_outb(reg, DM9000_IO);
	DM9000_outb(value, DM9000_DATA);
}

static u16 dm9000_phy_read(int reg)
{
   u16 val;

   /* Fill the phyxcer register into REG_0C */
   DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
   DM9000_iow(DM9000_EPCR, 0xc);   /* Issue phyxcer read command */
   OALStall(100);      /* Wait read complete */
   DM9000_iow(DM9000_EPCR, 0x0);   /* Clear phyxcer read command */
   val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);

   /* The read data keeps on REG_0D & REG_0E */
//   DM9000_DBG("phy_read(%d): %d\n", reg, val);
   return val;
}

static void dm9000_phy_write(int reg, u16 value)
{

   /* Fill the phyxcer register into REG_0C */
   DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);

   /* Fill the written data into REG_0D & REG_0E */
   DM9000_iow(DM9000_EPDRL, (value & 0xff));
   DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff));
   DM9000_iow(DM9000_EPCR, 0xa);   /* Issue phyxcer write command */
   OALStall(500);      /* Wait write complete */
   DM9000_iow(DM9000_EPCR, 0x0);   /* Clear phyxcer write command */
//   DM9000_DBG("phy_write(reg:%d, value:%d)\n", reg, value);
}

//------------------------------------------------------------------------------

static u8 dm9000_io_width[4] = { 16, 32, 8, 0 };

static BOOL dm9000_probe(void)
{
	u32 i, id;
	u8 iowd = 0;

	for( i=0; i<3; i++)
	{
		id = DM9000_ior(DM9000_VIDL);
		id |= DM9000_ior(DM9000_VIDH) << 8;
		id |= DM9000_ior(DM9000_PIDL) << 16;
		id |= DM9000_ior(DM9000_PIDH) << 24;

		if (id == DM9000_ID)
		{
			iowd = (DM9000_ior(DM9000_ISR) & 0xC0) >> 6;

			OALMSGS(DM9000_INFO, (L"DM9000 I/O: 0x%08x (%dbit), id: 0x%08x\r\n",
									DM9000_IO, dm9000_io_width[iowd], id));
			return TRUE;
		} else {
			OALMSGS(DM9000_INFO, (L"DM9000 not found at I/O: 0x%08x, id: 0x%08x\r\n", DM9000_IO, id));
		}
	}
	return FALSE;
}

static void dm9000_set_mode(u8 phy_mode)
{
	u16 phy_reg4 = 0x01e1, phy_reg0 = 0x1000;

	if (!(phy_mode & DM9000_AUTO)) {
		switch (phy_mode) {
		case DM9000_10MHD:
			phy_reg4 = 0x21;
			phy_reg0 = 0x0000;
			break;
		case DM9000_10MFD:
			phy_reg4 = 0x41;
			phy_reg0 = 0x1100;
			break;
		case DM9000_100MHD:
			phy_reg4 = 0x81;
			phy_reg0 = 0x2000;
			break;
		case DM9000_100MFD:
			phy_reg4 = 0x101;
			phy_reg0 = 0x3100;
			break;
		}
		dm9000_phy_write(4, phy_reg4);
		dm9000_phy_write(0, phy_reg0);

⌨️ 快捷键说明

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