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

📄 bcm570x.c

📁 U-boot源码 ARM7启动代码
💻 C
📖 第 1 页 / 共 3 页
字号:
void eth_isr (void){	LM_UINT32 oldtag, newtag;	int i;	pUmDevice->interrupt = 1;	if (pDevice->UseTaggedStatus) {		if ((pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED) ||		    pUmDevice->adapter_just_inited) {			MB_REG_WR (pDevice, Mailbox.Interrupt[0].Low, 1);			oldtag = pDevice->pStatusBlkVirt->StatusTag;			for (i = 0;; i++) {				pDevice->pStatusBlkVirt->Status &=				    ~STATUS_BLOCK_UPDATED;				LM_ServiceInterrupts (pDevice);				newtag = pDevice->pStatusBlkVirt->StatusTag;				if ((newtag == oldtag) || (i > 50)) {					MB_REG_WR (pDevice,						   Mailbox.Interrupt[0].Low,						   newtag << 24);					if (pDevice->UndiFix) {						REG_WR (pDevice, Grc.LocalCtrl,							pDevice->							GrcLocalCtrl | 0x2);					}					break;				}				oldtag = newtag;			}		}	} else {		while (pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED) {			unsigned int dummy;			pDevice->pMemView->Mailbox.Interrupt[0].Low = 1;			pDevice->pStatusBlkVirt->Status &=			    ~STATUS_BLOCK_UPDATED;			LM_ServiceInterrupts (pDevice);			pDevice->pMemView->Mailbox.Interrupt[0].Low = 0;			dummy = pDevice->pMemView->Mailbox.Interrupt[0].Low;		}	}	/* Allocate new RX buffers */	if (QQ_GetEntryCnt (&pUmDevice->rx_out_of_buf_q.Container)) {		bcm570xReplenishRxBuffers (pUmDevice);	}	/* Queue packets */	if (QQ_GetEntryCnt (&pDevice->RxPacketFreeQ.Container)) {		LM_QueueRxPackets (pDevice);	}	if (pUmDevice->tx_queued) {		pUmDevice->tx_queued = 0;	}	if (pUmDevice->tx_full) {		if (pDevice->LinkStatus != LM_STATUS_LINK_DOWN) {			printf			    ("NOTICE: tx was previously blocked, restarting MUX\n");			pUmDevice->tx_full = 0;		}	}	pUmDevice->interrupt = 0;}int eth_send (volatile void *packet, int length){	int status = 0;#if ET_DEBUG	unsigned char *ptr = (unsigned char *)packet;#endif	PLM_PACKET pPacket;	PUM_PACKET pUmPacket;	/* Link down, return */	while (pDevice->LinkStatus == LM_STATUS_LINK_DOWN) {#if 0		printf ("eth%d: link down - check cable or link partner.\n",			pUmDevice->index);#endif		eth_isr ();		/* Wait to see link for one-half a second before sending ... */		udelay (1500000);	}	/* Clear sent flag */	pUmDevice->tx_pkt = 0;	/* Previously blocked */	if (pUmDevice->tx_full) {		printf ("eth%d: tx blocked.\n", pUmDevice->index);		return 0;	}	pPacket = (PLM_PACKET)	    QQ_PopHead (&pDevice->TxPacketFreeQ.Container);	if (pPacket == 0) {		pUmDevice->tx_full = 1;		printf ("bcm570xEndSend: TX full!\n");		return 0;	}	if (pDevice->SendBdLeft.counter == 0) {		pUmDevice->tx_full = 1;		printf ("bcm570xEndSend: no more TX descriptors!\n");		QQ_PushHead (&pDevice->TxPacketFreeQ.Container, pPacket);		return 0;	}	if (length <= 0) {		printf ("eth: bad packet size: %d\n", length);		goto out;	}	/* Get packet buffers and fragment list */	pUmPacket = (PUM_PACKET) pPacket;	/* Single DMA Descriptor transmit.	 * Fragments may be provided, but one DMA descriptor max is	 * used to send the packet.	 */	if (MM_CoalesceTxBuffer (pDevice, pPacket) != LM_STATUS_SUCCESS) {		if (pUmPacket->skbuff == NULL) {			/* Packet was discarded */			printf ("TX: failed (1)\n");			status = 1;		} else {			printf ("TX: failed (2)\n");			status = 2;		}		QQ_PushHead (&pDevice->TxPacketFreeQ.Container, pPacket);		return status;	}	/* Copy packet to DMA buffer */	memset (pUmPacket->skbuff, 0x0, MAX_PACKET_SIZE);	memcpy ((void *)pUmPacket->skbuff, (void *)packet, length);	pPacket->PacketSize = length;	pPacket->Flags |= SND_BD_FLAG_END | SND_BD_FLAG_COAL_NOW;	pPacket->u.Tx.FragCount = 1;	/* We've already provided a frame ready for transmission */	pPacket->Flags &= ~SND_BD_FLAG_TCP_UDP_CKSUM;	if (LM_SendPacket (pDevice, pPacket) == LM_STATUS_FAILURE) {		/*		 *  A lower level send failure will push the packet descriptor back		 *  in the free queue, so just deal with the VxWorks clusters.		 */		if (pUmPacket->skbuff == NULL) {			printf ("TX failed (1)!\n");			/* Packet was discarded */			status = 3;		} else {			/* A resource problem ... */			printf ("TX failed (2)!\n");			status = 4;		}		if (QQ_GetEntryCnt (&pDevice->TxPacketFreeQ.Container) == 0) {			printf ("TX: emptyQ!\n");			pUmDevice->tx_full = 1;		}	}	while (pUmDevice->tx_pkt == 0) {		/* Service TX */		eth_isr ();	}#if ET_DEBUG	printf ("eth_send: 0x%x, %d bytes\n"		"[%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x] ...\n",		(int)pPacket, length,		ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5],		ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12],		ptr[13], ptr[14], ptr[15]);#endif	pUmDevice->tx_pkt = 0;	QQ_PushHead (&pDevice->TxPacketFreeQ.Container, pPacket);	/* Done with send */      out:	return status;}/* Ethernet receive */int eth_rx (void){	PLM_PACKET pPacket = NULL;	PUM_PACKET pUmPacket = NULL;	void *skb;	int size = 0;	while (TRUE) {	      bcm570x_service_isr:		/* Pull down packet if it is there */		eth_isr ();		/* Indicate RX packets called */		if (pUmDevice->rx_pkt) {			/* printf("eth_rx: got a packet...\n"); */			pUmDevice->rx_pkt = 0;		} else {			/* printf("eth_rx: waiting for packet...\n"); */			goto bcm570x_service_isr;		}		pPacket = (PLM_PACKET)		    QQ_PopHead (&pDevice->RxPacketReceivedQ.Container);		if (pPacket == 0) {			printf ("eth_rx: empty packet!\n");			goto bcm570x_service_isr;		}		pUmPacket = (PUM_PACKET) pPacket;#if ET_DEBUG		printf ("eth_rx: packet @0x%x\n", (int)pPacket);#endif		/* If the packet generated an error, reuse buffer */		if ((pPacket->PacketStatus != LM_STATUS_SUCCESS) ||		    ((size = pPacket->PacketSize) > pDevice->RxMtu)) {			/* reuse skb */			QQ_PushTail (&pDevice->RxPacketFreeQ.Container,				     pPacket);			printf ("eth_rx: error in packet dma!\n");			goto bcm570x_service_isr;		}		/* Set size and address */		skb = pUmPacket->skbuff;		size = pPacket->PacketSize;		/* Pass the packet up to the protocol		 * layers.		 */		NetReceive (skb, size);		/* Free packet buffer */		bcm570xPktFree (pUmDevice->index, skb);		pUmPacket->skbuff = NULL;		/* Reuse SKB */		QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);		return 0;	/* Got a packet, bail ... */	}	return size;}/* Shut down device */void eth_halt (void){	int i;	if (initialized)		if (pDevice && pUmDevice && pUmDevice->opened) {			printf ("\neth%d:%s,", pUmDevice->index,				pUmDevice->name);			printf ("HALT,");			/* stop device */			LM_Halt (pDevice);			printf ("POWER DOWN,");			LM_SetPowerState (pDevice, LM_POWER_STATE_D3);			/* Free the memory allocated by the device in tigon3 */			for (i = 0; i < pUmDevice->mem_list_num; i++) {				if (pUmDevice->mem_list[i]) {					/* sanity check */					if (pUmDevice->dma_list[i]) {	/* cache-safe memory */						free (pUmDevice->mem_list[i]);					} else {						free (pUmDevice->mem_list[i]);	/* normal memory   */					}				}			}			pUmDevice->opened = 0;			free (pDevice);			pDevice = NULL;			pUmDevice = NULL;			initialized = 0;			printf ("done - offline.\n");		}}/* * * Middle Module: Interface between the HW driver (tigon3 modules) and * the native (SENS) driver.  These routines implement the system * interface for tigon3 on VxWorks. *//* Middle module dependency - size of a packet descriptor */int MM_Packet_Desc_Size = sizeof (UM_PACKET);LM_STATUSMM_ReadConfig32 (PLM_DEVICE_BLOCK pDevice,		 LM_UINT32 Offset, LM_UINT32 * pValue32){	UM_DEVICE_BLOCK *pUmDevice;	pUmDevice = (UM_DEVICE_BLOCK *) pDevice;	pci_read_config_dword (pUmDevice->pdev, Offset, (u32 *) pValue32);	return LM_STATUS_SUCCESS;}LM_STATUSMM_WriteConfig32 (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, LM_UINT32 Value32){	UM_DEVICE_BLOCK *pUmDevice;	pUmDevice = (UM_DEVICE_BLOCK *) pDevice;	pci_write_config_dword (pUmDevice->pdev, Offset, Value32);	return LM_STATUS_SUCCESS;}LM_STATUSMM_ReadConfig16 (PLM_DEVICE_BLOCK pDevice,		 LM_UINT32 Offset, LM_UINT16 * pValue16){	UM_DEVICE_BLOCK *pUmDevice;	pUmDevice = (UM_DEVICE_BLOCK *) pDevice;	pci_read_config_word (pUmDevice->pdev, Offset, (u16 *) pValue16);	return LM_STATUS_SUCCESS;}LM_STATUSMM_WriteConfig16 (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, LM_UINT16 Value16){	UM_DEVICE_BLOCK *pUmDevice;	pUmDevice = (UM_DEVICE_BLOCK *) pDevice;	pci_write_config_word (pUmDevice->pdev, Offset, Value16);	return LM_STATUS_SUCCESS;}LM_STATUSMM_AllocateSharedMemory (PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,			 PLM_VOID * pMemoryBlockVirt,			 PLM_PHYSICAL_ADDRESS pMemoryBlockPhy, LM_BOOL Cached){	PLM_VOID pvirt;	PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;	dma_addr_t mapping;	pvirt = malloc (BlockSize);	mapping = (dma_addr_t) (pvirt);	if (!pvirt)		return LM_STATUS_FAILURE;	pUmDevice->mem_list[pUmDevice->mem_list_num] = pvirt;	pUmDevice->dma_list[pUmDevice->mem_list_num] = mapping;	pUmDevice->mem_size_list[pUmDevice->mem_list_num++] = BlockSize;	memset (pvirt, 0, BlockSize);	*pMemoryBlockVirt = (PLM_VOID) pvirt;	MM_SetAddr (pMemoryBlockPhy, (dma_addr_t) mapping);	return LM_STATUS_SUCCESS;}LM_STATUSMM_AllocateMemory (PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,		   PLM_VOID * pMemoryBlockVirt){	PLM_VOID pvirt;	PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;	pvirt = malloc (BlockSize);	if (!pvirt)		return LM_STATUS_FAILURE;	pUmDevice->mem_list[pUmDevice->mem_list_num] = pvirt;	pUmDevice->dma_list[pUmDevice->mem_list_num] = 0;	pUmDevice->mem_size_list[pUmDevice->mem_list_num++] = BlockSize;	memset (pvirt, 0, BlockSize);	*pMemoryBlockVirt = pvirt;	return LM_STATUS_SUCCESS;}LM_STATUS MM_MapMemBase (PLM_DEVICE_BLOCK pDevice){	printf ("BCM570x PCI Memory base address @0x%x\n",		(unsigned int)pDevice->pMappedMemBase);	return LM_STATUS_SUCCESS;}LM_STATUS MM_InitializeUmPackets (PLM_DEVICE_BLOCK pDevice){	int i;	void *skb;	PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;	PUM_PACKET pUmPacket = NULL;	PLM_PACKET pPacket = NULL;	for (i = 0; i < pDevice->RxPacketDescCnt; i++) {		pPacket = QQ_PopHead (&pDevice->RxPacketFreeQ.Container);		pUmPacket = (PUM_PACKET) pPacket;		if (pPacket == 0) {			printf ("MM_InitializeUmPackets: Bad RxPacketFreeQ\n");		}		skb = bcm570xPktAlloc (pUmDevice->index,				       pPacket->u.Rx.RxBufferSize + 2);		if (skb == 0) {			pUmPacket->skbuff = 0;			QQ_PushTail (&pUmDevice->rx_out_of_buf_q.Container,				     pPacket);			printf ("MM_InitializeUmPackets: out of buffer.\n");			continue;		}		pUmPacket->skbuff = skb;		QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);	}	pUmDevice->rx_low_buf_thresh = pDevice->RxPacketDescCnt / 8;	return LM_STATUS_SUCCESS;}LM_STATUS MM_GetConfig (PLM_DEVICE_BLOCK pDevice){	PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;	int index = pDevice->index;	if (auto_speed[index] == 0)		pDevice->DisableAutoNeg = TRUE;	else		pDevice->DisableAutoNeg = FALSE;	if (line_speed[index] == 0) {		pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_AUTO;		pDevice->DisableAutoNeg = FALSE;	} else {		if (line_speed[index] == 1000) {			if (pDevice->EnableTbi) {				pDevice->RequestedMediaType =				    LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS_FULL_DUPLEX;			} else if (full_duplex[index]) {				pDevice->RequestedMediaType =				    LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS_FULL_DUPLEX;			} else {				pDevice->RequestedMediaType =				    LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS;			}			if (!pDevice->EnableTbi)				pDevice->DisableAutoNeg = FALSE;		} else if (line_speed[index] == 100) {			if (full_duplex[index]) {				pDevice->RequestedMediaType =				    LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS_FULL_DUPLEX;			} else {				pDevice->RequestedMediaType =				    LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS;			}		} else if (line_speed[index] == 10) {			if (full_duplex[index]) {				pDevice->RequestedMediaType =				    LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS_FULL_DUPLEX;			} else {				pDevice->RequestedMediaType =				    LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS;			}		} else {			pDevice->RequestedMediaType =			    LM_REQUESTED_MEDIA_TYPE_AUTO;			pDevice->DisableAutoNeg = FALSE;		}	}	pDevice->FlowControlCap = 0;	if (rx_flow_control[index] != 0) {		pDevice->FlowControlCap |= LM_FLOW_CONTROL_RECEIVE_PAUSE;	}	if (tx_flow_control[index] != 0) {		pDevice->FlowControlCap |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;	}	if ((auto_flow_control[index] != 0) &&	    (pDevice->DisableAutoNeg == FALSE)) {		pDevice->FlowControlCap |= LM_FLOW_CONTROL_AUTO_PAUSE;		if ((tx_flow_control[index] == 0) &&		    (rx_flow_control[index] == 0)) {			pDevice->FlowControlCap |=			    LM_FLOW_CONTROL_TRANSMIT_PAUSE |			    LM_FLOW_CONTROL_RECEIVE_PAUSE;		}	}	/* Default MTU for now */	pUmDevice->mtu = 1500;#if T3_JUMBO_RCV_RCB_ENTRY_COUNT	if (pUmDevice->mtu > 1500) {		pDevice->RxMtu = pUmDevice->mtu;		pDevice->RxJumboDescCnt = DEFAULT_JUMBO_RCV_DESC_COUNT;	} else {		pDevice->RxJumboDescCnt = 0;	}	pDevice->RxJumboDescCnt = rx_jumbo_desc_cnt[index];#else	pDevice->RxMtu = pUmDevice->mtu;#endif	if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {		pDevice->UseTaggedStatus = TRUE;		pUmDevice->timer_interval = CFG_HZ;	} else {		pUmDevice->timer_interval = CFG_HZ / 50;	}	pDevice->TxPacketDescCnt = tx_pkt_desc_cnt[index];	pDevice->RxStdDescCnt = rx_std_desc_cnt[index];	/* Note:  adaptive coalescence really isn't adaptive in this driver */	pUmDevice->rx_adaptive_coalesce = rx_adaptive_coalesce[index];	if (!pUmDevice->rx_adaptive_coalesce) {		pDevice->RxCoalescingTicks = rx_coalesce_ticks[index];		if (pDevice->RxCoalescingTicks > MAX_RX_COALESCING_TICKS)			pDevice->RxCoalescingTicks = MAX_RX_COALESCING_TICKS;		pUmDevice->rx_curr_coalesce_ticks = pDevice->RxCoalescingTicks;		pDevice->RxMaxCoalescedFrames = rx_max_coalesce_frames[index];		if (pDevice->RxMaxCoalescedFrames > MAX_RX_MAX_COALESCED_FRAMES)			pDevice->RxMaxCoalescedFrames =			    MAX_RX_MAX_COALESCED_FRAMES;

⌨️ 快捷键说明

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