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

📄 enc28j60.c

📁 网卡的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* enc28j60.c: EDTP FrameThrower style enc28j60 driver for Linux 2.4
 *
 *	(c) Copyright 2006 American Microsystems Limited
 *	Written by David Anders.
 *
 *	Based on the Procyon AVRlib enc28j60.c written by Pascal Stang
 *
 *	This software may be used and distributed according to the terms
 *	of the GNU General Public License, incorporated herein by reference.
 *
 */
#ifndef MODULE
#define MODULE
#endif
#ifndef __KERNEL__
#define __KERNEL__
#endif
#include <linux/module.h>
#include <linux/config.h>
#include <linux/netdevice.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/in.h>
#include <linux/etherdevice.h> /* eth_type_trans */
#include <linux/ip.h>          /* struct iphdr */
#include <linux/tcp.h>         /* struct tcphdr */
#include <linux/skbuff.h>
#include <linux/types.h>  /* size_t */
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/byteorder.h>
#include "enc28j60.h"
#include <asm/arch-s3c2410/S3C2410.h>

u8 Enc28j60Bank=-1;
u16 NextPacketPtr;
int ResetCounter=100;
void enc28j60ChipSelect(int cs_stat)
{
    unsigned long tmpval;

    if ( cs_stat == 1 ) {
       	GPBDAT &= ~(1<<6);	// set GPB6=0,low, active the enc28j60 
    }
    else {
	GPBDAT |= (1<<6);
    }
}



void enc28j60ReadBuffer(u16 len, u8* data)
{
    u8 tmpval;
    int counter=1;
    // assert CS
    enc28j60ChipSelect(1);
    // issue read command
    SPTDAT0 = ENC28J60_READ_BUF_MEM;
    udelay(4);
    while(len--)
    {
        // read data
		SPTDAT0 = 0xff;	//0x00
		udelay(4);
		*data++ = SPRDAT0;
		udelay(4);
    }
    // release CS
    enc28j60ChipSelect(0);
}

void enc28j60WriteBuffer(u16 len, u8* data)
{
    u8 tmpval;
    // assert CS
    enc28j60ChipSelect(1);

    // issue write command
    SPTDAT0 = ENC28J60_WRITE_BUF_MEM;
    udelay(4);
    while(len--)
    {
        // write data
		SPTDAT0 = *data++;		
		udelay(4);
    }
    // release CS
    enc28j60ChipSelect(0);
}


u8 enc28j60ReadOp(u8 op, u8 address)
{
    u8 data;
    u8 tmpval;

    // assert CS
    enc28j60ChipSelect(1);

    // issue read command
    	SPTDAT0 = op | (address & ADDR_MASK);
 	data = SPRDAT0;

	udelay(4);
 	SPTDAT0 = 0xff;
	data = SPRDAT0;
    	udelay(4);

    // do dummy read if needed
    if(address & 0x80)
    {
    	SPTDAT0 = 0xff;
    	data = SPRDAT0;	
	udelay(4);
    }
    data = SPRDAT0;

    // release CS
    enc28j60ChipSelect(0);

    return data;
}

void enc28j60WriteOp(u8 op, u8 address, u8 data)
{
    u8 tmpval;

    // assert CS
    enc28j60ChipSelect(1);

    // issue write command
    SPTDAT0 = op | (address & ADDR_MASK);
    
    udelay(5);
    SPTDAT0 = data;

    udelay(5);

    // release CS
    enc28j60ChipSelect(0);
}


void enc28j60SetBank(u8 address)
{
    // set the bank (if needed)
    if((address & BANK_MASK) != Enc28j60Bank)
    {
        // set the bank
        enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0));
        enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5);
        Enc28j60Bank = (address & BANK_MASK);
    }
}

u8 enc28j60Read(u8 address)
{
    // set the bank
    enc28j60SetBank(address);
    // do the read
    return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address);
}

void enc28j60Write(u8 address, u8 data)
{
    // set the bank
    enc28j60SetBank(address);
    // do the write
    enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data);
}

u16 enc28j60PhyRead(u8 address)
{
    u16 data;

    // Set the right address and start the register read operation
    enc28j60Write(MIREGADR, address);
    enc28j60Write(MICMD, MICMD_MIIRD);

    // wait until the PHY read completes
    while(enc28j60Read(MISTAT) & MISTAT_BUSY);

    // quit reading
    enc28j60Write(MICMD, 0x00);

    // get data value
    data  = enc28j60Read(MIRDL);
    //data |= enc28j60Read(MIRDH);
    data =  enc28j60Read(MIRDH)<<8 | data;
    // return the data
    return data;
}

void enc28j60PhyWrite(u8 address, u16 data)
{
    // set the PHY register address
    enc28j60Write(MIREGADR, address);

    // write the PHY data
    enc28j60Write(MIWRL, data);
    enc28j60Write(MIWRH, data>>8);

    // wait until the PHY write completes
    while(enc28j60Read(MISTAT) & MISTAT_BUSY){
	printk("MISTAT:0x%02x\n",enc28j60Read(MISTAT));
	udelay(100);
    }
}

void nicGetMacAddress(u8* macaddr)
{
    // read MAC address registers
    // NOTE: MAC address in ENC28J60 is byte-backward
    *macaddr++ = enc28j60Read(MAADR5);
    *macaddr++ = enc28j60Read(MAADR4);
    *macaddr++ = enc28j60Read(MAADR3);
    *macaddr++ = enc28j60Read(MAADR2);
    *macaddr++ = enc28j60Read(MAADR1);
    *macaddr++ = enc28j60Read(MAADR0);
}

void nicSetMacAddress(u8* macaddr)
{
    // write MAC address
    // NOTE: MAC address in ENC28J60 is byte-backward
    enc28j60Write(MAADR5, *macaddr++);
    enc28j60Write(MAADR4, *macaddr++);
    enc28j60Write(MAADR3, *macaddr++);
    enc28j60Write(MAADR2, *macaddr++);
    enc28j60Write(MAADR1, *macaddr++);
    enc28j60Write(MAADR0, *macaddr++);
}

void enc28j60_RegDump(void)
{

    printk("RevID: 0x%02x\r\n", enc28j60Read(EREVID));

    printk("Cntrl: ECON1 ECON2 ESTAT  EIR  EIE\r\n");
    printk("       0x%02x  ",enc28j60Read(ECON1));
    printk("0x%02x  ",enc28j60Read(ECON2));
    printk("0x%02x  ",enc28j60Read(ESTAT));
    printk("0x%02x  ",enc28j60Read(EIR));
    printk("0x%02x\n\n",enc28j60Read(EIE));

    printk("MAC  : MACON1  MACON2  MACON3  MACON4  MAC-Address\r\n");
    printk("       0x%02x ",enc28j60Read(MACON1));
    printk("0x%02x ",enc28j60Read(MACON2));
    printk("0x%02x ",enc28j60Read(MACON3));
    printk("0x%02x ",enc28j60Read(MACON4));
    printk("%02x:",enc28j60Read(MAADR5));
    printk("%02x:",enc28j60Read(MAADR4));
    printk("%02x:",enc28j60Read(MAADR3));
    printk("%02x:",enc28j60Read(MAADR2));
    printk("%02x:",enc28j60Read(MAADR1));
    printk("%02x\n\n",enc28j60Read(MAADR0));


    printk("Rx   : ERXST  ERXND  ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL\r\n");
    printk("       0x%02x:",enc28j60Read(ERXSTH));
    printk("0x%02x ",enc28j60Read(ERXSTL));
    printk("0x%02x:",enc28j60Read(ERXNDH));
    printk("0x%02x ",enc28j60Read(ERXNDL));
    printk("0x%02x:",enc28j60Read(ERXWRPTH));
    printk("0x%02x ",enc28j60Read(ERXWRPTL));
    printk("0x%02x:",enc28j60Read(ERXRDPTH));
    printk("0x%02x ",enc28j60Read(ERXRDPTL));
    printk("0x%02x ",enc28j60Read(ERXFCON));
    printk("0x%02x ",enc28j60Read(EPKTCNT));
    printk("0x%02x:",enc28j60Read(MAMXFLH));
    printk("0x%02x\n",enc28j60Read(MAMXFLL));

    printk("Tx   : ETXST  ETXND  MACLCON1 MACLCON2 MAPHSUP\r\n");
    printk("0x%02x:",enc28j60Read(ETXSTH));
    printk("0x%02x ",enc28j60Read(ETXSTL));
    printk("0x%02x:",enc28j60Read(ETXNDH));
    printk("0x%02x ",enc28j60Read(ETXNDL));
    printk("0x%02x ",enc28j60Read(MACLCON1));
    printk("0x%02x ",enc28j60Read(MACLCON2));
    printk("0x%02x\n",enc28j60Read(MAPHSUP));
    udelay(1000);
}




static struct net_device_stats *
get_stats(struct net_device *dev)
{
    return (struct net_device_stats *)(dev->priv);
}

int enc28j60_open (struct net_device *dev)
{
	printk("enc28j60_open called\n");
	netif_start_queue (dev);
	return 0;
}

int enc28j60_release (struct net_device *dev)
{
	printk ("enc28j60_release called\n");
	netif_stop_queue(dev);
	return 0;
}

static int enc28j60_xmit (struct sk_buff *skb,
				struct net_device *dev)

⌨️ 快捷键说明

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