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

📄 comx-hw-munich.c

📁 该文件是rt_linux
💻 C
📖 第 1 页 / 共 5 页
字号:
{    u8 *lbi = slicecom_boards[boardnum].lbi;    spin_lock_irqsave(&mister_lock, flags);    slicecom_boards[boardnum].framing = value;    switch (value)    {	case SLICECOM_FRAMING_CRC4:	    writeb(readb(lbi + FMR1) | 8, lbi + FMR1);	    writeb((readb(lbi + FMR2) & 0x3f) | 0x80, lbi + FMR2);	    break;	case SLICECOM_FRAMING_NO_CRC4:	    writeb(readb(lbi + FMR1) & 0xf7, lbi + FMR1);	    writeb(readb(lbi + FMR2) & 0x3f, lbi + FMR2);	    break;	default:	    printk("slicecom: board %d: unhandled " FILENAME_FRAMING		   " value %d\n", boardnum, value);    }    spin_unlock_irqrestore(&mister_lock, flags);}/* * Set PCM linecode - /proc/comx/comx0/linecode */void slicecom_set_linecode(int boardnum, int value){    u8 *lbi = slicecom_boards[boardnum].lbi;    spin_lock_irqsave(&mister_lock, flags);    slicecom_boards[boardnum].linecode = value;    switch (value)    {	case SLICECOM_LINECODE_HDB3:	    writeb(readb(lbi + FMR0) | 0xf0, lbi + FMR0);	    break;	case SLICECOM_LINECODE_AMI:	    writeb((readb(lbi + FMR0) & 0x0f) | 0xa0, lbi + FMR0);	    break;	default:	    printk("slicecom: board %d: unhandled " FILENAME_LINECODE		   " value %d\n", boardnum, value);    }    spin_unlock_irqrestore(&mister_lock, flags);}/* * Set PCM clock source - /proc/comx/comx0/clock_source */void slicecom_set_clock_source(int boardnum, int value){    u8 *lbi = slicecom_boards[boardnum].lbi;    spin_lock_irqsave(&mister_lock, flags);    slicecom_boards[boardnum].clock_source = value;    switch (value)    {	case SLICECOM_CLOCK_SOURCE_LINE:	    writeb(readb(lbi + LIM0) & ~1, lbi + LIM0);	    break;	case SLICECOM_CLOCK_SOURCE_INTERNAL:	    writeb(readb(lbi + LIM0) | 1, lbi + LIM0);	    break;	default:	    printk("slicecom: board %d: unhandled " FILENAME_CLOCK_SOURCE		   " value %d\n", boardnum, value);    }    spin_unlock_irqrestore(&mister_lock, flags);}/* * Set loopbacks - /proc/comx/comx0/loopback */void slicecom_set_loopback(int boardnum, int value){    u8 *lbi = slicecom_boards[boardnum].lbi;    spin_lock_irqsave(&mister_lock, flags);    slicecom_boards[boardnum].loopback = value;    switch (value)    {	case SLICECOM_LOOPBACK_NONE:	    writeb(readb(lbi + LIM0) & ~2, lbi + LIM0);	/* Local Loop OFF  */	    writeb(readb(lbi + LIM1) & ~2, lbi + LIM1);	/* Remote Loop OFF */	    break;	case SLICECOM_LOOPBACK_LOCAL:	    writeb(readb(lbi + LIM1) & ~2, lbi + LIM1);	/* Remote Loop OFF */	    writeb(readb(lbi + LIM0) | 2, lbi + LIM0);	/* Local Loop ON   */	    break;	case SLICECOM_LOOPBACK_REMOTE:	    writeb(readb(lbi + LIM0) & ~2, lbi + LIM0);	/* Local Loop OFF  */	    writeb(readb(lbi + LIM1) | 2, lbi + LIM1);	/* Remote Loop ON  */	    break;	default:	    printk("slicecom: board %d: unhandled " FILENAME_LOOPBACK		   " value %d\n", boardnum, value);    }    spin_unlock_irqrestore(&mister_lock, flags);}/* * Update E1 line status LEDs on the adapter */void slicecom_update_leds(munich_board_t * board){    u32 *bar1 = board->bar1;    u8 *lbi = board->lbi;    u8 frs0;    u32 leds;    int i;    spin_lock_irqsave(&mister_lock, flags);    leds = 0;    frs0 = readb(lbi + FRS0);	/* FRS0 bits described on page 137 */    if (!(frs0 & 0xa0))    {	leds |= 0x2000;		/* Green LED: Input signal seems to be OK, no LOS, no LFA       */	if (frs0 & 0x10)	    leds |= 0x8000;	/* Red LED: Receiving Remote Alarm                                      */    }    writel(leds, MUNICH_VIRT(GPDATA));    if (leds == 0x2000 && !board->lineup)    {				/* line up */	board->lineup = 1;	for (i = 0; i < 32; i++)	{	    if (board->twins[i] && (board->twins[i]->flags & IFF_RUNNING))	    {		struct comx_channel *ch = board->twins[i]->priv;		if (!test_and_set_bit(0, &ch->lineup_pending))		{		    ch->lineup_timer.function = comx_lineup_func;		    ch->lineup_timer.data = (unsigned long)board->twins[i];		    ch->lineup_timer.expires = jiffies + HZ * ch->lineup_delay;		    add_timer(&ch->lineup_timer);		}	    }	}    }    else if (leds != 0x2000 && board->lineup)    {				/* line down */	board->lineup = 0;	for (i = 0; i < 32; i++)	    if (board->twins[i] && (board->twins[i]->flags & IFF_RUNNING))	    {		struct comx_channel *ch = board->twins[i]->priv;		if (test_and_clear_bit(0, &ch->lineup_pending))		    del_timer(&ch->lineup_timer);		else if (ch->line_status & LINE_UP)		{		    ch->line_status &= ~LINE_UP;		    if (ch->LINE_status)			ch->LINE_status(board->twins[i], ch->line_status);		}	    }    }    spin_unlock_irqrestore(&mister_lock, flags);}/* * This function gets called every second when the FALC issues the interrupt. * Hardware counters contain error counts for last 1-second time interval. * We add them to the global counters here. * Read rfc2495 to understand this. */void slicecom_update_line_counters(munich_board_t * board){    e1_stats_t *curr_int = &board->intervals[board->current_interval];    u8 *lbi = board->lbi;    unsigned framing_errors, code_violations, path_code_violations, crc4_errors,	e_bit_errors;    unsigned slip_detected,	/* this one has logical value, not the number of slips! */      out_of_frame_defect,	/* logical value        */      ais_defect,		/* logical value        */      errored_sec, bursty_err_sec, severely_err_sec = 0, failure_sec;    u8 isr2, isr3, isr5, frs0;    spin_lock_irqsave(&mister_lock, flags);    isr2 = readb(lbi + ISR2);	/* ISR0-5 described on page 156     */    isr3 = readb(lbi + ISR3);    isr5 = readb(lbi + ISR5);    frs0 = readb(lbi + FRS0);	/* FRS0 described on page 137       */    /* Error Events: */    code_violations = readb(lbi + CVCL) + (readb(lbi + CVCH) << 8);    framing_errors = readb(lbi + FECL) + (readb(lbi + FECH) << 8);    crc4_errors = readb(lbi + CEC1L) + (readb(lbi + CEC1H) << 8);    e_bit_errors = readb(lbi + EBCL) + (readb(lbi + EBCH) << 8);    slip_detected = isr3 & (ISR3_RSN | ISR3_RSP);    path_code_violations = framing_errors + crc4_errors;    curr_int->line_code_violations += code_violations;    curr_int->path_code_violations += path_code_violations;    curr_int->e_bit_errors += e_bit_errors;    /* Performance Defects: */    /* there was an LFA in the last second, but maybe disappeared: */    out_of_frame_defect = (isr2 & ISR2_LFA) || (frs0 & FRS0_LFA);    /* there was an AIS in the last second, but maybe disappeared: */    ais_defect = (isr2 & ISR2_AIS) || (frs0 & FRS0_AIS);    /* Performance Parameters: */    if (out_of_frame_defect)	curr_int->fr_loss_secs++;    if (code_violations)	curr_int->line_err_secs++;    errored_sec = ((board->framing == SLICECOM_FRAMING_NO_CRC4) &&		   (code_violations)) || path_code_violations ||	out_of_frame_defect || slip_detected || ais_defect;    bursty_err_sec = !out_of_frame_defect && !ais_defect &&	(path_code_violations > 1) && (path_code_violations < 320);    switch (board->framing)    {	case SLICECOM_FRAMING_CRC4:	    severely_err_sec = out_of_frame_defect ||		(path_code_violations >= 832);	    break;	case SLICECOM_FRAMING_NO_CRC4:	    severely_err_sec = (code_violations >= 2048);	    break;    }    /*     * failure_sec: true if there was a condition leading to a failure     * (and leading to unavailable state) in this second:     */    failure_sec = (isr2 & ISR2_RA) || (frs0 & FRS0_RRA)	/* Remote/Far End/Distant Alarm Failure */	|| ais_defect || out_of_frame_defect	/* AIS or LOF Failure                           */	|| (isr2 & ISR2_LOS) || (frs0 & FRS0_LOS)	/* Loss Of Signal Failure                       */	|| (board->loopback != SLICECOM_LOOPBACK_NONE);	/* Loopback has been set                        */    if (board->is_unavailable)    {	if (severely_err_sec)	    board->no_ses_seconds = 0;	else	    board->no_ses_seconds++;	if ((board->no_ses_seconds >= 10) && !failure_sec)	{	    board->is_unavailable = 0;	    board->ses_seconds = 0;	    board->no_ses_seconds = 0;	}    }    else    {	if (severely_err_sec)	    board->ses_seconds++;	else	    board->ses_seconds = 0;	if ((board->ses_seconds >= 10) || failure_sec)	{	    board->is_unavailable = 1;	    board->ses_seconds = 0;	    board->no_ses_seconds = 0;	}    }    if (board->is_unavailable)	curr_int->unavail_secs++;    else    {	if (slip_detected)	    curr_int->slip_secs++;	curr_int->errored_secs += errored_sec;	curr_int->bursty_err_secs += bursty_err_sec;	curr_int->severely_err_secs += severely_err_sec;    }    /* the RFC does not say clearly which errors to count here, we try to count bit errors */    if (!board->is_unavailable && !severely_err_sec)    {	board->deg_cumulated_errors += code_violations;	board->deg_elapsed_seconds++;	if (board->deg_elapsed_seconds >= 60)	{	    if (board->deg_cumulated_errors >= 123)		curr_int->degraded_mins++;	    board->deg_cumulated_errors = 0;	    board->deg_elapsed_seconds = 0;	}    }    board->elapsed_seconds++;    if (board->elapsed_seconds >= 900)    {	board->current_interval =	    (board->current_interval + 1) % SLICECOM_BOARD_INTERVALS_SIZE;	memset((void *)&board->intervals[board->current_interval], 0,	       sizeof(e1_stats_t));	board->elapsed_seconds = 0;    }    spin_unlock_irqrestore(&mister_lock, flags);}static void pcicom_modemline(unsigned long b){    munich_board_t *board = (munich_board_t *) b;    struct net_device *dev = board->twins[0];    struct comx_channel *ch = dev->priv;    unsigned long regs;    regs = readl((void *)(&board->bar1[GPDATA]));    if ((ch->line_status & LINE_UP) && (regs & 0x0800))    {	ch->line_status &= ~LINE_UP;	board->lineup = 0;	if (ch->LINE_status)	{	    ch->LINE_status(dev, ch->line_status);	}    }    if (!(ch->line_status & LINE_UP) && !(regs & 0x0800))    {	ch->line_status |= LINE_UP;	board->lineup = 1;	if (ch->LINE_status)	{	    ch->LINE_status(dev, ch->line_status);	}    }    mod_timer((struct timer_list *)&board->modemline_timer, jiffies + HZ);}/*  * Is it possible to transmit ? * Called (may be called) by the protocol layer  */static int MUNICH_txe(struct net_device *dev){    struct comx_channel *ch = dev->priv;    struct slicecom_privdata *hw = ch->HW_privdata;    return (hw->busy < TX_DESC_MAX - 1);}/*  * Hw probe function. Detects all the boards in the system, * and fills up slicecom_boards[] and pcicom_boards[] * Returns 0 on success. * We do not disable interrupts! */static int munich_probe(void){    struct pci_dev *pci;    int boardnum;    int slicecom_boardnum;    int pcicom_boardnum;    u32 *bar1;    u8 *lbi;    munich_board_t *board;    for (boardnum = 0; boardnum < MAX_BOARDS; boardnum++)    {	pcicom_boards[boardnum].pci = 0;	pcicom_boards[boardnum].bar1 = 0;	pcicom_boards[boardnum].lbi = 0;	slicecom_boards[boardnum].pci = 0;	slicecom_boards[boardnum].bar1 = 0;	slicecom_boards[boardnum].lbi = 0;    }    pci = NULL;    board = NULL;    slicecom_boardnum = 0;    pcicom_boardnum = 0;    for (boardnum = 0;

⌨️ 快捷键说明

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