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

📄 rrunner.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	struct rr_regs *regs;	rrpriv = (struct rr_private *)dev->priv;	regs = rrpriv->regs;#if 0	regs->HostCtrl |= (HALT_NIC | RR_CLEAR_INT);#endif	if (request_irq(dev->irq, rr_interrupt, SA_SHIRQ, rrpriv->name, dev))	{		printk(KERN_WARNING "%s: Requested IRQ %d is busy\n",		       dev->name, dev->irq);		return -EAGAIN;	}	rrpriv->rx_ctrl = kmalloc(256*sizeof(struct ring_ctrl),				  GFP_KERNEL | GFP_DMA);	rrpriv->info = kmalloc(sizeof(struct rr_info), GFP_KERNEL | GFP_DMA);	rr_init1(dev);	dev->tbusy = 0;#if 0	dev->interrupt = 0;#endif	dev->start = 1;	MOD_INC_USE_COUNT;	return 0;}static void rr_dump(struct device *dev){	struct rr_private *rrpriv;	struct rr_regs *regs;	u32 index, cons;	short i;	int len;	rrpriv = (struct rr_private *)dev->priv;	regs = rrpriv->regs;	printk("%s: dumping NIC TX rings\n", dev->name);	printk("RxPrd %08x, TxPrd %02x, EvtPrd %08x, TxPi %02x, TxCtrlPi %02x\n",	       regs->RxPrd, regs->TxPrd, regs->EvtPrd, regs->TxPi,	       rrpriv->info->tx_ctrl.pi);	printk("Error code 0x%x\n", regs->Fail1);	index = (((regs->EvtPrd >> 8) & 0xff ) - 1) % EVT_RING_ENTRIES;	cons = rrpriv->dirty_tx;	printk("TX ring index %i, TX consumer %i\n",	       index, cons);	if (rrpriv->tx_skbuff[index]){		len = min(0x80, rrpriv->tx_skbuff[index]->len);		printk("skbuff for index %i is valid - dumping data (0x%x bytes - DMA len 0x%x)\n", index, len, rrpriv->tx_ring[index].size);		for (i = 0; i < len; i++){			if (!(i & 7))				printk("\n");			printk("%02x ", (unsigned char) rrpriv->tx_skbuff[index]->data[i]);		}		printk("\n");	}	if (rrpriv->tx_skbuff[cons]){		len = min(0x80, rrpriv->tx_skbuff[cons]->len);		printk("skbuff for cons %i is valid - dumping data (0x%x bytes - skbuff len 0x%x)\n", cons, len, rrpriv->tx_skbuff[cons]->len);		printk("mode 0x%x, size 0x%x,\n phys %08x (virt %08x), skbuff-addr %08x, truesize 0x%x\n",		       rrpriv->tx_ring[cons].mode,		       rrpriv->tx_ring[cons].size,		       rrpriv->tx_ring[cons].addr,		       (unsigned int)bus_to_virt(rrpriv->tx_ring[cons].addr),		       (unsigned int)rrpriv->tx_skbuff[cons]->data,		       (unsigned int)rrpriv->tx_skbuff[cons]->truesize);		for (i = 0; i < len; i++){			if (!(i & 7))				printk("\n");			printk("%02x ", (unsigned char)rrpriv->tx_ring[cons].size);		}		printk("\n");	}	printk("dumping TX ring info:\n");	for (i = 0; i < TX_RING_ENTRIES; i++)		printk("mode 0x%x, size 0x%x, phys-addr %08x\n",		       rrpriv->tx_ring[i].mode,		       rrpriv->tx_ring[i].size,		       rrpriv->tx_ring[i].addr);}static int rr_close(struct device *dev){	struct rr_private *rrpriv;	struct rr_regs *regs;	u32 tmp;	short i;	dev->start = 0;	set_bit(0, (void*)&dev->tbusy);	rrpriv = (struct rr_private *)dev->priv;	regs = rrpriv->regs;	/*	 * Lock to make sure we are not cleaning up while another CPU	 * handling interrupts.	 */	spin_lock(&rrpriv->lock);	tmp = regs->HostCtrl;	if (tmp & NIC_HALTED){		printk("%s: NIC already halted\n", dev->name);		rr_dump(dev);	}else		tmp |= HALT_NIC;	regs->HostCtrl = tmp;	rrpriv->fw_running = 0;	regs->TxPi = 0;	regs->IpRxPi = 0;	regs->EvtCon = 0;	regs->EvtPrd = 0;	for (i = 0; i < CMD_RING_ENTRIES; i++)		regs->CmdRing[i] = 0;	rrpriv->info->tx_ctrl.entries = 0;	rrpriv->info->cmd_ctrl.pi = 0;	rrpriv->info->evt_ctrl.pi = 0;	rrpriv->rx_ctrl[4].entries = 0;	for (i = 0; i < TX_RING_ENTRIES; i++) {		if (rrpriv->tx_skbuff[i]) {			rrpriv->tx_ring[i].size = 0;			rrpriv->tx_ring[i].addr = 0;			dev_kfree_skb(rrpriv->tx_skbuff[i]);		}	}	for (i = 0; i < RX_RING_ENTRIES; i++) {		if (rrpriv->rx_skbuff[i]) {			rrpriv->rx_ring[i].size = 0;			rrpriv->rx_ring[i].addr = 0;			dev_kfree_skb(rrpriv->rx_skbuff[i]);		}	}	kfree(rrpriv->rx_ctrl);	kfree(rrpriv->info);	free_irq(dev->irq, dev);	spin_unlock(&rrpriv->lock);	MOD_DEC_USE_COUNT;	return 0;}static int rr_start_xmit(struct sk_buff *skb, struct device *dev){	struct rr_private *rrpriv = (struct rr_private *)dev->priv;	struct rr_regs *regs = rrpriv->regs;	struct ring_ctrl *txctrl;	unsigned long flags;	u32 index, len = skb->len;	u32 *ifield;	struct sk_buff *new_skb;	/*	 * We probably need to deal with tbusy here to prevent overruns.	 */	if (skb_headroom(skb) < 8){		printk("incoming skb too small - reallocating\n");		if (!(new_skb = dev_alloc_skb(len + 8))) {			dev_kfree_skb(skb);			dev->tbusy = 0;			return -EBUSY;		}		skb_reserve(new_skb, 8);		skb_put(new_skb, len);		memcpy(new_skb->data, skb->data, len);		dev_kfree_skb(skb);		skb = new_skb;	}	ifield = (u32 *)skb_push(skb, 8);	ifield[0] = 0;	ifield[1] = skb->private.ifield;	/*	 * We don't need the lock before we are actually going to start	 * fiddling with the control blocks.	 */	spin_lock_irqsave(&rrpriv->lock, flags);	txctrl = &rrpriv->info->tx_ctrl;	index = txctrl->pi;	rrpriv->tx_skbuff[index] = skb;	rrpriv->tx_ring[index].addr = virt_to_bus(skb->data);	rrpriv->tx_ring[index].size = len + 8; /* include IFIELD */	rrpriv->tx_ring[index].mode = PACKET_START | PACKET_END;	txctrl->pi = (index + 1) % TX_RING_ENTRIES;	regs->TxPi = txctrl->pi;	if (txctrl->pi == rrpriv->dirty_tx){		rrpriv->tx_full = 1;		set_bit(0, (void*)&dev->tbusy);	}	spin_unlock_irqrestore(&rrpriv->lock, flags);	dev->trans_start = jiffies;	return 0;}static struct net_device_stats *rr_get_stats(struct device *dev){	struct rr_private *rrpriv;	rrpriv = (struct rr_private *)dev->priv;	return(&rrpriv->stats);}/* * Read the firmware out of the EEPROM and put it into the SRAM * (or from user space - later) * * This operation requires the NIC to be halted and is performed with * interrupts disabled and with the spinlock hold. */static int rr_load_firmware(struct device *dev){	struct rr_private *rrpriv;	struct rr_regs *regs;	int i, j;	u32 localctrl, eptr, sptr, segptr, len, tmp;	u32 p2len, p2size, nr_seg, revision, io, sram_size;	struct eeprom *hw = NULL;	rrpriv = (struct rr_private *)dev->priv;	regs = rrpriv->regs;	if (dev->flags & IFF_UP)		return -EBUSY;	if (!(regs->HostCtrl & NIC_HALTED)){		printk("%s: Trying to load firmware to a running NIC.\n", 		       dev->name);		return -EBUSY;	}	localctrl = regs->LocalCtrl;	regs->LocalCtrl = 0;	regs->EvtPrd = 0;	regs->RxPrd = 0;	regs->TxPrd = 0;	/*	 * First wipe the entire SRAM, otherwise we might run into all	 * kinds of trouble ... sigh, this took almost all afternoon	 * to track down ;-(	 */	io = regs->ExtIo;	regs->ExtIo = 0;	sram_size = read_eeprom_word(rrpriv, (void *)8);	for (i = 200; i < sram_size / 4; i++){		regs->WinBase = i * 4;		regs->WinData = 0;	}	regs->ExtIo = io;	eptr = read_eeprom_word(rrpriv, &hw->rncd_info.AddrRunCodeSegs);	eptr = ((eptr & 0x1fffff) >> 3);	p2len = read_eeprom_word(rrpriv, (void *)(0x83*4));	p2len = (p2len << 2);	p2size = read_eeprom_word(rrpriv, (void *)(0x84*4));	p2size = ((p2size & 0x1fffff) >> 3);	if ((eptr < p2size) || (eptr > (p2size + p2len))){		printk("%s: eptr is invalid\n", dev->name);		goto out;	}	revision = read_eeprom_word(rrpriv, &hw->manf.HeaderFmt);	if (revision != 1){		printk("%s: invalid firmware format (%i)\n",		       dev->name, revision);		goto out;	}	nr_seg = read_eeprom_word(rrpriv, (void *)eptr);	eptr +=4;#if (DEBUG > 1)	printk("%s: nr_seg %i\n", dev->name, nr_seg);#endif	for (i = 0; i < nr_seg; i++){		sptr = read_eeprom_word(rrpriv, (void *)eptr);		eptr += 4;		len = read_eeprom_word(rrpriv, (void *)eptr);		eptr += 4;		segptr = read_eeprom_word(rrpriv, (void *)eptr);		segptr = ((segptr & 0x1fffff) >> 3);		eptr += 4;#if (DEBUG > 1)		printk("%s: segment %i, sram address %06x, length %04x, segptr %06x\n",		       dev->name, i, sptr, len, segptr);#endif		for (j = 0; j < len; j++){			tmp = read_eeprom_word(rrpriv, (void *)segptr);			regs->WinBase = sptr;			regs->WinData = tmp;			segptr += 4;			sptr += 4;		}	}out:	regs->LocalCtrl = localctrl;	return 0;}static int rr_ioctl(struct device *dev, struct ifreq *rq, int cmd){	struct rr_private *rrpriv;	unsigned char *image, *oldimage;	unsigned int i;	int error = -EOPNOTSUPP;	rrpriv = (struct rr_private *)dev->priv;	spin_lock(&rrpriv->lock);	switch(cmd){	case SIOCRRGFW:		if (!suser()){			error = -EPERM;			goto out;		}		if (rrpriv->fw_running){			printk("%s: Firmware already running\n", dev->name);			error = -EPERM;			goto out;		}		image = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL);		if (!image){			printk(KERN_ERR "%s: Unable to allocate memory "			       "for EEPROM image\n", dev->name);			error = -ENOMEM;			goto out;		}		i = read_eeprom(rrpriv, 0, image, EEPROM_BYTES);		if (i != EEPROM_BYTES){			kfree(image);			printk(KERN_ERR "%s: Error reading EEPROM\n",			       dev->name);			error = -EFAULT;			goto out;		}		error = copy_to_user(rq->ifr_data, image, EEPROM_BYTES);		if (error)			error = -EFAULT;		kfree(image);		break;	case SIOCRRPFW:		if (!suser()){			error = -EPERM;			goto out;		}		if (rrpriv->fw_running){			printk("%s: Firmware already running\n", dev->name);			error = -EPERM;			goto out;		}		image = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL);		if (!image){			printk(KERN_ERR "%s: Unable to allocate memory "			       "for EEPROM image\n", dev->name);			error = -ENOMEM;			goto out;		}		oldimage = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL);		if (!image){			printk(KERN_ERR "%s: Unable to allocate memory "			       "for old EEPROM image\n", dev->name);			error = -ENOMEM;			goto out;		}		error = copy_from_user(image, rq->ifr_data, EEPROM_BYTES);		if (error)			error = -EFAULT;		printk("%s: Updating EEPROM firmware\n", dev->name);		error = write_eeprom(rrpriv, 0, image, EEPROM_BYTES);		if (error)			printk(KERN_ERR "%s: Error writing EEPROM\n",			       dev->name);		i = read_eeprom(rrpriv, 0, oldimage, EEPROM_BYTES);		if (i != EEPROM_BYTES)			printk(KERN_ERR "%s: Error reading back EEPROM "			       "image\n", dev->name);		error = memcmp(image, oldimage, EEPROM_BYTES);		if (error){			printk(KERN_ERR "%s: Error verifying EEPROM image\n",			       dev->name);			error = -EFAULT;		}		kfree(image);		kfree(oldimage);		break;	case SIOCRRID:		error = put_user(0x52523032, (int *)(&rq->ifr_data[0]));		if (error)			error = -EFAULT;		break;	default:	} out:	spin_unlock(&rrpriv->lock);	return error;}/* * Local variables: * compile-command: "gcc -D__SMP__ -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -pipe -fomit-frame-pointer -fno-strength-reduce -m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2 -DCPU=686 -c rrunner.c" * End: */

⌨️ 快捷键说明

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