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

📄 pmcmspeth.c

📁 175dswitch的驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	int i;	printk("print_eth(%08x)\n", (unsigned int) add);	for (i = 0; i < 6; i++)		printk(" %2.2X", (unsigned char) add[i + 6]);	printk(" =>");	for (i = 0; i < 6; i++)		printk(" %2.2X", (unsigned char) add[i]);	printk(" : %2.2X%2.2X\n", (unsigned char) add[12],	       (unsigned char) add[13]);}/* Used mainly for debugging unusual conditions signalled by a  * fatal error interrupt (eg, IntBLEx). This function stops the transmit * and receive in an attempt to capture the true state of the queues * at the time of the interrupt. */#undef MSPETH_DUMP_QUEUES#define MSPETH_DUMP_QUEUES #ifdef MSPETH_DUMP_QUEUES/* Catalog the received buffers numbers */static int rx_bdnums[2][RX_BUF_NUM << 2];static int rx_bdnums_ind[2] = {0, 0};static inline void catalog_rx_bdnum(int hwnum, int bdnum){	rx_bdnums_ind[hwnum] = (rx_bdnums_ind[hwnum] + 1) & ((RX_BUF_NUM<<2)-1);	rx_bdnums[hwnum][rx_bdnums_ind[hwnum]] = bdnum;}static void mspeth_dump_queues(struct net_device *dev){	struct mspeth_local *lp = (struct mspeth_local *) dev->priv;	struct mspeth_regs *tr = (struct mspeth_regs *) dev->base_addr;	int unit = lp->unit;	int i;	/* Halt Xmit and Recv to preserve the state of queues */	/* write_mspreg (MAC_HaltReq, &tr->MAC_Ctl); */	write_mspreg(read_mspreg(&tr->Rx_Ctl) & ~Rx_RxEn, &tr->Rx_Ctl);	write_mspreg(read_mspreg(&tr->Tx_Ctl) & ~Tx_En, &tr->Tx_Ctl);	/* Print receive queue */	printk("Receive Queue\n");	printk("=============\n\n");	printk("rxfd_base = 0x%08x\n", (unsigned long) lp->rxfd_base);	printk("rxfd_curr = 0x%08x\n", (unsigned long) lp->rxfd_curr);	for (i = 0; i < RX_BUF_NUM; i++) {		printk("%d:", i);		dump_qdesc((struct Q_Desc *) &lp->rxfd_base[i]);	}	/* Print transmit queue */	printk("\nTransmit Queue\n");	printk("==============\n");	printk("txfd_base = 0x%08x\n", (unsigned long) lp->txfd_base);	printk("tx_head = %d, tx_tail = %d\n", lp->tx_head, lp->tx_tail);	for (i = 0; i < TX_BUF_NUM; i++) {		printk("%d:", i);		dump_qdesc((struct Q_Desc *) &lp->txfd_base[i]);	}	/* Print the free buffer list */	printk("\nFree Buffer List\n");	printk("================\n");	printk("blfd_ptr = 0x%08x\n", (unsigned long) lp->blfd_ptr);	dump_blist(lp->blfd_ptr);	/* Finally print the bdnum history and current index as a reference */	printk("\nbdnum history\n");	printk("=============\n");	for (i = 0; i < RX_BUF_NUM; i++) {		printk("\t%d\t%d\t%d\t%d\n", 			rx_bdnums[unit][4*i], rx_bdnums[unit][4*i+1],			rx_bdnums[unit][4*i+2], rx_bdnums[unit][4*i+3]);	}	printk("Current bdnum index: %d\n", rx_bdnums_ind[unit]);	/* Re-enable Xmit/Recv */	write_mspreg(read_mspreg(&tr->Rx_Ctl) | Rx_RxEn, &tr->Rx_Ctl);	write_mspreg(read_mspreg(&tr->Tx_Ctl) | Tx_En, &tr->Tx_Ctl);}static void mspeth_dump_stats(struct net_device *dev){	struct mspeth_local *lp = (struct mspeth_local *) dev->priv;	printk("Interface stats:\n");	printk("\ttx_ints: %d\n", lp->lstats.tx_ints);	printk("\trx_ints: %d\n", lp->lstats.rx_ints);	printk("\ttx_full: %d\n", lp->lstats.tx_full);	printk("\tfd_exha: %d\n", lp->lstats.fd_exha);}#else#define mspeth_dump_stats(a) do {} while (0)#define mspeth_dump_queues(a) do {} while (0)#define catalog_rx_bdnum(a,b) do {} while (0)#endif				/* MSPETH_DUMP_QUEUES *///sxj add testvoidwan_pro_tasklet (unsigned long data){    struct net_device *dev,*first;	    struct sdata *vp = (struct sdata *) data;    int i=0;	    read_lock(&dev_base_lock);	    while(1)    {			if(vp->nFlag[nrCur]==1)	{/*if(vp->skb[nrCur]->len==1518){	vp->skb[nrCur]->len-=4;//	for(i=0;i<vp->skb[nrCur]->len;i++)//		printk("%02x " ,vp->skb[nrCur]->data[i]);//	printk("\n");}*/    		for(dev=dev_base;dev!=NULL;dev=dev->next)    		{			if(vp->flag[nrCur]==0)			{						if(strcmp(dev->name,"eth1")==0)				{					first=dev;					break;				}			}			if(vp->flag[nrCur]==1)			{				if(strcmp(dev->name,"eth0")==0)				{					first=dev;					break;				}			}   		}		   		if(first!=NULL)   		{			vp->skb[nrCur]->dev=first;//printk("send packet is %d\n",vp->skb[nrCur]->len);			first->hard_start_xmit(vp->skb[nrCur],first);   		}   		else			dev_kfree_skb(vp->skb[nrCur]);		vp->nFlag[nrCur]=0;		nrCur++;		if(nrCur>=64)			nrCur=0;	}		else		break;   }		    }/*###############################################################################                                                                            ## Actual functions used in the driver are defined here.  They should         ##   all start with mspeth                                                    ##                                                                            ###############################################################################*//************************************************************************** * Check for an mspeth ethernet device and return 0 if there is one.  Also * a good time to fill out some of the device fields and do some preliminary * initialization.  The mspeth resources are statically allocated. */int __init mspeth_probe(struct net_device *dev){	int unit, hwunit;	int i, irqval;	u8 macaddr[20];	struct mspeth_local *lp;	struct mspeth_regs *tr;	//sxj add	unsigned int sxj=0;	//sxj add end	/* determine what interface we think we are */	if (sscanf(dev->name, "eth%d", &unit) != 1)		return -ENODEV;	/* scan the hardware list and associate a logical unit with a hardware unit	 * it's important to keep these two straight.  hwunit is used for accessing	 * the prom and all hardware.  unit is used when parsing the commandline and	 * any other uses that might refer to *all* eth devices (not just mspeth devices)	 * in the system	 */	for (i = 0, hwunit = 0; hwunit < MSPETH_MAX_UNITS; hwunit++) {		if (identify_enet(hwunit) != FEATURE_NOEXIST) {			if (i++ == unit)				break;		}	}	/* hughesan 7/22/2005 - I should add some testing code to make sure that we don't	 * attempt to find/initialize the same device twice	 */	if (unit < 0 || hwunit >= MSPETH_MAX_UNITS)		return -ENODEV;	mspeth_debug = MSPETH_DEBUG;#ifdef CONFIG_PMC_STEIN	/* make sure that macB is in reset and that we don't identify it */	if (hwunit == 1) {		*(volatile unsigned int *) RST_SET_REG = STEIN_MAC1_RST;		return -ENODEV;	}#endif	/* Retrieve the mac address from the PROM */	if (get_ethernet_addr(macname[hwunit], macaddr)) {		printk(KERN_INFO " No Mac addr specified for eth%d %s\n",		       unit, macname[hwunit]);		return -ENODEV;	}	if (macaddr[0] & 0x01) {		printk(KERN_INFO		       "Bad Multicast Mac addr specified for eth%d "		       "%s %02x:%02x:%02x:%02x:%02x:%02x\n", unit,		       macname[hwunit], macaddr[0], macaddr[1], macaddr[2],		       macaddr[3], macaddr[4], macaddr[5]);		return -ENODEV;	}	/*	 * The ethernet MACS have fixed interrupts and address spaces. Allocate	 * the interrupt vector now and reserve the address space. There is no	 * point in waiting since no other device can use the resources, and this	 * marks the irq as busy. Jumpered interrupts are typically not reported	 * by the boards. MAC 0 is fixed at IRQ 10, MAC 1 is fixed IRQ11 etc	 */	/* base address for register accesses */	dev->base_addr = MacBases[hwunit];	if (check_mem_region(dev->base_addr, MSPEthExtent))		return -ENODEV;	if (!request_mem_region(dev->base_addr, MSPEthExtent, cardname)) {		printk(KERN_WARNING		       "%s: unable to get memory/io address region %lx\n",		       dev->name, dev->base_addr);		return -ENODEV;	}	/* IRQ reservation */	dev->irq = MacIRQs[hwunit];	irqval = request_irq(dev->irq, &mspeth_interrupt,			     SA_SAMPLE_RANDOM, cardname, dev);	if (irqval) {		printk(KERN_WARNING		       "%s: unable to get IRQ %d (irqval=%d).\n",		       dev->name, dev->irq, irqval);		return -ENODEV;	}	/* MAC address */	dev->addr_len = ETH_ALEN;	for (i = 0; i < dev->addr_len; i++)		dev->dev_addr[i] = macaddr[i];	/* perform the "once only* tasks like creating the proc entry and probing the phys */	if (root_mspeth_dev == NULL) {		proc_net_create("pmcmspeth", 0, mspeth_proc_info);		mspeth_phyprobe();	}	/* do the default ethernet setup and then customize */	ether_setup(dev);	/* Create & initialize the local device structure */	if (dev->priv == NULL) {		dev->priv =		    kmalloc(sizeof(struct mspeth_local), GFP_KERNEL);		if (dev->priv == NULL)			return -ENODEV;	}	lp = (struct mspeth_local *) dev->priv;	tr = (struct mspeth_regs *) dev->base_addr;	/* zero out the local structure and start initializing */	memset(lp, 0, sizeof(struct mspeth_local));	lp->next_module = root_mspeth_dev;	root_mspeth_dev = dev;	/* set the logical and hardware units */	lp->unit = unit;	lp->hwunit = hwunit;	/* parse the environment and command line */	mspeth_init_cmdline(dev);	mspeth_init_phyaddr(dev);	/* determine speed and duplex settings */	if (lp->option & MSP_OPT_10M) {		lp->speed = 10;	} else {		lp->speed = 100;	}	if (lp->option & MSP_OPT_FDUP) {		lp->fullduplex = true;	} else {		lp->fullduplex = false;	}	/* configure the BRCTL RII registers if we're an RMII device */	if (identify_enet(hwunit) == ENET_RMII) {		u32 brctl = read_mspreg(&tr->BCTRL_Reg) & ~RMII_Reset;		if (identify_enetTxD(hwunit) == ENETTXD_RISING)			brctl |= RMII_ClkRising;		if (identify_enetTxD(hwunit) == ENETTXD_FALLING)			brctl &= ~RMII_ClkRising;		if (lp->speed == 10)			brctl |= RMII_10MBIT;		else			brctl &= ~RMII_10MBIT;		write_mspreg(brctl, &tr->BCTRL_Reg);	}	/* set the various call back functions */	dev->open = mspeth_open;	dev->stop = mspeth_close;	dev->tx_timeout = mspeth_tx_timeout;	dev->watchdog_timeo = TX_TIMEOUT * HZ;	dev->hard_start_xmit = mspeth_send_packet;	dev->get_stats = mspeth_get_stats;	dev->set_multicast_list = mspeth_set_multicast_list;	dev->do_ioctl = mspeth_do_ioctl;	/* set some device structure parameters */	dev->tx_queue_len = TX_BUF_NUM;	/* allocate and initialize the tasklets */	tasklet_init(&lp->rx_tasklet, mspeth_rx, (u32) dev);	tasklet_init(&lp->tx_tasklet, mspeth_txdone, (u32) dev);	/* hammtrev, 2005/12/08:	 * Adding a new BH handler to reset the device in response to BLEx.	 */	tasklet_init(&lp->hard_restart_tasklet, mspeth_hard_restart_bh, (u32) dev);	/* debugging output */#ifndef MODULE	{		static u8 printed_version;		if (!printed_version++) {			printk(KERN_INFO "%s: %s, %s\n", drv_file,			       drv_version, drv_reldate);			printk(KERN_INFO			       "%s: PMC-Sierra, www.pmc-sierra.com\n",			       drv_file);		}	}#endif				/* !MODULE */	/* debugging output */	printk(KERN_INFO	       "MSPETH (probe) %s: found at address %lx, irq %d\n",	       dev->name, dev->base_addr, dev->irq);		printk(KERN_INFO		       "MSPETH (probe) %s: assigned MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",		       dev->name, macaddr[0], macaddr[1], macaddr[2],		       macaddr[3], macaddr[4], macaddr[5]);	if (mspeth_debug > 1) {		printk(KERN_INFO		       "MSPETH (probe) %s: associated with hardware unit %d, %s\n",		       dev->name, hwunit, macname[hwunit]);		printk(KERN_INFO		       "MSPETH (probe) %s: assigned MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",		       dev->name, macaddr[0], macaddr[1], macaddr[2],		       macaddr[3], macaddr[4], macaddr[5]);		printk(KERN_INFO		       "MSPETH (probe) %s: phytype %c, phyclk %c, phyindex %d\n",		       dev->name, identify_enet(hwunit),		       identify_enetTxD(hwunit), lp->phyindex);	}	//sxj add 	sxj = read_mspphyreg(21, 22);	sxj|=0x0001;	write_mspphyreg(sxj, 21, 22);	sxj = read_mspphyreg(21, 22);	//add test port 0 is bridge	for(sxj=0;sxj<4;sxj++)	{		nFlag[sxj+1]=0;		tempdata[sxj]=0;	}	//sxj use test/*	nFlag[2]=1;	nFlag[4]=1;*/	nrCur=0;	nwCur=0;	    	tasklet_init(&wan_tasklet, wan_pro_tasklet, (unsigned long)&data) ;	//sxj add end	return 0;}/************************************************************************** * Scan the environment and fill the phyaddresses */static void __init mspeth_init_phyaddr(struct net_device *dev){	struct mspeth_local *lp = (struct mspeth_local *) dev->priv;	int hwindex;	int phyindex;	int phyaddr;	char *phystr;	char name[80];	/* default phy index */	lp->phyindex = 0;	/* new style enviroment scan to determine the phy addresses */	sprintf(name, "phyaddr%d", lp->hwunit);	phystr = prom_getenv(name);	if (mspeth_debug > 0) {		printk(			 "MSPETH (init_phyaddr) %s: hwunit = %d, phystr prom = \"%s\"\n",		     	dev->name, lp->hwunit, phystr);	}	if (phystr != NULL &&	    sscanf(phystr, "%d:%d", &hwindex, &phyaddr) == 2 &&	    hwindex < MSPETH_MAX_UNITS &&	    (phyaddr < MD_MAX_PHY || phyaddr == MD_DYNAMIC_PHY)) {		/* look through the phylist and find a phy that matches the PROM settings */		for (phyindex = 0; phyindex < MSPETH_MAX_UNITS; phyindex++) {			if (phy_ctrl[phyindex].hwindex == hwindex			    && phy_ctrl[phyindex].phyaddr == phyaddr) {				if (phy_ctrl[phyindex].assigned) {					printk(KERN_WARNING "MSPETH (init_phyaddr) %s: PROM phyaddress is already in use!\                                        phystr prom = \"%s\"\n", dev->name,					       phystr);				} else {					lp->phyindex = phyindex;					phy_ctrl[phyindex].assigned = true;				}

⌨️ 快捷键说明

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