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

📄 pi2.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
	lp->tstate = ACTIVE;	/* char going out now */	restore_flags(flags);	return;    case DEFER:	/* Check DCD - debounce it         * See Intel Microcommunications Handbook, p2-308         */	wrtscc(lp->cardbase, cmd, R0, RES_EXT_INT);	wrtscc(lp->cardbase, cmd, R0, RES_EXT_INT);	if ((rdscc(lp->cardbase, cmd, R0) & DCD) != 0) {	    lp->tstate = DEFER;	    tdelay(lp, 100);	    /* defer until DCD transition or timeout */	    wrtscc(lp->cardbase, cmd, R15, CTSIE | DCDIE);	    restore_flags(flags);	    return;	}	if (random() > lp->persist) {	    lp->tstate = DEFER;	    tdelay(lp, lp->slotime);	    restore_flags(flags);	    return;	}	rts(lp, ON);		/* Transmitter on */	lp->tstate = ST_TXDELAY;	tdelay(lp, lp->txdelay);	restore_flags(flags);	return;    case ST_TXDELAY:	/* Get first char to send */	lp->txcnt--;	c = *lp->txptr++;	wrtscc(lp->cardbase, cmd, R0, RES_Tx_CRC);	/* reset for next frame */	/* Send abort on underrun */	if (lp->speed) {	/* If internally clocked */	    wrtscc(lp->cardbase, cmd, R10, CRCPS | NRZI | ABUNDER);	} else {	    wrtscc(lp->cardbase, cmd, R10, CRCPS | ABUNDER);	}	wrtscc(lp->cardbase, cmd, R8, c);	/* First char out now */	wrtscc(lp->cardbase, cmd, R0, RES_EOM_L);	/* Reset end of message latch */#ifdef STUFF2        /* stuff an extra one if we can */	if (lp->txcnt) {	    lp->txcnt--;	    c = *lp->txptr++;	    /* Wait for tx buffer empty */	    while((rdscc(lp->cardbase, cmd, R0) & 0x04) == 0)		;	    wrtscc(lp->cardbase, cmd, R8, c);	}#endif	/* select transmit interrupts to enable */	wrtscc(lp->cardbase, cmd, R15, TxUIE);	/* allow Underrun int only */	wrtscc(lp->cardbase, cmd, R0, RES_EXT_INT);	/* Tx/Extern ints on */	wrtscc(lp->cardbase, cmd, R1, TxINT_ENAB | EXT_INT_ENAB);	lp->tstate = ACTIVE;	/* char going out now */	restore_flags(flags);	return;    }    /* Receive Mode only     * This triggers when hunt mode is entered, & since an ABORT     * automatically enters hunt mode, we use that to clean up     * any waiting garbage     */    if ((lp->rstate == ACTIVE) && (st & BRK_ABRT)) {	(void) rdscc(lp->cardbase, cmd, R8);	(void) rdscc(lp->cardbase, cmd, R8);	(void) rdscc(lp->cardbase, cmd, R8);	lp->rcp = lp->rcvbuf->data;	lp->rcvbuf->cnt = 0;	/* rewind on DCD transition */    }    restore_flags(flags);}/* Probe for a PI card. *//* This routine also initializes the timer chip */__initfunc(static int hw_probe(int ioaddr)){    int time = 1000;		/* Number of milliseconds for test */    unsigned long start_time, end_time;    int base, tmr0, tmr1, tmrcmd;    int a = 1;    int b = 1;    base = ioaddr & 0x3f0;    tmr0 = TMR0 + base;    tmr1 = TMR1 + base;    tmrcmd = TMRCMD + base;    /* Set up counter chip timer 0 for 500 uS period square wave */    /* assuming a 3.68 mhz clock for now */    outb_p(SC0 | LSB_MSB | MODE3, tmrcmd);    outb_p(922 & 0xFF, tmr0);    outb_p(922 >> 8, tmr0);    /* Setup timer control word for timer 1*/    outb_p(SC1 | LSB_MSB | MODE0, tmrcmd);    outb_p((time << 1) & 0xFF, tmr1);    outb_p((time >> 7) & 0XFF, tmr1);    /* wait until counter reg is loaded */    do {	/* Latch count for reading */	outb_p(SC1, tmrcmd);	a = inb_p(tmr1);	b = inb_p(tmr1);    } while (b == 0);    start_time = jiffies;    while (b != 0) {	/* Latch count for reading */	outb_p(SC1, tmrcmd);	a = inb_p(tmr1);	b = inb_p(tmr1);	end_time = jiffies;	/* Don't wait forever - there may be no card here */	if ((end_time - start_time) > 200)	    return 0;		/* No card found */    }    end_time = jiffies;    /* 87 jiffies, for a 3.68 mhz clock, half that for a double speed clock */    if ((end_time - start_time) > 65) {	return (1);		/* PI card found */    } else {	/* Faster crystal - tmr0 needs adjusting */	/* Set up counter chip */	/* 500 uS square wave */	outb_p(SC0 | LSB_MSB | MODE3, tmrcmd);	outb_p(1844 & 0xFF, tmr0);	outb_p(1844 >> 8, tmr0);	return (2);		/* PI2 card found */    }}static void rts(struct pi_local *lp, int x){    int tc;    long br;    int cmd;    int dummy;    /* assumes interrupts are off */    cmd = CTL + lp->base;    /* Reprogram BRG and turn on transmitter to send flags */    if (x == ON) {		/* Turn Tx ON and Receive OFF */	/* Exints off first to avoid abort int */	wrtscc(lp->cardbase, cmd, R15, 0);	wrtscc(lp->cardbase, cmd, R3, Rx8);	/* Rx off */	lp->rstate = IDLE;	if (cmd & 2) {		/* if channel a */	    /* Set up for TX dma */	    wrtscc(lp->cardbase, cmd, R1, WT_FN_RDYFN | EXT_INT_ENAB);	} else {	    wrtscc(lp->cardbase, cmd, R1, 0);	/* No interrupts */	}	if (!lp->clockmode) {	    if (lp->speed) {	/* if internally clocked */		br = lp->speed;	/* get desired speed */		tc = (lp->xtal / br) - 2;	/* calc 1X BRG divisor */		wrtscc(lp->cardbase, cmd, R12, tc & 0xFF);	/* lower byte */		wrtscc(lp->cardbase, cmd, R13, (tc >> 8) & 0xFF);	/* upper byte */	    }	}	wrtscc(lp->cardbase, cmd, R5, TxCRC_ENAB | RTS | TxENAB | Tx8 | DTR);	/* Transmitter now on */    } else {			/* Tx OFF and Rx ON */	lp->tstate = IDLE;	wrtscc(lp->cardbase, cmd, R5, Tx8 | DTR);	/*  TX off */	if (!lp->clockmode) {	    if (lp->speed) {	/* if internally clocked */		/* Reprogram BRG for 32x clock for receive DPLL */		/* BRG off, keep Pclk source */		wrtscc(lp->cardbase, cmd, R14, BRSRC);		br = lp->speed;	/* get desired speed */		/* calc 32X BRG divisor */		tc = ((lp->xtal / 32) / br) - 2;		wrtscc(lp->cardbase, cmd, R12, tc & 0xFF);	/* lower byte */		wrtscc(lp->cardbase, cmd, R13, (tc >> 8) & 0xFF);	/* upper byte */		/* SEARCH mode, BRG source */		wrtscc(lp->cardbase, cmd, R14, BRSRC | SEARCH);		/* Enable the BRG */		wrtscc(lp->cardbase, cmd, R14, BRSRC | BRENABL);	    }	}	/* Flush rx fifo */	wrtscc(lp->cardbase, cmd, R3, Rx8);	/* Make sure rx is off */	wrtscc(lp->cardbase, cmd, R0, ERR_RES);	/* reset err latch */	dummy = rdscc(lp->cardbase, cmd, R1);	/* get status byte from R1 */	(void) rdscc(lp->cardbase, cmd, R8);	(void) rdscc(lp->cardbase, cmd, R8);	(void) rdscc(lp->cardbase, cmd, R8);	/* Now, turn on the receiver and hunt for a flag */	wrtscc(lp->cardbase, cmd, R3, RxENABLE | Rx8);	lp->rstate = ACTIVE;	/* Normal state */	if (cmd & 2) {		/* if channel a */	    setup_rx_dma(lp);	} else {	    /* reset buffer pointers */	    lp->rcp = lp->rcvbuf->data;	    lp->rcvbuf->cnt = 0;	    wrtscc(lp->cardbase, cmd, R1, (INT_ALL_Rx | EXT_INT_ENAB));	}	wrtscc(lp->cardbase, cmd, R15, BRKIE);	/* allow ABORT int */    }}static void scc_init(struct device *dev){    unsigned long flags;    struct pi_local *lp = (struct pi_local *) dev->priv;    int tc;    long br;    register int cmd;    /* Initialize 8530 channel for SDLC operation */    cmd = CTL + lp->base;    save_flags(flags);    cli();    switch (cmd & CHANA) {    case CHANA:	wrtscc(lp->cardbase, cmd, R9, CHRA);	/* Reset channel A */	wrtscc(lp->cardbase, cmd, R2, 0xff);	/* Initialize interrupt vector */	break;    default:	wrtscc(lp->cardbase, cmd, R9, CHRB);	/* Reset channel B */	break;    }    /* Deselect all Rx and Tx interrupts */    wrtscc(lp->cardbase, cmd, R1, 0);    /* Turn off external interrupts (like CTS/CD) */    wrtscc(lp->cardbase, cmd, R15, 0);    /* X1 clock, SDLC mode */    wrtscc(lp->cardbase, cmd, R4, SDLC | X1CLK);    /* Tx/Rx parameters */    if (lp->speed) {		/* Use internal clocking */	wrtscc(lp->cardbase, cmd, R10, CRCPS | NRZI);	if (!lp->clockmode)	    /* Tx Clk from BRG. Rcv Clk from DPLL, TRxC pin outputs DPLL */	    wrtscc(lp->cardbase, cmd, R11, TCBR | RCDPLL | TRxCDP | TRxCOI);	else	    /* Tx Clk from DPLL, Rcv Clk from DPLL, TRxC Outputs BRG */	    wrtscc(lp->cardbase, cmd, R11, TCDPLL | RCDPLL | TRxCBR | TRxCOI);    } else {			/* Use external clocking */	wrtscc(lp->cardbase, cmd, R10, CRCPS);	/* Tx Clk from Trxcl. Rcv Clk from Rtxcl, TRxC pin is input */	wrtscc(lp->cardbase, cmd, R11, TCTRxCP);    }    /* Null out SDLC start address */    wrtscc(lp->cardbase, cmd, R6, 0);    /* SDLC flag */    wrtscc(lp->cardbase, cmd, R7, FLAG);    /* Set up the Transmitter but don't enable it     *  DTR, 8 bit TX chars only     */    wrtscc(lp->cardbase, cmd, R5, Tx8 | DTR);    /* Receiver initial setup */    wrtscc(lp->cardbase, cmd, R3, Rx8);	/* 8 bits/char */    /* Setting up BRG now - turn it off first */    wrtscc(lp->cardbase, cmd, R14, BRSRC);	/* BRG off, keep Pclk source */    /* set the 32x time constant for the BRG in Receive mode */    if (lp->speed) {	br = lp->speed;		/* get desired speed */	tc = ((lp->xtal / 32) / br) - 2;	/* calc 32X BRG divisor */    } else {	tc = 14;    }    wrtscc(lp->cardbase, cmd, R12, tc & 0xFF);	/* lower byte */    wrtscc(lp->cardbase, cmd, R13, (tc >> 8) & 0xFF);	/* upper byte */    /* Following subroutine sets up and ENABLES the receiver */    rts(lp, OFF);		/* TX OFF and RX ON */    if (lp->speed) {	/* DPLL frm BRG, BRG src PCLK */	wrtscc(lp->cardbase, cmd, R14, BRSRC | SSBR);    } else {	/* DPLL frm rtxc,BRG src PCLK */	wrtscc(lp->cardbase, cmd, R14, BRSRC | SSRTxC);    }    wrtscc(lp->cardbase, cmd, R14, BRSRC | SEARCH);	/* SEARCH mode, keep BRG src */    wrtscc(lp->cardbase, cmd, R14, BRSRC | BRENABL);	/* Enable the BRG */    if (!(cmd & 2))		/* if channel b */	wrtscc(lp->cardbase, cmd, R1, (INT_ALL_Rx | EXT_INT_ENAB));    wrtscc(lp->cardbase, cmd, R15, BRKIE);	/* ABORT int */    /* Now, turn on the receiver and hunt for a flag */    wrtscc(lp->cardbase, cmd, R3, RxENABLE | RxCRC_ENAB | Rx8);    restore_flags(flags);}static void chipset_init(struct device *dev){    int cardbase;    unsigned long flags;    cardbase = dev->base_addr & 0x3f0;    save_flags(flags);    cli();    wrtscc(cardbase, dev->base_addr + CTL, R9, FHWRES);	/* Hardware reset */    /* Disable interrupts with master interrupt ctrl reg */    wrtscc(cardbase, dev->base_addr + CTL, R9, 0);    restore_flags(flags);}__initfunc(int pi_init(void)){    int *port;    int ioaddr = 0;    int card_type = 0;    int ports[] = {0x380, 0x300, 0x320, 0x340, 0x360, 0x3a0, 0};    printk(KERN_INFO "PI: V0.8 ALPHA April 23 1995 David Perry (dp@hydra.carleton.ca)\n");    /* Only one card supported for now */    for (port = &ports[0]; *port && !card_type; port++) {	ioaddr = *port;	if (check_region(ioaddr, PI_TOTAL_SIZE) == 0) {	    printk(KERN_INFO "PI: Probing for card at address %#3x\n",ioaddr);	    card_type = hw_probe(ioaddr);	}    }    switch (card_type) {    case 1:	printk(KERN_INFO "PI: Found a PI card at address %#3x\n", ioaddr);	break;    case 2:	printk(KERN_INFO "PI: Found a PI2 card at address %#3x\n", ioaddr);	break;    default:	printk(KERN_ERR "PI: ERROR: No card found\n");	return -EIO;    }    /* Link a couple of device structures into the chain */    /* For the A port */    /* Allocate space for 4 buffers even though we only need 3,       because one of them may cross a DMA page boundary and       be rejected by get_dma_buffer().    */    register_netdev(&pi0a);    pi0a.priv = kmalloc(sizeof(struct pi_local) + (DMA_BUFF_SIZE + sizeof(struct mbuf)) * 4, GFP_KERNEL | GFP_DMA);    pi0a.dma = PI_DMA;    pi0a.base_addr = ioaddr + 2;    pi0a.irq = 0;    /* And the B port */    register_netdev(&pi0b);    pi0b.base_addr = ioaddr;    pi0b.irq = 0;    pi0b.priv = kmalloc(sizeof(struct pi_local) + (DMA_BUFF_SIZE + sizeof(struct mbuf)) * 4, GFP_KERNEL | GFP_DMA);    /* Now initialize them */    pi_probe(&pi0a, card_type);    pi_probe(&pi0b, card_type);    pi0b.irq = pi0a.irq;	/* IRQ is shared */    return 0;}static int valid_dma_page(unsigned long addr, unsigned long dev_buffsize){    if (((addr & 0xffff) + dev_buffsize) <= 0x10000)	return 1;    else	return 0;}static int pi_set_mac_address(struct device *dev, void *addr){    struct sockaddr *sa = (struct sockaddr *)addr;    memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);	/* addr is an AX.25 shifted ASCII */    return 0;						/* mac address */}

⌨️ 快捷键说明

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