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

📄 comx-hw-munich.c

📁 该文件是rt_linux
💻 C
📖 第 1 页 / 共 5 页
字号:
	boardnum < MAX_BOARDS && (pci = pci_find_device(PCI_VENDOR_ID_SIEMENS,	PCI_DEVICE_ID_SIEMENS_MUNICH32X, pci)); boardnum++)    {	if (pci_enable_device(pci))	    continue;	printk("munich_probe: munich chip found, IRQ %d\n", pci->irq);#if (LINUX_VERSION_CODE < 0x02030d)	bar1 = ioremap_nocache(pci->base_address[0], 0x100);	lbi = ioremap_nocache(pci->base_address[1], 0x100);#else	bar1 = ioremap_nocache(pci->resource[0].start, 0x100);	lbi = ioremap_nocache(pci->resource[1].start, 0x100);#endif	if (bar1 && lbi)	{	    pci_write_config_dword(pci, MUNICH_PCI_PCIRES, 0xe0000);	    set_current_state(TASK_UNINTERRUPTIBLE);	    schedule_timeout(1);	    pci_write_config_dword(pci, MUNICH_PCI_PCIRES, 0);	    set_current_state(TASK_UNINTERRUPTIBLE);	    schedule_timeout(1);	    /* check the type of the card */	    writel(LREG0_MAGIC, MUNICH_VIRT(LREG0));	    writel(LREG1_MAGIC, MUNICH_VIRT(LREG1));	    writel(LREG2_MAGIC, MUNICH_VIRT(LREG2));	    writel(LREG3_MAGIC, MUNICH_VIRT(LREG3));	    writel(LREG4_MAGIC, MUNICH_VIRT(LREG4));	    writel(LREG5_MAGIC, MUNICH_VIRT(LREG5));	    writel(LCONF_MAGIC2,MUNICH_VIRT(LCONF));	/* enable the DMSM */	    if ((readb(lbi + VSTR) == 0x13) || (readb(lbi + VSTR) == 0x10))	    {		board = slicecom_boards + slicecom_boardnum;		sprintf((char *)board->devname, "slicecom%d",			slicecom_boardnum);		board->isx21 = 0;		slicecom_boardnum++;	    }	    else if ((readb(lbi + VSTR) == 0x6) || (readb(lbi + GIS) == 0x6))	    {		board = pcicom_boards + pcicom_boardnum;		sprintf((char *)board->devname, "pcicom%d", pcicom_boardnum);		board->isx21 = 1;		pcicom_boardnum++;	    }	    if (board)	    {		printk("munich_probe: %s board found\n", board->devname);		writel(LCONF_MAGIC1, MUNICH_VIRT(LCONF));	/* reset the DMSM */		board->pci = pci;		board->bar1 = bar1;		board->lbi = lbi;		board->framing = SLICECOM_FRAMING_DEFAULT;		board->linecode = SLICECOM_LINECODE_DEFAULT;		board->clock_source = SLICECOM_CLOCK_SOURCE_DEFAULT;		board->loopback = SLICECOM_LOOPBACK_DEFAULT;		SET_MODULE_OWNER(board);	    }	    else	    {		printk("munich_probe: Board error, VSTR: %02X\n",		       readb(lbi + VSTR));		iounmap((void *)bar1);		iounmap((void *)lbi);	    }	}	else	{	    printk("munich_probe: ioremap() failed, not enabling this board!\n");	    /* .pci = NULL, so the MUNICH_open will not try to open it            */	    if (bar1) iounmap((void *)bar1);	    if (lbi) iounmap((void *)lbi);	}    }    if (!pci && !boardnum)    {	printk("munich_probe: no PCI present!\n");	return -ENODEV;    }    if (pcicom_boardnum + slicecom_boardnum == 0)    {	printk	    ("munich_probe: Couldn't find any munich board: vendor:device %x:%x not found\n",	     PCI_VENDOR_ID_SIEMENS, PCI_DEVICE_ID_SIEMENS_MUNICH32X);	return -ENODEV;    }    /* Found some */    if (pcicom_boardnum)	printk("%d pcicom board(s) found.\n", pcicom_boardnum);    if (slicecom_boardnum)	printk("%d slicecom board(s) found.\n", slicecom_boardnum);    return 0;}/*  * Reset the hardware. Get called only from within this module if needed. */#if 0static int slicecom_reset(struct net_device *dev){    struct comx_channel *ch = dev->priv;    printk("slicecom_reset: resetting the hardware\n");    /* Begin to reset the hardware */    if (ch->HW_set_clock)	ch->HW_set_clock(dev);    /* And finish it */    return 0;}#endif/*  * Transmit a packet.  * Called by the protocol layer * Return values:	 *	FRAME_ACCEPTED:	frame is being transmited, transmitter is busy *	FRAME_QUEUED:	frame is being transmitted, there's more room in *				the transmitter for additional packet(s) *	FRAME_ERROR: *	FRAME_DROPPED:	there was some error */static int MUNICH_send_packet(struct net_device *dev, struct sk_buff *skb){    struct comx_channel *ch = (struct comx_channel *)dev->priv;    struct slicecom_privdata *hw = ch->HW_privdata;    /* Send it to the debug facility too if needed: */    if (ch->debug_flags & DEBUG_HW_TX)	comx_debug_bytes(dev, skb->data, skb->len, "MUNICH_send_packet");    /* If the line is inactive, don't accept: */    /* TODO: atgondolni hogy mi is legyen itt */    /* if (!(ch->line_status & LINE_UP)) return FRAME_DROPPED; */    /* More check, to be sure: */    if (skb->len > TXBUFFER_SIZE)    {	ch->stats.tx_errors++;	kfree_skb(skb);	return FRAME_ERROR;    }    /* Maybe you have to disable irq's while programming the hw: */    spin_lock_irqsave(&mister_lock, flags);    /* And more check: */    if (hw->busy >= TX_DESC_MAX - 1)    {	printk(KERN_ERR	       "%s: Transmitter called while busy... dropping frame, busy = %d\n",	       dev->name, hw->busy);	spin_unlock_irqrestore(&mister_lock, flags);	kfree_skb(skb);	return FRAME_DROPPED;    }    if (hw->busy >= 0)	hw->tx_ring_hist[hw->busy]++;    /* DELL: */    else	printk("slicecom: %s: FATAL: busy = %d\n", dev->name, hw->busy);//              /* DEL: *///      printk("slicecom: %s: _send_packet called, busy = %d\n", dev->name, hw->busy );    /* Packet can go, update stats: */    ch->stats.tx_packets++;    ch->stats.tx_bytes += skb->len;    /* Pass the packet to the HW:                   */    /* Step forward with the transmit descriptors:  */    hw->tx_desc_ptr = (hw->tx_desc_ptr + 1) % TX_DESC_MAX;    memcpy(&(hw->tx_data[hw->tx_desc_ptr][0]), skb->data, skb->len);    hw->tx_desc[hw->tx_desc_ptr].no = skb->len;    /* We don't issue any command, just step with the HOLD bit      */    hw->tx_desc[hw->tx_desc_ptr].hold = 1;    hw->tx_desc[(hw->tx_desc_ptr + TX_DESC_MAX - 1) % TX_DESC_MAX].hold = 0;#ifdef COMX_NEW    dev_kfree_skb(skb);#endif    /* csomag kerult a Tx ringbe: */    hw->busy++;    /* Report it: */    if (ch->debug_flags & DEBUG_HW_TX)	comx_debug(dev, "%s: MUNICH_send_packet was successful\n\n", dev->name);    if (hw->busy >= TX_DESC_MAX - 1)    {	spin_unlock_irqrestore(&mister_lock, flags);	return FRAME_ACCEPTED;    }    spin_unlock_irqrestore(&mister_lock, flags);    /* All done */    return FRAME_QUEUED;}/* * Interrupt handler routine. * Called by the Linux kernel. * BEWARE! The interrupts are enabled on the call! */static void MUNICH_interrupt(int irq, void *dev_id, struct pt_regs *regs){    struct sk_buff *skb;    int length;    int rx_status;    int work;			/* hany esemenyt kezeltem mar le                                */    u32 *bar1;    u8 *lbi;    u32 stat,			/* az esemenyek, amiket a ebben a loop korben le kell meg kezelni       */      race_stat = 0,		/* race eseten ebben uzenek magamnak hogy mit kell meg lekezelni        */      ack;			/* ezt fogom a vegen a STAT-ba irni, kiveszek belole 1-1 bitet ha       */    /* az adott dolgot nem kell ack-olni mert volt vele munkam, es  */    /* legjobb ha visszaterek ide megegyszer                        */    munich_intq_t int_info;    struct net_device *dev;    struct comx_channel *ch;    struct slicecom_privdata *hw;    munich_board_t *board = (munich_board_t *) dev_id;    int channel;    //      , boardnum = (int)dev_id;    // board = munich_boards + boardnum;    bar1 = board->bar1;    lbi = board->lbi;    //      Do not uncomment this under heavy load! :->    //      printk("MUNICH_interrupt: masked STAT=0x%08x, tiq=0x%08x, riq=0x%08x, piq=0x%08x\n", stat, board->tiq[0].all, board->riq[0].all, board->piq[0].all );    for (work = 0; (stat = (race_stat | (readl(MUNICH_VIRT(STAT)) & ~STAT_NOT_HANDLED_BY_INTERRUPT))) && (work < MAX_WORK - 1); work++)    {	ack = stat & (STAT_PRI | STAT_PTI | STAT_LBII);	/* Handle the interrupt information in the Rx queue. We don't really trust      */	/* info from this queue, because it can be overflowed, so later check           */	/* every Rx ring for received packets. But there are some errors which can't    */	/* be counted from the Rx rings, so we parse it.                                        */	int_info = board->riq[board->riq_ptr];	if (int_info.all & 0xF0000000)	/* ha ez nem 0, akkor itt interrupt_info van                    */	{	    ack &= ~STAT_PRI;	/* don't ack the interrupt, we had some work to do              */	    channel = PCM_INT_CHANNEL(int_info.all);	    dev = board->twins[channel];	    if (dev == NULL)	    {		printk		    ("MUNICH_interrupt: got an Rx interrupt info for NULL device "		     "%s.twins[%d], int_info = 0x%08x\n", board->devname,		     channel, int_info.all);		goto go_for_next_interrupt;	    }	    ch = (struct comx_channel *)dev->priv;	    hw = (struct slicecom_privdata *)ch->HW_privdata;	    //      printk("Rx STAT=0x%08x int_info=0x%08x rx_desc_ptr=%d rx_desc.status=0x%01x\n",	    //              stat, int_info.all, hw->rx_desc_ptr, hw->rx_desc[ hw->rx_desc_ptr ].status );	    if (int_info.all & PCM_INT_HI)		printk("SliceCOM: %s: Host Initiated interrupt\n", dev->name);	    if (int_info.all & PCM_INT_IFC)		printk("SliceCOM: %s: Idle/Flag Change\n", dev->name);	    /* TOD: jo ez az Idle/Flag Change valamire? - azonnal latszik belole hogy mikor ad a masik oldal */	    /* TOD: ilyen IT most nem is jon, mert ki van maszkolva az interrupt, biztosan kell ez? */	    if (int_info.all & PCM_INT_FO)		/* Internal buffer (RB) overrun */		ch->stats.rx_over_errors++;	/* TOD: Ez azt jelenti hogy a belso RB nem volt hozzaferheto, es ezert kihagyott valamit. De nem csak csomag lehetett, hanem esemeny, stb. is. lasd page 247. Ezzel a 'cat status'-hoz igazodok, de a netdevice.h szerint nem egyertelmu hogy ide ez kellene. Nem lehet hogy rx_missed ? */		/* DE: nem gotozok sehova, elvileg jo igy */		/* kesobb meg visszaterek az FO-ra, ha packet-FO volt. Keresd a "packet-FO"-t. */	    if (int_info.all & PCM_INT_FI)	/* frame received, but we do not trust the int_info queue       */		if (int_info.all & PCM_INT_SF)		{		/* Short Frame: rovidebb mint a CRC */		    /* "rovidebb mint CRC+2byte" vizsgalat a "CRC+2"-nel */		    ch->stats.rx_length_errors++;	/* TOD: noveljem? ne noveljem? */		    goto go_for_next_interrupt;		}	    go_for_next_interrupt:	/* One step in the interrupt queue */	    board->riq[board->riq_ptr].all = 0;	/* megjelolom hogy itt meg nem jart a hw */	    board->riq_ptr = (board->riq_ptr + 1) % MUNICH_INTQMAX;	}	/* Check every Rx ring for incomed packets: */	for (channel = 0; channel < 32; channel++)	{	    dev = board->twins[channel];	    if (dev != NULL)	    {		ch = (struct comx_channel *)dev->priv;		hw = (struct slicecom_privdata *)ch->HW_privdata;		rx_status = hw->rx_desc[hw->rx_desc_ptr].status;		if (!(rx_status & 0x80))	/* mar jart itt a hardver */		{		    ack &= ~STAT_PRI;	/* Don't ack, we had some work          */		    /* Ez most egy kicsit zuros, mert itt mar nem latom az int_infot        */		    if (rx_status & RX_STATUS_ROF)			ch->stats.rx_over_errors++;	/* TOD: 'cat status'-hoz igazodok */		    if (rx_status & RX_STATUS_RA)			/* Abort received or issued on channel  */			ch->stats.rx_frame_errors++;	/* or HOLD bit in the descriptor                */			/* TOD: 'cat status'-hoz igazodok */		    if (rx_status & RX_STATUS_LFD)		    {		/* Long Frame (longer then MFL in the MODE1) */			ch->stats.rx_length_errors++;			goto go_for_next_frame;		    }		    if (rx_status & RX_STATUS_NOB)		    {		/* Not n*8 bits long frame - frame alignment */			ch->stats.rx_frame_errors++;	/* ez viszont nem igazodik a 'cat status'-hoz */			goto go_for_next_frame;		    }		    if (rx_status & RX_STATUS_CRCO)		    {		/* CRC error */			ch->stats.rx_crc_errors++;			goto go_for_next_frame;		    }		    if (rx_status & RX_STATUS_SF)		    {		/* Short Frame: rovidebb mint CRC+2byte */			ch->stats.rx_errors++;	/* The HW does not set PCI_INT_ERR bit for this one, see page 246 */			ch->stats.rx_length_errors++;			goto go_for_next_frame;		    }		    if (rx_status != 0)		    {			printk("SliceCOM: %s: unhandled rx_status: 0x%02x\n",			       dev->name, rx_status);			goto go_for_next_frame;		    }		    /* frame received without errors: */		    length = hw->rx_desc[hw->rx_desc_ptr].bno;		    ch->stats.rx_packets++;	/* Count only 'good' packets */		    ch->stats.rx_bytes += length;		    /* Allocate a larger skb and reserve the heading for efficiency: */		    if ((skb = dev_alloc_skb(length + 16)) == NULL)		    {			ch->stats.rx_dropped++;			goto go_for_next_frame;		    }		    /* Do bookkeeping: */		    skb_reserve(skb, 16);		    skb_put(skb, length);		    skb->dev = dev;		    /* Now copy the data into the buffer: */		    memcpy(skb->data, &(hw->rx_data[hw->rx_desc_ptr][0]), length);		    /* DEL: UGLY HACK!!!! */		    if (*((int *)skb->data) == 0x02000000 &&

⌨️ 快捷键说明

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