📄 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 defined(CONFIG_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_UINT32 LM_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_UINT32 LM_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_STATUS LM_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_VOID LM_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); if (Value32 & NVRAM_CMD_DONE) { Status = LM_STATUS_SUCCESS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -