📄 tigon3.c
字号:
/******************************************************************************//* *//* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom *//* Corporation. *//* All rights reserved. *//* *//* This program is free software; you can redistribute it and/or modify *//* it under the terms of the GNU General Public License as published by *//* the Free Software Foundation, located in the file LICENSE. *//* *//* History: *//******************************************************************************/#include <common.h>#include <asm/types.h>#if (CONFIG_COMMANDS & CFG_CMD_NET) && !defined(CONFIG_NET_MULTI) && \ defined(CONFIG_TIGON3)#ifdef CONFIG_BMW#include <mpc824x.h>#endif#include <malloc.h>#include <linux/byteorder/big_endian.h>#include "bcm570x_mm.h"#define EMBEDDED 1/******************************************************************************//* Local functions. *//******************************************************************************/LM_STATUS LM_Abort(PLM_DEVICE_BLOCK pDevice);LM_STATUS LM_QueueRxPackets(PLM_DEVICE_BLOCK pDevice);static LM_STATUS LM_TranslateRequestedMediaType( LM_REQUESTED_MEDIA_TYPE RequestedMediaType, PLM_MEDIA_TYPE pMediaType, PLM_LINE_SPEED pLineSpeed, PLM_DUPLEX_MODE pDuplexMode);static LM_STATUS LM_InitBcm540xPhy(PLM_DEVICE_BLOCK pDevice);__inline static LM_VOID LM_ServiceRxInterrupt(PLM_DEVICE_BLOCK pDevice);__inline static LM_VOID LM_ServiceTxInterrupt(PLM_DEVICE_BLOCK pDevice);static LM_STATUS LM_ForceAutoNegBcm540xPhy(PLM_DEVICE_BLOCK pDevice, LM_REQUESTED_MEDIA_TYPE RequestedMediaType);static LM_STATUS LM_ForceAutoNeg(PLM_DEVICE_BLOCK pDevice, LM_REQUESTED_MEDIA_TYPE RequestedMediaType);static LM_UINT32 GetPhyAdFlowCntrlSettings(PLM_DEVICE_BLOCK pDevice);STATIC LM_STATUS LM_SetFlowControl(PLM_DEVICE_BLOCK pDevice, LM_UINT32 LocalPhyAd, LM_UINT32 RemotePhyAd);#if INCLUDE_TBI_SUPPORTSTATIC LM_STATUS LM_SetupFiberPhy(PLM_DEVICE_BLOCK pDevice);STATIC LM_STATUS LM_InitBcm800xPhy(PLM_DEVICE_BLOCK pDevice);#endifSTATIC LM_STATUS LM_SetupCopperPhy(PLM_DEVICE_BLOCK pDevice);STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid(LM_UINT16 Svid, LM_UINT16 Ssid);STATIC LM_STATUS LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt, LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize);STATIC LM_STATUS LM_HaltCpu(PLM_DEVICE_BLOCK pDevice,LM_UINT32 cpu_number);STATIC LM_STATUS LM_ResetChip(PLM_DEVICE_BLOCK pDevice);STATIC LM_STATUS LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket, PT3_SND_BD pSendBd);/******************************************************************************//* External functions. *//******************************************************************************/LM_STATUS LM_LoadRlsFirmware(PLM_DEVICE_BLOCK pDevice);/******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/LM_UINT32LM_RegRdInd(PLM_DEVICE_BLOCK pDevice,LM_UINT32 Register) { LM_UINT32 Value32;#if PCIX_TARGET_WORKAROUND MM_ACQUIRE_UNDI_LOCK(pDevice);#endif MM_WriteConfig32(pDevice, T3_PCI_REG_ADDR_REG, Register); MM_ReadConfig32(pDevice, T3_PCI_REG_DATA_REG, &Value32);#if PCIX_TARGET_WORKAROUND MM_RELEASE_UNDI_LOCK(pDevice);#endif return Value32;} /* LM_RegRdInd *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/LM_VOIDLM_RegWrInd(PLM_DEVICE_BLOCK pDevice,LM_UINT32 Register,LM_UINT32 Value32) {#if PCIX_TARGET_WORKAROUND MM_ACQUIRE_UNDI_LOCK(pDevice);#endif MM_WriteConfig32(pDevice, T3_PCI_REG_ADDR_REG, Register); MM_WriteConfig32(pDevice, T3_PCI_REG_DATA_REG, Value32);#if PCIX_TARGET_WORKAROUND MM_RELEASE_UNDI_LOCK(pDevice);#endif} /* LM_RegWrInd *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/LM_UINT32LM_MemRdInd(PLM_DEVICE_BLOCK pDevice,LM_UINT32 MemAddr) { LM_UINT32 Value32; MM_ACQUIRE_UNDI_LOCK(pDevice);#ifdef BIG_ENDIAN_HOST MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr); Value32 = REG_RD(pDevice, PciCfg.MemWindowData); /* Value32 = REG_RD(pDevice,uIntMem.Mbuf[(MemAddr & 0x7fff)/4]); */#else MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr); MM_ReadConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, &Value32);#endif MM_RELEASE_UNDI_LOCK(pDevice); return Value32;} /* LM_MemRdInd *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/LM_VOIDLM_MemWrInd(PLM_DEVICE_BLOCK pDevice,LM_UINT32 MemAddr,LM_UINT32 Value32) { MM_ACQUIRE_UNDI_LOCK(pDevice);#ifdef BIG_ENDIAN_HOST REG_WR(pDevice,PciCfg.MemWindowBaseAddr,MemAddr); REG_WR(pDevice,uIntMem.Mbuf[(MemAddr & 0x7fff)/4],Value32);#else MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr); MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, Value32);#endif MM_RELEASE_UNDI_LOCK(pDevice);} /* LM_MemWrInd *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/LM_STATUSLM_QueueRxPackets(PLM_DEVICE_BLOCK pDevice) { LM_STATUS Lmstatus; PLM_PACKET pPacket; PT3_RCV_BD pRcvBd; LM_UINT32 StdBdAdded = 0;#if T3_JUMBO_RCV_RCB_ENTRY_COUNT LM_UINT32 JumboBdAdded = 0;#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */ Lmstatus = LM_STATUS_SUCCESS; pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container); while(pPacket) { switch(pPacket->u.Rx.RcvProdRing) {#if T3_JUMBO_RCV_RCB_ENTRY_COUNT case T3_JUMBO_RCV_PROD_RING: /* Jumbo Receive Ring. */ /* Initialize the buffer descriptor. */ pRcvBd = &pDevice->pRxJumboBdVirt[pDevice->RxJumboProdIdx]; pRcvBd->Flags = RCV_BD_FLAG_END | RCV_BD_FLAG_JUMBO_RING; pRcvBd->Len = (LM_UINT16) pDevice->RxJumboBufferSize; /* Initialize the receive buffer pointer */#if 0 /* Jimmy, deleted in new */ pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low; pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;#endif MM_MapRxDma(pDevice, pPacket, &pRcvBd->HostAddr); /* The opaque field may point to an offset from a fix addr. */ pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR(pPacket) - MM_UINT_PTR(pDevice->pPacketDescBase)); /* Update the producer index. */ pDevice->RxJumboProdIdx = (pDevice->RxJumboProdIdx + 1) & T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK; JumboBdAdded++; break;#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */ case T3_STD_RCV_PROD_RING: /* Standard Receive Ring. */ /* Initialize the buffer descriptor. */ pRcvBd = &pDevice->pRxStdBdVirt[pDevice->RxStdProdIdx]; pRcvBd->Flags = RCV_BD_FLAG_END; pRcvBd->Len = MAX_STD_RCV_BUFFER_SIZE; /* Initialize the receive buffer pointer */#if 0 /* Jimmy, deleted in new replaced with MM_MapRxDma */ pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low; pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;#endif MM_MapRxDma(pDevice, pPacket, &pRcvBd->HostAddr); /* The opaque field may point to an offset from a fix addr. */ pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR(pPacket) - MM_UINT_PTR(pDevice->pPacketDescBase)); /* Update the producer index. */ pDevice->RxStdProdIdx = (pDevice->RxStdProdIdx + 1) & T3_STD_RCV_RCB_ENTRY_COUNT_MASK; StdBdAdded++; break; case T3_UNKNOWN_RCV_PROD_RING: default: Lmstatus = LM_STATUS_FAILURE; break; } /* switch */ /* Bail out if there is any error. */ if(Lmstatus != LM_STATUS_SUCCESS) { break; } pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container); } /* while */ wmb(); /* Update the procedure index. */ if(StdBdAdded) { MB_REG_WR(pDevice, Mailbox.RcvStdProdIdx.Low, pDevice->RxStdProdIdx); }#if T3_JUMBO_RCV_RCB_ENTRY_COUNT if(JumboBdAdded) { MB_REG_WR(pDevice, Mailbox.RcvJumboProdIdx.Low, pDevice->RxJumboProdIdx); }#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */ return Lmstatus;} /* LM_QueueRxPackets *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/STATIC LM_VOIDLM_NvramInit( PLM_DEVICE_BLOCK pDevice){ LM_UINT32 Value32; LM_UINT32 j; /* Intialize clock period and state machine. */ Value32 = SEEPROM_ADDR_CLK_PERD(SEEPROM_CLOCK_PERIOD) | SEEPROM_ADDR_FSM_RESET; REG_WR(pDevice, Grc.EepromAddr, Value32); for(j = 0; j < 100; j++) { MM_Wait(10); } /* Serial eeprom access using the Grc.EepromAddr/EepromData registers. */ Value32 = REG_RD(pDevice, Grc.LocalCtrl); REG_WR(pDevice, Grc.LocalCtrl, Value32 | GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM); /* Set the 5701 compatibility mode if we are using EEPROM. */ if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 && T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701) { Value32 = REG_RD(pDevice, Nvram.Config1); if((Value32 & FLASH_INTERFACE_ENABLE) == 0) { /* Use the new interface to read EEPROM. */ Value32 &= ~FLASH_COMPAT_BYPASS; REG_WR(pDevice, Nvram.Config1, Value32); } }} /* LM_NvRamInit *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/STATIC LM_STATUSLM_EepromRead( PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, LM_UINT32 *pData){ LM_UINT32 Value32; LM_UINT32 Addr; LM_UINT32 Dev; LM_UINT32 j; if(Offset > SEEPROM_CHIP_SIZE) { return LM_STATUS_FAILURE; } Dev = Offset / SEEPROM_CHIP_SIZE; Addr = Offset % SEEPROM_CHIP_SIZE; Value32 = REG_RD(pDevice, Grc.EepromAddr); Value32 &= ~(SEEPROM_ADDR_ADDRESS_MASK | SEEPROM_ADDR_DEV_ID_MASK | SEEPROM_ADDR_RW_MASK); REG_WR(pDevice, Grc.EepromAddr, Value32 | SEEPROM_ADDR_DEV_ID(Dev) | SEEPROM_ADDR_ADDRESS(Addr) | SEEPROM_ADDR_START | SEEPROM_ADDR_READ); for(j = 0; j < 1000; j++) { Value32 = REG_RD(pDevice, Grc.EepromAddr); if(Value32 & SEEPROM_ADDR_COMPLETE) { break; } MM_Wait(10); } if(Value32 & SEEPROM_ADDR_COMPLETE) { Value32 = REG_RD(pDevice, Grc.EepromData); *pData = Value32; return LM_STATUS_SUCCESS; } return LM_STATUS_FAILURE;} /* LM_EepromRead *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/STATIC LM_STATUSLM_NvramRead( PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, LM_UINT32 *pData){ LM_UINT32 Value32; LM_STATUS Status; LM_UINT32 j; if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 || T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701) { Status = LM_EepromRead(pDevice, Offset, pData); } else { /* Determine if we have flash or EEPROM. */ Value32 = REG_RD(pDevice, Nvram.Config1); if(Value32 & FLASH_INTERFACE_ENABLE) { if(Value32 & FLASH_SSRAM_BUFFERRED_MODE) { Offset = ((Offset/BUFFERED_FLASH_PAGE_SIZE) << BUFFERED_FLASH_PAGE_POS) + (Offset % BUFFERED_FLASH_PAGE_SIZE); } } REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_SET1); for (j = 0; j < 1000; j++) { if (REG_RD(pDevice, Nvram.SwArb) & SW_ARB_GNT1) { break; } MM_Wait(20); } if (j == 1000) { return LM_STATUS_FAILURE; } /* Read from flash or EEPROM with the new 5703/02 interface. */ REG_WR(pDevice, Nvram.Addr, Offset & NVRAM_ADDRESS_MASK); REG_WR(pDevice, Nvram.Cmd, NVRAM_CMD_RD | NVRAM_CMD_DO_IT | NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE); /* Wait for the done bit to clear. */ for(j = 0; j < 500; j++) { MM_Wait(10); Value32 = REG_RD(pDevice, Nvram.Cmd); if(!(Value32 & NVRAM_CMD_DONE)) { break; } } /* Wait for the done bit. */ if(!(Value32 & NVRAM_CMD_DONE)) { for(j = 0; j < 500; j++) { MM_Wait(10); Value32 = REG_RD(pDevice, Nvram.Cmd); if(Value32 & NVRAM_CMD_DONE) { MM_Wait(10); *pData = REG_RD(pDevice, Nvram.ReadData); /* Change the endianess. */ *pData = ((*pData & 0xff) << 24)| ((*pData & 0xff00) << 8)| ((*pData & 0xff0000) >> 8) | ((*pData >> 24) & 0xff); break; } } } REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_CLR1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -