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

📄 sk_g16.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 3 页
字号:
 *       Two different registers which share the same address, Status is *       read-only, Control is write-only. * * I/O Command: *       Any bitcombination written in here starts the transmission between *       Host and LANCE. */typedef struct{	unsigned char  ram[0x3fc0];   /* 16KB dual ported ram */	unsigned char  rom[0x0020];   /* 32Byte PROM containing 6Byte MAC */	unsigned char  res1[0x0010];  /* reserved */	unsigned volatile short ioreg;/* LANCE I/O Register */	unsigned volatile char  port; /* Statusregister and Controlregister */	unsigned char  iocom;         /* I/O Command Register */} SK_RAM;/* struct  *//* * This is the structure for the dual ported ram. We * have exactly 16 320 Bytes. In here there must be: * *     - Initialize Block   (starting at a word boundary) *     - Receive and Transmit Descriptor Rings (quadword boundary) *     - Data Buffers (arbitrary boundary) * * This is because LANCE has on SK_G16 only access to the dual ported * RAM and nowhere else. */struct SK_ram{    struct init_block ib;    struct tmd tmde[TMDNUM];    struct rmd rmde[RMDNUM];    char tmdbuf[TMDNUM][PKT_BUF_SZ];    char rmdbuf[RMDNUM][PKT_BUF_SZ];};/* * Structure where all necessary information is for ring buffer * management and statistics. */struct priv{    struct SK_ram *ram;  /* dual ported ram structure */    struct rmd *rmdhead; /* start of receive ring descriptors */    struct tmd *tmdhead; /* start of transmit ring descriptors */    int        rmdnum;   /* actual used ring descriptor */    int        tmdnum;   /* actual transmit descriptor for transmitting data */    int        tmdlast;  /* last sent descriptor used for error handling, etc */    void       *rmdbufs[RMDNUM]; /* pointer to the receive buffers */    void       *tmdbufs[TMDNUM]; /* pointer to the transmit buffers */};/* global variable declaration *//* static variables */static SK_RAM *board;  /* pointer to our memory mapped board components */static unsigned short	ioaddr; /* base io address */static struct priv	p_data;/* Macros *//* Function Prototypes *//* * Device Driver functions * ----------------------- * See for short explanation of each function its definitions header. */static int   SK_probe1(struct nic *nic, short ioaddr1);static void SK_reset(struct nic *nic);static int SK_poll(struct nic *nic);static void SK_transmit(struct nic *nic,const char *d,			/* Destination */unsigned int t,			/* Type */unsigned int s,			/* size */const char *p);			/* Packet */static void SK_disable(struct nic *nic);struct nic *SK_probe(struct nic *nic, unsigned short *probe_addrs);/* * LANCE Functions * --------------- */static int SK_lance_init(struct nic *nic, unsigned short mode);static void SK_reset_board(void);static void SK_set_RAP(int reg_number);static int SK_read_reg(int reg_number);static int SK_rread_reg(void);static void SK_write_reg(int reg_number, int value);/* * Debugging functions * ------------------- */static void SK_print_pos(struct nic *nic, char *text);static void SK_print_ram(struct nic *nic);/**************************************************************************RESET - Reset adapter***************************************************************************/static void SK_reset(struct nic *nic){	/* put the card in its initial state */	SK_lance_init(nic, MODE_NORMAL);}/**************************************************************************POLL - Wait for a frame***************************************************************************/static int SK_poll(struct nic *nic){	/* return true if there's an ethernet packet ready to read */	struct priv *p;         /* SK_G16 private structure */	struct rmd *rmdp;	int csr0, rmdstat, packet_there;    PRINTF2(("## %s: At beginning of SK_poll(). CSR0: %#hX\n",           SK_NAME, SK_read_reg(CSR0)));	p = nic->priv_data;    csr0 = SK_read_reg(CSR0);      /* store register for checking */    /*     * Acknowledge all of the current interrupt sources, disable     * Interrupts (INEA = 0)     */    SK_write_reg(CSR0, csr0 & CSR0_CLRALL);    if (csr0 & CSR0_ERR) /* LANCE Error */    {	printf("%s: error: %#hX", SK_NAME, csr0);        if (csr0 & CSR0_MISS)      /* No place to store packet ? */        {		printf(", Packet dropped.");        }	putchar('\n');    }    rmdp = p->rmdhead + p->rmdnum;    packet_there = 0;    /* As long as we own the next entry, check status and send     * it up to higher layer     */    while (!( (rmdstat = rmdp->u.s.status) & RX_OWN))    {	/*         * Start and end of packet must be set, because we use	 * the ethernet maximum packet length (1518) as buffer size.	 *	 * Because our buffers are at maximum OFLO and BUFF errors are	 * not to be concerned (see Data sheet)	 */	if ((rmdstat & (RX_STP | RX_ENP)) != (RX_STP | RX_ENP))	{	    /* Start of a frame > 1518 Bytes ? */	    if (rmdstat & RX_STP)	    {		printf("%s: packet too long\n", SK_NAME);	    }	    /*             * All other packets will be ignored until a new frame with	     * start (RX_STP) set follows.	     *	     * What we do is just give descriptor free for new incoming	     * packets.	     */	    rmdp->u.s.status = RX_OWN;      /* Relinquish ownership to LANCE */	}	else if (rmdstat & RX_ERR)          /* Receive Error ? */	{	    printf("%s: RX error: %#hX\n", SK_NAME, (int) rmdstat);	    rmdp->u.s.status = RX_OWN;      /* Relinquish ownership to LANCE */	}	else /* We have a packet which can be queued for the upper layers */	{	    int len = (rmdp->mlen & 0x0fff);  /* extract message length from receive buffer */	    /*             * Copy data out of our receive descriptor into nic->packet.	     *	     * (rmdp->u.buffer & 0x00ffffff) -> get address of buffer and	     * ignore status fields)	     */	    memcpy(nic->packet, (unsigned char *) (rmdp->u.buffer & 0x00ffffff), nic->packetlen = len);	    packet_there = 1;	    /*             * Packet is queued and marked for processing so we	     * free our descriptor	     */	    rmdp->u.s.status = RX_OWN;	    p->rmdnum++;	    p->rmdnum %= RMDNUM;	    rmdp = p->rmdhead + p->rmdnum;	}    }    SK_write_reg(CSR0, CSR0_INEA); /* Enable Interrupts */	return (packet_there);}/**************************************************************************TRANSMIT - Transmit a frame***************************************************************************/static void SK_transmit(struct nic *nic,const char *d,			/* Destination */unsigned int t,			/* Type */unsigned int s,			/* size */const char *pack)		/* Packet */{	/* send the packet to destination */    struct priv *p;         /* SK_G16 private structure */    struct tmd *tmdp;    short len;    int csr0, i, tmdstat;    PRINTF2(("## %s: At beginning of SK_transmit(). CSR0: %#hX\n",           SK_NAME, SK_read_reg(CSR0)));	p = nic->priv_data;	tmdp = p->tmdhead + p->tmdnum; /* Which descriptor for transmitting */	/* Copy data into dual ported ram */	memcpy(&p->ram->tmdbuf[p->tmdnum][0], d, ETH_ALEN);	/* dst */	memcpy(&p->ram->tmdbuf[p->tmdnum][ETH_ALEN], nic->node_addr, ETH_ALEN); /* src */	p->ram->tmdbuf[p->tmdnum][ETH_ALEN + ETH_ALEN] = t >> 8;	/* type */	p->ram->tmdbuf[p->tmdnum][ETH_ALEN + ETH_ALEN + 1] = t;	/* type */	memcpy(&p->ram->tmdbuf[p->tmdnum][ETH_HLEN], pack, s);	s += ETH_HLEN;	while (s < ETH_ZLEN)	/* pad to min length */		p->ram->tmdbuf[p->tmdnum][s++] = 0;	p->ram->tmde[p->tmdnum].status2 = 0x0;	/* Evaluate Packet length */	len = ETH_ZLEN < s ? s : ETH_ZLEN;	/* Fill in Transmit Message Descriptor */	tmdp->blen = -len;            /* set length to transmit */	/*	 * Packet start and end is always set because we use the maximum	 * packet length as buffer length.	 * Relinquish ownership to LANCE	 */	tmdp->u.s.status = TX_OWN | TX_STP | TX_ENP;	/* Start Demand Transmission */	SK_write_reg(CSR0, CSR0_TDMD | CSR0_INEA);    csr0 = SK_read_reg(CSR0);      /* store register for checking */    /*     * Acknowledge all of the current interrupt sources, disable     * Interrupts (INEA = 0)     */    SK_write_reg(CSR0, csr0 & CSR0_CLRALL);    if (csr0 & CSR0_ERR) /* LANCE Error */    {	printf("%s: error: %#hX", SK_NAME, csr0);        if (csr0 & CSR0_MISS)      /* No place to store packet ? */        {		printf(", Packet dropped.");        }	putchar('\n');    }    /* Set next buffer */    p->tmdlast++;    p->tmdlast &= TMDNUM-1;    tmdstat = tmdp->u.s.status & 0xff00; /* filter out status bits 15:08 */    /*     * We check status of transmitted packet.     * see LANCE data-sheet for error explanation     */    if (tmdstat & TX_ERR) /* Error occurred */    {	printf("%s: TX error: %#hX %#hX\n", SK_NAME, (int) tmdstat,		(int) tmdp->status2);	if (tmdp->status2 & TX_TDR)    /* TDR problems? */	{	    printf("%s: tdr-problems \n", SK_NAME);	}        if (tmdp->status2 & TX_UFLO)   /* Underflow error ? */        {            /*             * If UFLO error occurs it will turn transmitter of.             * So we must reinit LANCE             */            SK_lance_init(nic, MODE_NORMAL);        }	tmdp->status2 = 0;             /* Clear error flags */    }    SK_write_reg(CSR0, CSR0_INEA); /* Enable Interrupts */	/* Set pointer to next transmit buffer */	p->tmdnum++;	p->tmdnum &= TMDNUM-1;}/**************************************************************************DISABLE - Turn off ethernet interface***************************************************************************/static void SK_disable(struct nic *nic){    PRINTF(("## %s: At beginning of SK_disable(). CSR0: %#hX\n",           SK_NAME, SK_read_reg(CSR0)));    PRINTF(("%s: Shutting %s down CSR0 %#hX\n", SK_NAME, SK_NAME,           (int) SK_read_reg(CSR0)));    SK_write_reg(CSR0, CSR0_STOP); /* STOP the LANCE */}/**************************************************************************PROBE - Look for an adapter, this routine's visible to the outside***************************************************************************/struct nic *SK_probe(struct nic *nic, unsigned short *probe_addrs){	unsigned short		*p;	static unsigned short	io_addrs[] = SK_IO_PORTS;	/* if probe_addrs is 0, then routine can use a hardwired default */	putchar('\n');	nic->priv_data = &p_data;	if (probe_addrs == 0)		probe_addrs = io_addrs;	for (p = probe_addrs; (ioaddr = *p) != 0; ++p)	{		long		offset1, offset0 = inb(ioaddr);		if ((offset0 == SK_IDLOW) &&		 ((offset1 = inb(ioaddr + 1)) == SK_IDHIGH))			if (SK_probe1(nic, ioaddr) >= 0)				break;	}	/* if board found */	if (ioaddr != 0)	{		/* point to NIC specific routines */		nic->reset = SK_reset;		nic->poll = SK_poll;		nic->transmit = SK_transmit;		nic->disable = SK_disable;		return nic;	}	/* else */	{		return 0;	}

⌨️ 快捷键说明

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