📄 bcm570x.c
字号:
/* * 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 (CONFIG_COMMANDS & CFG_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. */voidbcm570xPktFree(int u, void *p){ free(p);}intbcm570xReplenishRxBuffers(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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -