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

📄 gmv1rom.c

📁 一个开放源码
💻 C
字号:
/* $Id: gmv1rom.c,v 1.2 2000/11/15 17:44:54 apc Exp $ *//* Copyright 2000  AG Electronics Ltd. *//* This code is distributed without warranty under the GPL v2 (see COPYING) */#include <stdio.h>#include <io.h>#include <pci.h>#define HW_ROM		0x00	/* IEEE Address PROM */#define HW_RDP		0x10	/* Register data port */#define HW_RAP		0x12	/* Register/ISA address port */#define HW_RESET	0x14	/* Reset register */#define HW_BDP		0x16	/* ISA data register */static ioaddr lance_port;	/* I/O port of the card */enum eeprom_consts{    eeprom_sk = 0x0002,    eeprom_cs = 0x0004,    eeprom_di = 0x0001,    eeprom_do = 0x0001,    eeprom_een = 0x0010,    eeprom_present = 0x2000,};typedef u16 WORD;static WORD read_reg (void){    return in_16 (lance_port + HW_BDP);}/*  * pause for at least (delay * 100ns). The implementation depends on the * fact that PCI bus reads take 3 PCI clocks (approx = 100ns). The actual * delay is likely to be much longer than the requested delay, but will be * software independent */static void pause (unsigned delay){    volatile WORD junk;    unsigned i;    for (i = 0; i < 4*delay; i += 1)    {	junk = in_16(lance_port + HW_RAP);        out_16(lance_port + HW_RAP, junk);    }}static void write_bit (u16 mask, u32 data, unsigned delay){    static u16 reg = eeprom_een;    if (data)	reg |= mask;    else	reg &= ~mask;    out_16 (lance_port +  HW_BDP, reg);    pause ( delay);}static int read_bit (u16 mask){    u16 reg = read_reg () & mask;    if (reg)	return 1;    else	return 0;}static void write_sk (unsigned data, unsigned delay){    write_bit ( eeprom_sk, data, delay);}static void write_cs (unsigned data, unsigned delay){    write_bit ( eeprom_cs, data, delay);}static void write_di ( unsigned data, unsigned delay){    write_bit ( eeprom_di, data, delay);}static unsigned read_do (void){    return read_bit (eeprom_do);}static void write_instruction (u32 data, unsigned nbits){    u32 rd_mask = 0x1 << (nbits - 1);    unsigned i;    for (i = 0; i < nbits; i += 1)    {	write_di (data & rd_mask, 1);	data <<= 1;	write_sk (1, 10);	/* ensure max freq < 500KHz */	write_sk (0, 10);    }}u16 serprom_read (u16 addr){    u32 instr = 0x180 | (addr & 0x3f);    u16 res = 0;    unsigned i;    write_sk (0, 1);    write_cs (1, 1);    write_instruction (instr, 9);    for (i = 0; i < 16; i += 1)    {	write_sk (1, 10);	/* tPD0/1 = 500ns */	res <<= 1;	res |= read_do ();	write_sk ( 0, 10);    }    write_cs ( 0, 5);    return res;}static int serprom_write (u16 addr, u16 data){    u32 wr_instr = ((0x140 | (addr & 0x3f)) << 16) | data;    unsigned timeout = 0;    u16 word;    write_sk ( 0, 1);    write_cs ( 1, 1);	/* prepare */    write_instruction ( 0x130, 9);	/* WEN */    write_cs ( 0, 5);	/* pulse CS off */    write_cs ( 1, 1);    write_instruction ( wr_instr, 25);	/* WRITE */    write_cs ( 0, 5);	/* pulse CS off */    write_cs ( 1, 5);	/* tSV */    if (read_do () == 1)	printf ("Suspiciously short EEPROM program time\n");    while (read_do () == 0)	/* BUSY */	if (++timeout > 100000)	{	    write_cs ( 0, 5);	    printf ("Timeout waiting for EEPROM to program\n");            return -1;	}	else	    pause ( 10);	/* 1 usec */    write_instruction ( 0x100, 9);	/* WDS */    write_cs ( 0, 5);    /*     * // validate     */    {	word = serprom_read ( addr);	if (word != data)	   printf ("EEPROM write validation: exp:0x%x got:0x%x\n", data, word);    }    return 0;}static unsigned char pcnet_eeprom[] = {    0x02, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* NODE address */    0, 0, /* ON Now */    0x00, 0x11, /* Hardware ID */    0, 0, 0, 0, /* Checksum */    'W', 'W',    0x02, 0x00, /* BCR2, Misc. Config. */    0xc0, 0x00, /* BCR4, LED0 */    0x84, 0x00, /* BCR5, LED1 */    0x80, 0x10, /* BCR6, LED2 */    0x90, 0x00, /* BCR7, LED3 */    0x00, 0x00, /* BCR9, Full-Duplex Ctrl. */    0x60, 0x28, /* BCR18, Burst and Bus Ctrl. */    0x06, 0xff, /* BCR22, PCI Latency */    0xcb, 0x15, /* BCR23, Subsys vendor */    0x00, 0x00, /* BCR24, Subsys ID */    0x17, 0x00, /* BCR25, SRAM size */    0x0c, 0x00, /* BCR26, SRAM boundary */    0x00, 0x00, /* BCR27, SRAM cntrl */    0x20, 0x01, /* BCR32, MII cntrl */    0xc0, 0x03, /* BCR33, MII addr */    0x22, 0x10, /* BCR35, vendor */    0x11, 0xc8, /* BCR36, power management */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* BCR37-40 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* BCR41-44 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* BCR48-51 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* BCR52-54 */    0x00, 0x00 /* Checksum */};static void make_pcnet_checksums(void){    int i;    unsigned short wsum;    unsigned char bsum;        wsum = 0;    for(i = 0; i < 0xc; i++)        wsum += pcnet_eeprom[i];    wsum += pcnet_eeprom[0xe] + pcnet_eeprom[0xf];    pcnet_eeprom[0xc] = wsum & 0xff;    pcnet_eeprom[0xd] = wsum >> 8;        bsum = 0;    for(i = 0; i < 81; i++)        bsum += pcnet_eeprom[i];    pcnet_eeprom[0x51] = 0xff - bsum;}#define PCI_AMD_VENDOR_ID	0x1022	/* AMD's vendor ID */#define PCI_LANCE_DEVICE_ID	0x2000	/* Am79C970 device ID */unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base);void gmv1_program (int argc, char **argv){    int i;    struct pci_device *dev;    char *mac_string;        dev = pci_find_device (PCI_AMD_VENDOR_ID, PCI_LANCE_DEVICE_ID, 0);        if (! dev)    {        printf("PCNET32 not found\n");        return -1;    }    lance_port = dev->region[0];        if (argc != 1)    {        printf("usage: test gmv1rom xx:xx:xx:xx:xx:xx\n");        return;    }        mac_string = argv[0];    printf("MAC address: ");    for(i = 0; i < 6; i++)    {        char *next;        unsigned long byte;                if (*mac_string==':')            mac_string++;                if (! (*mac_string))        {            printf("   MAC address too short\n");            return;        }        byte = simple_strtoul(mac_string, &next, 16);        if (byte > 255)        {            printf("  Illegal MAC address: \"%s\"\n", mac_string);            return;        }        pcnet_eeprom[i] = byte;        if (i != 0)           printf(":");        printf("%02x", byte);        mac_string = next;    }    printf("\n");    /* Set up to access BCR19 (EEPROM) */    out_16(lance_port + HW_RAP, 19);        if ((read_reg () & eeprom_present) != eeprom_present)    {	    printf ("PCnet32 reports EEPROM not present\n");            return -1;    }        make_pcnet_checksums();    write_sk(0, 0);    for(i = 0; i < 0x52; i += 2)    {        u16 data = pcnet_eeprom[i] | (pcnet_eeprom[i+1] << 8);        if (serprom_read(i / 2) != data)            serprom_write(i / 2, data);    }    out_16 (lance_port +  HW_BDP, 0);        return 0;}

⌨️ 快捷键说明

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