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

📄 spider_net.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 * * spider_net_handle_error_irq treats or ignores all error conditions * found when an interrupt is presented */static voidspider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg){	u32 error_reg1, error_reg2;	u32 i;	int show_error = 1;	error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS);	error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS);	error_reg1 &= SPIDER_NET_INT1_MASK_VALUE;	error_reg2 &= SPIDER_NET_INT2_MASK_VALUE;	/* check GHIINT0STS ************************************/	if (status_reg)		for (i = 0; i < 32; i++)			if (status_reg & (1<<i))				switch (i)	{	/* let error_reg1 and error_reg2 evaluation decide, what to do	case SPIDER_NET_PHYINT:	case SPIDER_NET_GMAC2INT:	case SPIDER_NET_GMAC1INT:	case SPIDER_NET_GFIFOINT:	case SPIDER_NET_DMACINT:	case SPIDER_NET_GSYSINT:		break; */	case SPIDER_NET_GIPSINT:		show_error = 0;		break;	case SPIDER_NET_GPWOPCMPINT:		/* PHY write operation completed */		show_error = 0;		break;	case SPIDER_NET_GPROPCMPINT:		/* PHY read operation completed */		/* we don't use semaphores, as we poll for the completion		 * of the read operation in spider_net_read_phy. Should take		 * about 50 us */		show_error = 0;		break;	case SPIDER_NET_GPWFFINT:		/* PHY command queue full */		if (netif_msg_intr(card))			dev_err(&card->netdev->dev, "PHY write queue full\n");		show_error = 0;		break;	/* case SPIDER_NET_GRMDADRINT: not used. print a message */	/* case SPIDER_NET_GRMARPINT: not used. print a message */	/* case SPIDER_NET_GRMMPINT: not used. print a message */	case SPIDER_NET_GDTDEN0INT:		/* someone has set TX_DMA_EN to 0 */		show_error = 0;		break;	case SPIDER_NET_GDDDEN0INT: /* fallthrough */	case SPIDER_NET_GDCDEN0INT: /* fallthrough */	case SPIDER_NET_GDBDEN0INT: /* fallthrough */	case SPIDER_NET_GDADEN0INT:		/* someone has set RX_DMA_EN to 0 */		show_error = 0;		break;	/* RX interrupts */	case SPIDER_NET_GDDFDCINT:	case SPIDER_NET_GDCFDCINT:	case SPIDER_NET_GDBFDCINT:	case SPIDER_NET_GDAFDCINT:	/* case SPIDER_NET_GDNMINT: not used. print a message */	/* case SPIDER_NET_GCNMINT: not used. print a message */	/* case SPIDER_NET_GBNMINT: not used. print a message */	/* case SPIDER_NET_GANMINT: not used. print a message */	/* case SPIDER_NET_GRFNMINT: not used. print a message */		show_error = 0;		break;	/* TX interrupts */	case SPIDER_NET_GDTFDCINT:		show_error = 0;		break;	case SPIDER_NET_GTTEDINT:		show_error = 0;		break;	case SPIDER_NET_GDTDCEINT:		/* chain end. If a descriptor should be sent, kick off		 * tx dma		if (card->tx_chain.tail != card->tx_chain.head)			spider_net_kick_tx_dma(card);		*/		show_error = 0;		break;	/* case SPIDER_NET_G1TMCNTINT: not used. print a message */	/* case SPIDER_NET_GFREECNTINT: not used. print a message */	}	/* check GHIINT1STS ************************************/	if (error_reg1)		for (i = 0; i < 32; i++)			if (error_reg1 & (1<<i))				switch (i)	{	case SPIDER_NET_GTMFLLINT:		/* TX RAM full may happen on a usual case.		 * Logging is not needed. */		show_error = 0;		break;	case SPIDER_NET_GRFDFLLINT: /* fallthrough */	case SPIDER_NET_GRFCFLLINT: /* fallthrough */	case SPIDER_NET_GRFBFLLINT: /* fallthrough */	case SPIDER_NET_GRFAFLLINT: /* fallthrough */	case SPIDER_NET_GRMFLLINT:		/* Could happen when rx chain is full */		if (card->ignore_rx_ramfull == 0) {			card->ignore_rx_ramfull = 1;			spider_net_resync_head_ptr(card);			spider_net_refill_rx_chain(card);			spider_net_enable_rxdmac(card);			card->num_rx_ints ++;			netif_rx_schedule(card->netdev,					  &card->napi);		}		show_error = 0;		break;	/* case SPIDER_NET_GTMSHTINT: problem, print a message */	case SPIDER_NET_GDTINVDINT:		/* allrighty. tx from previous descr ok */		show_error = 0;		break;	/* chain end */	case SPIDER_NET_GDDDCEINT: /* fallthrough */	case SPIDER_NET_GDCDCEINT: /* fallthrough */	case SPIDER_NET_GDBDCEINT: /* fallthrough */	case SPIDER_NET_GDADCEINT:		spider_net_resync_head_ptr(card);		spider_net_refill_rx_chain(card);		spider_net_enable_rxdmac(card);		card->num_rx_ints ++;		netif_rx_schedule(card->netdev,				  &card->napi);		show_error = 0;		break;	/* invalid descriptor */	case SPIDER_NET_GDDINVDINT: /* fallthrough */	case SPIDER_NET_GDCINVDINT: /* fallthrough */	case SPIDER_NET_GDBINVDINT: /* fallthrough */	case SPIDER_NET_GDAINVDINT:		/* Could happen when rx chain is full */		spider_net_resync_head_ptr(card);		spider_net_refill_rx_chain(card);		spider_net_enable_rxdmac(card);		card->num_rx_ints ++;		netif_rx_schedule(card->netdev,				  &card->napi);		show_error = 0;		break;	/* case SPIDER_NET_GDTRSERINT: problem, print a message */	/* case SPIDER_NET_GDDRSERINT: problem, print a message */	/* case SPIDER_NET_GDCRSERINT: problem, print a message */	/* case SPIDER_NET_GDBRSERINT: problem, print a message */	/* case SPIDER_NET_GDARSERINT: problem, print a message */	/* case SPIDER_NET_GDSERINT: problem, print a message */	/* case SPIDER_NET_GDTPTERINT: problem, print a message */	/* case SPIDER_NET_GDDPTERINT: problem, print a message */	/* case SPIDER_NET_GDCPTERINT: problem, print a message */	/* case SPIDER_NET_GDBPTERINT: problem, print a message */	/* case SPIDER_NET_GDAPTERINT: problem, print a message */	default:		show_error = 1;		break;	}	/* check GHIINT2STS ************************************/	if (error_reg2)		for (i = 0; i < 32; i++)			if (error_reg2 & (1<<i))				switch (i)	{	/* there is nothing we can (want  to) do at this time. Log a	 * message, we can switch on and off the specific values later on	case SPIDER_NET_GPROPERINT:	case SPIDER_NET_GMCTCRSNGINT:	case SPIDER_NET_GMCTLCOLINT:	case SPIDER_NET_GMCTTMOTINT:	case SPIDER_NET_GMCRCAERINT:	case SPIDER_NET_GMCRCALERINT:	case SPIDER_NET_GMCRALNERINT:	case SPIDER_NET_GMCROVRINT:	case SPIDER_NET_GMCRRNTINT:	case SPIDER_NET_GMCRRXERINT:	case SPIDER_NET_GTITCSERINT:	case SPIDER_NET_GTIFMTERINT:	case SPIDER_NET_GTIPKTRVKINT:	case SPIDER_NET_GTISPINGINT:	case SPIDER_NET_GTISADNGINT:	case SPIDER_NET_GTISPDNGINT:	case SPIDER_NET_GRIFMTERINT:	case SPIDER_NET_GRIPKTRVKINT:	case SPIDER_NET_GRISPINGINT:	case SPIDER_NET_GRISADNGINT:	case SPIDER_NET_GRISPDNGINT:		break;	*/		default:			break;	}	if ((show_error) && (netif_msg_intr(card)) && net_ratelimit())		dev_err(&card->netdev->dev, "Error interrupt, GHIINT0STS = 0x%08x, "		       "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n",		       status_reg, error_reg1, error_reg2);	/* clear interrupt sources */	spider_net_write_reg(card, SPIDER_NET_GHIINT1STS, error_reg1);	spider_net_write_reg(card, SPIDER_NET_GHIINT2STS, error_reg2);}/** * spider_net_interrupt - interrupt handler for spider_net * @irq: interrupt number * @ptr: pointer to net_device * @regs: PU registers * * returns IRQ_HANDLED, if interrupt was for driver, or IRQ_NONE, if no * interrupt found raised by card. * * This is the interrupt handler, that turns off * interrupts for this device and makes the stack poll the driver */static irqreturn_tspider_net_interrupt(int irq, void *ptr){	struct net_device *netdev = ptr;	struct spider_net_card *card = netdev_priv(netdev);	u32 status_reg;	status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS);	status_reg &= SPIDER_NET_INT0_MASK_VALUE;	if (!status_reg)		return IRQ_NONE;	if (status_reg & SPIDER_NET_RXINT ) {		spider_net_rx_irq_off(card);		netif_rx_schedule(netdev, &card->napi);		card->num_rx_ints ++;	}	if (status_reg & SPIDER_NET_TXINT)		netif_rx_schedule(netdev, &card->napi);	if (status_reg & SPIDER_NET_LINKINT)		spider_net_link_reset(netdev);	if (status_reg & SPIDER_NET_ERRINT )		spider_net_handle_error_irq(card, status_reg);	/* clear interrupt sources */	spider_net_write_reg(card, SPIDER_NET_GHIINT0STS, status_reg);	return IRQ_HANDLED;}#ifdef CONFIG_NET_POLL_CONTROLLER/** * spider_net_poll_controller - artificial interrupt for netconsole etc. * @netdev: interface device structure * * see Documentation/networking/netconsole.txt */static voidspider_net_poll_controller(struct net_device *netdev){	disable_irq(netdev->irq);	spider_net_interrupt(netdev->irq, netdev);	enable_irq(netdev->irq);}#endif /* CONFIG_NET_POLL_CONTROLLER *//** * spider_net_enable_interrupts - enable interrupts * @card: card structure * * spider_net_enable_interrupt enables several interrupts */static void spider_net_enable_interrupts(struct spider_net_card *card){	spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK,			     SPIDER_NET_INT0_MASK_VALUE);	spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK,			     SPIDER_NET_INT1_MASK_VALUE);	spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK,			     SPIDER_NET_INT2_MASK_VALUE);}/** * spider_net_disable_interrupts - disable interrupts * @card: card structure * * spider_net_disable_interrupts disables all the interrupts */static void spider_net_disable_interrupts(struct spider_net_card *card){	spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);	spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);	spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);	spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);}/** * spider_net_init_card - initializes the card * @card: card structure * * spider_net_init_card initializes the card so that other registers can * be used */static voidspider_net_init_card(struct spider_net_card *card){	spider_net_write_reg(card, SPIDER_NET_CKRCTRL,			     SPIDER_NET_CKRCTRL_STOP_VALUE);	spider_net_write_reg(card, SPIDER_NET_CKRCTRL,			     SPIDER_NET_CKRCTRL_RUN_VALUE);	/* trigger ETOMOD signal */	spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,		spider_net_read_reg(card, SPIDER_NET_GMACOPEMD) | 0x4);	spider_net_disable_interrupts(card);}/** * spider_net_enable_card - enables the card by setting all kinds of regs * @card: card structure * * spider_net_enable_card sets a lot of SMMIO registers to enable the device */static voidspider_net_enable_card(struct spider_net_card *card){	int i;	/* the following array consists of (register),(value) pairs	 * that are set in this function. A register of 0 ends the list */	u32 regs[][2] = {		{ SPIDER_NET_GRESUMINTNUM, 0 },		{ SPIDER_NET_GREINTNUM, 0 },		/* set interrupt frame number registers */		/* clear the single DMA engine registers first */		{ SPIDER_NET_GFAFRMNUM, SPIDER_NET_GFXFRAMES_VALUE },		{ SPIDER_NET_GFBFRMNUM, SPIDER_NET_GFXFRAMES_VALUE },		{ SPIDER_NET_GFCFRMNUM, SPIDER_NET_GFXFRAMES_VALUE },		{ SPIDER_NET_GFDFRMNUM, SPIDER_NET_GFXFRAMES_VALUE },		/* then set, what we really need */		{ SPIDER_NET_GFFRMNUM, SPIDER_NET_FRAMENUM_VALUE },		/* timer counter registers and stuff */		{ SPIDER_NET_GFREECNNUM, 0 },		{ SPIDER_NET_GONETIMENUM, 0 },		{ SPIDER_NET_GTOUTFRMNUM, 0 },		/* RX mode setting */		{ SPIDER_NET_GRXMDSET, SPIDER_NET_RXMODE_VALUE },		/* TX mode setting */		{ SPIDER_NET_GTXMDSET, SPIDER_NET_TXMODE_VALUE },		/* IPSEC mode setting */		{ SPIDER_NET_GIPSECINIT, SPIDER_NET_IPSECINIT_VALUE },		{ SPIDER_NET_GFTRESTRT, SPIDER_NET_RESTART_VALUE },		{ SPIDER_NET_GMRWOLCTRL, 0 },		{ SPIDER_NET_GTESTMD, 0x10000000 },		{ SPIDER_NET_GTTQMSK, 0x00400040 },		{ SPIDER_NET_GMACINTEN, 0 },		/* flow control stuff */		{ SPIDER_NET_GMACAPAUSE, SPIDER_NET_MACAPAUSE_VALUE },		{ SPIDER_NET_GMACTXPAUSE, SPIDER_NET_TXPAUSE_VALUE },		{ SPIDER_NET_GMACBSTLMT, SPIDER_NET_BURSTLMT_VALUE },		{ 0, 0}	};	i = 0;	while (regs[i][0]) {		spider_net_write_reg(card, regs[i][0], regs[i][1]);		i++;	}	/* clear unicast filter table entries 1 to 14 */	for (i = 1; i <= 14; i++) {		spider_net_write_reg(card,				     SPIDER_NET_GMRUAFILnR + i * 8,				     0x00080000);		spider_net_write_reg(card,				     SPIDER_NET_GMRUAFILnR + i * 8 + 4,				     0x00000000);	}	spider_net_write_reg(card, SPIDER_NET_GMRUA0FIL15R, 0x08080000);	spider_net_write_reg(card, SPIDER_NET_ECMODE, SPIDER_NET_ECMODE_VALUE);	/* set chain tail adress for RX chains and	 * enable DMA */	spider_net_enable_rxchtails(card);	spider_net_enable_rxdmac(card);	spider_net_write_reg(card, SPIDER_NET_GRXDMAEN, SPIDER_NET_WOL_VALUE);	spider_net_write_reg(card, SPIDER_NET_GMACLENLMT,			     SPIDER_NET_LENLMT_VALUE);	spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,			     SPIDER_NET_OPMODE_VALUE);	spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,			     SPIDER_NET_GDTBSTA);}/** * spider_net_download_firmware - loads firmware into the adapter * @card: card structure * @firmware_ptr: pointer to firmware data * * spider_net_download_firmware loads the firmware data into the * adapter. It assumes the length etc. to be allright. */static intspider_net_download_firmware(struct spider_net_card *card,			     const void *firmware_ptr){	int sequencer, i;	const u32 *fw_ptr = firmware_ptr;	/* stop sequencers */	spider_net_write_reg(card, SPIDER_NET_GSINIT,			     SPIDER_NET_STOP_SEQ_VALUE);	for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS;	     sequencer++) {		spider_net_write_reg(card,				     SPIDER_NET_GSnPRGADR + sequencer * 8, 0);		for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) {			spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT +					     sequencer * 8, *fw_ptr);			fw_ptr++;		}	}	if (spider_net_read_reg(card, SPIDER_NET_GSINIT))		return -EIO;	spider_net_write_reg(card, SPIDER_NET_GSINIT,			     SPIDER_NET_RUN_SEQ_VALUE);

⌨️ 快捷键说明

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