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

📄 hp100.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
				lp->lan_type = i;				hp100_stop_interface(dev);				if (lp->lan_type == HP100_LAN_100)					lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);				hp100_start_interface(dev);			} else {				printk("hp100: %s: interface reset\n", dev->name);				hp100_stop_interface(dev);				if (lp->lan_type == HP100_LAN_100)					lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);				hp100_start_interface(dev);				mdelay(1);			}		}		dev->trans_start = jiffies;		return -EAGAIN;	}	for (i = 0; i < 6000 && (hp100_inb(OPTION_MSW) & HP100_TX_CMD); i++) {#ifdef HP100_DEBUG_TX		printk("hp100: %s: start_xmit: busy\n", dev->name);#endif	}	spin_lock_irqsave(&lp->lock, flags);	hp100_ints_off();	val = hp100_inw(IRQ_STATUS);	/* Ack / clear the interrupt TX_COMPLETE interrupt - this interrupt is set	 * when the current packet being transmitted on the wire is completed. */	hp100_outw(HP100_TX_COMPLETE, IRQ_STATUS);#ifdef HP100_DEBUG_TX	printk("hp100: %s: start_xmit: irq_status=0x%.4x, irqmask=0x%.4x, len=%d\n",			dev->name, val, hp100_inw(IRQ_MASK), (int) skb->len);#endif	ok_flag = skb->len >= HP100_MIN_PACKET_SIZE;	i = ok_flag ? skb->len : HP100_MIN_PACKET_SIZE;	hp100_outw(i, DATA32);	/* tell card the total packet length */	hp100_outw(i, FRAGMENT_LEN);	/* and first/only fragment length    */	if (lp->mode == 2) {	/* memory mapped */		if (lp->mem_ptr_virt) {	/* high pci memory was remapped */			/* Note: The J2585B needs alignment to 32bits here!  */			memcpy_toio(lp->mem_ptr_virt, skb->data, (skb->len + 3) & ~3);			if (!ok_flag)				memset_io(lp->mem_ptr_virt, 0, HP100_MIN_PACKET_SIZE - skb->len);		} else {			/* Note: The J2585B needs alignment to 32bits here!  */			isa_memcpy_toio(lp->mem_ptr_phys, skb->data, (skb->len + 3) & ~3);			if (!ok_flag)				isa_memset_io(lp->mem_ptr_phys, 0, HP100_MIN_PACKET_SIZE - skb->len);		}	} else {		/* programmed i/o */		outsl(ioaddr + HP100_REG_DATA32, skb->data,		      (skb->len + 3) >> 2);		if (!ok_flag)			for (i = (skb->len + 3) & ~3; i < HP100_MIN_PACKET_SIZE; i += 4)				hp100_outl(0, DATA32);	}	hp100_outb(HP100_TX_CMD | HP100_SET_LB, OPTION_MSW);	/* send packet */	lp->stats.tx_packets++;	lp->stats.tx_bytes += skb->len;	dev->trans_start = jiffies;	hp100_ints_on();	spin_unlock_irqrestore(&lp->lock, flags);	dev_kfree_skb_any(skb);#ifdef HP100_DEBUG_TX	printk("hp100: %s: start_xmit: end\n", dev->name);#endif	return 0;}/* * Receive Function (Non-Busmaster mode) * Called when an "Receive Packet" interrupt occurs, i.e. the receive  * packet counter is non-zero. * For non-busmaster, this function does the whole work of transfering * the packet to the host memory and then up to higher layers via skb * and netif_rx.  */static void hp100_rx(struct net_device *dev){	int packets, pkt_len;	int ioaddr = dev->base_addr;	struct hp100_private *lp = (struct hp100_private *) dev->priv;	u_int header;	struct sk_buff *skb;#ifdef DEBUG_B	hp100_outw(0x4213, TRACE);	printk("hp100: %s: rx\n", dev->name);#endif	/* First get indication of received lan packet */	/* RX_PKT_CND indicates the number of packets which have been fully */	/* received onto the card but have not been fully transferred of the card */	packets = hp100_inb(RX_PKT_CNT);#ifdef HP100_DEBUG_RX	if (packets > 1)		printk("hp100: %s: rx: waiting packets = %d\n", dev->name, packets);#endif	while (packets-- > 0) {		/* If ADV_NXT_PKT is still set, we have to wait until the card has */		/* really advanced to the next packet. */		for (pkt_len = 0; pkt_len < 6000 && (hp100_inb(OPTION_MSW) & HP100_ADV_NXT_PKT); pkt_len++) {#ifdef HP100_DEBUG_RX			printk ("hp100: %s: rx: busy, remaining packets = %d\n", dev->name, packets);#endif		}		/* First we get the header, which contains information about the */		/* actual length of the received packet. */		if (lp->mode == 2) {	/* memory mapped mode */			if (lp->mem_ptr_virt)	/* if memory was remapped */				header = readl(lp->mem_ptr_virt);			else				header = isa_readl(lp->mem_ptr_phys);		} else		/* programmed i/o */			header = hp100_inl(DATA32);		pkt_len = ((header & HP100_PKT_LEN_MASK) + 3) & ~3;#ifdef HP100_DEBUG_RX		printk("hp100: %s: rx: new packet - length=%d, errors=0x%x, dest=0x%x\n",				     dev->name, header & HP100_PKT_LEN_MASK,				     (header >> 16) & 0xfff8, (header >> 16) & 7);#endif		/* Now we allocate the skb and transfer the data into it. */		skb = dev_alloc_skb(pkt_len);		if (skb == NULL) {	/* Not enough memory->drop packet */#ifdef HP100_DEBUG			printk("hp100: %s: rx: couldn't allocate a sk_buff of size %d\n",					     dev->name, pkt_len);#endif			lp->stats.rx_dropped++;		} else {	/* skb successfully allocated */			u_char *ptr;			skb->dev = dev;			/* ptr to start of the sk_buff data area */			ptr = (u_char *) skb_put(skb, pkt_len);			/* Now transfer the data from the card into that area */			if (lp->mode == 2) {				if (lp->mem_ptr_virt)					memcpy_fromio(ptr, lp->mem_ptr_virt,pkt_len);				/* Note alignment to 32bit transfers */				else					isa_memcpy_fromio(ptr, lp->mem_ptr_phys, pkt_len);			} else	/* io mapped */				insl(ioaddr + HP100_REG_DATA32, ptr, pkt_len >> 2);			skb->protocol = eth_type_trans(skb, dev);#ifdef HP100_DEBUG_RX			printk("hp100: %s: rx: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",					dev->name, ptr[0], ptr[1], ptr[2], ptr[3],		 			ptr[4], ptr[5], ptr[6], ptr[7], ptr[8],					ptr[9], ptr[10], ptr[11]);#endif			netif_rx(skb);			dev->last_rx = jiffies;			lp->stats.rx_packets++;			lp->stats.rx_bytes += pkt_len;		}		/* Indicate the card that we have got the packet */		hp100_outb(HP100_ADV_NXT_PKT | HP100_SET_LB, OPTION_MSW);		switch (header & 0x00070000) {		case (HP100_MULTI_ADDR_HASH << 16):		case (HP100_MULTI_ADDR_NO_HASH << 16):			lp->stats.multicast++;			break;		}	}			/* end of while(there are packets) loop */#ifdef HP100_DEBUG_RX	printk("hp100_rx: %s: end\n", dev->name);#endif}/*  * Receive Function for Busmaster Mode */static void hp100_rx_bm(struct net_device *dev){	int ioaddr = dev->base_addr;	struct hp100_private *lp = (struct hp100_private *) dev->priv;	hp100_ring_t *ptr;	u_int header;	int pkt_len;#ifdef HP100_DEBUG_B	hp100_outw(0x4214, TRACE);	printk("hp100: %s: rx_bm\n", dev->name);#endif#ifdef HP100_DEBUG	if (0 == lp->rxrcommit) {		printk("hp100: %s: rx_bm called although no PDLs were committed to adapter?\n", dev->name);		return;	} else		/* RX_PKT_CNT states how many PDLs are currently formatted and available to 		 * the cards BM engine */	if ((hp100_inw(RX_PKT_CNT) & 0x00ff) >= lp->rxrcommit) {		printk("hp100: %s: More packets received than commited? RX_PKT_CNT=0x%x, commit=0x%x\n",				     dev->name, hp100_inw(RX_PKT_CNT) & 0x00ff,				     lp->rxrcommit);		return;	}#endif	while ((lp->rxrcommit > hp100_inb(RX_PDL))) {		/*		 * The packet was received into the pdl pointed to by lp->rxrhead (		 * the oldest pdl in the ring 		 */		/* First we get the header, which contains information about the */		/* actual length of the received packet. */		ptr = lp->rxrhead;		header = *(ptr->pdl - 1);		pkt_len = (header & HP100_PKT_LEN_MASK);#ifdef HP100_DEBUG_BM		printk("hp100: %s: rx_bm: header@0x%x=0x%x length=%d, errors=0x%x, dest=0x%x\n",				dev->name, (u_int) (ptr->pdl - 1), (u_int) header,				pkt_len, (header >> 16) & 0xfff8, (header >> 16) & 7);		printk("hp100: %s: RX_PDL_COUNT:0x%x TX_PDL_COUNT:0x%x, RX_PKT_CNT=0x%x PDH=0x%x, Data@0x%x len=0x%x\n",		   		dev->name, hp100_inb(RX_PDL), hp100_inb(TX_PDL),				hp100_inb(RX_PKT_CNT), (u_int) * (ptr->pdl),				(u_int) * (ptr->pdl + 3), (u_int) * (ptr->pdl + 4));#endif		if ((pkt_len >= MIN_ETHER_SIZE) &&		    (pkt_len <= MAX_ETHER_SIZE)) {			if (ptr->skb == NULL) {				printk("hp100: %s: rx_bm: skb null\n", dev->name);				/* can happen if we only allocated room for the pdh due to memory shortage. */				lp->stats.rx_dropped++;			} else {				skb_trim(ptr->skb, pkt_len);	/* Shorten it */				ptr->skb->protocol =				    eth_type_trans(ptr->skb, dev);				netif_rx(ptr->skb);	/* Up and away... */				dev->last_rx = jiffies;				lp->stats.rx_packets++;				lp->stats.rx_bytes += pkt_len;			}			switch (header & 0x00070000) {			case (HP100_MULTI_ADDR_HASH << 16):			case (HP100_MULTI_ADDR_NO_HASH << 16):				lp->stats.multicast++;				break;			}		} else {#ifdef HP100_DEBUG			printk("hp100: %s: rx_bm: Received bad packet (length=%d)\n", dev->name, pkt_len);#endif			if (ptr->skb != NULL)				dev_kfree_skb_any(ptr->skb);			lp->stats.rx_errors++;		}		lp->rxrhead = lp->rxrhead->next;		/* Allocate a new rx PDL (so lp->rxrcommit stays the same) */		if (0 == hp100_build_rx_pdl(lp->rxrtail, dev)) {			/* No space for skb, header can still be received. */#ifdef HP100_DEBUG			printk("hp100: %s: rx_bm: No space for new PDL.\n", dev->name);#endif			return;		} else {	/* successfully allocated new PDL - put it in ringlist at tail. */			hp100_outl((u32) lp->rxrtail->pdl_paddr, RX_PDA);			lp->rxrtail = lp->rxrtail->next;		}	}}/* *  statistics */static hp100_stats_t *hp100_get_stats(struct net_device *dev){	unsigned long flags;	int ioaddr = dev->base_addr;	struct hp100_private *lp = (struct hp100_private *) dev->priv;#ifdef HP100_DEBUG_B	hp100_outw(0x4215, TRACE);#endif	spin_lock_irqsave(&lp->lock, flags);	hp100_ints_off();	/* Useful ? Jean II */	hp100_update_stats(dev);	hp100_ints_on();	spin_unlock_irqrestore(&lp->lock, flags);	return &(lp->stats);}static void hp100_update_stats(struct net_device *dev){	int ioaddr = dev->base_addr;	u_short val;	struct hp100_private *lp = (struct hp100_private *) dev->priv;#ifdef HP100_DEBUG_B	hp100_outw(0x4216, TRACE);	printk("hp100: %s: update-stats\n", dev->name);#endif	/* Note: Statistics counters clear when read. */	hp100_page(MAC_CTRL);	val = hp100_inw(DROPPED) & 0x0fff;	lp->stats.rx_errors += val;	lp->stats.rx_over_errors += val;	val = hp100_inb(CRC);	lp->stats.rx_errors += val;	lp->stats.rx_crc_errors += val;	val = hp100_inb(ABORT);	lp->stats.tx_errors += val;	lp->stats.tx_aborted_errors += val;	hp100_page(PERFORMANCE);}static void hp100_misc_interrupt(struct net_device *dev){	struct hp100_private *lp = (struct hp100_private *) dev->priv;#ifdef HP100_DEBUG_B	hp100_outw(0x4216, TRACE);	printk("hp100: %s: misc_interrupt\n", dev->name);#endif	/* Note: Statistics counters clear when read. */	lp->stats.rx_errors++;	lp->stats.tx_errors++;}static void hp100_clear_stats(struct hp100_private *lp, int ioaddr){	unsigned long flags;#ifdef HP100_DEBUG_B	hp100_outw(0x4217, TRACE);	printk("hp100: %s: clear_stats\n", dev->name);#endif	spin_lock_irqsave(&lp->lock, flags);	hp100_page(MAC_CTRL);	/* get all statistics bytes */	hp100_inw(DROPPED);	hp100_inb(CRC);	hp100_inb(ABORT);	hp100_page(PERFORMANCE);	spin_unlock_irqrestore(&lp->lock, flags);}/* *  multicast setup *//* *  Set or clear the multicast filter for this adapter. */static void hp100_set_multicast_list(struct net_device *dev){	unsigned long flags;	int ioaddr = dev->base_addr;	struct hp100_private *lp = (struct hp100_private *) dev->priv;#ifdef HP100_DEBUG_B	hp100_outw(0x4218, TRACE);	printk("hp100: %s: set_mc_list\n", dev->name);#endif	spin_lock_irqsave(&lp->lock, flags);	hp100_ints_off();	hp100_page(MAC_CTRL);	hp100_andb(~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1);	/* stop rx/tx */	if (dev->flags & IFF_PROMISC) {		lp->mac2_mode = HP100_MAC2MODE6;	/* promiscuous mode = get all good */		lp->mac1_mode = HP100_MAC1MODE6;	/* packets on the net */		memset(&lp->hash_bytes, 0xff, 8);	} else if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) {		lp->mac2_mode = HP100_MAC2MODE5;	/* multicast mode = get packets for */		lp->mac1_mode = HP100_MAC1MODE5;	/* me, broadcasts and all multicasts */#ifdef HP100_MULTICAST_FILTER	/* doesn't work!!! */		if (dev->flags & IFF_ALLMULTI) {			/* set hash filter to receive all multicast packets */			memset(&lp->hash_bytes, 0xff, 8);		} else {			int i, j, idx;			u_char *addrs;			struct dev_mc_list *dmi;			memset(&lp->hash_bytes, 0x00, 8);#ifdef HP100_DEBUG			printk("hp100: %s: computing hash filter - mc_count = %i\n", dev->name, dev->mc_count);#endif			for (i = 0, dmi = dev->mc_list; i < dev->mc_count; i++, dmi = dmi->next) {				addrs = dmi->dmi_addr;				if ((*addrs & 0x01) == 0x01) {	/* multicast address? */#ifdef HP100_DEBUG					printk("hp100: %s: multicast = %02x:%02x:%02x:%02x:%02x:%02x, ",						     dev->name, addrs[0], addrs[1], addr

⌨️ 快捷键说明

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