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

📄 bcm570x.c

📁 U-boot源码 ARM7启动代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Broadcom BCM570x Ethernet Driver for U-Boot. * Support 5701, 5702, 5703, and 5704. Single instance driver. * Copyright (C) 2002 James F. Dougherty (jfd@broadcom.com) */#include <common.h>#if defined(CONFIG_CMD_NET) \	&& (!defined(CONFIG_NET_MULTI)) && defined(CONFIG_BCM570x)#ifdef CONFIG_BMW#include <mpc824x.h>#endif#include <net.h>#include "bcm570x_mm.h"#include "bcm570x_autoneg.h"#include <pci.h>#include <malloc.h>/* * PCI Registers and definitions. */#define PCI_CMD_MASK	0xffff0000	/* mask to save status bits */#define PCI_ANY_ID (~0)/* * PCI memory base for Ethernet device as well as device Interrupt. */#define BCM570X_MBAR 	0x80100000#define BCM570X_ILINE   1#define SECOND_USEC	1000000#define MAX_PACKET_SIZE 1600#define MAX_UNITS       4/* Globals to this module */int initialized = 0;unsigned int ioBase = 0;volatile PLM_DEVICE_BLOCK pDevice = NULL;	/* 570x softc */volatile PUM_DEVICE_BLOCK pUmDevice = NULL;/* Used to pass the full-duplex flag, etc. */int line_speed[MAX_UNITS] = { 0, 0, 0, 0 };static int full_duplex[MAX_UNITS] = { 1, 1, 1, 1 };static int rx_flow_control[MAX_UNITS] = { 0, 0, 0, 0 };static int tx_flow_control[MAX_UNITS] = { 0, 0, 0, 0 };static int auto_flow_control[MAX_UNITS] = { 0, 0, 0, 0 };static int tx_checksum[MAX_UNITS] = { 1, 1, 1, 1 };static int rx_checksum[MAX_UNITS] = { 1, 1, 1, 1 };static int auto_speed[MAX_UNITS] = { 1, 1, 1, 1 };#if JUMBO_FRAMES/* Jumbo MTU for interfaces. */static int mtu[MAX_UNITS] = { 0, 0, 0, 0 };#endif/* Turn on Wake-on lan for a device unit */static int enable_wol[MAX_UNITS] = { 0, 0, 0, 0 };#define TX_DESC_CNT DEFAULT_TX_PACKET_DESC_COUNTstatic unsigned int tx_pkt_desc_cnt[MAX_UNITS] =    { TX_DESC_CNT, TX_DESC_CNT, TX_DESC_CNT, TX_DESC_CNT };#define RX_DESC_CNT DEFAULT_STD_RCV_DESC_COUNTstatic unsigned int rx_std_desc_cnt[MAX_UNITS] =    { RX_DESC_CNT, RX_DESC_CNT, RX_DESC_CNT, RX_DESC_CNT };static unsigned int rx_adaptive_coalesce[MAX_UNITS] = { 1, 1, 1, 1 };#if T3_JUMBO_RCV_RCB_ENTRY_COUNT#define JBO_DESC_CNT DEFAULT_JUMBO_RCV_DESC_COUNTstatic unsigned int rx_jumbo_desc_cnt[MAX_UNITS] =    { JBO_DESC_CNT, JBO_DESC_CNT, JBO_DESC_CNT, JBO_DESC_CNT };#endif#define RX_COAL_TK DEFAULT_RX_COALESCING_TICKSstatic unsigned int rx_coalesce_ticks[MAX_UNITS] =    { RX_COAL_TK, RX_COAL_TK, RX_COAL_TK, RX_COAL_TK };#define RX_COAL_FM DEFAULT_RX_MAX_COALESCED_FRAMESstatic unsigned int rx_max_coalesce_frames[MAX_UNITS] =    { RX_COAL_FM, RX_COAL_FM, RX_COAL_FM, RX_COAL_FM };#define TX_COAL_TK DEFAULT_TX_COALESCING_TICKSstatic unsigned int tx_coalesce_ticks[MAX_UNITS] =    { TX_COAL_TK, TX_COAL_TK, TX_COAL_TK, TX_COAL_TK };#define TX_COAL_FM DEFAULT_TX_MAX_COALESCED_FRAMESstatic unsigned int tx_max_coalesce_frames[MAX_UNITS] =    { TX_COAL_FM, TX_COAL_FM, TX_COAL_FM, TX_COAL_FM };#define ST_COAL_TK DEFAULT_STATS_COALESCING_TICKSstatic unsigned int stats_coalesce_ticks[MAX_UNITS] =    { ST_COAL_TK, ST_COAL_TK, ST_COAL_TK, ST_COAL_TK };/* * Legitimate values for BCM570x device types */typedef enum {	BCM5700VIGIL = 0,	BCM5700A6,	BCM5700T6,	BCM5700A9,	BCM5700T9,	BCM5700,	BCM5701A5,	BCM5701T1,	BCM5701T8,	BCM5701A7,	BCM5701A10,	BCM5701A12,	BCM5701,	BCM5702,	BCM5703,	BCM5703A31,	TC996T,	TC996ST,	TC996SSX,	TC996SX,	TC996BT,	TC997T,	TC997SX,	TC1000T,	TC940BR01,	TC942BR01,	NC6770,	NC7760,	NC7770,	NC7780} board_t;/* Chip-Rev names for each device-type */static struct {	char *name;} chip_rev[] = {	{	"BCM5700VIGIL"}, {	"BCM5700A6"}, {	"BCM5700T6"}, {	"BCM5700A9"}, {	"BCM5700T9"}, {	"BCM5700"}, {	"BCM5701A5"}, {	"BCM5701T1"}, {	"BCM5701T8"}, {	"BCM5701A7"}, {	"BCM5701A10"}, {	"BCM5701A12"}, {	"BCM5701"}, {	"BCM5702"}, {	"BCM5703"}, {	"BCM5703A31"}, {	"TC996T"}, {	"TC996ST"}, {	"TC996SSX"}, {	"TC996SX"}, {	"TC996BT"}, {	"TC997T"}, {	"TC997SX"}, {	"TC1000T"}, {	"TC940BR01"}, {	"TC942BR01"}, {	"NC6770"}, {	"NC7760"}, {	"NC7770"}, {	"NC7780"}, {	0}};/* indexed by board_t, above */static struct {	char *name;} board_info[] = {	{	"Broadcom Vigil B5700 1000Base-T"}, {	"Broadcom BCM5700 1000Base-T"}, {	"Broadcom BCM5700 1000Base-SX"}, {	"Broadcom BCM5700 1000Base-SX"}, {	"Broadcom BCM5700 1000Base-T"}, {	"Broadcom BCM5700"}, {	"Broadcom BCM5701 1000Base-T"}, {	"Broadcom BCM5701 1000Base-T"}, {	"Broadcom BCM5701 1000Base-T"}, {	"Broadcom BCM5701 1000Base-SX"}, {	"Broadcom BCM5701 1000Base-T"}, {	"Broadcom BCM5701 1000Base-T"}, {	"Broadcom BCM5701"}, {	"Broadcom BCM5702 1000Base-T"}, {	"Broadcom BCM5703 1000Base-T"}, {	"Broadcom BCM5703 1000Base-SX"}, {	"3Com 3C996 10/100/1000 Server NIC"}, {	"3Com 3C996 10/100/1000 Server NIC"}, {	"3Com 3C996 Gigabit Fiber-SX Server NIC"}, {	"3Com 3C996 Gigabit Fiber-SX Server NIC"}, {	"3Com 3C996B Gigabit Server NIC"}, {	"3Com 3C997 Gigabit Server NIC"}, {	"3Com 3C997 Gigabit Fiber-SX Server NIC"}, {	"3Com 3C1000 Gigabit NIC"}, {	"3Com 3C940 Gigabit LOM (21X21)"}, {	"3Com 3C942 Gigabit LOM (31X31)"}, {	"Compaq NC6770 Gigabit Server Adapter"}, {	"Compaq NC7760 Gigabit Server Adapter"}, {	"Compaq NC7770 Gigabit Server Adapter"}, {	"Compaq NC7780 Gigabit Server Adapter"}, {0},};/* PCI Devices which use the 570x chipset */struct pci_device_table {	unsigned short vendor_id, device_id;	/* Vendor/DeviceID */	unsigned short subvendor, subdevice;	/* Subsystem ID's or PCI_ANY_ID */	unsigned int class, class_mask;	/* (class,subclass,prog-if) triplet */	unsigned long board_id;	/* Data private to the driver */	int io_size, min_latency;} bcm570xDevices[] = {	{	0x14e4, 0x1644, 0x1014, 0x0277, 0, 0, BCM5700VIGIL, 128, 32}, {	0x14e4, 0x1644, 0x14e4, 0x1644, 0, 0, BCM5700A6, 128, 32}, {	0x14e4, 0x1644, 0x14e4, 0x2, 0, 0, BCM5700T6, 128, 32}, {	0x14e4, 0x1644, 0x14e4, 0x3, 0, 0, BCM5700A9, 128, 32}, {	0x14e4, 0x1644, 0x14e4, 0x4, 0, 0, BCM5700T9, 128, 32}, {	0x14e4, 0x1644, 0x1028, 0xd1, 0, 0, BCM5700, 128, 32}, {	0x14e4, 0x1644, 0x1028, 0x0106, 0, 0, BCM5700, 128, 32}, {	0x14e4, 0x1644, 0x1028, 0x0109, 0, 0, BCM5700, 128, 32}, {	0x14e4, 0x1644, 0x1028, 0x010a, 0, 0, BCM5700, 128, 32}, {	0x14e4, 0x1644, 0x10b7, 0x1000, 0, 0, TC996T, 128, 32}, {	0x14e4, 0x1644, 0x10b7, 0x1001, 0, 0, TC996ST, 128, 32}, {	0x14e4, 0x1644, 0x10b7, 0x1002, 0, 0, TC996SSX, 128, 32}, {	0x14e4, 0x1644, 0x10b7, 0x1003, 0, 0, TC997T, 128, 32}, {	0x14e4, 0x1644, 0x10b7, 0x1005, 0, 0, TC997SX, 128, 32}, {	0x14e4, 0x1644, 0x10b7, 0x1008, 0, 0, TC942BR01, 128, 32}, {	0x14e4, 0x1644, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5700, 128, 32}, {	0x14e4, 0x1645, 0x14e4, 1, 0, 0, BCM5701A5, 128, 32}, {	0x14e4, 0x1645, 0x14e4, 5, 0, 0, BCM5701T1, 128, 32}, {	0x14e4, 0x1645, 0x14e4, 6, 0, 0, BCM5701T8, 128, 32}, {	0x14e4, 0x1645, 0x14e4, 7, 0, 0, BCM5701A7, 128, 32}, {	0x14e4, 0x1645, 0x14e4, 8, 0, 0, BCM5701A10, 128, 32}, {	0x14e4, 0x1645, 0x14e4, 0x8008, 0, 0, BCM5701A12, 128, 32}, {	0x14e4, 0x1645, 0x0e11, 0xc1, 0, 0, NC6770, 128, 32}, {	0x14e4, 0x1645, 0x0e11, 0x7c, 0, 0, NC7770, 128, 32}, {	0x14e4, 0x1645, 0x0e11, 0x85, 0, 0, NC7780, 128, 32}, {	0x14e4, 0x1645, 0x1028, 0x0121, 0, 0, BCM5701, 128, 32}, {	0x14e4, 0x1645, 0x10b7, 0x1004, 0, 0, TC996SX, 128, 32}, {	0x14e4, 0x1645, 0x10b7, 0x1006, 0, 0, TC996BT, 128, 32}, {	0x14e4, 0x1645, 0x10b7, 0x1007, 0, 0, TC1000T, 128, 32}, {	0x14e4, 0x1645, 0x10b7, 0x1008, 0, 0, TC940BR01, 128, 32}, {	0x14e4, 0x1645, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5701, 128, 32}, {	0x14e4, 0x1646, 0x14e4, 0x8009, 0, 0, BCM5702, 128, 32}, {	0x14e4, 0x1646, 0x0e11, 0xbb, 0, 0, NC7760, 128, 32}, {	0x14e4, 0x1646, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5702, 128, 32}, {	0x14e4, 0x16a6, 0x14e4, 0x8009, 0, 0, BCM5702, 128, 32}, {	0x14e4, 0x16a6, 0x0e11, 0xbb, 0, 0, NC7760, 128, 32}, {	0x14e4, 0x16a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5702, 128, 32}, {	0x14e4, 0x1647, 0x14e4, 0x0009, 0, 0, BCM5703, 128, 32}, {	0x14e4, 0x1647, 0x14e4, 0x000a, 0, 0, BCM5703A31, 128, 32}, {	0x14e4, 0x1647, 0x14e4, 0x000b, 0, 0, BCM5703, 128, 32}, {	0x14e4, 0x1647, 0x14e4, 0x800a, 0, 0, BCM5703, 128, 32}, {	0x14e4, 0x1647, 0x0e11, 0x9a, 0, 0, NC7770, 128, 32}, {	0x14e4, 0x1647, 0x0e11, 0x99, 0, 0, NC7780, 128, 32}, {	0x14e4, 0x1647, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5703, 128, 32}, {	0x14e4, 0x16a7, 0x14e4, 0x0009, 0, 0, BCM5703, 128, 32}, {	0x14e4, 0x16a7, 0x14e4, 0x000a, 0, 0, BCM5703A31, 128, 32}, {	0x14e4, 0x16a7, 0x14e4, 0x000b, 0, 0, BCM5703, 128, 32}, {	0x14e4, 0x16a7, 0x14e4, 0x800a, 0, 0, BCM5703, 128, 32}, {	0x14e4, 0x16a7, 0x0e11, 0x9a, 0, 0, NC7770, 128, 32}, {	0x14e4, 0x16a7, 0x0e11, 0x99, 0, 0, NC7780, 128, 32}, {	0x14e4, 0x16a7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5703, 128, 32}};#define n570xDevices   (sizeof(bcm570xDevices)/sizeof(bcm570xDevices[0]))/* * Allocate a packet buffer from the bcm570x packet pool. */void *bcm570xPktAlloc (int u, int pksize){	return malloc (pksize);}/* * Free a packet previously allocated from the bcm570x packet * buffer pool. */void bcm570xPktFree (int u, void *p){	free (p);}int bcm570xReplenishRxBuffers (PUM_DEVICE_BLOCK pUmDevice){	PLM_PACKET pPacket;	PUM_PACKET pUmPacket;	void *skb;	int queue_rx = 0;	int ret = 0;	while ((pUmPacket = (PUM_PACKET)		QQ_PopHead (&pUmDevice->rx_out_of_buf_q.Container)) != 0) {		pPacket = (PLM_PACKET) pUmPacket;		/* reuse an old skb */		if (pUmPacket->skbuff) {			QQ_PushTail (&pDevice->RxPacketFreeQ.Container,				     pPacket);			queue_rx = 1;			continue;		}		if ((skb = bcm570xPktAlloc (pUmDevice->index,					    pPacket->u.Rx.RxBufferSize + 2)) ==		    0) {			QQ_PushHead (&pUmDevice->rx_out_of_buf_q.Container,				     pPacket);			printf ("NOTICE: Out of RX memory.\n");			ret = 1;			break;		}		pUmPacket->skbuff = skb;		QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);		queue_rx = 1;	}	if (queue_rx) {		LM_QueueRxPackets (pDevice);	}	return ret;}/* * Probe, Map, and Init 570x device. */int eth_init (bd_t * bis){	int i, rv, devFound = FALSE;	pci_dev_t devbusfn;	unsigned short status;	/* Find PCI device, if it exists, configure ...  */	for (i = 0; i < n570xDevices; i++) {		devbusfn = pci_find_device (bcm570xDevices[i].vendor_id,					    bcm570xDevices[i].device_id, 0);		if (devbusfn == -1) {			continue;	/* No device of that vendor/device ID */		} else {			/* Set ILINE */			pci_write_config_byte (devbusfn,					       PCI_INTERRUPT_LINE,					       BCM570X_ILINE);			/*			 * 0x10 - 0x14 define one 64-bit MBAR.			 * 0x14 is the higher-order address bits of the BAR.			 */			pci_write_config_dword (devbusfn,						PCI_BASE_ADDRESS_1, 0);			ioBase = BCM570X_MBAR;			pci_write_config_dword (devbusfn,						PCI_BASE_ADDRESS_0, ioBase);			/*			 * Enable PCI memory, IO, and Master -- don't			 * reset any status bits in doing so.			 */			pci_read_config_word (devbusfn, PCI_COMMAND, &status);			status |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;			pci_write_config_word (devbusfn, PCI_COMMAND, status);			printf			    ("\n%s: bus %d, device %d, function %d: MBAR=0x%x\n",			     board_info[bcm570xDevices[i].board_id].name,			     PCI_BUS (devbusfn), PCI_DEV (devbusfn),			     PCI_FUNC (devbusfn), ioBase);			/* Allocate once, but always clear on init */			if (!pDevice) {				pDevice = malloc (sizeof (UM_DEVICE_BLOCK));				pUmDevice = (PUM_DEVICE_BLOCK) pDevice;				memset (pDevice, 0x0, sizeof (UM_DEVICE_BLOCK));			}			/* Configure pci dev structure */			pUmDevice->pdev = devbusfn;			pUmDevice->index = 0;			pUmDevice->tx_pkt = 0;			pUmDevice->rx_pkt = 0;			devFound = TRUE;			break;		}	}	if (!devFound) {		printf		    ("eth_init: FAILURE: no BCM570x Ethernet devices found.\n");		return -1;	}	/* Setup defaults for chip */	pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;	if (pDevice->ChipRevId == T3_CHIP_ID_5700_B0) {		pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;	} else {		if (rx_checksum[i]) {			pDevice->TaskToOffload |=			    LM_TASK_OFFLOAD_RX_TCP_CHECKSUM |			    LM_TASK_OFFLOAD_RX_UDP_CHECKSUM;		}		if (tx_checksum[i]) {			pDevice->TaskToOffload |=			    LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |			    LM_TASK_OFFLOAD_TX_UDP_CHECKSUM;			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 */

⌨️ 快捷键说明

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