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

📄 tulip.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 5 页
字号:
    volatile u32 status;    u32 length;    u32 buffer1, buffer2;};struct tulip_tx_desc {    volatile u32 status;    u32 length;    u32 buffer1, buffer2;};/*********************************************************************//* Global Storage                                                    *//*********************************************************************/static u32 ioaddr;/* Note: transmit and receive buffers must be longword aligned and   longword divisable */#define TX_RING_SIZE	2static struct tulip_tx_desc tx_ring[TX_RING_SIZE] __attribute__ ((aligned(4)));#ifdef USE_LOWMEM_BUFFER#define txb ((char *)0x10000 - BUFLEN)#elsestatic unsigned char txb[BUFLEN] __attribute__ ((aligned(4)));#endif#define RX_RING_SIZE	4static struct tulip_rx_desc rx_ring[RX_RING_SIZE] __attribute__ ((aligned(4)));#ifdef USE_LOWMEM_BUFFER#define rxb ((char *)0x10000 - RX_RING_SIZE * BUFLEN - BUFLEN)#elsestatic unsigned char rxb[RX_RING_SIZE * BUFLEN] __attribute__ ((aligned(4)));#endifstatic struct tulip_private {    int cur_rx;    int chip_id;                        /* index into tulip_tbl[]  */    int pci_id_idx;                     /* index into pci_id_tbl[] */    int revision;    int flags;    unsigned short vendor_id;           /* PCI card vendor code */    unsigned short dev_id;              /* PCI card device code */    unsigned char ehdr[ETH_HLEN];       /* buffer for ethernet header */    const char *nic_name;    unsigned int csr0, csr6;            /* Current CSR0, CSR6 settings. */    unsigned int if_port;    unsigned int full_duplex;         /* Full-duplex operation requested. */    unsigned int full_duplex_lock;    unsigned int medialock;           /* Do not sense media type. */    unsigned int mediasense;          /* Media sensing in progress. */    unsigned int nway, nwayset;     /* 21143 internal NWay. */    unsigned int default_port;    unsigned char eeprom[EEPROM_SIZE];  /* Serial EEPROM contents. */    u8 media_table_storage[(sizeof(struct mediatable) + 32*sizeof(struct medialeaf))];    u16 sym_advertise, mii_advertise;   /* NWay to-advertise. */    struct mediatable *mtable;    u16 lpar;                           /* 21143 Link partner ability. */    u16 advertising[4];                 /* MII advertise, from SROM table. */    signed char phys[4], mii_cnt;       /* MII device addresses. */    int cur_index;                      /* Current media index. */    int saved_if_port;} tpx;static struct tulip_private *tp;/* Known cards that have old-style EEPROMs.   Writing this table is described at   http://cesdis.gsfc.nasa.gov/linux/drivers/tulip-drivers/tulip-media.html */static struct fixups {    char *name;    unsigned char addr0, addr1, addr2;    u16 newtable[32];                           /* Max length below. */} eeprom_fixups[] = {    {"Asante", 0, 0, 0x94, {0x1e00, 0x0000, 0x0800, 0x0100, 0x018c,                            0x0000, 0x0000, 0xe078, 0x0001, 0x0050, 0x0018 }},    {"SMC9332DST", 0, 0, 0xC0, { 0x1e00, 0x0000, 0x0800, 0x041f,                                 0x0000, 0x009E, /* 10baseT */                                 0x0004, 0x009E, /* 10baseT-FD */                                 0x0903, 0x006D, /* 100baseTx */                                 0x0905, 0x006D, /* 100baseTx-FD */ }},    {"Cogent EM100", 0, 0, 0x92, { 0x1e00, 0x0000, 0x0800, 0x063f,                                   0x0107, 0x8021, /* 100baseFx */                                   0x0108, 0x8021, /* 100baseFx-FD */                                   0x0100, 0x009E, /* 10baseT */                                   0x0104, 0x009E, /* 10baseT-FD */                                   0x0103, 0x006D, /* 100baseTx */                                   0x0105, 0x006D, /* 100baseTx-FD */ }},    {"Maxtech NX-110", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x0513,                                     0x1001, 0x009E, /* 10base2, CSR12 0x10*/                                     0x0000, 0x009E, /* 10baseT */                                     0x0004, 0x009E, /* 10baseT-FD */                                     0x0303, 0x006D, /* 100baseTx, CSR12 0x03 */                                     0x0305, 0x006D, /* 100baseTx-FD CSR12 0x03 */}},    {"Accton EN1207", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x051F,                                    0x1B01, 0x0000, /* 10base2,   CSR12 0x1B */                                    0x0B00, 0x009E, /* 10baseT,   CSR12 0x0B */                                    0x0B04, 0x009E, /* 10baseT-FD,CSR12 0x0B */                                    0x1B03, 0x006D, /* 100baseTx, CSR12 0x1B */                                    0x1B05, 0x006D, /* 100baseTx-FD CSR12 0x1B */    }},    {0, 0, 0, 0, {}}};static const char * block_name[] = {"21140 non-MII", "21140 MII PHY",                                    "21142 Serial PHY", "21142 MII PHY", "21143 SYM PHY", "21143 reset method"};/*********************************************************************//* Function Prototypes                                               *//*********************************************************************/static int mdio_read(struct nic *nic, int phy_id, int location);static void mdio_write(struct nic *nic, int phy_id, int location, int value);static int read_eeprom(unsigned long ioaddr, int location, int addr_len);static void parse_eeprom(struct nic *nic);struct nic *tulip_probe(struct nic *nic, unsigned short *io_addrs,                        struct pci_device *pci);static void tulip_init_ring(struct nic *nic);static void tulip_reset(struct nic *nic);static void tulip_transmit(struct nic *nic, const char *d, unsigned int t,                           unsigned int s, const char *p);static int tulip_poll(struct nic *nic);static void tulip_disable(struct nic *nic);static void nway_start(struct nic *nic);static void pnic_do_nway(struct nic *nic);static void select_media(struct nic *nic, int startup);static void init_media(struct nic *nic);static void start_link(struct nic *nic);static int tulip_check_duplex(struct nic *nic);static void tulip_wait(unsigned int nticks);#ifdef TULIP_DEBUG_WHEREstatic void whereami(const char *str);#endif#ifdef TULIP_DEBUGstatic void tulip_more(void);#endif/*********************************************************************//* Utility Routines                                                  *//*********************************************************************/#ifdef TULIP_DEBUG_WHEREstatic void whereami (const char *str){    printf("%s: %s\n", tp->nic_name, str);    /* sleep(2); */}#endif#ifdef  TULIP_DEBUGstatic void tulip_more(void){    printf("\n\n-- more --");    while (!iskey())        /* wait */;    getchar();    printf("\n\n");}#endif /* TULIP_DEBUG */static void tulip_wait(unsigned int nticks){    unsigned int to = currticks() + nticks;    while (currticks() < to)        /* wait */ ;}/*********************************************************************//* Media Descriptor Code                                             *//*********************************************************************//* MII transceiver control section.   Read and write the MII registers using software-generated serial   MDIO protocol.  See the MII specifications or DP83840A data sheet   for details. *//* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually   met by back-to-back PCI I/O cycles, but we insert a delay to avoid   "overclocking" issues or future 66Mhz PCI. */#define mdio_delay() inl(mdio_addr)/* Read and write the MII registers using software-generated serial   MDIO protocol.  It is just different enough from the EEPROM protocol   to not share code.  The maxium data clock rate is 2.5 Mhz. */#define MDIO_SHIFT_CLK  0x10000#define MDIO_DATA_WRITE0 0x00000#define MDIO_DATA_WRITE1 0x20000#define MDIO_ENB                0x00000         /* Ignore the 0x02000 databook setting. */#define MDIO_ENB_IN             0x40000#define MDIO_DATA_READ  0x80000/* MII transceiver control section.   Read and write the MII registers using software-generated serial   MDIO protocol.  See the MII specifications or DP83840A data sheet   for details. */int mdio_read(struct nic *nic, int phy_id, int location){    int i;    int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;    int retval = 0;    long mdio_addr = ioaddr + CSR9;#ifdef TULIP_DEBUG_WHERE    whereami("mdio_read\n");#endif    if (tp->chip_id == LC82C168) {	int i = 1000;	outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);	inl(ioaddr + 0xA0);	inl(ioaddr + 0xA0);	while (--i > 0)	    if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))		return retval & 0xffff;	return 0xffff;    }    if (tp->chip_id == COMET) {	if (phy_id == 1) {	    if (location < 7)		return inl(ioaddr + 0xB4 + (location<<2));	    else if (location == 17)		return inl(ioaddr + 0xD0);	    else if (location >= 29 && location <= 31)		return inl(ioaddr + 0xD4 + ((location-29)<<2));	}	return 0xffff;    }    /* Establish sync by sending at least 32 logic ones. */    for (i = 32; i >= 0; i--) {	outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);	mdio_delay();	outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);	mdio_delay();    }    /* Shift the read command bits out. */    for (i = 15; i >= 0; i--) {	int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;	outl(MDIO_ENB | dataval, mdio_addr);	mdio_delay();	outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);	mdio_delay();    }    /* Read the two transition, 16 data, and wire-idle bits. */    for (i = 19; i > 0; i--) {	outl(MDIO_ENB_IN, mdio_addr);	mdio_delay();	retval = (retval << 1) | ((inl(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);	outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);	mdio_delay();    }    return (retval>>1) & 0xffff;}void mdio_write(struct nic *nic, int phy_id, int location, int value){    int i;    int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;    long mdio_addr = ioaddr + CSR9;#ifdef TULIP_DEBUG_WHERE    whereami("mdio_write\n");#endif    if (tp->chip_id == LC82C168) {	int i = 1000;	outl(cmd, ioaddr + 0xA0);	do	    if ( ! (inl(ioaddr + 0xA0) & 0x80000000))		break;	while (--i > 0);	return;    }    if (tp->chip_id == COMET) {	if (phy_id != 1)	    return;	if (location < 7)	    outl(value, ioaddr + 0xB4 + (location<<2));	else if (location == 17)	    outl(value, ioaddr + 0xD0);	else if (location >= 29 && location <= 31)	    outl(value, ioaddr + 0xD4 + ((location-29)<<2));	return;    }    /* Establish sync by sending 32 logic ones. */    for (i = 32; i >= 0; i--) {	outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);	mdio_delay();	outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);	mdio_delay();    }    /* Shift the command bits out. */    for (i = 31; i >= 0; i--) {	int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;	outl(MDIO_ENB | dataval, mdio_addr);	mdio_delay();	outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);	mdio_delay();    }    /* Clear out extra bits. */    for (i = 2; i > 0; i--) {	outl(MDIO_ENB_IN, mdio_addr);	mdio_delay();	outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);	mdio_delay();    }}/*********************************************************************//* EEPROM Reading Code                                               *//*********************************************************************//* EEPROM routines adapted from the Linux Tulip Code *//* Reading a serial EEPROM is a "bit" grungy, but we work our way   through:->.*/static int read_eeprom(unsigned long ioaddr, int location, int addr_len){    int i;    unsigned short retval = 0;    long ee_addr = ioaddr + CSR9;    int read_cmd = location | EE_READ_CMD;#ifdef TULIP_DEBUG_WHERE    whereami("read_eeprom\n");#endif    outl(EE_ENB & ~EE_CS, ee_addr);    outl(EE_ENB, ee_addr);    /* Shift the read command bits out. */    for (i = 4 + addr_len; i >= 0; i--) {        short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;        outl(EE_ENB | dataval, ee_addr);        eeprom_delay();        outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);        eeprom_delay();    }    outl(EE_ENB, ee_addr);    for (i = 16; i > 0; i--) {        outl(EE_ENB | EE_SHIFT_CLK, ee_addr);        eeprom_delay();        retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);        outl(EE_ENB, ee_addr);        eeprom_delay();    }    /* Terminate the EEPROM access. */    outl(EE_ENB & ~EE_CS, ee_addr);    return retval;}

⌨️ 快捷键说明

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