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

📄 fmvj18x_cs.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    ioaddr_t ioaddr = dev->base_addr;    printk(KERN_NOTICE "%s: transmit timed out with status %04x, %s?\n",	   dev->name, htons(inw(ioaddr + TX_STATUS)),	   inb(ioaddr + TX_STATUS) & F_TMT_RDY	   ? "IRQ conflict" : "network cable problem");    printk(KERN_NOTICE "%s: timeout registers: %04x %04x %04x "	   "%04x %04x %04x %04x %04x.\n",	   dev->name, htons(inw(ioaddr + 0)),	   htons(inw(ioaddr + 2)), htons(inw(ioaddr + 4)),	   htons(inw(ioaddr + 6)), htons(inw(ioaddr + 8)),	   htons(inw(ioaddr +10)), htons(inw(ioaddr +12)),	   htons(inw(ioaddr +14)));    lp->stats.tx_errors++;    /* ToDo: We should try to restart the adaptor... */    local_irq_disable();    fjn_reset(dev);    lp->tx_started = 0;    lp->tx_queue = 0;    lp->tx_queue_len = 0;    lp->sent = 0;    lp->open_time = jiffies;    local_irq_enable();    netif_wake_queue(dev);}static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev){    struct local_info_t *lp = netdev_priv(dev);    ioaddr_t ioaddr = dev->base_addr;    short length = skb->len;        if (length < ETH_ZLEN)    {    	skb = skb_padto(skb, ETH_ZLEN);    	if (skb == NULL)    		return 0;    	length = ETH_ZLEN;    }    netif_stop_queue(dev);    {	unsigned char *buf = skb->data;	if (length > ETH_FRAME_LEN) {	    printk(KERN_NOTICE "%s: Attempting to send a large packet"		   " (%d bytes).\n", dev->name, length);	    return 1;	}	DEBUG(4, "%s: Transmitting a packet of length %lu.\n",	      dev->name, (unsigned long)skb->len);	lp->stats.tx_bytes += skb->len;	/* Disable both interrupts. */	outw(0x0000, ioaddr + TX_INTR);	/* wait for a while */	udelay(1);	outw(length, ioaddr + DATAPORT);	outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);	lp->tx_queue++;	lp->tx_queue_len += ((length+3) & ~1);	if (lp->tx_started == 0) {	    /* If the Tx is idle, always trigger a transmit. */	    outb(DO_TX | lp->tx_queue, ioaddr + TX_START);	    lp->sent = lp->tx_queue ;	    lp->tx_queue = 0;	    lp->tx_queue_len = 0;	    dev->trans_start = jiffies;	    lp->tx_started = 1;	    netif_start_queue(dev);	} else {	    if( sram_config == 0 ) {		if (lp->tx_queue_len < (4096 - (ETH_FRAME_LEN +2)) )		    /* Yes, there is room for one more packet. */		    netif_start_queue(dev);	    } else {		if (lp->tx_queue_len < (8192 - (ETH_FRAME_LEN +2)) && 						lp->tx_queue < 127 )		    /* Yes, there is room for one more packet. */		    netif_start_queue(dev);	    }	}	/* Re-enable interrupts */	outb(D_TX_INTR, ioaddr + TX_INTR);	outb(D_RX_INTR, ioaddr + RX_INTR);    }    dev_kfree_skb (skb);    return 0;} /* fjn_start_xmit *//*====================================================================*/static void fjn_reset(struct net_device *dev){    struct local_info_t *lp = netdev_priv(dev);    ioaddr_t ioaddr = dev->base_addr;    int i;    DEBUG(4, "fjn_reset(%s) called.\n",dev->name);    /* Reset controller */    if( sram_config == 0 ) 	outb(CONFIG0_RST, ioaddr + CONFIG_0);    else	outb(CONFIG0_RST_1, ioaddr + CONFIG_0);    /* Power On chip and select bank 0 */    if (lp->cardtype == MBH10302)	outb(BANK_0, ioaddr + CONFIG_1);    else	outb(BANK_0U, ioaddr + CONFIG_1);    /* Set Tx modes */    outb(D_TX_MODE, ioaddr + TX_MODE);    /* set Rx modes */    outb(ID_MATCHED, ioaddr + RX_MODE);    /* Set hardware address */    for (i = 0; i < 6; i++)         outb(dev->dev_addr[i], ioaddr + NODE_ID + i);    /* Switch to bank 1 */    if (lp->cardtype == MBH10302)	outb(BANK_1, ioaddr + CONFIG_1);    else	outb(BANK_1U, ioaddr + CONFIG_1);    /* set the multicast table to accept none. */    for (i = 0; i < 6; i++)         outb(0x00, ioaddr + MAR_ADR + i);    /* Switch to bank 2 (runtime mode) */    if (lp->cardtype == MBH10302)	outb(BANK_2, ioaddr + CONFIG_1);    else	outb(BANK_2U, ioaddr + CONFIG_1);    /* set 16col ctrl bits */    if( lp->cardtype == TDK || lp->cardtype == CONTEC)         outb(TDK_AUTO_MODE, ioaddr + COL_CTRL);    else        outb(AUTO_MODE, ioaddr + COL_CTRL);    /* clear Reserved Regs */    outb(0x00, ioaddr + BMPR12);    outb(0x00, ioaddr + BMPR13);    /* reset Skip packet reg. */    outb(0x01, ioaddr + RX_SKIP);    /* Enable Tx and Rx */    if( sram_config == 0 )	outb(CONFIG0_DFL, ioaddr + CONFIG_0);    else	outb(CONFIG0_DFL_1, ioaddr + CONFIG_0);    /* Init receive pointer ? */    inw(ioaddr + DATAPORT);    inw(ioaddr + DATAPORT);    /* Clear all status */    outb(0xff, ioaddr + TX_STATUS);    outb(0xff, ioaddr + RX_STATUS);    if (lp->cardtype == MBH10302)	outb(INTR_OFF, ioaddr + LAN_CTRL);    /* Turn on Rx interrupts */    outb(D_TX_INTR, ioaddr + TX_INTR);    outb(D_RX_INTR, ioaddr + RX_INTR);    /* Turn on interrupts from LAN card controller */    if (lp->cardtype == MBH10302)	outb(INTR_ON, ioaddr + LAN_CTRL);} /* fjn_reset *//*====================================================================*/static void fjn_rx(struct net_device *dev){    struct local_info_t *lp = netdev_priv(dev);    ioaddr_t ioaddr = dev->base_addr;    int boguscount = 10;	/* 5 -> 10: by agy 19940922 */    DEBUG(4, "%s: in rx_packet(), rx_status %02x.\n",	  dev->name, inb(ioaddr + RX_STATUS));    while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {	u_short status = inw(ioaddr + DATAPORT);	DEBUG(4, "%s: Rxing packet mode %02x status %04x.\n",	      dev->name, inb(ioaddr + RX_MODE), status);#ifndef final_version	if (status == 0) {	    outb(F_SKP_PKT, ioaddr + RX_SKIP);	    break;	}#endif	if ((status & 0xF0) != 0x20) {	/* There was an error. */	    lp->stats.rx_errors++;	    if (status & F_LEN_ERR) lp->stats.rx_length_errors++;	    if (status & F_ALG_ERR) lp->stats.rx_frame_errors++;	    if (status & F_CRC_ERR) lp->stats.rx_crc_errors++;	    if (status & F_OVR_FLO) lp->stats.rx_over_errors++;	} else {	    u_short pkt_len = inw(ioaddr + DATAPORT);	    /* Malloc up new buffer. */	    struct sk_buff *skb;	    if (pkt_len > 1550) {		printk(KERN_NOTICE "%s: The FMV-18x claimed a very "		       "large packet, size %d.\n", dev->name, pkt_len);		outb(F_SKP_PKT, ioaddr + RX_SKIP);		lp->stats.rx_errors++;		break;	    }	    skb = dev_alloc_skb(pkt_len+2);	    if (skb == NULL) {		printk(KERN_NOTICE "%s: Memory squeeze, dropping "		       "packet (len %d).\n", dev->name, pkt_len);		outb(F_SKP_PKT, ioaddr + RX_SKIP);		lp->stats.rx_dropped++;		break;	    }	    skb->dev = dev;	    skb_reserve(skb, 2);	    insw(ioaddr + DATAPORT, skb_put(skb, pkt_len),		 (pkt_len + 1) >> 1);	    skb->protocol = eth_type_trans(skb, dev);#ifdef PCMCIA_DEBUG	    if (pc_debug > 5) {		int i;		printk(KERN_DEBUG "%s: Rxed packet of length %d: ",		       dev->name, pkt_len);		for (i = 0; i < 14; i++)		    printk(" %02x", skb->data[i]);		printk(".\n");	    }#endif	    netif_rx(skb);	    dev->last_rx = jiffies;	    lp->stats.rx_packets++;	    lp->stats.rx_bytes += pkt_len;	}	if (--boguscount <= 0)	    break;    }    /* If any worth-while packets have been received, dev_rint()	   has done a netif_wake_queue() for us and will work on them	   when we get to the bottom-half routine. *//*    if (lp->cardtype != TDK) {	int i;	for (i = 0; i < 20; i++) {	    if ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == F_BUF_EMP)		break;	    (void)inw(ioaddr + DATAPORT);  /+ dummy status read +/	    outb(F_SKP_PKT, ioaddr + RX_SKIP);	}	if (i > 0)	    DEBUG(5, "%s: Exint Rx packet with mode %02x after "		  "%d ticks.\n", dev->name, inb(ioaddr + RX_MODE), i);    }*/    return;} /* fjn_rx *//*====================================================================*/static void netdev_get_drvinfo(struct net_device *dev,			       struct ethtool_drvinfo *info){	strcpy(info->driver, DRV_NAME);	strcpy(info->version, DRV_VERSION);	sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);}#ifdef PCMCIA_DEBUGstatic u32 netdev_get_msglevel(struct net_device *dev){	return pc_debug;}static void netdev_set_msglevel(struct net_device *dev, u32 level){	pc_debug = level;}#endif /* PCMCIA_DEBUG */static struct ethtool_ops netdev_ethtool_ops = {	.get_drvinfo		= netdev_get_drvinfo,#ifdef PCMCIA_DEBUG	.get_msglevel		= netdev_get_msglevel,	.set_msglevel		= netdev_set_msglevel,#endif /* PCMCIA_DEBUG */};static int fjn_config(struct net_device *dev, struct ifmap *map){    return 0;}static int fjn_open(struct net_device *dev){    struct local_info_t *lp = netdev_priv(dev);    dev_link_t *link = &lp->link;    DEBUG(4, "fjn_open('%s').\n", dev->name);    if (!DEV_OK(link))	return -ENODEV;        link->open++;        fjn_reset(dev);        lp->tx_started = 0;    lp->tx_queue = 0;    lp->tx_queue_len = 0;    lp->open_time = jiffies;    netif_start_queue(dev);        return 0;} /* fjn_open *//*====================================================================*/static int fjn_close(struct net_device *dev){    struct local_info_t *lp = netdev_priv(dev);    dev_link_t *link = &lp->link;    ioaddr_t ioaddr = dev->base_addr;    DEBUG(4, "fjn_close('%s').\n", dev->name);    lp->open_time = 0;    netif_stop_queue(dev);    /* Set configuration register 0 to disable Tx and Rx. */    if( sram_config == 0 ) 	outb(CONFIG0_RST ,ioaddr + CONFIG_0);    else	outb(CONFIG0_RST_1 ,ioaddr + CONFIG_0);    /* Update the statistics -- ToDo. */    /* Power-down the chip.  Green, green, green! */    outb(CHIP_OFF ,ioaddr + CONFIG_1);    /* Set the ethernet adaptor disable IRQ */    if (lp->cardtype == MBH10302)	outb(INTR_OFF, ioaddr + LAN_CTRL);    link->open--;    return 0;} /* fjn_close *//*====================================================================*/static struct net_device_stats *fjn_get_stats(struct net_device *dev){    local_info_t *lp = netdev_priv(dev);    return &lp->stats;} /* fjn_get_stats *//*====================================================================*//*  Set the multicast/promiscuous mode for this adaptor.*/static void set_rx_mode(struct net_device *dev){    ioaddr_t ioaddr = dev->base_addr;    struct local_info_t *lp = netdev_priv(dev);    u_char mc_filter[8];		 /* Multicast hash filter */    u_long flags;    int i;        if (dev->flags & IFF_PROMISC) {	/* Unconditionally log net taps. */	printk("%s: Promiscuous mode enabled.\n", dev->name);	memset(mc_filter, 0xff, sizeof(mc_filter));	outb(3, ioaddr + RX_MODE);	/* Enable promiscuous mode */    } else if (dev->mc_count > MC_FILTERBREAK	       ||  (dev->flags & IFF_ALLMULTI)) {	/* Too many to filter perfectly -- accept all multicasts. */	memset(mc_filter, 0xff, sizeof(mc_filter));	outb(2, ioaddr + RX_MODE);	/* Use normal mode. */    } else if (dev->mc_count == 0) {	memset(mc_filter, 0x00, sizeof(mc_filter));	outb(1, ioaddr + RX_MODE);	/* Ignore almost all multicasts. */    } else {	struct dev_mc_list *mclist;	int i;		memset(mc_filter, 0, sizeof(mc_filter));	for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;	     i++, mclist = mclist->next) {	    unsigned int bit =	    	ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f;	    mc_filter[bit >> 3] |= (1 << bit);	}    }    local_irq_save(flags);     if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) {	int saved_bank = inb(ioaddr + CONFIG_1);	/* Switch to bank 1 and set the multicast table. */	outb(0xe4, ioaddr + CONFIG_1);	for (i = 0; i < 8; i++)	    outb(mc_filter[i], ioaddr + 8 + i);	memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter));	outb(saved_bank, ioaddr + CONFIG_1);    }    local_irq_restore(flags);}

⌨️ 快捷键说明

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