/*linux/drivers/mtd/maps/s3c2410-gggggg.h,mapping驱动*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
/*######################modified according to jx2410*/
#define FLASH_PHYS_ADDR 0x0
#define FLASH_SIZE 0x02000000
#define FLASH_PARTITION0_ADDR 0x0000000
#define FLASH_PARTITION0_SIZE 0x00080000
#define FLASH_PARTITION1_ADDR 0x00080000
#define FLASH_PARTITION1_SIZE (0x00800000-0x00080000)
#define FLASH_PARTITION2_ADDR 0x00800000
#define FLASH_PARTITION2_SIZE (0x02000000-0x00800000)
#define FLASH_PARTITION3_ADDR 0x02000000
#define FLASH_PARTITION3_SIZE 0x0
struct map_info gggggg_map = {
.name = "gggggg flash device",
.size = FLASH_SIZE,
.bankwidth = 4,
};
struct mtd_partition gggggg_parts[] = {
{
.name = "Bootloader",
.offset = FLASH_PARTITION0_ADDR,
.size = FLASH_PARTITION0_SIZE
},
{
.name = "jffs2(8m)",
.offset = FLASH_PARTITION1_ADDR,
.size = FLASH_PARTITION1_SIZE
},
{
.name = "reserved",
.offset = FLASH_PARTITION2_ADDR,
.size = FLASH_PARTITION2_SIZE
},
{
.name = "nothing",
.offset = FLASH_PARTITION3_ADDR,
.size = FLASH_PARTITION3_SIZE
}
};
#define PARTITION_COUNT (sizeof(gggggg_parts)/sizeof(struct mtd_partition))
static struct mtd_info *mymtd;
int __init init_gggggg(void)
{
printk(KERN_NOTICE "S3C2410-gggggg flash device: %x at %x\n",
FLASH_SIZE, FLASH_PHYS_ADDR);
gggggg_map.phys = FLASH_PHYS_ADDR;
gggggg_map.virt = ioremap(FLASH_PHYS_ADDR,
FLASH_SIZE);
if (!gggggg_map.virt) {
printk("Failed to ioremap\n");
return -EIO;
}
simple_map_init(&gggggg_map);
mymtd = do_map_probe("cfi_probe", &gggggg_map);
if (mymtd) {
mymtd->owner = THIS_MODULE;
add_mtd_partitions(mymtd, gggggg_parts, PARTITION_COUNT);
printk(KERN_NOTICE "S3C2410-gggggg flash device initialized\n");
return 0;
}
iounmap((void *)gggggg_map.virt);
return -ENXIO;
}
static void __exit cleanup_gggggg(void)
{
if (mymtd) {
del_mtd_partitions(mymtd);
map_destroy(mymtd);
}
if (gggggg_map.virt) {
iounmap((void *)gggggg_map.virt);
gggggg_map.virt = 0;
}
}
module_init(init_gggggg);
module_exit(cleanup_gggggg);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("ly44770");
MODULE_DESCRIPTION("MTD map driver for S3C2410 digital module");
2、修改map.h文件
/* linux/include/asm-arm/arch-s3c2410/map.h*/
添加如下代码:
/***************ggggggggggggggg****************************/
#define S3C2410_VA_ISA_NET S3C2410_ADDR(0x02100000)
#define S3C2410_PA_ISA_NET (0x19000000)
#define S3C2410_SZ_ISA_NET SZ_1M
/**********************ggggggggggggggggggg********************/
3、新建smdk2410-gggggg.h文件
/*include/asm-arm/arch-s3c2410/smdk2410-gggggg.h*/
#include <asm-arm/arch-s3c2410/map.h>
#define IRQ_RTL8019 IRQ_EINT4
#define EXTINT_OFF (IRQ_EINT4 - 4)
/* RTL8019a, nGCS3 */
#define pRTL8019_BASE S3C2410_PA_ISA_NET
#define vRTL8019_BASE S3C2410_VA_ISA_NET
4、修改mach-smdk2410.c
/***********************************************************************
* linux/arch/arm/mach-s3c2410/mach-smdk2410.c
***********************************************************************/
/********************gggggggggggggggggggggg*****/
#include <asm-arm/setup.h>
#include <linux/initrd.h>
#include <linux/kdev_t.h>
#include <linux/major.h>
#include <asm-arm/arch-s3c2410/fb.h>
//#include <asm-arm/mach/map.h>
#include <asm-arm/arch-s3c2410/gggggg.h>
/**********************************************/
/*****************added---gggggggggggggg*/
extern dev_t ROOT_DEV;
extern unsigned long initrd_start ,initrd_end;
extern void __init
setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz);
/*{
#ifdef CONFIG_BLK_DEV_RAM
extern int rd_size, rd_image_start, rd_prompt, rd_doload;
rd_image_start = image_start;
rd_prompt = prompt;
rd_doload = doload;
if (rd_sz)
rd_size = rd_sz;
#endif
}*/
static void __init setup_initrd(unsigned int start, unsigned int size)
{
#ifdef CONFIG_BLK_DEV_INITRD
if (start == 0)
size = 0;
initrd_start = start;
initrd_end = start + size;
#endif
}
static void __init
fixup_smdk(struct machine_desc *desc, struct param_struct *params,
char **cmdline, struct meminfo *mi)
{
/* TODO */
#if 0 /* hacked by nandy. Is these codes need ? */
struct tag *t = (struct tag *)params;
if (t->hdr.tag != ATAG_CORE)
convert_to_tag_list(params, 1);
if (t->hdr.tag != ATAG_CORE) {
t->hdr.tag = ATAG_CORE;
t = tag_next(t);
t->hdr.tag = ATAG_MEM;
t->u.mem.start = 0x0c000000;
t->u.mem.size = 32 * 1024 * 1024;
}
#endif
#if 1
/* used in asm/kernel/setup.c and asm/arch/arch.c */
#define S3C2410_MEM_SIZE (64*1024*1024)
#define PA_SDRAM_BASE 0x30000000 /* used in asm/arch/arch.c */
#define RAMDISK_DN_ADDR 0x30800000 /* used in asm/arch/arch.c */
#define ZIP_RAMDISK_SIZE (10*1024*1024) /* used in asm/arch/arch.c */
/* setup ramdisk */
mi->bank[0].start = PA_SDRAM_BASE;
mi->bank[0].size = S3C2410_MEM_SIZE;
mi->bank[0].node = 0;
mi->nr_banks = 1;
ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
#ifdef CONFIG_BLK_DEV_RAM_SIZE
setup_ramdisk( 1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE);
#else
setup_ramdisk( 1, 0, 0, BLK_DEV_RAM_SIZE);
#endif
setup_initrd( __phys_to_virt(RAMDISK_DN_ADDR), ZIP_RAMDISK_SIZE);
#endif
}
/***************************************ggggggggggggggg*******/
/********************lcd ggggggggggggggggggggggggggg*************/
static struct s3c2410fb_mach_info gggggg_lcdcfg
__initdata = {
.fixed_syncs= 0,
.regs={
.lcdcon1= S3C2410_LCDCON1_TFT16BPP | \
S3C2410_LCDCON1_TFT | \
S3C2410_LCDCON1_CLKVAL(2),
.lcdcon2= S3C2410_LCDCON2_VBPD(10) | \
S3C2410_LCDCON2_LINEVAL(479) | \
S3C2410_LCDCON2_VFPD(25) | \
S3C2410_LCDCON2_VSPW(30),
.lcdcon3= S3C2410_LCDCON3_HBPD(2) | \
S3C2410_LCDCON3_HOZVAL(639) | \
S3C2410_LCDCON3_HFPD(4),
.lcdcon4= S3C2410_LCDCON4_MVAL(13) | \
S3C2410_LCDCON4_HSPW(79),
.lcdcon5= S3C2410_LCDCON5_FRM565 | \
S3C2410_LCDCON5_INVVLINE | \
S3C2410_LCDCON5_HWSWP,
},
.lpcsel= 0x0,
.gpccon= 0xaaaaaaaa,
.gpccon_mask= 0xffffffff,
.gpcup= 0xffffffff,
.gpcup_mask= 0xffffffff,
.gpdcon= 0xaaaaaaaa,
.gpdcon_mask= 0x0,
.gpdup= 0xffffffff,
.gpdup_mask= 0xffffffff,
.width= 640,
.height= 480,
.xres= {640,640,640},
.yres= {480,480,480},
.bpp= {16,16,16},
};
static void __init smdk2410_init(void)
{
set_s3c2410fb_info(&gggggg_lcdcfg);
}
/**********************end gggggggggggggg****************/
MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
* to SMDK2410 */
/* Maintainer: Jonas Dietsche */
.phys_ram = S3C2410_SDRAM_PA,
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = smdk2410_map_io,
.init_irq = smdk2410_init_irq,
.timer = &s3c24xx_timer,
/*******************added gggggggggggggg***************/
.fixup = fixup_smdk,
.init_machine = smdk2410_init,
MACHINE_END
5、修改ne.c文件(文件中标记gggggggg的地方是需要改动的地方):
/* ne.c: A general non-shared-memory NS8390 ethernet driver for linux. */
/*****************added ggggggggggggggggggggg*******************/
#include <asm-arm/arch-s3c2410/regs-mem.h>
#include <asm-arm/arch-s3c2410/irqs.h>
#include <asm-arm/arch-s3c2410/hardware.h>
#include <asm-arm/arch-s3c2410/regs-gpio.h>
#include <asm-arm/arch-s3c2410/gggggg.h>
/*********************gggggggggggggggggggggg********************/
/************************** ggggggggggggggg******/
static unsigned int netcard_portlist[] __initdata = {
vRTL8019_BASE+0x300,0x280, 0x320, 0x340, 0x360, 0x380, 0
};
/**********************************end gggggggggggggg************/
/*******************gggggggggggggggggggggggggggg****************/
#define CONFIG_gggggg
/*******************gggggggggggggggggggggggggggg*****/
static int __init do_ne_probe(struct net_device *dev)
{ printk(KERN_WARNING"NET START ggggggggggg\n");
unsigned int base_addr = dev->base_addr;
//ggggg#ifndef MODULE
//gggg int orig_irq = dev->irq;
//gggg#endif
// SET_MODULE_OWNER(dev);
/***********************add ggggggggggggggggggggggggg*********/
#if defined(CONFIG_gggggg)
printk(KERN_WARNING"configed smdk2410 gggggggggg\n");
static int once=0;
if (once)
return -ENXIO;
unsigned int value;
value = __raw_readl(S3C2410_BWSCON);
printk(KERN_WARNING"value=%x\n",value);
value &= ~(S3C2410_BWSCON_WS3|S3C2410_BWSCON_ST3|(1<<12)|(1<<13));
printk(KERN_WARNING"value=%x\n",value);
value |= (S3C2410_BWSCON_WS3|S3C2410_BWSCON_ST3|S3C2410_BWSCON_DW3_8);
printk(KERN_WARNING"value=%x\n",value);
__raw_writel(value, S3C2410_BWSCON);
value = __raw_readl(S3C2410_BWSCON);
printk(KERN_WARNING"value=%x\n",value);
value=0;
value = (S3C2410_BANKCON_Tacs0|S3C2410_BANKCON_Tcos4|S3C2410_BANKCON_Tacc14|S3C2410_BANKCON_Tcoh1|S3C2410_BANKCON_Tcah4|S3C2410_BANKCON_Tacp6|S3C2410_BANKCON_PMC16);
printk(KERN_WARNING"value=%x\n",value);
__raw_writel(value,S3C2410_BANKCON3);
//ext-interupt
static int
s3c_irqext_type(unsigned int irq, unsigned int type)
{ printk(KERN_WARNING"set irqext type gggggg\n ");
void __iomem *extint_reg;
void __iomem *gpcon_reg;
unsigned long gpcon_offset, extint_offset;
unsigned long newvalue = 0, value;
if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
{
gpcon_reg = S3C2410_GPFCON;
extint_reg = S3C2410_EXTINT0;
gpcon_offset = (irq - IRQ_EINT0) * 2;
extint_offset = (irq - IRQ_EINT0) * 4;
}
else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
{
gpcon_reg = S3C2410_GPFCON;
extint_reg = S3C2410_EXTINT0;
gpcon_offset = (irq - (EXTINT_OFF)) * 2;
extint_offset = (irq - (EXTINT_OFF)) * 4;
}
else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
{
gpcon_reg = S3C2410_GPGCON;
extint_reg = S3C2410_EXTINT1;
gpcon_offset = (irq - IRQ_EINT8) * 2;
extint_offset = (irq - IRQ_EINT8) * 4;
}
else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
{
gpcon_reg = S3C2410_GPGCON;
extint_reg = S3C2410_EXTINT2;
gpcon_offset = (irq - IRQ_EINT8) * 2;
extint_offset = (irq - IRQ_EINT16) * 4;
} else
return -1;
/* Set the GPIO to external interrupt mode */
value = __raw_readl(gpcon_reg);
value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
__raw_writel(value, gpcon_reg);
/* Set the external interrupt to pointed trigger type */
switch (type)
{
case IRQT_NOEDGE:
printk(KERN_WARNING "No edge setting!\n");
break;
case IRQT_RISING:
newvalue = S3C2410_EXTINT_RISEEDGE;
break;
case IRQT_FALLING:
newvalue = S3C2410_EXTINT_FALLEDGE;
break;
case IRQT_BOTHEDGE:
newvalue = S3C2410_EXTINT_BOTHEDGE;
break;
case IRQT_LOW:
newvalue = S3C2410_EXTINT_LOWLEV;
break;
case IRQT_HIGH:
newvalue = S3C2410_EXTINT_HILEV;
break;
default:
printk(KERN_ERR "No such irq type %d", type);
return -1;
}
value = __raw_readl(extint_reg);
value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
__raw_writel(value, extint_reg);
return 0;
}
s3c_irqext_type(IRQ_RTL8019,IRQT_RISING );
printk(KERN_WARNING"IRQ=%x\n",IRQ_RTL8019);
s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_EINT4);
s3c2410_gpio_pullup(S3C2410_GPF4, 0);
//dev->irq = IRQ_RTL8019;
//printk(KERN_WARNING"irq=%d",dev->irq);
if(base_addr==0){
dev->base_addr=base_addr=ioremap(pRTL8019_BASE,SZ_1M);
dev->irq = IRQ_RTL8019;
once++;
}
#endif
/*******************ggggggggggggggggggg**************************/
static int __init ne_probe1(struct net_device *dev, int ioaddr)
{
int i;
unsigned char ne_defethaddr[]={0x8,0x0,0x3e,0x26,0xa,0x5b,0};//ggggggggg
unsigned char SA_prom[32];
int wordlength = 2;
const char *name = NULL;
int start_page, stop_page;
int neX000, ctron, copam, bad_card;
int reg0, ret;
static unsigned version_printed;
if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME))
return -EBUSY;
reg0 = inb_p(ioaddr);
printk("Found the card at %x\n",ioaddr);//ggggggggggg
if (reg0 == 0xFF) {
ret = -ENODEV;
goto err_out;
}
/* Do a preliminary verification that we have a 8390. */
{
int regd;
outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
regd = inb_p(ioaddr + 0x0d);
outb_p(0xff, ioaddr + 0x0d);
outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
inb_p(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
if (inb_p(ioaddr + EN0_COUNTER0) != 0) {
outb_p(reg0, ioaddr);
outb_p(regd, ioaddr + 0x0d); /* Restore the old values. */
ret = -ENODEV;
goto err_out;
}
}
if (ei_debug && version_printed++ == 0)
printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2);
printk(KERN_INFO "NE*000 ethercard probe at %#3x:", ioaddr);
/* A user with a poor card that fails to ack the reset, or that
does not have a valid 0x57,0x57 signature can still use this
without having to recompile. Specifying an i/o address along
with an otherwise unused dev->mem_end value of "0xBAD" will
cause the driver to skip these parts of the probe. */
bad_card = ((dev->base_addr != 0) && (dev->mem_end == 0xbad));
/* Reset card. Who knows what dain-bramaged state it was left in. */
{
unsigned long reset_start_time = jiffies;
/* DON'T change these to inb_p/outb_p or reset will fail on clones. */
outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET);
while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0)
if (jiffies - reset_start_time > 2*HZ/100) {
if (bad_card) {
printk(" (warning: no reset ack)");
break;
} else {
printk(" not found (no reset ack).\n");
ret = -ENODEV;
goto err_out;
}
}
outb_p(0xff, ioaddr + EN0_ISR); /* Ack all intr. */
}
/* Read the 16 bytes of station address PROM.
We must first initialize registers, similar to NS8390_init(eifdev, 0).
We can't reliably read the SAPROM address without this.
(I learned the hard way!). */
{
struct {unsigned char value, offset; } program_seq[] =
{
{E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
{0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */
{0x00, EN0_RCNTLO}, /* Clear the count regs. */
{0x00, EN0_RCNTHI},
{0x00, EN0_IMR}, /* Mask completion irq. */
{0xFF, EN0_ISR},
{E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */
{E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */
{32, EN0_RCNTLO},
{0x00, EN0_RCNTHI},
{0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */
{0x00, EN0_RSARHI},
{E8390_RREAD+E8390_START, E8390_CMD},
};
for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
}
#if defined (CONFIG_gggggg) //gggggggggggggggg
{
unsigned char *ep;
static int nr = 0;
ep = (unsigned char * ) &ne_defethaddr[0];
ne_defethaddr[5]++;
for(i=0;i<6;i++)
SA_prom[i] = ep[i];
SA_prom[14] = SA_prom[15]=0x57;
wordlength =2;
}
#else // gggggggggggggg
for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) {
SA_prom[i] = inb(ioaddr + NE_DATAPORT);
SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
if (SA_prom[i] != SA_prom[i+1])
wordlength = 2;
}
#endif
if (wordlength == 2)
{
#if ! defined(CONFIG_ARCH_S3C2410) //ggggggggggggggggg
for (i = 0; i < 16; i++)
SA_prom[i] = SA_prom[i+i];
/* We must set the 8390 for word mode. */
#endif
outb_p(DCR_VAL, ioaddr + EN0_DCFG);
start_page = NESM_START_PG;
stop_page = NESM_STOP_PG;
} else {
start_page = NE1SM_START_PG;
stop_page = NE1SM_STOP_PG;
}
#if defined(CONFIG_PLAT_MAPPI) || defined(CONFIG_PLAT_OAKS32R)
neX000 = ((SA_prom[14] == 0x57 && SA_prom[15] == 0x57)
|| (SA_prom[14] == 0x42 && SA_prom[15] == 0x42));
#else
neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57);
#endif
ctron = (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d);
copam = (SA_prom[14] == 0x49 && SA_prom[15] == 0x00);
/* Set up the rest of the parameters. */
if (neX000 || bad_card || copam) {
name = (wordlength == 2) ? "NE2000" : "NE1000";
}
else if (ctron)
{
name = (wordlength == 2) ? "Ctron-8" : "Ctron-16";
start_page = 0x01;
stop_page = (wordlength == 2) ? 0x40 : 0x20;
}
else
{
#ifdef SUPPORT_NE_BAD_CLONES
/* Ack! Well, there might be a *bad* NE*000 clone there.
Check for total bogus addresses. */
for (i = 0; bad_clone_list[i].name8; i++)
{
if (SA_prom[0] == bad_clone_list[i].SAprefix[0] &&
SA_prom[1] == bad_clone_list[i].SAprefix[1] &&
SA_prom[2] == bad_clone_list[i].SAprefix[2])
{
if (wordlength == 2)
{
name = bad_clone_list[i].name16;
} else {
name = bad_clone_list[i].name8;
}
break;
}
}
if (bad_clone_list[i].name8 == NULL)
{
printk(" not found (invalid signature %2.2x %2.2x).\n",
SA_prom[14], SA_prom[15]);
ret = -ENXIO;
goto err_out;
}
#else
printk(" not found.\n");
ret = -ENXIO;
goto err_out;
#endif
}
#if ! defined (CONFIG_ARM) //ggggggggg
if (dev->irq < 2)
{
unsigned long cookie = probe_irq_on();
outb_p(0x50, ioaddr + EN0_IMR); /* Enable one interrupt. */
outb_p(0x00, ioaddr + EN0_RCNTLO);
outb_p(0x00, ioaddr + EN0_RCNTHI);
outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */
mdelay(10); /* wait 10ms for interrupt to propagate */
outb_p(0x00, ioaddr + EN0_IMR); /* Mask it again. */
dev->irq = probe_irq_off(cookie);
if (ei_debug > 2)
printk(" autoirq is %d\n", dev->irq);
} else if (dev->irq == 2)
/* Fixup for users that don't know that IRQ 2 is really IRQ 9,
or don't know which one to set. */
dev->irq = 9;
#endif
if (! dev->irq) {
printk(" failed to detect IRQ line.\n");
ret = -EAGAIN;
goto err_out;
}
/* Snarf the interrupt now. There's no point in waiting since we cannot
share and the board will usually be enabled. */
ret = request_irq(dev->irq, ei_interrupt, 0, name, dev);
if (ret) {
printk (" unable to get IRQ %d (errno=%d).\n", dev->irq, ret);
goto err_out;
}
dev->base_addr = ioaddr;
#ifdef CONFIG_PLAT_MAPPI
outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
ioaddr + E8390_CMD); /* 0x61 */
for (i = 0 ; i < ETHER_ADDR_LEN ; i++) {
dev->dev_addr[i] = SA_prom[i]
= inb_p(ioaddr + EN1_PHYS_SHIFT(i));
printk(" %2.2x", SA_prom[i]);
}
#else
for(i = 0; i < ETHER_ADDR_LEN; i++) {
printk(" %2.2x", SA_prom[i]);
dev->dev_addr[i] = SA_prom[i];
}
#endif
printk("\n%s: %s found at %#x, using IRQ %d.\n",
dev->name, name, ioaddr, dev->irq);
ei_status.name = name;
ei_status.tx_start_page = start_page;
ei_status.stop_page = stop_page;
#ifdef CONFIG_PLAT_OAKS32R
ei_status.word16 = 0;
#else
ei_status.word16 = (wordlength == 2);
#endif
ei_status.rx_start_page = start_page + TX_PAGES;
#ifdef PACKETBUF_MEMSIZE
/* Allow the packet buffer size to be overridden by know-it-alls. */
ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
#endif
ei_status.reset_8390 = &ne_reset_8390;
ei_status.block_input = &ne_block_input;
ei_status.block_output = &ne_block_output;
ei_status.get_8390_hdr = &ne_get_8390_hdr;
ei_status.priv = 0;
ei_status.word16 =0;//ggggggggggg
dev->open = &ne_open;
dev->stop = &ne_close;