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

📄 bcm570x.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 4 页
字号:
	    pDevice->NoTxPseudoHdrChksum = TRUE;	}    }    /* Set Device PCI Memory base address */    pDevice->pMappedMemBase = (PLM_UINT8) ioBase;    /* Pull down adapter info */    if ((rv = LM_GetAdapterInfo(pDevice)) != LM_STATUS_SUCCESS) {	printf("bcm570xEnd: LM_GetAdapterInfo failed: rv=%d!\n", rv );	return -2;    }    /* Lock not needed */    pUmDevice->do_global_lock = 0;    if (T3_ASIC_REV(pUmDevice->lm_dev.ChipRevId) == T3_ASIC_REV_5700) {	/* The 5700 chip works best without interleaved register */	/* accesses on certain machines. */	pUmDevice->do_global_lock = 1;    }    /* Setup timer delays */    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;    }    /* Grab name .... */    pUmDevice->name =	(char*)malloc(strlen(board_info[bcm570xDevices[i].board_id].name)+1);    strcpy(pUmDevice->name,board_info[bcm570xDevices[i].board_id].name);    memcpy(pDevice->NodeAddress, bis->bi_enetaddr, 6);    LM_SetMacAddress(pDevice, bis->bi_enetaddr);    /* Init queues  .. */    QQ_InitQueue(&pUmDevice->rx_out_of_buf_q.Container,		 MAX_RX_PACKET_DESC_COUNT);    pUmDevice->rx_last_cnt = pUmDevice->tx_last_cnt = 0;    /* delay for 4 seconds */    pUmDevice->delayed_link_ind =	(4 * CFG_HZ) / pUmDevice->timer_interval;    pUmDevice->adaptive_expiry =	CFG_HZ / pUmDevice->timer_interval;    /* Sometimes we get spurious ints. after reset when link is down. */    /* This field tells the isr to service the int. even if there is */    /* no status block update. */    pUmDevice->adapter_just_inited =	(3 * CFG_HZ) / pUmDevice->timer_interval;    /* Initialize 570x */    if (LM_InitializeAdapter(pDevice) != LM_STATUS_SUCCESS) {	printf("ERROR: Adapter initialization failed.\n");	return ERROR;    }    /* Enable chip ISR */    LM_EnableInterrupt(pDevice);    /* Clear MC table */    LM_MulticastClear(pDevice);    /* Enable Multicast */    LM_SetReceiveMask(pDevice,		      pDevice->ReceiveMask | LM_ACCEPT_ALL_MULTICAST);    pUmDevice->opened = 1;    pUmDevice->tx_full = 0;    pUmDevice->tx_pkt = 0;    pUmDevice->rx_pkt = 0;    printf("eth%d: %s @0x%lx,",	   pDevice->index, pUmDevice->name, (unsigned long)ioBase);    printf(	"node addr ");    for (i = 0; i < 6; i++) {	printf("%2.2x", pDevice->NodeAddress[i]);    }    printf("\n");    printf("eth%d: ", pDevice->index);    printf("%s with ",	   chip_rev[bcm570xDevices[i].board_id].name);    if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5400_PHY_ID)	printf("Broadcom BCM5400 Copper ");    else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)	printf("Broadcom BCM5401 Copper ");    else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5411_PHY_ID)	printf("Broadcom BCM5411 Copper ");    else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5701_PHY_ID)	printf("Broadcom BCM5701 Integrated Copper ");    else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5703_PHY_ID)	printf("Broadcom BCM5703 Integrated Copper ");    else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM8002_PHY_ID)	printf("Broadcom BCM8002 SerDes ");    else if (pDevice->EnableTbi)	printf("Agilent HDMP-1636 SerDes ");    else	printf("Unknown ");    printf("transceiver found\n");    printf("eth%d: %s, MTU: %d,",	   pDevice->index, pDevice->BusSpeedStr, 1500);    if ((pDevice->ChipRevId != T3_CHIP_ID_5700_B0) &&	rx_checksum[i])	printf("Rx Checksum ON\n");    else	printf("Rx Checksum OFF\n");    initialized++;    return 0;}/* Ethernet Interrupt service routine */voideth_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;}inteth_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 */inteth_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 */voideth_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);

⌨️ 快捷键说明

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