/* * See file CREDITS for list of people who contributed to this * project. * * 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; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include #include #include #include #include #include #include #undef DEBUG #define BIT(x) ((1 << x)) /* ====================================== */ #define GDM_DISPAD BIT(18) #define GDM_DISCRC BIT(17) #define GDM_STRPCRC BIT(16) //GDMA1 uni-cast frames destination port #define GDM_UFRC_P_CPU ((u32)(~(0x7 << 12))) #define GDM_UFRC_P_GDMA1 (1 << 12) #define GDM_UFRC_P_GDMA2 (2 << 12) #define GDM_UFRC_P_ppe (6 << 12) #define GDM_UFRC_P_DROP (7 << 12) //GDMA1 broad-cast MAC address frames #define GDM_BFRC_P_CPU ((u32)(~(0x7 << 8))) #define GDM_BFRC_P_GDMA1 (1 << 8) #define GDM_BFRC_P_GDMA2 (2 << 8) #define GDM_BFRC_P_PPE (6 << 8) #define GDM_BFRC_P_DROP (7 << 8) //GDMA1 multi-cast MAC address frames #define GDM_MFRC_P_CPU ((u32)(~(0x7 << 4))) #define GDM_MFRC_P_GDMA1 (1 << 4) #define GDM_MFRC_P_GDMA2 (2 << 4) #define GDM_MFRC_P_PPE (6 << 4) #define GDM_MFRC_P_DROP (7 << 4) //GDMA1 other MAC address frames destination port #define GDM_OFRC_P_CPU ((u32)(~(0x7))) #define GDM_OFRC_P_GDMA1 1 #define GDM_OFRC_P_GDMA2 2 #define GDM_OFRC_P_PPE 6 #define GDM_OFRC_P_DROP 7 #define PSE_RESET BIT(0) #define RST_DRX_IDX0 BIT(16) #define RST_DTX_IDX0 BIT(0) #define TX_WB_DDONE BIT(6) #define RX_DMA_BUSY BIT(3) #define TX_DMA_BUSY BIT(1) #define RX_DMA_EN BIT(2) #define TX_DMA_EN BIT(0) #define GP1_FRC_EN BIT(15) #define GP1_FC_TX BIT(11) #define GP1_FC_RX BIT(10) #define GP1_LNK_DWN BIT(9) #define GP1_AN_OK BIT(8) /* * FE_INT_STATUS */ #define CNT_PPE_AF BIT(31) #define CNT_GDM1_AF BIT(29) #define PSE_P1_FC BIT(22) #define PSE_P0_FC BIT(21) #define PSE_FQ_EMPTY BIT(20) #define GE1_STA_CHG BIT(18) #define TX_COHERENT BIT(17) #define RX_COHERENT BIT(16) #define TX_DONE_INT1 BIT(9) #define TX_DONE_INT0 BIT(8) #define RX_DONE_INT0 BIT(2) #define TX_DLY_INT BIT(1) #define RX_DLY_INT BIT(0) /* * Ethernet chip registers.RT2880 */ #if defined (RT5350_ASIC_BOARD) || defined (RT5350_FPGA_BOARD) #define PDMA_RELATED 0x0800 /* 1. PDMA */ #define TX_BASE_PTR0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x000) #define TX_MAX_CNT0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x004) #define TX_CTX_IDX0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x008) #define TX_DTX_IDX0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x00C) #define TX_BASE_PTR1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x010) #define TX_MAX_CNT1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x014) #define TX_CTX_IDX1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x018) #define TX_DTX_IDX1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x01C) #define TX_BASE_PTR2 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x020) #define TX_MAX_CNT2 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x024) #define TX_CTX_IDX2 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x028) #define TX_DTX_IDX2 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x02C) #define TX_BASE_PTR3 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x030) #define TX_MAX_CNT3 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x034) #define TX_CTX_IDX3 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x038) #define TX_DTX_IDX3 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x03C) #define RX_BASE_PTR0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x100) #define RX_MAX_CNT0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x104) #define RX_CALC_IDX0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x108) #define RX_DRX_IDX0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x10C) #define RX_BASE_PTR1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x110) #define RX_MAX_CNT1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x114) #define RX_CALC_IDX1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x118) #define RX_DRX_IDX1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x11C) #define PDMA_INFO (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x200) #define PDMA_GLO_CFG (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x204) #define PDMA_RST_IDX (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x208) #define PDMA_RST_CFG (RALINK_FRAME_ENGINE_BASE + PDMA_RST_IDX) #define DLY_INT_CFG (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x20C) #define FREEQ_THRES (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x210) #define INT_STATUS (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x220) #define FE_INT_STATUS (INT_STATUS) #define INT_MASK (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x228) #define FE_INT_ENABLE (INT_MASK) #define PDMA_WRR (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x280) #define PDMA_SCH_CFG (PDMA_WRR) #define SDM_RELATED 0x0C00 #define SDM_CON (RALINK_FRAME_ENGINE_BASE + SDM_RELATED+0x00) //Switch DMA configuration #define SDM_RRING (RALINK_FRAME_ENGINE_BASE + SDM_RELATED+0x04) //Switch DMA Rx Ring #define SDM_TRING (RALINK_FRAME_ENGINE_BASE + SDM_RELATED+0x08) //Switch DMA Tx Ring #define SDM_MAC_ADRL (RALINK_FRAME_ENGINE_BASE + SDM_RELATED+0x0C) //Switch MAC address LSB #define SDM_MAC_ADRH (RALINK_FRAME_ENGINE_BASE + SDM_RELATED+0x10) //Switch MAC Address MSB #define SDM_TPCNT (RALINK_FRAME_ENGINE_BASE + SDM_RELATED+0x100) //Switch DMA Tx packet count #define SDM_TBCNT (RALINK_FRAME_ENGINE_BASE + SDM_RELATED+0x104) //Switch DMA Tx byte count #define SDM_RPCNT (RALINK_FRAME_ENGINE_BASE + SDM_RELATED+0x108) //Switch DMA rx packet count #define SDM_RBCNT (RALINK_FRAME_ENGINE_BASE + SDM_RELATED+0x10C) //Switch DMA rx byte count #define SDM_CS_ERR (RALINK_FRAME_ENGINE_BASE + SDM_RELATED+0x110) //Switch DMA rx checksum error count #elif defined (RT6855_ASIC_BOARD) || defined (RT6855_FPGA_BOARD) || \ defined (RT6855A_FPGA_BOARD) || defined (RT6855A_ASIC_BOARD) || \ defined (RT6352_ASIC_BOARD) || defined (RT6352_FPGA_BOARD) || \ defined (RT71100_ASIC_BOARD) || defined (RT71100_FPGA_BOARD) /* Old FE with New PDMA */ #define PDMA_RELATED 0x0800 /* 1. PDMA */ #define TX_BASE_PTR0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x000) #define TX_MAX_CNT0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x004) #define TX_CTX_IDX0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x008) #define TX_DTX_IDX0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x00C) #define TX_BASE_PTR1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x010) #define TX_MAX_CNT1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x014) #define TX_CTX_IDX1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x018) #define TX_DTX_IDX1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x01C) #define TX_BASE_PTR2 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x020) #define TX_MAX_CNT2 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x024) #define TX_CTX_IDX2 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x028) #define TX_DTX_IDX2 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x02C) #define TX_BASE_PTR3 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x030) #define TX_MAX_CNT3 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x034) #define TX_CTX_IDX3 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x038) #define TX_DTX_IDX3 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x03C) #define RX_BASE_PTR0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x100) #define RX_MAX_CNT0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x104) #define RX_CALC_IDX0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x108) #define RX_DRX_IDX0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x10C) #define RX_BASE_PTR1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x110) #define RX_MAX_CNT1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x114) #define RX_CALC_IDX1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x118) #define RX_DRX_IDX1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x11C) #define PDMA_INFO (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x200) #define PDMA_GLO_CFG (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x204) #define PDMA_RST_IDX (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x208) #define PDMA_RST_CFG (RALINK_FRAME_ENGINE_BASE + PDMA_RST_IDX) #define DLY_INT_CFG (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x20C) #define FREEQ_THRES (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x210) #define INT_STATUS (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x220) /* FIXME */ #define INT_MASK (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x228) /* FIXME */ #define PDMA_WRR (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x280) #define PDMA_SCH_CFG (PDMA_WRR) /* TODO: change FE_INT_STATUS->INT_STATUS * FE_INT_ENABLE->INT_MASK */ #define MDIO_ACCESS RALINK_FRAME_ENGINE_BASE + 0x00 #define MDIO_CFG RALINK_FRAME_ENGINE_BASE + 0x04 #define FE_DMA_GLO_CFG RALINK_FRAME_ENGINE_BASE + 0x08 #define FE_RST_GLO RALINK_FRAME_ENGINE_BASE + 0x0C #define FE_INT_STATUS RALINK_FRAME_ENGINE_BASE + 0x10 #define FE_INT_ENABLE RALINK_FRAME_ENGINE_BASE + 0x14 #define FC_DROP_STA RALINK_FRAME_ENGINE_BASE + 0x18 #define FOE_TS_T RALINK_FRAME_ENGINE_BASE + 0x1C #if defined (PDMA_NEW) #define GDMA1_RELATED 0x0600 #define GDMA1_FWD_CFG (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x00) #define GDMA1_SHRP_CFG (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x04) #define GDMA1_MAC_ADRL (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x08) #define GDMA1_MAC_ADRH (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x0C) #else #define GDMA1_RELATED 0x0020 #define GDMA1_FWD_CFG (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x00) #define GDMA1_SCH_CFG (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x04) #define GDMA1_SHRP_CFG (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x08) #define GDMA1_MAC_ADRL (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x0C) #define GDMA1_MAC_ADRH (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x10) #endif #define PSE_RELATED 0x0040 #define PSE_FQFC_CFG (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x00) #define CDMA_FC_CFG (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x04) #define GDMA1_FC_CFG (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x08) #define GDMA2_FC_CFG (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x0C) #define CDMA_OQ_STA (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x10) #define GDMA1_OQ_STA (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x14) #define GDMA2_OQ_STA (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x18) #define PSE_IQ_STA (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x1C) #define CDMA_RELATED 0x0080 #define CDMA_CSG_CFG (RALINK_FRAME_ENGINE_BASE + CDMA_RELATED + 0x00) #define CDMA_SCH_CFG (RALINK_FRAME_ENGINE_BASE + CDMA_RELATED + 0x04) #else #define MDIO_ACCESS RALINK_FRAME_ENGINE_BASE + 0x00 #ifdef RT3883_USE_GE2 #define MDIO_CFG RALINK_FRAME_ENGINE_BASE + 0x18 #else #define MDIO_CFG RALINK_FRAME_ENGINE_BASE + 0x04 #endif // RT3883_USE_GE2 // #define FE_DMA_GLO_CFG RALINK_FRAME_ENGINE_BASE + 0x08 #define FE_RST_GLO RALINK_FRAME_ENGINE_BASE + 0x0C #define FE_INT_STATUS RALINK_FRAME_ENGINE_BASE + 0x10 #define FE_INT_ENABLE RALINK_FRAME_ENGINE_BASE + 0x14 #define FC_DROP_STA RALINK_FRAME_ENGINE_BASE + 0x18 #define FOE_TS_T RALINK_FRAME_ENGINE_BASE + 0x1C #define GDMA1_RELATED 0x0020 #define GDMA1_FWD_CFG (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x00) #define GDMA1_SCH_CFG (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x04) #define GDMA1_SHRP_CFG (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x08) #define GDMA1_MAC_ADRL (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x0C) #define GDMA1_MAC_ADRH (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x10) #define GDMA2_RELATED 0x0060 #define GDMA2_FWD_CFG (RALINK_FRAME_ENGINE_BASE + GDMA2_RELATED + 0x00) #define GDMA2_SCH_CFG (RALINK_FRAME_ENGINE_BASE + GDMA2_RELATED + 0x04) #define GDMA2_SHRP_CFG (RALINK_FRAME_ENGINE_BASE + GDMA2_RELATED + 0x08) #define GDMA2_MAC_ADRL (RALINK_FRAME_ENGINE_BASE + GDMA2_RELATED + 0x0C) #define GDMA2_MAC_ADRH (RALINK_FRAME_ENGINE_BASE + GDMA2_RELATED + 0x10) #define PSE_RELATED 0x0040 #define PSE_FQFC_CFG (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x00) #define CDMA_FC_CFG (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x04) #define GDMA1_FC_CFG (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x08) #define GDMA2_FC_CFG (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x0C) #define CDMA_OQ_STA (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x10) #define GDMA1_OQ_STA (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x14) #define GDMA2_OQ_STA (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x18) #define PSE_IQ_STA (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x1C) #define CDMA_RELATED 0x0080 #define CDMA_CSG_CFG (RALINK_FRAME_ENGINE_BASE + CDMA_RELATED + 0x00) #define CDMA_SCH_CFG (RALINK_FRAME_ENGINE_BASE + CDMA_RELATED + 0x04) #define PDMA_RELATED 0x0100 #define PDMA_GLO_CFG (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED + 0x00) #define PDMA_RST_IDX (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED + 0x04) #define PDMA_SCH_CFG (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED + 0x08) #define DELAY_INT_CFG (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED + 0x0C) #define TX_BASE_PTR0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED + 0x10) #define TX_MAX_CNT0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED + 0x14) #define TX_CTX_IDX0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED + 0x18) #define TX_DTX_IDX0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED + 0x1C) #define TX_BASE_PTR1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED + 0x20) #define TX_MAX_CNT1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED + 0x24) #define TX_CTX_IDX1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED + 0x28) #define TX_DTX_IDX1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED + 0x2C) #define RX_BASE_PTR0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED + 0x30) #define RX_MAX_CNT0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED + 0x34) #define RX_CALC_IDX0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED + 0x38) #define RX_DRX_IDX0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED + 0x3C) #endif #define INTERNAL_LOOPBACK_ENABLE 1 #define INTERNAL_LOOPBACK_DISABLE 0 #define ESRAM_ON 1 #define ESRAM_OFF 0 //#define CONFIG_UNH_TEST /*****************************************/ //PCI define #ifdef RALINK_PCI_HOST_TEST_FUN //RTL8139.h.................................................. #define DelayCount 0X8000 #define RTL8139_DEVICE_VENDOR_ID 0x813910EC #define PCI_BRIDGE_DEVICE_VENDOR_ID 0x0000eeee #define RTL8139_VENDOR_ID 0x10EC #define RTL8139_DEVICE_ID 0x8139 #define RTL8139_RX_BUFFER_LENGTH (32 * 1024) #define RX_MAX_PACKET_LENGTH 1518 #define RX_MIN_PACKET_LENGTH 60 #define PACKET_CRC_LENGTH 4 #define RTL8139_TX_BUF_NUM 0x100 #define PACKET_HDR_LENGTH 14 //#define PCI_BRIDGE_DMA_SIZE 0x0 //power of 2 =>16(MB) //*** PCI Bridge Definition Configuration Space & Value #define PCI_BRIDGE_CONFIGURATION_SPACE_CONTROL 0x4C #define PCI_BRIDGE_CONFIGURATION_INTABCD_STATUS 0x4F #define PCI_BRIDGE_CONFIGURATION_INTMASK 0x4E #define PCI_BRIDGE_CONFIGURATION_SPACE_MEM1_BA 0x80000050 #define PCI_BRIDGE_CONFIGURATION_SPACE_MEM2_BA 0x80000054 #define PCI_BRIDGE_CONFIGURATION_SPACE_MEM3_BA 0x80000058 #define PCI_ENABLE_INTA_INTB_INTC_INTD 0x03C00000 #define PCI_BRIDGE_MAX_INT_NUMBER 0x04 #define PCI_DMA_MEM_REQUEST_FAIL 0xFFFFFFFF #define PCI_DMA_DEFAULT_SIZE 0x00 #define PCI_MAX_SLOT_NUM 0x04 #define PCI_BRIDGE_MAX_INT_NUMBER 0x04 // PCI dev ID define #define PCI_BRIDGE_ID 0x4321159B #define PCI_RTL8139_ID 0x813910EC /*3.PCI configuration register */ #define PCI_CSH_VENDOR_ID_REG 0x00 #define PCI_CSH_DEVICE_ID_REG 0x02 #define PCI_CSH_COMMAND_REG 0x04 #define PCI_CSH_STATUS_REG 0x06 #define PCI_CSH_REVISION_CLASS_REG 0x08 #define PCI_CSH_CACHE_LINE_SIZE_REG 0x0C #define PCI_CSH_LATENCY_TIMER_REG 0x0D #define PCI_CSH_HEADER_TYPE_REG 0x0E #define PCI_CSH_BIST_REG 0x0F #define PCI_CSH_BASE_ADDR_REG 0x10 /*7.Alignment Constants */ #define PCI_MEM_SPACE_ALIGNMENT 0x10 #define PCI_IO_SPACE_ALIGNMENT 0x4 #define SYS_DDR_SDRAM_BASE_ADDR 0x00000000 #define PCI_ALLOCATE_SPACE 0x20000000 /*5.PCI command status register bit mapping */ #define PCI_CMD_IO_ENABLE 0x00000001 #define PCI_CMD_MEM_ENABLE 0x00000002 #define PCI_CMD_BUS_MASTER_ENABLE 0x00000004 #define PCI_CMD_MEM_WRITE_INVALIDATE 0X00000010 #define PCI_CMD_PARITY_ERR 0x00000040 #define PCI_CMD_STEPPING_CONTROL 0x00000080 #define PCI_CMD_SERR_ENABLE 0x00000100 #define PCI_CMD_FBB_ENABLE 0x00000200 typedef struct { u32 RegNum:8; u32 FunNum:3; u32 DevNum:5; u32 BusNum:8; u32 Always0:7; u32 Enable:1; } PCIDeviceIDStruct; struct _PCI_DEV { u32 dev_ven; PCIDeviceIDStruct PCIDeviceID; }; //kaiker #define RALINK_PCI_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_SYSCTL_BASE + 0x1010) #define RALINK_PCI_BAR1SETUP_ADDR *(volatile u32 *)(RALINK_SYSCTL_BASE + 0x1014) #define RALINK_PCI_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_SYSCTL_BASE + 0x1018) #define RALINK_PCI_IMBASEBAR1_ADDR *(volatile u32 *)(RALINK_SYSCTL_BASE + 0x101C) struct _PCI_DEV Finded_PCIDeviceID[PCI_MAX_SLOT_NUM]; #endif // RT2880_ON_UBOOT_TEST_FUNC // #define TOUT_LOOP 1000 #define ENABLE 1 #define DISABLE 0 VALID_BUFFER_STRUCT rt2880_free_buf_list; VALID_BUFFER_STRUCT rt2880_busing_buf_list; static BUFFER_ELEM rt2880_free_buf[PKTBUFSRX]; /*=======================================*/ struct palmeth_desc { volatile s32 status; u32 des1; u32 buf; u32 next; }; #if 1 /*========================================= PDMA RX Descriptor Format define =========================================*/ //------------------------------------------------- typedef struct _PDMA_RXD_INFO1_ PDMA_RXD_INFO1_T; struct _PDMA_RXD_INFO1_ { unsigned int PDP0; }; //------------------------------------------------- typedef struct _PDMA_RXD_INFO2_ PDMA_RXD_INFO2_T; struct _PDMA_RXD_INFO2_ { unsigned int PLEN1 : 14; unsigned int LS1 : 1; unsigned int UN_USED : 1; unsigned int PLEN0 : 14; unsigned int LS0 : 1; unsigned int DDONE_bit : 1; }; //------------------------------------------------- typedef struct _PDMA_RXD_INFO3_ PDMA_RXD_INFO3_T; struct _PDMA_RXD_INFO3_ { unsigned int PDP1; }; //------------------------------------------------- typedef struct _PDMA_RXD_INFO4_ PDMA_RXD_INFO4_T; struct _PDMA_RXD_INFO4_ { #if defined (PDMA_NEW) unsigned int FOE_Entry : 14; unsigned int CRSN : 5; unsigned int SP : 3; unsigned int L4F : 1; unsigned int L4VLD : 1; unsigned int TACK : 1; unsigned int IP4F : 1; unsigned int IP4 : 1; unsigned int IP6 : 1; unsigned int UN_USE1 : 4; #else unsigned int FOE_Entry : 14; unsigned int FVLD : 1; unsigned int UN_USE1 : 1; unsigned int AI : 8; unsigned int SP : 3; unsigned int AIS : 1; unsigned int L4F : 1; unsigned int IPF : 1; unsigned int L4FVLD_bit : 1; unsigned int IPFVLD_bit : 1; #endif }; struct PDMA_rxdesc { PDMA_RXD_INFO1_T rxd_info1; PDMA_RXD_INFO2_T rxd_info2; PDMA_RXD_INFO3_T rxd_info3; PDMA_RXD_INFO4_T rxd_info4; }; #endif /*========================================= PDMA TX Descriptor Format define =========================================*/ //------------------------------------------------- typedef struct _PDMA_TXD_INFO1_ PDMA_TXD_INFO1_T; struct _PDMA_TXD_INFO1_ { unsigned int SDP0; }; //------------------------------------------------- typedef struct _PDMA_TXD_INFO2_ PDMA_TXD_INFO2_T; struct _PDMA_TXD_INFO2_ { unsigned int SDL1 : 14; unsigned int LS1_bit : 1; unsigned int BURST_bit : 1; unsigned int SDL0 : 14; unsigned int LS0_bit : 1; unsigned int DDONE_bit : 1; }; //------------------------------------------------- typedef struct _PDMA_TXD_INFO3_ PDMA_TXD_INFO3_T; struct _PDMA_TXD_INFO3_ { unsigned int SDP1; }; //------------------------------------------------- typedef struct _PDMA_TXD_INFO4_ PDMA_TXD_INFO4_T; struct _PDMA_TXD_INFO4_ { unsigned int VIDX : 4; unsigned int VPRI : 3; unsigned int INSV : 1; unsigned int SIDX : 4; unsigned int INSP : 1; #if defined (PDMA_NEW) unsigned int RESV : 2; unsigned int UDF : 5; unsigned int FP_BMAP : 8; unsigned int TSO : 1; unsigned int TCO : 1; unsigned int UCO : 1; unsigned int ICO : 1; #else unsigned int UN_USE3 : 3; unsigned int QN : 3; unsigned int UN_USE2 : 5; unsigned int PN : 3; unsigned int UN_USE1 : 2; unsigned int TC0 : 1; unsigned int UC0_bit : 1; unsigned int IC0_bit : 1; #endif }; struct PDMA_txdesc { PDMA_TXD_INFO1_T txd_info1; PDMA_TXD_INFO2_T txd_info2; PDMA_TXD_INFO3_T txd_info3; PDMA_TXD_INFO4_T txd_info4; }; static int is_internal_loopback_test; static struct PDMA_txdesc tx_ring0_cache[NUM_TX_DESC] __attribute__ ((aligned(32))); /* TX descriptor ring */ static struct PDMA_rxdesc rx_ring_cache[NUM_RX_DESC] __attribute__ ((aligned(32))); /* RX descriptor ring */ static int rx_dma_owner_idx0; /* Point to the next RXD DMA wants to use in RXD Ring#0. */ static int rx_wants_alloc_idx0; /* Point to the next RXD CPU wants to allocate to RXD Ring #0. */ static int tx_cpu_owner_idx0; /* Point to the next TXD in TXD_Ring0 CPU wants to use */ static int tx_cpu_owner_idx1; static volatile struct PDMA_rxdesc *rx_ring; static volatile struct PDMA_txdesc *tx_ring0; #ifdef RALINK_GDMA_DUP_TX_RING_TEST_FUN static volatile struct PDMA_txdesc *tx_ring1; static struct PDMA_txdesc tx_ring1_cache[NUM_TX_DESC] __attribute__ ((aligned(32))); /* TX descriptor ring */ #endif static char rxRingSize; static char txRingSize; static int rt2880_eth_init(struct eth_device* dev, bd_t* bis); static int rt2880_eth_send(struct eth_device* dev, volatile void *packet, int length); static int rt2880_eth_recv(struct eth_device* dev); void rt2880_eth_halt(struct eth_device* dev); int mii_mgr_read(u32 phy_addr, u32 phy_register, u32 *read_data); int mii_mgr_write(u32 phy_addr, u32 phy_register, u32 write_data); static int rt2880_eth_setup(struct eth_device* dev); static int rt2880_eth_initd; void rt6855A_gsw_init(void); static int eth_loopback_mode,loopback_protect; static int force_queue_n; static int sdp0_alig_16n_x; static int sdp1_alig_16n_x; /* RT3052 PHY TEST */ #ifdef RT3052_PHY_TEST #define PHY_TEST_ENABLE 1 #define PHY_TEST_DISABLE 0 int rt3052_phy_test = PHY_TEST_DISABLE; int rt3052_phy_test_debug = 0; unsigned char rt3052_phy_test_buf[1520]; int rt3052_phy_test_ret_code; int phy_init_setup = 0; #define ETH_P_8021Q 0x8100 int rt3052_port_test_status = 0; // rt3052 phy production test, intermediate result void phy_link_detect(); void test_nop(); void packet_dump(unsigned char* packet, unsigned int length); int phy_mdio_link_check(u32 phy_addr); #endif /* END OF RT3052 PHY TEST */ static int internal_loopback_test; static int rt2880_esram_gear; static int rt2880_size_of_mem; static int header_payload_scatter_en; static u32 rt2880_hdrlen; static int rt2880_buf_in_esram_en; static int rt2880_desc_in_esram; static int rt2880_sdp0_buf_in_esram_en; static int rt2880_debug_en; extern char console_buffer[CONFIG_SYS_CBSIZE]; /* console I/O buffer */ #define phys_to_bus(a) (a & 0x1FFFFFFF) #define PCI_WAIT_INPUT_CHAR(ch) while((ch = getc())== 0) struct eth_device* rt2880_pdev; volatile uchar *PKT_HEADER_Buf;// = (uchar *)CFG_EMBEDED_SRAM_SDP0_BUF_START; static volatile uchar PKT_HEADER_Buf_Pool[(PKTBUFSRX * PKTSIZE_ALIGN) + PKTALIGN]; #ifdef RALINK_GDMA_SCATTER_TEST_FUN static volatile uchar *pkthdrbuf[PKTBUFSRX]; #endif extern volatile uchar *NetTxPacket; /* THE transmit packet */ extern volatile uchar *PktBuf; extern volatile uchar Pkt_Buf_Pool[]; #define PIODIR_R (RALINK_PIO_BASE + 0X24) #define PIODATA_R (RALINK_PIO_BASE + 0X20) #define PIODIR3924_R (RALINK_PIO_BASE + 0x4c) #define PIODATA3924_R (RALINK_PIO_BASE + 0x48) #define FREEBUF_OFFSET(CURR) ((int)(((0x0FFFFFFF & (u32)CURR) - (u32) (0x0FFFFFFF & (u32) rt2880_free_buf[0].pbuf)) / 1536)) void START_ETH(struct eth_device *dev ) { s32 omr; omr=RALINK_REG(PDMA_GLO_CFG); udelay(100); if(is_internal_loopback_test) { omr |= TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN ; omr &= ~RX_DMA_EN; printf("\n Interloopback test! So RxDMA is Stop ! \n"); } else { omr |= TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN ; } RALINK_REG(PDMA_GLO_CFG)=omr; udelay(500); } void STOP_ETH(struct eth_device *dev) { s32 omr; omr=RALINK_REG(PDMA_GLO_CFG); udelay(100); omr &= ~(TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN) ; RALINK_REG(PDMA_GLO_CFG)=omr; udelay(500); } BUFFER_ELEM *rt2880_free_buf_entry_dequeue(VALID_BUFFER_STRUCT *hdr) { int zero = 0; /* causes most compilers to place this */ /* value in a register only once */ BUFFER_ELEM *node; /* Make sure we were not passed a null pointer. */ if (!hdr) { return (NULL); } /* If there is a node in the list we want to remove it. */ if (hdr->head) { /* Get the node to be removed */ node = hdr->head; /* Make the hdr point the second node in the list */ hdr->head = node->next; /* If this is the last node the headers tail pointer needs to be nulled We do not need to clear the node's next since it is already null */ if (!(hdr->head)) { hdr->tail = (BUFFER_ELEM *)zero; } node->next = (BUFFER_ELEM *)zero; } else { node = NULL; return (node); } /* Restore the previous interrupt lockout level. */ /* Return a pointer to the removed node */ //shnat_validation_flow_table_entry[node->index].state = SHNAT_FLOW_TABLE_NODE_USED; return (node); } static BUFFER_ELEM *rt2880_free_buf_entry_enqueue(VALID_BUFFER_STRUCT *hdr, BUFFER_ELEM *item) { int zero =0; if (!hdr) { return (NULL); } if (item != NULL) { /* Temporarily lockout interrupts to protect global buffer variables. */ // Sys_Interrupt_Disable_Save_Flags(&cpsr_flags); /* Set node's next to point at NULL */ item->next = (BUFFER_ELEM *)zero; /* If there is currently a node in the linked list, we want to add the new node to the end. */ if (hdr->head) { /* Make the last node's next point to the new node. */ hdr->tail->next = item; /* Make the roots tail point to the new node */ hdr->tail = item; } else { /* If the linked list was empty, we want both the root's head and tial to point to the new node. */ hdr->head = item; hdr->tail = item; } /* Restore the previous interrupt lockout level. */ } else { printf("\n shnat_flow_table_free_entry_enqueue is called,item== NULL \n"); } return(item); } /* MEM_Buffer_Enqueue */ #if defined (CONFIG_MII) || defined(CONFIG_CMD_MII) static int rt2880_mii_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value) { u32 phy_addr=addr, phy_reg=reg, phy_val; if ( mii_mgr_read(phy_addr, phy_reg, &phy_val) ) { *value = (unsigned short)(phy_val&0xffff); //printf(" value=0x%04X\n", phy_val); return 0; } return 1; } static int rt2880_mii_write (char *devname, unsigned char addr, unsigned char reg, unsigned short value) { u32 phy_addr=addr, phy_reg=reg, phy_val=value; if ( mii_mgr_write(phy_addr, phy_reg, phy_val) ) { return 0; } return 1; } #endif int rt2880_eth_initialize(bd_t *bis) { struct eth_device* dev; int i; u32 regValue; if (!(dev = (struct eth_device *) malloc (sizeof *dev))) { printf("Failed to allocate memory\n"); return -1; } memset(dev, 0, sizeof(*dev)); sprintf(dev->name, "Eth0 (10/100-M)"); dev->iobase = RALINK_FRAME_ENGINE_BASE; dev->init = rt2880_eth_init; dev->halt = rt2880_eth_halt; dev->send = rt2880_eth_send; dev->recv = rt2880_eth_recv; eth_register(dev); #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) /* register mii command access routines */ miiphy_register(dev->name, rt2880_mii_read, rt2880_mii_write); #endif #if defined (RT6855A_ASIC_BOARD) || defined (RT6855A_FPGA_BOARD) rt6855A_gsw_init(); #endif eth_loopback_mode = 0; rt2880_pdev = dev; loopback_protect = 0; force_queue_n = 3; sdp0_alig_16n_x = 0; sdp1_alig_16n_x = 0; rt2880_eth_initd =0; rt2880_size_of_mem = 0; rt2880_esram_gear = ESRAM_OFF; internal_loopback_test = INTERNAL_LOOPBACK_DISABLE; header_payload_scatter_en = DISABLE; rt2880_buf_in_esram_en = DISABLE; rt2880_desc_in_esram = DISABLE; rt2880_sdp0_buf_in_esram_en = DISABLE; PktBuf = Pkt_Buf_Pool; PKT_HEADER_Buf = PKT_HEADER_Buf_Pool; is_internal_loopback_test = 0; rt2880_hdrlen = 20; NetTxPacket = NULL; rt2880_debug_en = DISABLE; rx_ring = (struct PDMA_rxdesc *)KSEG1ADDR((ulong)&rx_ring_cache[0]); tx_ring0 = (struct PDMA_txdesc *)KSEG1ADDR((ulong)&tx_ring0_cache[0]); rt2880_free_buf_list.head = NULL; rt2880_free_buf_list.tail = NULL; rt2880_busing_buf_list.head = NULL; rt2880_busing_buf_list.tail = NULL; //2880_free_buf /* * Setup packet buffers, aligned correctly. */ rt2880_free_buf[0].pbuf = (unsigned char *)(&PktBuf[0] + (PKTALIGN - 1)); rt2880_free_buf[0].pbuf -= (ulong)rt2880_free_buf[0].pbuf % PKTALIGN; rt2880_free_buf[0].next = NULL; rt2880_free_buf_entry_enqueue(&rt2880_free_buf_list,&rt2880_free_buf[0]); #ifdef DEBUG printf("\n rt2880_free_buf[0].pbuf = 0x%08X \n",rt2880_free_buf[0].pbuf); #endif for (i = 1; i < PKTBUFSRX; i++) { rt2880_free_buf[i].pbuf = rt2880_free_buf[0].pbuf + (i)*PKTSIZE_ALIGN; rt2880_free_buf[i].next = NULL; #ifdef DEBUG printf("\n rt2880_free_buf[%d].pbuf = 0x%08X\n",i,rt2880_free_buf[i].pbuf); #endif rt2880_free_buf_entry_enqueue(&rt2880_free_buf_list,&rt2880_free_buf[i]); } for (i = 0; i < PKTBUFSRX; i++) { rt2880_free_buf[i].tx_idx = NUM_TX_DESC; #ifdef DEBUG printf("\n rt2880_free_buf[%d] = 0x%08X,rt2880_free_buf[%d].next=0x%08X \n",i,&rt2880_free_buf[i],i,rt2880_free_buf[i].next); #endif } //set clock resolution extern unsigned long mips_bus_feq; regValue = le32_to_cpu(*(volatile u_long *)(RALINK_FRAME_ENGINE_BASE + 0x0008)); regValue |= ((mips_bus_feq/1000000) << 8); *((volatile u_long *)(RALINK_FRAME_ENGINE_BASE + 0x0008)) = cpu_to_le32(regValue); return 0; } static int rt2880_eth_init(struct eth_device* dev, bd_t* bis) { if(rt2880_eth_initd == 0) { rt2880_eth_setup(dev); } else { START_ETH(dev); } rt2880_eth_initd = 1; return (1); } void LANWANPartition(void) { #ifdef MAC_TO_100SW_MODE int sw_id = 0; mii_mgr_read(29, 31, &sw_id); #ifdef RALINK_DEMO_BOARD_PVLAN if (sw_id == 0x175c) { //disable tagged VLAN mii_mgr_write(29, 23, 0); //WLLLL, wan at P0, demo board mii_mgr_write(29, 19, 0x809c); mii_mgr_write(29, 20, 0x9a96); mii_mgr_write(29, 21, 0x8e00); mii_mgr_write(29, 22, 0x8420); } else { mii_mgr_write(20, 13, 0x21); mii_mgr_write(22, 14, 0x2002); mii_mgr_write(22, 15, 0x1001); mii_mgr_write(22, 16, 0x1001); mii_mgr_write(22, 17, 0x1001); mii_mgr_write(22, 18, 0x1001); mii_mgr_write(22, 19, 0x1001); mii_mgr_write(23, 0, 0x3e21); mii_mgr_write(23, 1, 0x3e3e); mii_mgr_write(23, 2, 0x3e3e); mii_mgr_write(23, 16, 0x3f3f); mii_mgr_write(23, 17, 0x3f3f); mii_mgr_write(23, 18, 0x3f3f); } #endif #ifdef RALINK_EV_BOARD_PVLAN if (sw_id == 0x175c) { //disable tagged VLAN mii_mgr_write(29, 23, 0); //LLLLW, wan at P4, ev board mii_mgr_write(29, 19, 0x8e8d); mii_mgr_write(29, 20, 0x8b87); mii_mgr_write(29, 21, 0x8000); mii_mgr_write(29, 22, 0x8420); } else { mii_mgr_write(20, 13, 0x21); mii_mgr_write(22, 14, 0x1001); mii_mgr_write(22, 15, 0x1001); mii_mgr_write(22, 16, 0x1001); mii_mgr_write(22, 17, 0x1001); mii_mgr_write(22, 18, 0x2002); mii_mgr_write(22, 19, 0x1001); mii_mgr_write(23, 0, 0x2f2f); mii_mgr_write(23, 1, 0x2f2f); mii_mgr_write(23, 2, 0x2f30); mii_mgr_write(23, 16, 0x3f3f); mii_mgr_write(23, 17, 0x3f3f); mii_mgr_write(23, 18, 0x3f3f); } #endif #endif // MAC_TO_100SW_MODE // #if defined (RT3052_ASIC_BOARD) || defined (RT3052_FPGA_BOARD) || \ defined (RT3352_ASIC_BOARD) || defined (RT3352_FPGA_BOARD) || \ defined (RT5350_ASIC_BOARD) || defined (RT5350_FPGA_BOARD) // Only for first generation Switch (RT3052,RT3350,RT3352,RT5350) // *((volatile u32 *)(RALINK_ETH_SW_BASE + 0x14)) = 0x405555; //enable VLANa // *((volatile u32 *)(RALINK_ETH_SW_BASE + 0x50)) = 0x2001; //VLAN id // *((volatile u32 *)(RALINK_ETH_SW_BASE + 0x98)) = 0x7f7f; //remove VLAN tag #ifdef RALINK_DEMO_BOARD_PVLAN //WLLLL, wan at P0, demo board *((volatile u32 *)(RALINK_ETH_SW_BASE + 0x40)) = 0x1002; //PVID *((volatile u32 *)(RALINK_ETH_SW_BASE + 0x44)) = 0x1001; //PVID *((volatile u32 *)(RALINK_ETH_SW_BASE + 0x48)) = 0x1001; //PVID *((volatile u32 *)(RALINK_ETH_SW_BASE + 0x70)) = 0xffff417e; //VLAN member #endif #ifdef RALINK_EV_BOARD_PVLAN //LLLLW, wan at P4, ev board *((volatile u32 *)(RALINK_ETH_SW_BASE + 0x40)) = 0x1001; //PVID *((volatile u32 *)(RALINK_ETH_SW_BASE + 0x44)) = 0x1001; //PVID *((volatile u32 *)(RALINK_ETH_SW_BASE + 0x48)) = 0x1002; //PVID *((volatile u32 *)(RALINK_ETH_SW_BASE + 0x70)) = 0xffff506f; //VLAN member #endif #endif // (RT3052_ASIC_BOARD || RT3052_FPGA_BOARD || RT3352_ASIC_BOARD || RT3352_FPGA_BOARD) } #if defined (P5_RGMII_TO_MAC_MODE) || defined (MAC_TO_VITESSE_MODE) static void ResetSWusingGPIOx(void) { #ifdef GPIOx_RESET_MODE u32 value; #if defined (RT2880_FPGA_BOARD) || defined (RT2880_ASIC_BOARD) printf("\n GPIO pin 10 reset to switch\n"); //set spi/gpio share pin to gpio mode value = le32_to_cpu(*(volatile u_long *)RT2880_GPIOMODE_REG); value |= (1 << 1); *(volatile u_long *)(RT2880_GPIOMODE_REG) = cpu_to_le32(value); //Set Gpio pin 10 to output value = le32_to_cpu(*(volatile u_long *)PIODIR_R); value |= (1 << 10); *(volatile u_long *)(PIODIR_R) = cpu_to_le32(value); //Set Gpio pin 10 to low value = le32_to_cpu(*(volatile u_long *)PIODATA_R); value &= ~(1 << 10); *(volatile u_long *)(PIODATA_R) = cpu_to_le32(value); udelay(50000); //Set Gpio pin 10 to high value = le32_to_cpu(*(volatile u_long *)PIODATA_R); value |= (1 << 10); *(volatile u_long *)(PIODATA_R) = cpu_to_le32(value); #elif defined (RT2883_FPGA_BOARD) || defined (RT2883_ASIC_BOARD) printf("\n GPIO pin 12 reset to switch\n"); //Set UARTF_SHARED_MODE to 3'b111 bcs we need gpio 12, and SPI to normal mode value = le32_to_cpu(*(volatile u_long *)RT2880_GPIOMODE_REG); value |= (7 << 2); value &= ~(1 << 1); *(volatile u_long *)(RT2880_GPIOMODE_REG) = cpu_to_le32(value); //Set Gpio pin 12 to output, and pin 7(RTS) to input value = le32_to_cpu(*(volatile u_long *)PIODIR_R); value |= (1 << 12); value &= ~(1 << 7); *(volatile u_long *)(PIODIR_R) = cpu_to_le32(value); //Set Gpio pin 12 to low value = le32_to_cpu(*(volatile u_long *)PIODATA_R); value &= ~(1 << 12); *(volatile u_long *)(PIODATA_R) = cpu_to_le32(value); udelay(50000); //Set Gpio pin 12 to high value = le32_to_cpu(*(volatile u_long *)PIODATA_R); value |= (1 << 12); *(volatile u_long *)(PIODATA_R) = cpu_to_le32(value); #elif defined (RT3052_ASIC_BOARD) || defined (RT3052_FPGA_BOARD) printf("\n GPIO pin 36 reset to switch\n"); //Set UARTF_SHARED_MODE to 3'b111 bcs we need gpio 36, and SPI to normal mode value = le32_to_cpu(*(volatile u_long *)RT2880_GPIOMODE_REG); value |= (7 << 2); value &= ~(1 << 1); *(volatile u_long *)(RT2880_GPIOMODE_REG) = cpu_to_le32(value); //Set Gpio pin 36 to output value = le32_to_cpu(*(volatile u_long *)0xb000064c); value |= (1 << 12); *(volatile u_long *)(0xb000064c) = cpu_to_le32(value); //Set Gpio pin 36 to low value = le32_to_cpu(*(volatile u_long *)0xb0000648); value &= ~(1 << 12); *(volatile u_long *)(0xb0000648) = cpu_to_le32(value); udelay(50000); //Set Gpio pin 36 to high value = le32_to_cpu(*(volatile u_long *)0xb0000648); value |= (1 << 12); *(volatile u_long *)(0xb0000648) = cpu_to_le32(value); #elif defined (RT3352_ASIC_BOARD) || defined (RT3352_FPGA_BOARD) printf("\n Please FIXME... \n"); #elif defined (RT3883_ASIC_BOARD) printf("\n GPIO pin 24 reset to switch\n"); //Set Gpio pin 24 to output value = le32_to_cpu(*(volatile u_long *)PIODIR3924_R); value |= 1; *(volatile u_long *)(PIODIR3924_R) = cpu_to_le32(value); //Set Gpio pin 24 to low value = le32_to_cpu(*(volatile u_long *)PIODATA3924_R); value &= ~1; *(volatile u_long *)(PIODATA3924_R) = cpu_to_le32(value); udelay(50000); //Set Gpio pin 24 to high value = le32_to_cpu(*(volatile u_long *)PIODATA3924_R); value |= 1; *(volatile u_long *)(PIODATA3924_R) = cpu_to_le32(value); #else #error "Unknown Chip" #endif #endif // GPIOx_RESET_MODE // } #endif #if defined (MAC_TO_GIGAPHY_MODE) || defined (P5_MAC_TO_PHY_MODE) #ifdef CONFIG_ICPLUS_GPHY #define EV_ICPLUS_PHY_ID0 CONFIG_ICPLUS_GPHY_ID0 #define EV_ICPLUS_PHY_ID1 CONFIG_ICPLUS_GPHY_ID1 static int isICPlusGigaPHY(int ge) { u32 phy_id0,phy_id1; u32 phy_addr = 0; if(ge == 1) phy_addr = MAC_TO_GIGAPHY_MODE_ADDR; #if defined (P4_MAC_TO_PHY_MODE) else phy_addr = MAC_TO_GIGAPHY_MODE_ADDR2; #endif if( ! mii_mgr_read(phy_addr, 2, &phy_id0)){ printf("\n Read PhyID 0 is Fail!!\n"); phy_id0 =0; } if( ! mii_mgr_read(phy_addr, 3, &phy_id1)){ printf("\n Read PhyID 1 is Fail!!\n"); phy_id1 = 0; } if((phy_id0 == EV_ICPLUS_PHY_ID0) && ((phy_id1 & 0xfff0)== EV_ICPLUS_PHY_ID1)) return 1; return 0; } #endif // CONFIG_ICPLUS_GPHY #ifdef CONFIG_MARVELL_GPHY #define EV_MARVELL_PHY_ID0 CONFIG_MARVELL_GPHY_ID0 #define EV_MARVELL_PHY_ID1 CONFIG_MARVELL_GPHY_ID1 static int isMarvellGigaPHY(int ge) { u32 phy_id0,phy_id1; u32 phy_addr = 0; if(ge == 1) phy_addr = MAC_TO_GIGAPHY_MODE_ADDR; #if defined (P4_MAC_TO_PHY_MODE) else phy_addr = MAC_TO_GIGAPHY_MODE_ADDR2; #endif if( ! mii_mgr_read(phy_addr, 2, &phy_id0)){ printf("\n Read PhyID 0 is Fail!!\n"); phy_id0 =0; } if( ! mii_mgr_read(phy_addr, 3, &phy_id1)){ printf("\n Read PhyID 1 is Fail!!\n"); phy_id1 = 0; } if((phy_id0 == EV_MARVELL_PHY_ID0) && (phy_id1 == EV_MARVELL_PHY_ID1)) return 1; return 0; } #endif // CONFIG_MARVELL_GPHY #ifdef CONFIG_VTSS_GPHY #define EV_VTSS_PHY_ID0 CONFIG_VTSS_GPHY_ID0 #define EV_VTSS_PHY_ID1 CONFIG_VTSS_GPHY_ID1 static int isVtssGigaPHY(int ge) { u32 phy_id0,phy_id1; u32 phy_addr = 0; if(ge == 1) phy_addr = MAC_TO_GIGAPHY_MODE_ADDR; #if defined (P4_MAC_TO_PHY_MODE) else phy_addr = MAC_TO_GIGAPHY_MODE_ADDR2; #endif if( ! mii_mgr_read(phy_addr, 2, &phy_id0)){ printf("\n Read PhyID 0 is Fail!!\n"); phy_id0 =0; } if( ! mii_mgr_read(phy_addr, 3, &phy_id1)){ printf("\n Read PhyID 1 is Fail!!\n"); phy_id1 = 0; } if((phy_id0 == EV_VTSS_PHY_ID0) && (phy_id1 == EV_VTSS_PHY_ID1)) return 1; return 0; } #endif // CONFIG_VTSS_GPHY #endif // MAC_TO_GIGAPHY_MODE || P5_MAC_TO_PHY_MODE // #if defined (MAC_TO_GIGAPHY_MODE) || defined (P5_MAC_TO_PHY_MODE) || defined (MAC_TO_100PHY_MODE) #if defined (RT6855_ASIC_BOARD) || defined (RT6855_FPGA_BOARD) || \ defined (RT6855A_ASIC_BOARD) || defined (RT6855A_FPGA_BOARD) void enable_auto_negotiate(void) { u32 regValue; u32 addr = MAC_TO_GIGAPHY_MODE_ADDR; // define in config.mk regValue = le32_to_cpu(*(volatile u_long *)(RALINK_ETH_SW_BASE+0x7000)); regValue |= (1<<31); regValue &= ~(0x1f); regValue &= ~(0x1f<<8); regValue |= (addr << 0);// setup PHY address for auto polling (start Addr). regValue |= (addr << 8);// setup PHY address for auto polling (End Addr). *(volatile u_long *)(RALINK_ETH_SW_BASE+0x7000) = cpu_to_le32(regValue); } #elif defined (RT6352_ASIC_BOARD) || defined (RT6352_FPGA_BOARD) || \ defined (RT71100_ASIC_BOARD) || defined (RT71100_FPGA_BOARD) void enable_auto_negotiate(void) { u32 regValue; u32 addr = MAC_TO_GIGAPHY_MODE_ADDR; // define in config.mk regValue = le32_to_cpu(*(volatile u_long *)(RALINK_ETH_SW_BASE+0x7000)); regValue |= (1<<31); regValue &= ~(0x1f); regValue &= ~(0x1f<<8); regValue |= ((addr-1) << 0);// setup PHY address for auto polling (start Addr). regValue |= (addr << 8);// setup PHY address for auto polling (End Addr). *(volatile u_long *)(RALINK_ETH_SW_BASE+0x7000) = cpu_to_le32(regValue); #if defined (P4_MAC_TO_PHY_MODE) *(volatile u_long *)(RALINK_ETH_SW_BASE+0x3400) &= ~(0x1 << 15); #endif #if defined (P5_MAC_TO_PHY_MODE) *(volatile u_long*)(RALINK_ETH_SW_BASE+0x3500) &= ~(0x1 << 15); #endif } #elif defined (RT2880_ASIC_BOARD) || defined (RT2880_FPGA_BOARD) || \ defined (RT3883_ASIC_BOARD) || defined (RT3883_FPGA_BOARD) || \ defined (RT3052_ASIC_BOARD) || defined (RT3052_FPGA_BOARD) || \ defined (RT3352_ASIC_BOARD) || defined (RT3352_FPGA_BOARD) void enable_auto_negotiate(void) { u32 regValue; u32 addr = MAC_TO_GIGAPHY_MODE_ADDR; // define in config.mk #if defined (RT3052_ASIC_BOARD) || defined (RT3052_FPGA_BOARD) || \ defined (RT3352_ASIC_BOARD) || defined (RT3352_FPGA_BOARD) regValue = le32_to_cpu(*(volatile u_long *)(RALINK_ETH_SW_BASE+0x00C8)); #else regValue = RALINK_REG(MDIO_CFG); #endif regValue &= 0xe0ff7fff; // clear auto polling related field: // (MD_PHY1ADDR & GP1_FRC_EN). regValue |= 0x20000000; // force to enable MDC/MDIO auto polling. regValue |= (addr << 24); // setup PHY address for auto polling. #if defined (RT3052_ASIC_BOARD) || defined (RT3052_FPGA_BOARD) || \ defined (RT3352_ASIC_BOARD) || defined (RT3352_FPGA_BOARD) *(volatile u_long *)(RALINK_ETH_SW_BASE+0x00C8) = cpu_to_le32(regValue); #else RALINK_REG(MDIO_CFG) = cpu_to_le32(regValue); #endif } #else #endif #endif // defined (MAC_TO_GIGAPHY_MODE) || defined (P5_MAC_TO_PHY_MODE) || defined (MAC_TO_100PHY_MODE) // int isDMABusy(struct eth_device* dev) { u32 kk; kk = RALINK_REG(PDMA_GLO_CFG); if((kk & RX_DMA_BUSY)){ return 1; } if((kk & TX_DMA_BUSY)){ printf("\n TX_DMA_BUSY !!! "); return 1; } return 0; } #if defined (RT6855A_ASIC_BOARD) || defined (RT6855A_FPGA_BOARD) #define RSTCTRL_EPHY_RST (1<<24) void rt6855A_gsw_init(void) { u32 i = 0; u32 phy_val=0; u32 rev=0; #if defined (RT6855A_FPGA_BOARD) RALINK_REG(RALINK_ETH_SW_BASE+0x3000) = 0x5e353;//(P0, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) RALINK_REG(RALINK_ETH_SW_BASE+0x3100) = 0x5e353;//(P1, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) //RALINK_REG(RALINK_ETH_SW_BASE+0x3000) = 0x5e333;//(P0, Force mode, Link Up, 10Mbps, Full-Duplex, FC ON) //RALINK_REG(RALINK_ETH_SW_BASE+0x3100) = 0x5e333;//(P1, Force mode, Link Up, 10Mbps, Full-Duplex, FC ON) RALINK_REG(RALINK_ETH_SW_BASE+0x3200) = 0x8000;//P2, link down RALINK_REG(RALINK_ETH_SW_BASE+0x3300) = 0x8000;//P3, link down RALINK_REG(RALINK_ETH_SW_BASE+0x3400) = 0x8000;//P4, link down RALINK_REG(RALINK_ETH_SW_BASE+0x3500) = 0x8000;//P5, link down /* In order to use 10M/Full on FPGA board. We configure phy capable to * 10M Full/Half duplex, so we can use auto-negotiation on PC side */ for (i=6; i<8; i++) { mii_mgr_write(i, 4, 0x07e1); //Capable of 10M&100M Full/Half Duplex, flow control on/off //mii_mgr_write(i, 4, 0x0461); //Capable of 10M Full/Half Duplex, flow control on/off mii_mgr_write(i, 0, 0xB100); //reset all digital logic, except phy_reg mii_mgr_read(i, 9, &phy_val); phy_val &= ~(3<<8); //turn off 1000Base-T Advertisement mii_mgr_write(i, 9, phy_val); } #elif defined (RT6855A_ASIC_BOARD) RALINK_REG(RALINK_ETH_SW_BASE+0x3600) = 0x5e33b;//CPU Port6 Force Link 1G, FC ON RALINK_REG(RALINK_ETH_SW_BASE+0x0010) = 0xffffffe0;//CPU exist in port 6 RALINK_REG(RALINK_FRAME_ENGINE_BASE+0x1ec) = 0x0fffffff;//Set PSE should pause 4 tx ring as default RALINK_REG(RALINK_FRAME_ENGINE_BASE+0x1f0) = 0x0fffffff;//switch IOT more stable RALINK_REG(RALINK_ETH_SW_BASE+0x30f0) &= ~(3 << 4); ////keep rx/tx port clock ticking, disable internal clock-gating to avoid switch stuck /* * Reg 31: Page Control * Bit 15 => PortPageSel, 1=local, 0=global * Bit 14:12 => PageSel, local:0~3, global:0~4 * Reg16~30:Local/Global registers */ /*correct PHY setting J8.0*/ mii_mgr_read(0, 31, &rev); rev &= (0x0f); mii_mgr_write(1, 31, 0x4000); //global, page 4 mii_mgr_write(1, 16, 0xd4cc); mii_mgr_write(1, 17, 0x7444); mii_mgr_write(1, 19, 0x0112); mii_mgr_write(1, 21, 0x7160); mii_mgr_write(1, 22, 0x10cf); mii_mgr_write(1, 26, 0x0777); if(rev == 0){ mii_mgr_write(1, 25, 0x0102); mii_mgr_write(1, 29, 0x8641); } else{ mii_mgr_write(1, 25, 0x0212); mii_mgr_write(1, 29, 0x4640); } mii_mgr_write(1, 31, 0x2000); //global, page 2 mii_mgr_write(1, 21, 0x0655); mii_mgr_write(1, 22, 0x0fd3); mii_mgr_write(1, 23, 0x003d); mii_mgr_write(1, 24, 0x096e); mii_mgr_write(1, 25, 0x0fed); mii_mgr_write(1, 26, 0x0fc4); mii_mgr_write(1, 31, 0x1000); //global, page 1 mii_mgr_write(1, 17, 0xe7f8); mii_mgr_write(1, 31, 0xa000); //local, page 2 mii_mgr_write(0, 16, 0x0e0e); mii_mgr_write(1, 16, 0x0c0c); mii_mgr_write(2, 16, 0x0f0f); mii_mgr_write(3, 16, 0x1010); mii_mgr_write(4, 16, 0x0909); mii_mgr_write(0, 17, 0x0000); mii_mgr_write(1, 17, 0x0000); mii_mgr_write(2, 17, 0x0000); mii_mgr_write(3, 17, 0x0000); mii_mgr_write(4, 17, 0x0000); /*restart AN to make PHY work normal*/ for (i=0; i<5; i++) { mii_mgr_read(i, 0, &phy_val); phy_val |= 1<<9; //restart AN mii_mgr_write(i, 0, phy_val); } #endif #if defined (RT6855A_ASIC_BOARD) #if defined (P5_RGMII_TO_MAC_MODE) RALINK_REG(RALINK_ETH_SW_BASE+0x3500) = 0x5e33b; ////(P5, Force mode, Link Up, 1000Mbps, Full-Duplex, FC ON) #ifdef CONFIG_RTL8367B_SWITCH /* * TX/RX CLOCK Phase select * Change base PHY address of internal 5-port Ethernet PHY, need to reset Ethernet PHY block. */ RALINK_REG(RALINK_ETH_SW_BASE+0x7014) = 0x7000c; { // Reset phy i = RALINK_REG(RT2880_RSTCTRL_REG); i = i | RSTCTRL_EPHY_RST; RALINK_REG(RT2880_RSTCTRL_REG)= i; i = i & ~(RSTCTRL_EPHY_RST); RALINK_REG(RT2880_RSTCTRL_REG)= i; } #endif #elif defined (P5_MII_TO_MAC_MODE) RALINK_REG(RALINK_ETH_SW_BASE+0x3500) = 0x5e337; ////(P5, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) #elif defined (P5_MAC_TO_PHY_MODE) #ifdef CONFIG_RTL8367B_SWITCH RALINK_REG(RALINK_ETH_SW_BASE+0x7014) = 0x7000c;//need to improve { // Reset phy i = RALINK_REG(RT2880_RSTCTRL_REG); i = i | RSTCTRL_EPHY_RST; RALINK_REG(RT2880_RSTCTRL_REG)= i; i = i & ~(RSTCTRL_EPHY_RST); RALINK_REG(RT2880_RSTCTRL_REG)= i; } #else RALINK_REG(RALINK_ETH_SW_BASE+0x7014) = 0xc;//TX/RX CLOCK Phase select #endif enable_auto_negotiate(); #ifdef CONFIG_ICPLUS_GPHY if (isICPlusGigaPHY(1)) { printf("ICPLUS Phy1\n"); mii_mgr_read(MAC_TO_GIGAPHY_MODE_ADDR, 4, &phy_val); phy_val |= 1<<10; //enable pause ability mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 4, phy_val); mii_mgr_read(MAC_TO_GIGAPHY_MODE_ADDR, 0, &phy_val); phy_val |= 1<<9; //restart AN mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 0, phy_val); } #endif #ifdef CONFIG_MARVELL_GPHY if (isMarvellGigaPHY(1)) { printf("MARVELL Phy1\n"); mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 20, 0x0ce0); mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 0, 0x9140); } #endif #ifdef CONFIG_VTSS_GPHY if (isVtssGigaPHY(1)) { mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 31, 0x0001); //extended page mii_mgr_read(MAC_TO_GIGAPHY_MODE_ADDR, 28, &phy_val); printf("GE1 Vitesse Phy reg28 %x --> ",phy_val); phy_val |= (0x3<<12); // RGMII RX skew compensation= 2.0 ns phy_val &= ~(0x3<<14); // RGMII TX skew compensation= 0 ns printf("%x (without reset PHY)\n", phy_val); mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 28, phy_val); mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 31, 0); //main registers } #endif #elif defined (P5_RMII_TO_MAC_MODE) RALINK_REG(RALINK_ETH_SW_BASE+0x3500) = 0x5e337; ////(P5, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) #else /* Port 5 disabled */ RALINK_REG(RALINK_ETH_SW_BASE+0x3500) = 0x8000; ////(P5, Link Down) #endif // P5_RGMII_TO_MAC_MODE // #endif } #endif #if defined (RT6855_ASIC_BOARD) || defined (RT6855_FPGA_BOARD) || \ defined (RT6352_ASIC_BOARD) || defined (RT6352_FPGA_BOARD) || \ defined (RT71100_ASIC_BOARD) || defined (RT71100_FPGA_BOARD) void rt_gsw_init(void) { u32 i = 0; u32 phy_val=0; u32 rev=0; #if defined (RT6855_FPGA_BOARD) || defined (RT6352_FPGA_BOARD) || \ defined (RT71100_FPGA_BOARD) /*keep dump switch mode */ RALINK_REG(RALINK_ETH_SW_BASE+0x3000) = 0x5e333;//(P0, Force mode, Link Up, 10Mbps, Full-Duplex, FC ON) RALINK_REG(RALINK_ETH_SW_BASE+0x3100) = 0x5e333;//(P1, Force mode, Link Up, 10Mbps, Full-Duplex, FC ON) RALINK_REG(RALINK_ETH_SW_BASE+0x3200) = 0x5e333;//(P2, Force mode, Link Up, 10Mbps, Full-Duplex, FC ON) RALINK_REG(RALINK_ETH_SW_BASE+0x3300) = 0x5e333;//(P3, Force mode, Link Up, 10Mbps, Full-Duplex, FC ON) #if defined (RT6352_FPGA_BOARD) RALINK_REG(RALINK_ETH_SW_BASE+0x3400) = 0x5e337;//(P4, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) #else RALINK_REG(RALINK_ETH_SW_BASE+0x3400) = 0x5e333;//(P4, Force mode, Link Up, 10Mbps, Full-Duplex, FC ON) #endif RALINK_REG(RALINK_ETH_SW_BASE+0x3500) = 0x5e337;//(P5, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) /* In order to use 10M/Full on FPGA board. We configure phy capable to * 10M Full/Half duplex, so we can use auto-negotiation on PC side */ #if defined (RT6352_FPGA_BOARD) for(i=0;i<4;i++){ #else for(i=0;i<5;i++){ #endif mii_mgr_write(i, 4, 0x0461); //Capable of 10M Full/Half Duplex, flow control on/off mii_mgr_write(i, 0, 0xB100); //reset all digital logic, except phy_reg } #endif #if defined (PDMA_NEW) RALINK_REG(RT2880_SYSCFG1_REG) |= (0x1 << 8); //PCIE_RC_MODE=1 #endif #if defined (RT6352_FPGA_BOARD) || defined (RT6352_ASIC_BOARD) #if defined (P5_RGMII_TO_MAC_MODE) RALINK_REG(RALINK_ETH_SW_BASE+0x3500) = 0x5e33b; ////(P5, Force mode, Link Up, 1000Mbps, Full-Duplex, FC ON) RALINK_REG(0xb0000060) &= ~(1 << 9); //set RGMII to Normal mode RALINK_REG(RT2880_SYSCFG1_REG) &= ~(0x3<<12); ////GE1_MODE=RGMii Mode #elif defined (P5_MII_TO_MAC_MODE) RALINK_REG(RALINK_ETH_SW_BASE+0x3500) = 0x5e337; ////(P5, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) RALINK_REG(0xb0000060) &= ~(1 << 9); //set RGMII to Normal mode RALINK_REG(RT2880_SYSCFG1_REG) &= ~(0x3 << 12); //GE1_MODE=Mii Mode RALINK_REG(RT2880_SYSCFG1_REG) |= (0x1 << 12); #elif defined (P5_MAC_TO_PHY_MODE) RALINK_REG(0xb0000060) &= ~(1 << 9); //set RGMII to Normal mode RALINK_REG(0xb0000060) &= ~(3 << 7); //set MDIO to Normal mode RALINK_REG(RT2880_SYSCFG1_REG) &= ~(0x3 << 12); //GE1_MODE=RGMii Mode enable_auto_negotiate(); if (isICPlusGigaPHY(1)) { printf("ICPLUS Phy1\n"); mii_mgr_read(MAC_TO_GIGAPHY_MODE_ADDR, 4, &phy_val); phy_val |= 1<<10; //enable pause ability mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 4, phy_val); mii_mgr_read(MAC_TO_GIGAPHY_MODE_ADDR, 0, &phy_val); phy_val |= 1<<9; //restart AN mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 0, phy_val); } if (isMarvellGigaPHY(1)) { printf("MARVELL Phy1\n"); mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 20, 0x0ce0); #if defined (RT6352_FPGA_BOARD) mii_mgr_read(MAC_TO_GIGAPHY_MODE_ADDR, 9, &phy_val); phy_val &= ~(3<<8); //turn off 1000Base-T Advertisement mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 9, phy_val); #endif mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 0, 0x9140); } if (isVtssGigaPHY(1)) { mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 31, 0x0001); //extended page mii_mgr_read(MAC_TO_GIGAPHY_MODE_ADDR, 28, &phy_val); printf("GE1 Vitesse Phy reg28 %x --> ",phy_val); phy_val |= (0x3<<12); // RGMII RX skew compensation= 2.0 ns phy_val &= ~(0x3<<14); // RGMII TX skew compensation= 0 ns printf("%x (without reset PHY)\n", phy_val); mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 28, phy_val); mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 31, 0); //main registers } #elif defined (P5_RMII_TO_MAC_MODE) RALINK_REG(RALINK_ETH_SW_BASE+0x3500) = 0x5e337; ////(P5, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) RALINK_REG(0xb0000060) &= ~(1 << 9); //set RGMII to Normal mode RALINK_REG(RT2880_SYSCFG1_REG) &= ~(0x3 << 12); //GE1_MODE=Mii Mode RALINK_REG(RT2880_SYSCFG1_REG) |= (0x2 << 12); #else /* Port 5 disabled */ RALINK_REG(RALINK_ETH_SW_BASE+0x3500) = 0x8000; ////(P5, Link Down) #endif // P5_RGMII_TO_MAC_MODE // #endif #if defined (P4_RGMII_TO_MAC_MODE) RALINK_REG(RALINK_ETH_SW_BASE+0x3400) = 0x5e33b; ////(P4, Force mode, Link Up, 1000Mbps, Full-Duplex, FC ON) RALINK_REG(0xb0000060) &= ~(1 << 10); //set RGMII to Normal mode RALINK_REG(RT2880_SYSCFG1_REG) &= ~(0x3<<14); ////GE2_MODE=RGMii Mode #elif defined (P4_MII_TO_MAC_MODE) RALINK_REG(RALINK_ETH_SW_BASE+0x3400) = 0x5e337; ////(P4, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) RALINK_REG(0xb0000060) &= ~(1 << 10); //set RGMII2 to Normal mode RALINK_REG(RT2880_SYSCFG1_REG) &= ~(0x3 << 14); //GE2_MODE=Mii Mode RALINK_REG(RT2880_SYSCFG1_REG) |= (0x1 << 14); #elif defined (P4_MAC_TO_PHY_MODE) RALINK_REG(0xb0000060) &= ~(1 << 10); //set RGMII2 to Normal mode RALINK_REG(0xb0000060) &= ~(3 << 7); //set MDIO to Normal mode RALINK_REG(RT2880_SYSCFG1_REG) &= ~(0x3<<14); ////GE2_MODE=RGMii Mode #if defined (RT6352_FPGA_BOARD) mii_mgr_write(4, 4, 0x05e1); //Capable of 100M Full/Half Duplex, flow control on/off mii_mgr_write(4, 0, 0xB100); //reset all digital logic, except phy_reg #endif enable_auto_negotiate(); if (isICPlusGigaPHY(2)) { printf("ICPLUS Phy2\n"); mii_mgr_read(MAC_TO_GIGAPHY_MODE_ADDR2, 4, &phy_val); phy_val |= 1<<10; //enable pause ability mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR2, 4, phy_val); mii_mgr_read(MAC_TO_GIGAPHY_MODE_ADDR2, 0, &phy_val); phy_val |= 1<<9; //restart AN mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR2, 0, phy_val); } if (isMarvellGigaPHY(2)) { printf("MARVELL Phy2\n"); mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR2, 20, 0x0ce0); #if defined (RT6352_FPGA_BOARD) mii_mgr_read(MAC_TO_GIGAPHY_MODE_ADDR2, 9, &phy_val); phy_val &= ~(3<<8); //turn off 1000Base-T Advertisement mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR2, 9, phy_val); #endif mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR2, 0, 0x9140); } if (isVtssGigaPHY(2)) { mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR2, 31, 0x0001); //extended page mii_mgr_read(MAC_TO_GIGAPHY_MODE_ADDR2, 28, &phy_val); printf("GE1 Vitesse Phy reg28 %x --> ",phy_val); phy_val |= (0x3<<12); // RGMII RX skew compensation= 2.0 ns phy_val &= ~(0x3<<14); // RGMII TX skew compensation= 0 ns printf("%x (without reset PHY)\n", phy_val); mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR2, 28, phy_val); mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR2, 31, 0); //main registers } #elif defined (P4_RMII_TO_MAC_MODE) RALINK_REG(RALINK_ETH_SW_BASE+0x3400) = 0x5e337; ////(P4, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) RALINK_REG(0xb0000060) &= ~(1 << 10); //set RGMII2 to Normal mode RALINK_REG(RT2880_SYSCFG1_REG) &= ~(0x3 << 14); //GE2_MODE=Mii Mode RALINK_REG(RT2880_SYSCFG1_REG) |= (0x2 << 14); #else /* Port 4 disabled */ #endif // P4_RGMII_TO_MAC_MODE // } #endif #if defined (RT6855A_FPGA_BOARD) void rt6855A_eth_gpio_reset(void) { u8 ether_gpio = 12; /* Load the ethernet gpio value to reset Ethernet PHY */ ra_or(RALINK_PIO_BASE, 1<<(ether_gpio<<1)); ra_or(RALINK_PIO_BASE+0x14, 1< ",phy_val); phy_val |= (0x3<<12); // RGMII RX skew compensation= 2.0 ns phy_val &= ~(0x3<<14); // RGMII TX skew compensation= 0 ns printf("%x (without reset PHY)\n", phy_val); mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 28, phy_val); mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 31, 0); //main registers } #elif defined (P5_RMII_TO_MAC_MODE) /* Reserved */ RALINK_REG(0xb0000060) &= ~(1 << 9); //set RGMII to Normal mode RALINK_REG(RALINK_ETH_SW_BASE+0x00C8) &= ~(1<<29); //disable port 5 auto-polling RALINK_REG(RALINK_ETH_SW_BASE+0x00C8) &= ~(0x3fff); RALINK_REG(RALINK_ETH_SW_BASE+0x00C8) |= 0x3ffd; //force 100M full duplex #if defined (RT3352_ASIC_BOARD) RALINK_REG(RT2880_SYSCFG1_REG) &= ~(0x3 << 12); //GE1_MODE=RvMii Mode RALINK_REG(RT2880_SYSCFG1_REG) |= (0x2 << 12); #endif #else /* Port 5 disabled */ #if defined (RT3052_ASIC_BOARD) RALINK_REG(RALINK_ETH_SW_BASE+0x00C8) &= ~(1 << 29); //port5 auto polling disable RALINK_REG(0xb0000060) |= (1 << 7); //set MDIO to GPIO mode (GPIO22-GPIO23) RALINK_REG(0xb0000060) |= (1 << 9); //set RGMII to GPIO mode (GPIO41-GPIO50) RALINK_REG(0xb0000674) = 0xFFF; //GPIO41-GPIO50 output mode RALINK_REG(0xb000067C) = 0x0; //GPIO41-GPIO50 output low #elif defined (RT3352_ASIC_BOARD) RALINK_REG(RALINK_ETH_SW_BASE+0x00C8) &= ~(1 << 29); //port5 auto polling disable RALINK_REG(0xb0000060) |= (1 << 7); //set MDIO to GPIO mode (GPIO22-GPIO23) RALINK_REG(0xb0000624) = 0xC0000000; //GPIO22-GPIO23 output mode RALINK_REG(0xb000062C) = 0xC0000000; //GPIO22-GPIO23 output high RALINK_REG(0xb0000060) |= (1 << 9); //set RGMII to GPIO mode (GPIO24-GPIO35) RALINK_REG(0xb000064C) = 0xFFF; //GPIO24-GPIO35 output mode RALINK_REG(0xb0000654) = 0xFFF; //GPIO24-GPIO35 output high #endif #endif // P5_RGMII_TO_MAC_MODE // #define RSTCTRL_EPHY_RST (1<<24) /* We shall prevent modifying PHY registers if it is FPGA mode */ #if defined (RT3052_ASIC_BOARD) || defined (RT3352_ASIC_BOARD) || defined (RT5350_ASIC_BOARD) #if defined (RT3052_ASIC_BOARD) rw_rf_reg(0, 0, &phy_val); phy_val = phy_val >> 4; if(phy_val > 0x5) { rw_rf_reg(0, 26, &phy_val); phy_val2 = (phy_val | (0x3 << 5)); rw_rf_reg(1, 26, &phy_val2); // reset phy i = RALINK_REG(RT2880_RSTCTRL_REG); i = i | RSTCTRL_EPHY_RST; RALINK_REG(RT2880_RSTCTRL_REG)= i; i = i & ~(RSTCTRL_EPHY_RST); RALINK_REG(RT2880_RSTCTRL_REG)= i; rw_rf_reg(1, 26, &phy_val); //select local register mii_mgr_write(0, 31, 0x8000); for(i=0;i<5;i++){ mii_mgr_write(i, 26, 0x1600); //TX10 waveform coefficient //LSB=0 disable PHY mii_mgr_write(i, 29, 0x7058); //TX100/TX10 AD/DA current bias mii_mgr_write(i, 30, 0x0018); //TX100 slew rate control } //select global register mii_mgr_write(0, 31, 0x0); mii_mgr_write(0, 1, 0x4a40); //enlarge agcsel threshold 3 and threshold 2 mii_mgr_write(0, 2, 0x6254); //enlarge agcsel threshold 5 and threshold 4 mii_mgr_write(0, 3, 0xa17f); //enlarge agcsel threshold 6 //#define ENABLE_LDPS #if defined (ENABLE_LDPS) mii_mgr_write(0, 12, 0x7eaa); mii_mgr_write(0, 22, 0x252f); //tune TP_IDL tail and head waveform, enable power down slew rate control #else mii_mgr_write(0, 12, 0x0); mii_mgr_write(0, 22, 0x052f); #endif mii_mgr_write(0, 14, 0x65); //longer TP_IDL tail length mii_mgr_write(0, 16, 0x0684); //increased squelch pulse count threshold. mii_mgr_write(0, 17, 0x0fe0); //set TX10 signal amplitude threshold to minimum mii_mgr_write(0, 18, 0x40ba); //set squelch amplitude to higher threshold mii_mgr_write(0, 27, 0x2fce); //set PLL/Receive bias current are calibrated mii_mgr_write(0, 28, 0xc410); //change PLL/Receive bias current to internal(RT3350) mii_mgr_write(0, 29, 0x598b); //change PLL bias current to internal(RT3052_MP3) mii_mgr_write(0, 31, 0x8000); //select local register for(i=0;i<5;i++){ //LSB=1 enable PHY mii_mgr_read(i, 26, &phy_val); phy_val |= 0x0001; mii_mgr_write(i, 26, phy_val); } } else { //select local register mii_mgr_write(0, 31, 0x8000); for(i=0;i<5;i++){ mii_mgr_write(i, 26, 0x1600); //TX10 waveform coefficient //LSB=0 disable PHY mii_mgr_write(i, 29, 0x7058); //TX100/TX10 AD/DA current bias mii_mgr_write(i, 30, 0x0018); //TX100 slew rate control } //select global register mii_mgr_write(0, 31, 0x0); mii_mgr_write(0, 1, 0x4a40); //enlarge agcsel threshold 3 and threshold 2 mii_mgr_write(0, 2, 0x6254); //enlarge agcsel threshold 5 and threshold 4 mii_mgr_write(0, 3, 0xa17f); //enlarge agcsel threshold 6 mii_mgr_write(0, 14, 0x65); //longer TP_IDL tail length mii_mgr_write(0, 16, 0x0684); //increased squelch pulse count threshold. mii_mgr_write(0, 17, 0x0fe0); //set TX10 signal amplitude threshold to minimum mii_mgr_write(0, 18, 0x40ba); //set squelch amplitude to higher threshold mii_mgr_write(0, 22, 0x052f); //tune TP_IDL tail and head waveform mii_mgr_write(0, 27, 0x2fce); //set PLL/Receive bias current are calibrated mii_mgr_write(0, 28, 0xc410); //change PLL/Receive bias current to internal(RT3350) mii_mgr_write(0, 29, 0x598b); //change PLL bias current to internal(RT3052_MP3) mii_mgr_write(0, 31, 0x8000); //select local register for(i=0;i<5;i++){ //LSB=1 enable PHY mii_mgr_read(i, 26, &phy_val); phy_val |= 0x0001; mii_mgr_write(i, 26, phy_val); } } #elif defined (RT3352_ASIC_BOARD) //PHY IOT // reset phy i = RALINK_REG(RT2880_RSTCTRL_REG); i = i | RSTCTRL_EPHY_RST; RALINK_REG(RT2880_RSTCTRL_REG) = i; i = i & ~(RSTCTRL_EPHY_RST); RALINK_REG(RT2880_RSTCTRL_REG) = i; //select local register mii_mgr_write(0, 31, 0x8000); for(i=0;i<5;i++){ mii_mgr_write(i, 26, 0x1600); //TX10 waveform coefficient //LSB=0 disable PHY mii_mgr_write(i, 29, 0x7016); //TX100/TX10 AD/DA current bias mii_mgr_write(i, 30, 0x0038); //TX100 slew rate control } //select global register mii_mgr_write(0, 31, 0x0); mii_mgr_write(0, 1, 0x4a40); //enlarge agcsel threshold 3 and threshold 2 mii_mgr_write(0, 2, 0x6254); //enlarge agcsel threshold 5 and threshold 4 mii_mgr_write(0, 3, 0xa17f); //enlarge agcsel threshold 6 mii_mgr_write(0, 12, 0x7eaa); mii_mgr_write(0, 14, 0x65); //longer TP_IDL tail length mii_mgr_write(0, 16, 0x0684); //increased squelch pulse count threshold. mii_mgr_write(0, 17, 0x0fe0); //set TX10 signal amplitude threshold to minimum mii_mgr_write(0, 18, 0x40ba); //set squelch amplitude to higher threshold mii_mgr_write(0, 22, 0x253f); //tune TP_IDL tail and head waveform, enable power down slew rate control mii_mgr_write(0, 27, 0x2fda); //set PLL/Receive bias current are calibrated mii_mgr_write(0, 28, 0xc410); //change PLL/Receive bias current to internal(RT3350) mii_mgr_write(0, 29, 0x598b); //change PLL bias current to internal(RT3052_MP3) mii_mgr_write(0, 31, 0x8000); //select local register for(i=0;i<5;i++){ //LSB=1 enable PHY mii_mgr_read(i, 26, &phy_val); phy_val |= 0x0001; mii_mgr_write(i, 26, phy_val); } #elif defined (RT5350_ASIC_BOARD) //PHY IOT // reset phy i = RALINK_REG(RT2880_RSTCTRL_REG); i = i | RSTCTRL_EPHY_RST; RALINK_REG(RT2880_RSTCTRL_REG) = i; i = i & ~(RSTCTRL_EPHY_RST); RALINK_REG(RT2880_RSTCTRL_REG) = i; //select local register mii_mgr_write(0, 31, 0x8000); for(i=0;i<5;i++){ mii_mgr_write(i, 26, 0x1600); //TX10 waveform coefficient //LSB=0 disable PHY mii_mgr_write(i, 29, 0x7015); //TX100/TX10 AD/DA current bias mii_mgr_write(i, 30, 0x0038); //TX100 slew rate control } //select global register mii_mgr_write(0, 31, 0x0); mii_mgr_write(0, 1, 0x4a40); //enlarge agcsel threshold 3 and threshold 2 mii_mgr_write(0, 2, 0x6254); //enlarge agcsel threshold 5 and threshold 4 mii_mgr_write(0, 3, 0xa17f); //enlarge agcsel threshold 6 mii_mgr_write(0, 12, 0x7eaa); mii_mgr_write(0, 14, 0x65); //longer TP_IDL tail length mii_mgr_write(0, 16, 0x0684); //increased squelch pulse count threshold. mii_mgr_write(0, 17, 0x0fe0); //set TX10 signal amplitude threshold to minimum mii_mgr_write(0, 18, 0x40ba); //set squelch amplitude to higher threshold mii_mgr_write(0, 22, 0x253f); //tune TP_IDL tail and head waveform, enable power down slew rate control mii_mgr_write(0, 27, 0x2fda); //set PLL/Receive bias current are calibrated mii_mgr_write(0, 28, 0xc410); //change PLL/Receive bias current to internal(RT3350) mii_mgr_write(0, 29, 0x598b); //change PLL bias current to internal(RT3052_MP3) mii_mgr_write(0, 31, 0x8000); //select local register for(i=0;i<5;i++){ //LSB=1 enable PHY mii_mgr_read(i, 26, &phy_val); phy_val |= 0x0001; mii_mgr_write(i, 26, phy_val); } #elif defined (RT6855_ASIC_BOARD) /* TBD */ #elif defined (RT6352_ASIC_BOARD) /* TBD */ #elif defined (RT71100_ASIC_BOARD) /* TBD */ #else #error "Chip is not supported" #endif // RT3052_ASIC_BOARD // #endif // RT3052_ASIC_BOARD || RT3352_ASIC_BOARD // } #endif static int rt2880_eth_setup(struct eth_device* dev) { u32 i; u32 regValue; u16 wTmp; uchar *temp; printf("\n Waitting for RX_DMA_BUSY status Start... "); while(1) if(!isDMABusy(dev)) break; printf("done\n\n"); // GigaPhy #if defined (MAC_TO_GIGAPHY_MODE) enable_auto_negotiate(); if (isMarvellGigaPHY(1)) { #if defined (RT3883_FPGA_BOARD) mii_mgr_read(MAC_TO_GIGAPHY_MODE_ADDR, 9, ®Value); regValue &= ~(3<<8); //turn off 1000Base-T Advertisement mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 9, regValue); #endif printf("\n Reset MARVELL phy\n"); mii_mgr_read(MAC_TO_GIGAPHY_MODE_ADDR, 20, ®Value); regValue |= 1<<7; //Add delay to RX_CLK for RXD Outputs mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 20, regValue); mii_mgr_read(MAC_TO_GIGAPHY_MODE_ADDR, 0, ®Value); regValue |= 1<<15; //PHY Software Reset mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 0, regValue); } if (isVtssGigaPHY(1)) { mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 31, 1); mii_mgr_read(MAC_TO_GIGAPHY_MODE_ADDR, 28, ®Value); printf("GE1 Vitesse Phy reg28 %x --> ",regValue); regValue |= (0x3<<12); regValue &= ~(0x3<<14); printf("%x (without reset PHY)\n", regValue); mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 28, regValue); mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 31, 0); /* mii_mgr_read(MAC_TO_GIGAPHY_MODE_ADDR, 0, ®Value); regValue |= 1<<15; //PHY Software Reset mii_mgr_write(MAC_TO_GIGAPHY_MODE_ADDR, 0, regValue); */ } // RT305x/RT335x + EmbeddedSW #elif defined (RT3052_ASIC_BOARD) || defined (RT3052_FPGA_BOARD) || \ defined (RT3352_ASIC_BOARD) || defined (RT3352_FPGA_BOARD) || \ defined (RT5350_ASIC_BOARD) || defined (RT5350_FPGA_BOARD) || \ defined (RT6855_ASIC_BOARD) || defined (RT6855_FPGA_BOARD) || \ defined (RT6855A_ASIC_BOARD) || defined (RT6855A_FPGA_BOARD) || \ defined (RT6352_ASIC_BOARD) || defined (RT6352_FPGA_BOARD) || \ defined (RT71100_ASIC_BOARD) || defined (RT71100_FPGA_BOARD) #if defined(P5_RGMII_TO_MAC_MODE) && defined(CONFIG_VTSS_GPHY) printf("\n Vitesse giga Mac support \n"); ResetSWusingGPIOx(); udelay(125000); vtss_init(); #endif // RT288x/RT388x + GigaSW #elif defined (MAC_TO_VITESSE_MODE) printf("\n Vitesse giga Mac support \n"); RALINK_REG(MDIO_CFG)=cpu_to_le32((u32)(0x1F01DC01)); ResetSWusingGPIOx(); udelay(125000); vtss_init(); // RT288x/RT388x + (10/100 Switch or 100PHY) #elif defined (MAC_TO_100SW_MODE) || defined (MAC_TO_100PHY_MODE) #if defined (RT3883_FPGA_BOARD) || defined (RT3883_ASIC_BOARD) regValue = RALINK_REG(RT2880_SYSCFG1_REG); regValue &= ~(0xF << 12); /* 0=RGMII, 1=MII, 2=RvMii */ #if defined (RT3883_USE_GE2) #if defined (GE_MII_FORCE_100) || defined (GE_MII_AN) regValue |= (0x1 << 14); // GE2 MII Mode #elif defined (GE_RVMII_FORCE_100) regValue |= (0x2 << 14); // GE2 RvMII Mode #endif #else //GE1 #if defined (GE_MII_FORCE_100) || defined (GE_MII_AN) regValue |= (0x1 << 12); // GE1 MII Mode #elif defined (GE_RVMII_FORCE_100) regValue |= (0x2 << 12); // GE1 RvMII Mode #endif #endif // RT3883_USE_GE2 // RALINK_REG(RT2880_SYSCFG1_REG)=regValue; #endif // #if defined (RT3883_FPGA_BOARD) || defined (RT3883_ASIC_BOARD) // #if defined (MAC_TO_100SW_MODE) // due to the flaws of RT2880 GMAC implementation (or IC+ SW ?) we use the // fixed capability instead of auto-polling. RALINK_REG(MDIO_CFG)=cpu_to_le32((u32)(0x1F01BC01)); //force cpu port is 100F mii_mgr_write(29, 22, 0x8420); #elif defined (MAC_TO_100PHY_MODE) enable_auto_negotiate(); #endif #endif // MAC_TO_GIGAPHY_MODE // LANWANPartition(); #ifdef RT3883_USE_GE2 wTmp = (u16)dev->enetaddr[0]; regValue = (wTmp << 8) | dev->enetaddr[1]; RALINK_REG(GDMA2_MAC_ADRH)=regValue; wTmp = (u16)dev->enetaddr[2]; regValue = (wTmp << 8) | dev->enetaddr[3]; regValue = regValue << 16; wTmp = (u16)dev->enetaddr[4]; regValue |= (wTmp<<8) | dev->enetaddr[5]; RALINK_REG(GDMA2_MAC_ADRL)=regValue; regValue = RALINK_REG(GDMA2_FWD_CFG); if(is_internal_loopback_test) { regValue = regValue & GDM_UFRC_P_CPU; //Broad-cast MAC address frames forward to CPU regValue = regValue & GDM_BFRC_P_CPU; //Multi-cast MAC address frames forward to CPU regValue = regValue & GDM_MFRC_P_CPU; //Other MAC address frames forward to CPU regValue = regValue & GDM_OFRC_P_CPU; //All Drop regValue = regValue | GDM_UFRC_P_DROP; regValue = regValue | GDM_BFRC_P_DROP; regValue = regValue | GDM_MFRC_P_DROP; regValue = regValue | GDM_OFRC_P_DROP; printf("\n At interloopback mode, so all drop !\n"); } else { regValue = regValue & GDM_UFRC_P_CPU; //Broad-cast MAC address frames forward to CPU regValue = regValue & GDM_BFRC_P_CPU; //Multi-cast MAC address frames forward to CPU regValue = regValue & GDM_MFRC_P_CPU; //Other MAC address frames forward to CPU regValue = regValue & GDM_OFRC_P_CPU; } RALINK_REG(GDMA2_FWD_CFG)=regValue; udelay(500); regValue = RALINK_REG(GDMA2_FWD_CFG); #else // non RT3883_USE_GE2 // /* Set MAC address. */ wTmp = (u16)dev->enetaddr[0]; regValue = (wTmp << 8) | dev->enetaddr[1]; #if defined (RT5350_ASIC_BOARD) || defined (RT5350_FPGA_BOARD) RALINK_REG(SDM_MAC_ADRH)=regValue; // printf("\n dev->iobase=%08X,SDM_MAC_ADRH=%08X\n",dev->iobase,regValue); #else RALINK_REG(GDMA1_MAC_ADRH)=regValue; // printf("\n dev->iobase=%08X,GDMA1_MAC_ADRH=%08X\n ",dev->iobase, regValue); #endif wTmp = (u16)dev->enetaddr[2]; regValue = (wTmp << 8) | dev->enetaddr[3]; regValue = regValue << 16; wTmp = (u16)dev->enetaddr[4]; regValue |= (wTmp<<8) | dev->enetaddr[5]; #if defined (RT5350_ASIC_BOARD) || defined (RT5350_FPGA_BOARD) RALINK_REG(SDM_MAC_ADRL)=regValue; // printf("\n dev->iobase=%08X,SDM_MAC_ADRL=%08X\n",dev->iobase,regValue); #else RALINK_REG(GDMA1_MAC_ADRL)=regValue; // printf("\n dev->iobase=%08X,GDMA1_MAC_ADRL=%08X\n ",dev->iobase, regValue); #endif //printf("\n rt2880_eth_init,set MAC reg to [%02X:%02X:%02X:%02X:%02X:%02X]\n", // dev->enetaddr[0],dev->enetaddr[1],dev->enetaddr[2], // dev->enetaddr[3],dev->enetaddr[4],dev->enetaddr[5]); #if ! defined (RT5350_ASIC_BOARD) && ! defined (RT5350_FPGA_BOARD) regValue = RALINK_REG(GDMA1_FWD_CFG); //printf("\n old,GDMA1_FWD_CFG = %08X \n",regValue); #if defined (PDMA_NEW) //frames destination port = port 0 CPU regValue = regValue & ~(0x7); #else //Uni-cast frames forward to CPU regValue = regValue & GDM_UFRC_P_CPU; //Broad-cast MAC address frames forward to CPU regValue = regValue & GDM_BFRC_P_CPU; //Multi-cast MAC address frames forward to CPU regValue = regValue & GDM_MFRC_P_CPU; //Other MAC address frames forward to CPU regValue = regValue & GDM_OFRC_P_CPU; #endif RALINK_REG(GDMA1_FWD_CFG)=regValue; udelay(500); regValue = RALINK_REG(GDMA1_FWD_CFG); //printf("\n new,GDMA1_FWD_CFG = %08X \n",regValue); regValue = 0x80504000; RALINK_REG(PSE_FQFC_CFG)=regValue; #endif // RT3883_USE_GE2 // #endif #ifdef RALINK_GDMA_DUP_TX_RING_TEST_FUN tx_ring1 = KSEG1ADDR((ulong)&tx_ring1_cache[0]); #endif #ifdef RALINK_GDMA_SCATTER_TEST_FUN u32 kk; if(header_payload_scatter_en == ENABLE) { temp = &PKT_HEADER_Buf[0] + (PKTALIGN - 1); temp -= (ulong)temp % PKTALIGN; for (i = 0; i < PKTBUFSRX; i++) { pkthdrbuf[i] = temp + (i*PKTSIZE_ALIGN) + sdp0_alig_16n_x; kk = (u32)pkthdrbuf[i]; printf("\n pkthdrbuf[%d]=0x%08X,16N alignment= %d \n",i,kk, (kk % FLANK_TEST_SPX_ALIGNMENT)); } } #endif // RALINK_GDMA_SCATTER_TEST_FUN // for (i = 0; i < NUM_RX_DESC; i++) { temp = memset((void *)&rx_ring[i],0,16); rx_ring[i].rxd_info2.DDONE_bit = 0; #ifdef RALINK_GDMA_SCATTER_TEST_FUN if(header_payload_scatter_en == ENABLE) { NetRxPackets[i]+= sdp1_alig_16n_x; rx_ring[i].rxd_info1.PDP0 = cpu_to_le32(phys_to_bus((u32) pkthdrbuf[i])); rx_ring[i].rxd_info3.PDP1 = cpu_to_le32(phys_to_bus((u32) (NetRxPackets[i]))); rx_ring[i].rxd_info2.LS0= 0; rx_ring[i].rxd_info2.LS1= 1; printf("\n rx_ring[%d].rxd_info3.PDP1 = 0x%08X",i,rx_ring[i].rxd_info3.PDP1); } else #endif // RALINK_GDMA_SCATTER_TEST_FUN // { BUFFER_ELEM *buf; buf = rt2880_free_buf_entry_dequeue(&rt2880_free_buf_list); NetRxPackets[i] = buf->pbuf; #if defined (RX_SCATTER_GATTER_DMA) rx_ring[i].rxd_info2.LS0= 0; rx_ring[i].rxd_info2.PLEN0= PKTSIZE_ALIGN; #else rx_ring[i].rxd_info2.LS0= 1; #endif rx_ring[i].rxd_info1.PDP0 = cpu_to_le32(phys_to_bus((u32) NetRxPackets[i])); } } for (i=0; i < NUM_TX_DESC; i++) { temp = memset((void *)&tx_ring0[i],0,16); #ifdef RALINK_MUTI_TX_DESCRIPTOR_TEST_FUN //tx_ring0[i].txd_info2.LS1_bit = 1; #else tx_ring0[i].txd_info2.LS0_bit = 1; #endif tx_ring0[i].txd_info2.DDONE_bit = 1; /* PN: * 0:CPU * 1:GE1 * 2:GE2 (for RT2883) * 6:PPE * 7:Discard */ if (internal_loopback_test == INTERNAL_LOOPBACK_ENABLE) { #if defined (PDMA_NEW) tx_ring0[i].txd_info4.FP_BMAP=0x40; #else tx_ring0[i].txd_info4.PN = 0; printf("\n Ring0,Set TX DMA loop back to CPU !! \n"); #endif } else { #ifdef RT3883_USE_GE2 tx_ring0[i].txd_info4.PN = 2; #else #if defined (PDMA_NEW) tx_ring0[i].txd_info4.FP_BMAP=0x0; #else tx_ring0[i].txd_info4.PN = 1; #endif #endif } } #ifdef RALINK_GDMA_DUP_TX_RING_TEST_FUN for (i=0; i < NUM_TX_DESC; i++) { temp = memset(&tx_ring1[i],0,16); #ifdef RALINK_MUTI_TX_DESCRIPTOR_TEST_FUN //tx_ring1[i].txd_info2.LS1_bit = 1; #else tx_ring1[i].txd_info2.LS0_bit = 1; #endif tx_ring1[i].txd_info2.DDONE_bit = 1; /* PN: * 0:CPU * 1:GE1 * 2:GE2 (for RT2883) * 6:PPE * 7:Discard */ if (internal_loopback_test == INTERNAL_LOOPBACK_ENABLE) { #if defined (PDMA_NEW) tx_ring0[i].txd_info4.FP_BMAP=0x40; #else tx_ring1[i].txd_info4.PN = 0; #endif printf("\n Ring1,Set TX DMA loop back to CPU ! \n"); } else { #ifdef RT3883_USE_GE2 tx_ring1[i].txd_info4.PN = 2; #else #if defined (PDMA_NEW) tx_ring0[i].txd_info4.FP_BMAP=0x0; #else tx_ring1[i].txd_info4.PN = 1; #endif #endif } tx_ring1[i].txd_info4.QN = 0; } #endif // RALINK_GDMA_DUP_TX_RING_TEST_FUN // rxRingSize = NUM_RX_DESC; txRingSize = NUM_TX_DESC; rx_dma_owner_idx0 = 0; rx_wants_alloc_idx0 = (NUM_RX_DESC - 1); tx_cpu_owner_idx0 = 0; tx_cpu_owner_idx1 = 0; regValue=RALINK_REG(PDMA_GLO_CFG); udelay(100); #ifdef RALINK_GDMA_SCATTER_TEST_FUN if(header_payload_scatter_en == ENABLE) { regValue &= 0x0000FFFF; regValue |= (rt2880_hdrlen << 16); RALINK_REG(PDMA_GLO_CFG)=regValue; udelay(500); regValue=RALINK_REG(PDMA_GLO_CFG); printf("\n Default of Header Length = 20 \n"); printf("\n PDMA_GLO_CFG=%08X \n",regValue); } else #endif // RALINK_GDMA_SCATTER_TEST_FUN // { regValue &= 0x0000FFFF; RALINK_REG(PDMA_GLO_CFG)=regValue; udelay(500); regValue=RALINK_REG(PDMA_GLO_CFG); #ifndef RT3052_PHY_TEST printf("\n Header Payload scatter function is Disable !! \n"); #endif } #ifdef RALINK_GDMA_DUP_TX_RING_TEST_FUN RALINK_REG(TX_BASE_PTR1)=phys_to_bus((u32) &tx_ring1[0]); RALINK_REG(TX_MAX_CNT1)=cpu_to_le32((u32) NUM_TX_DESC); RALINK_REG(TX_CTX_IDX1)=cpu_to_le32((u32) tx_cpu_owner_idx1); #endif // RALINK_GDMA_DUP_TX_RING_TEST_FUN // /* Tell the adapter where the TX/RX rings are located. */ RALINK_REG(RX_BASE_PTR0)=phys_to_bus((u32) &rx_ring[0]); //printf("\n rx_ring=%08X ,RX_BASE_PTR0 = %08X \n",&rx_ring[0],RALINK_REG(RX_BASE_PTR0)); RALINK_REG(TX_BASE_PTR0)=phys_to_bus((u32) &tx_ring0[0]); //printf("\n tx_ring0=%08X, TX_BASE_PTR0 = %08X \n",&tx_ring0[0],RALINK_REG(TX_BASE_PTR0)); RALINK_REG(RX_MAX_CNT0)=cpu_to_le32((u32) NUM_RX_DESC); RALINK_REG(TX_MAX_CNT0)=cpu_to_le32((u32) NUM_TX_DESC); RALINK_REG(TX_CTX_IDX0)=cpu_to_le32((u32) tx_cpu_owner_idx0); RALINK_REG(PDMA_RST_IDX)=cpu_to_le32((u32)RST_DTX_IDX0); RALINK_REG(RX_CALC_IDX0)=cpu_to_le32((u32) (NUM_RX_DESC - 1)); RALINK_REG(PDMA_RST_IDX)=cpu_to_le32((u32)RST_DRX_IDX0); udelay(500); START_ETH(dev); return 1; } static int rt2880_eth_send(struct eth_device* dev, volatile void *packet, int length) { int status = -1; int i; int retry_count = 0, temp; #ifdef RALINK_MUTI_TX_DESCRIPTOR_TEST_FUN int bk_len = 0; u8 *sdp1_seg_p; u32 *txd_info; #endif #ifdef RALINK_GDMA_DUP_TX_RING_TEST_FUN static int tingx_is_free = 0; #endif #if defined (RT3052_FPGA_BOARD) || defined (RT3052_ASIC_BOARD) || \ defined (RT3352_ASIC_BOARD) || defined (RT3352_FPGA_BOARD) || \ defined (RT5350_ASIC_BOARD) || defined (RT5350_FPGA_BOARD) || \ defined (RT3883_ASIC_BOARD) || defined (RT3883_FPGA_BOARD) || \ defined (RT6855_ASIC_BOARD) || defined (RT6855_FPGA_BOARD) || \ defined (RT6855A_ASIC_BOARD) || defined (RT6855A_FPGA_BOARD) || \ defined (RT6352_ASIC_BOARD) || defined (RT6352_FPGA_BOARD) || \ defined (RT71100_ASIC_BOARD) || defined (RT71100_FPGA_BOARD) char *p=(char *)packet; #endif Retry: if (retry_count > 10) { return (status); } if (length <= 0) { printf("%s: bad packet size: %d\n", dev->name, length); return (status); } #if defined (RT3052_FPGA_BOARD) || defined (RT3052_ASIC_BOARD) || \ defined (RT3352_ASIC_BOARD) || defined (RT3352_FPGA_BOARD) || \ defined (RT5350_ASIC_BOARD) || defined (RT5350_FPGA_BOARD) || \ defined (RT3883_ASIC_BOARD) || defined (RT3883_FPGA_BOARD) || \ defined (RT6855_ASIC_BOARD) || defined (RT6855_FPGA_BOARD) || \ defined (RT6855A_ASIC_BOARD) || defined (RT6855A_FPGA_BOARD) #define PADDING_LENGTH 60 if (length < PADDING_LENGTH) { // print_packet(packet,length); for(i=0;i= TOUT_LOOP) { //printf("%s: TX DMA is Busy !! TX desc is Empty!\n", dev->name); goto Done; } } //dump_reg(); temp = RALINK_REG(TX_DTX_IDX0); if(temp == (tx_cpu_owner_idx0+1) % NUM_TX_DESC) { puts(" @ "); goto Done; } #ifdef RALINK_GDMA_DUP_TX_RING_TEST_FUN if(tx_ring0[tx_cpu_owner_idx0].txd_info2.DDONE_bit == 1 && tx_ring1[tx_cpu_owner_idx1].txd_info2.DDONE_bit == 1) { if(tingx_is_free == 0 ) { printf("\n Sent packet with ring1\n"); tingx_is_free = 1; } else { printf("\n Sent packet with ring0\n"); tingx_is_free = 0; } } else if(tx_ring0[tx_cpu_owner_idx0].txd_info2.DDONE_bit == 1) { //printf("\n Sent packet with ring0\n"); tingx_is_free = 0; } else { //printf("\n Sent packet with ring1\n"); tingx_is_free = 1; } if(force_queue_n == 0) { //printf("\n Force Sent packet with ring0\n"); tingx_is_free = 0; } else if (force_queue_n == 1) { //printf("\n Force Sent packet with ring1\n"); tingx_is_free = 1; } #endif // RALINK_GDMA_DUP_TX_RING_TEST_FUN // #ifdef RALINK_MUTI_TX_DESCRIPTOR_TEST_FUN //printf(" Send's Packet addr= 0x%08X,Total length=%d \n",packet,length); #ifdef RALINK_GDMA_DUP_TX_RING_TEST_FUN if(tingx_is_free == 0) { txd_info = (u32 *)&tx_ring0[tx_cpu_owner_idx0].txd_info2; *txd_info = 0; bk_len = (length >> 2); length = length - (bk_len * 3); //Segment 0 tx_ring0[tx_cpu_owner_idx0].txd_info1.SDP0 = cpu_to_le32(phys_to_bus((u32) packet)); tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL0 = bk_len; //printf("\n tx_ring0[tx_cpu_owner_idx0].txd_info1.SDP0=%08X",tx_ring0[tx_cpu_owner_idx0].txd_info1.SDP0); //printf("\n tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL0=%d",tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL0); sdp1_seg_p = packet; sdp1_seg_p += bk_len; //Segment 1 tx_ring0[tx_cpu_owner_idx0].txd_info3.SDP1 = cpu_to_le32(phys_to_bus((u32) sdp1_seg_p)); tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL1 = bk_len; //printf("\n tx_ring0[tx_cpu_owner_idx0].txd_info3.SDP1=%08X",tx_ring0[tx_cpu_owner_idx0].txd_info3.SDP1); //printf("\n tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL1=%d",tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL1); sdp1_seg_p += bk_len; //Segment 2 tx_ring0[tx_cpu_owner_idx0 + 1].txd_info1.SDP0 = cpu_to_le32(phys_to_bus((u32) sdp1_seg_p)); tx_ring0[tx_cpu_owner_idx0 + 1].txd_info2.SDL0 = bk_len; //printf("\n tx_ring0[tx_cpu_owner_idx0 + 1].txd_info1.SDP0=%08X",tx_ring0[tx_cpu_owner_idx0 + 1].txd_info1.SDP0); //printf("\n tx_ring0[tx_cpu_owner_idx0 + 1].txd_info2.SDL0=%d",tx_ring0[tx_cpu_owner_idx0 + 1].txd_info2.SDL0); sdp1_seg_p += bk_len; //Segment 3 tx_ring0[tx_cpu_owner_idx0 + 1].txd_info3.SDP1 = cpu_to_le32(phys_to_bus((u32) sdp1_seg_p)); tx_ring0[tx_cpu_owner_idx0 + 1].txd_info2.SDL1 = length; //printf("\n tx_ring0[tx_cpu_owner_idx0 + 1].txd_info3.SDP1=%08X",tx_ring0[tx_cpu_owner_idx0 + 1].txd_info3.SDP1); //printf("\n tx_ring0[tx_cpu_owner_idx0 + 1].txd_info2.SDL1=%d",tx_ring0[tx_cpu_owner_idx0 + 1].txd_info2.SDL1); } else { txd_info = (u32 *)&tx_ring1[tx_cpu_owner_idx1].txd_info2; *txd_info = 0; bk_len = (length >> 2); length = length - (bk_len * 3); //Segment 0 tx_ring1[tx_cpu_owner_idx1].txd_info1.SDP0 = cpu_to_le32(phys_to_bus((u32) packet)); tx_ring1[tx_cpu_owner_idx1].txd_info2.SDL0 = bk_len; //printf("\n tx_ring1[tx_cpu_owner_idx0].txd_info1.SDP0=%08X",tx_ring1[tx_cpu_owner_idx0].txd_info1.SDP0); //printf("\n tx_ring1[tx_cpu_owner_idx0].txd_info2.SDL0=%d",tx_ring1[tx_cpu_owner_idx0].txd_info2.SDL0); sdp1_seg_p = packet; sdp1_seg_p += bk_len; //Segment 1 tx_ring1[tx_cpu_owner_idx1].txd_info3.SDP1 = cpu_to_le32(phys_to_bus((u32) sdp1_seg_p)); tx_ring1[tx_cpu_owner_idx1].txd_info2.SDL1 = bk_len; //printf("\n tx_ring1[tx_cpu_owner_idx0].txd_info3.SDP1=%08X",tx_ring1[tx_cpu_owner_idx0].txd_info3.SDP1); //printf("\n tx_ring1[tx_cpu_owner_idx0].txd_info2.SDL1=%d",tx_ring1[tx_cpu_owner_idx0].txd_info2.SDL1); sdp1_seg_p += bk_len; //Segment 2 tx_ring1[tx_cpu_owner_idx1 + 1].txd_info1.SDP0 = cpu_to_le32(phys_to_bus((u32) sdp1_seg_p)); tx_ring1[tx_cpu_owner_idx1 + 1].txd_info2.SDL0 = bk_len; //printf("\n tx_ring1[tx_cpu_owner_idx0 + 1].txd_info1.SDP0=%08X",tx_ring1[tx_cpu_owner_idx0 + 1].txd_info1.SDP0); //printf("\n tx_ring1[tx_cpu_owner_idx0 + 1].txd_info2.SDL0=%d",tx_ring1[tx_cpu_owner_idx0 + 1].txd_info2.SDL0); sdp1_seg_p += bk_len; //Segment 3 tx_ring1[tx_cpu_owner_idx1 + 1].txd_info3.SDP1 = cpu_to_le32(phys_to_bus((u32) sdp1_seg_p)); tx_ring1[tx_cpu_owner_idx1 + 1].txd_info2.SDL1 = length; //printf("\n tx_ring1[tx_cpu_owner_idx0 + 1].txd_info3.SDP1=%08X",tx_ring1[tx_cpu_owner_idx0 + 1].txd_info3.SDP1); //printf("\n tx_ring1[tx_cpu_owner_idx0 + 1].txd_info2.SDL1=%d",tx_ring1[tx_cpu_owner_idx0 + 1].txd_info2.SDL1); } #else // Non RALINK_GDMA_DUP_TX_RING_TEST_FUN // txd_info = (u32 *)&tx_ring0[tx_cpu_owner_idx0].txd_info2; *txd_info = 0; bk_len = (length >> 2); length = length - (bk_len * 3); //Segment 0 tx_ring0[tx_cpu_owner_idx0].txd_info1.SDP0 = cpu_to_le32(phys_to_bus((u32) packet)); tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL0 = bk_len; //printf("\n tx_ring0[tx_cpu_owner_idx0].txd_info1.SDP0=%08X",tx_ring0[tx_cpu_owner_idx0].txd_info1.SDP0); //printf("\n tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL0=%d",tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL0); sdp1_seg_p = packet; sdp1_seg_p += bk_len; //Segment 1 tx_ring0[tx_cpu_owner_idx0].txd_info3.SDP1 = cpu_to_le32(phys_to_bus((u32) sdp1_seg_p)); tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL1 = bk_len; //printf("\n tx_ring0[tx_cpu_owner_idx0].txd_info3.SDP1=%08X",tx_ring0[tx_cpu_owner_idx0].txd_info3.SDP1); //printf("\n tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL1=%d",tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL1); sdp1_seg_p += bk_len; //Segment 2 tx_ring0[tx_cpu_owner_idx0 + 1].txd_info1.SDP0 = cpu_to_le32(phys_to_bus((u32) sdp1_seg_p)); tx_ring0[tx_cpu_owner_idx0 + 1].txd_info2.SDL0 = bk_len; //printf("\n tx_ring0[tx_cpu_owner_idx0 + 1].txd_info1.SDP0=%08X",tx_ring0[tx_cpu_owner_idx0 + 1].txd_info1.SDP0); //printf("\n tx_ring0[tx_cpu_owner_idx0 + 1].txd_info2.SDL0=%d",tx_ring0[tx_cpu_owner_idx0 + 1].txd_info2.SDL0); sdp1_seg_p += bk_len; //Segment 3 tx_ring0[tx_cpu_owner_idx0 + 1].txd_info3.SDP1 = cpu_to_le32(phys_to_bus((u32) sdp1_seg_p)); tx_ring0[tx_cpu_owner_idx0 + 1].txd_info2.SDL1 = length; //printf("\n tx_ring0[tx_cpu_owner_idx0 + 1].txd_info3.SDP1=%08X",tx_ring0[tx_cpu_owner_idx0 + 1].txd_info3.SDP1); //printf("\n tx_ring0[tx_cpu_owner_idx0 + 1].txd_info2.SDL1=%d",tx_ring0[tx_cpu_owner_idx0 + 1].txd_info2.SDL1); #endif // RALINK_GDMA_DUP_TX_RING_TEST_FUN // #else // Non RALINK_MUTI_TX_DESCRIPTOR_TEST_FUN // #ifdef RALINK_GDMA_DUP_TX_RING_TEST_FUN if(tingx_is_free == 0) { tx_ring0[tx_cpu_owner_idx0].txd_info1.SDP0 = cpu_to_le32(phys_to_bus((u32) packet)); tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL0 = length; } else { tx_ring1[tx_cpu_owner_idx1].txd_info1.SDP0 = cpu_to_le32(phys_to_bus((u32) packet)); tx_ring1[tx_cpu_owner_idx1].txd_info2.SDL0 = length; } #else // Non RALINK_GDMA_DUP_TX_RING_TEST_FUN // tx_ring0[tx_cpu_owner_idx0].txd_info1.SDP0 = cpu_to_le32(phys_to_bus((u32) packet)); tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL0 = length; //printf("\n tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL0 =%d \n",tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL0); #endif // RALINK_GDMA_DUP_TX_RING_TEST_FUN // #endif // RALINK_MUTI_TX_DESCRIPTOR_TEST_FUN // #ifdef RALINK_GDMA_DUP_TX_RING_TEST_FUN if(tingx_is_free == 0) { #ifdef RALINK_MUTI_TX_DESCRIPTOR_TEST_FUN tx_ring0[tx_cpu_owner_idx0 +1 ].txd_info2.LS1_bit = 1; tx_ring0[tx_cpu_owner_idx0 +1 ].txd_info2.DDONE_bit = 0; tx_ring0[tx_cpu_owner_idx0].txd_info2.DDONE_bit = 0; status = length; tx_cpu_owner_idx0 = (tx_cpu_owner_idx0+2) % NUM_TX_DESC; RALINK_REG(TX_CTX_IDX0)=cpu_to_le32((u32) tx_cpu_owner_idx0); #else tx_ring0[tx_cpu_owner_idx0].txd_info2.DDONE_bit = 0; status = length; tx_cpu_owner_idx0 = (tx_cpu_owner_idx0+1) % NUM_TX_DESC; RALINK_REG(TX_CTX_IDX0)=cpu_to_le32((u32) tx_cpu_owner_idx0); //printf("\TX_CTX_IDX0 = %08X \n",RALINK_REG(TX_CTX_IDX0)); //printf("\TX_DTX_IDX0 = %08X \n",RALINK_REG(TX_DTX_IDX0)); #endif // RALINK_MUTI_TX_DESCRIPTOR_TEST_FUN // } else { #ifdef RALINK_MUTI_TX_DESCRIPTOR_TEST_FUN tx_ring1[tx_cpu_owner_idx1 +1 ].txd_info2.LS1_bit = 1; tx_ring1[tx_cpu_owner_idx1 +1 ].txd_info2.DDONE_bit = 0; tx_ring1[tx_cpu_owner_idx1].txd_info2.DDONE_bit = 0; status = length; tx_cpu_owner_idx1 = (tx_cpu_owner_idx1+2) % NUM_TX_DESC; RALINK_ERG(TX_CTX_IDX1)=cpu_to_le32((u32) tx_cpu_owner_idx1); #else tx_ring1[tx_cpu_owner_idx1].txd_info2.DDONE_bit = 0; status = length; tx_cpu_owner_idx1 = (tx_cpu_owner_idx1+1) % NUM_TX_DESC; RALINK_REG(TX_CTX_IDX1)=cpu_to_le32((u32) tx_cpu_owner_idx1); //printf("\TX_CTX_IDX1 = %08X \n",RALINK_REG(TX_CTX_IDX1)); //printf("\TX_DTX_IDX1 = %08X \n",RALINK_REG(TX_DTX_IDX1)); #endif // RALINK_MUTI_TX_DESCRIPTOR_TEST_FUN // } #else // Non RALINK_GDMA_DUP_TX_RING_TEST_FUN // #ifdef RALINK_MUTI_TX_DESCRIPTOR_TEST_FUN tx_ring0[tx_cpu_owner_idx0 +1 ].txd_info2.LS1_bit = 1; tx_ring0[tx_cpu_owner_idx0 +1 ].txd_info2.DDONE_bit = 0; tx_ring0[tx_cpu_owner_idx0].txd_info2.DDONE_bit = 0; status = length; tx_cpu_owner_idx0 = (tx_cpu_owner_idx0+2) % NUM_TX_DESC; RALINK_REG(TX_CTX_IDX0)=cpu_to_le32((u32) tx_cpu_owner_idx0); #else // Non RALINK_MUTI_TX_DESCRIPTOR_TEST_FUN tx_ring0[tx_cpu_owner_idx0].txd_info2.DDONE_bit = 0; status = length; #ifdef RT3052_PHY_TEST if ( rt3052_phy_test == PHY_TEST_DISABLE ) { #endif if(loopback_protect == 1) { BUFFER_ELEM *buf; #if defined (RT3883_FPGA_BOARD) || defined (RT3883_ASIC_BOARD) PDMA_RXD_INFO4_T *rxd4 = (PDMA_RXD_INFO4_T *)&rx_ring[rx_dma_owner_idx0].rxd_info4; if (rxd4->SP == 1) tx_ring0[tx_cpu_owner_idx0].txd_info4.PN = 2; else if (rxd4->SP == 2) tx_ring0[tx_cpu_owner_idx0].txd_info4.PN = 1; else tx_ring0[tx_cpu_owner_idx0].txd_info4.PN = 1; #endif buf = rt2880_free_buf_entry_dequeue(&rt2880_busing_buf_list); //while while(buf != NULL) { //printf("\n check to Bufnum[%d] \n",FREEBUF_OFFSET(buf->pbuf)); if(tx_ring0[buf->tx_idx].txd_info2.DDONE_bit == 1) { //printf("\n Precedent of Packet was send \n"); rt2880_free_buf_entry_enqueue(&rt2880_free_buf_list,buf); } else { //printf("\n Precedent of Packet was pending !! \n"); rt2880_free_buf_entry_enqueue(&rt2880_busing_buf_list,buf); } buf = rt2880_free_buf_entry_dequeue(&rt2880_busing_buf_list); } i = FREEBUF_OFFSET(packet); rt2880_free_buf[i].tx_idx = tx_cpu_owner_idx0; rt2880_free_buf_entry_enqueue(&rt2880_busing_buf_list,&rt2880_free_buf[i]); //printf("\n Loopback Send Bufnum = %d\n",i); } #ifdef RT3052_PHY_TEST } // if not rt3052_phy_test #endif tx_cpu_owner_idx0 = (tx_cpu_owner_idx0+1) % NUM_TX_DESC; RALINK_REG(TX_CTX_IDX0)=cpu_to_le32((u32) tx_cpu_owner_idx0); #endif // RALINK_MUTI_TX_DESCRIPTOR_TEST_FUN // #endif // RALINK_GDMA_DUP_TX_RING_TEST_FUN // //kaiker_led_tx_ring(); return status; Done: udelay(500); retry_count++; goto Retry; } static int rt2880_eth_recv(struct eth_device* dev) { #ifdef RT3052_PHY_TEST int recv_cnt, i; #endif int length = 0,hdr_len=0,bb=0; int inter_loopback_cnt =0; u32 *rxd_info; #ifdef RALINK_RUN_COMMAD_AT_ETH_RCV_FUN char lastcommand[30]; #endif #if !defined (RT3883_FPGA_BOARD) && !defined (RT3883_ASIC_BOARD) u8 temp_mac[6]; #endif #ifdef RALINK_GDMA_SCATTER_TEST_FUN uchar *scatter_src,*scatter_dst; #endif #ifdef RALINK_SWITCH_LOOPBACK_DEBUG_FUN static u8 mac_1[]={0x00,0xAA,0xBB,0xCC,0xDD,0x01}; static u8 mac_2[]={0x00,0xAA,0xBB,0xCC,0xDD,0x02}; static u8 mac_3[]={0x00,0xAA,0xBB,0xCC,0xDD,0x03}; static u8 mac_4[]={0x00,0xAA,0xBB,0xCC,0xDD,0x04}; static u8 mac_5[]={0x00,0xAA,0xBB,0xCC,0xDD,0x05}; static u8 mac_6[]={0x00,0xAA,0xBB,0xCC,0xDD,0x06}; #endif // RALINK_SWITCH_LOOPBACK_DEBUG_FUN // for (; ; ) { #ifdef RALINK_RUN_COMMAD_AT_ETH_RCV_FUN bb = kaiker_button_p(); if(bb == 3 ) { //kaiker_debug_show(dev); input_value(lastcommand); kaiker_run_command(lastcommand,0); } #endif // RALINK_RUN_COMMAD_AT_ETH_RCV_FUN // rxd_info = (u32 *)KSEG1ADDR(&rx_ring[rx_dma_owner_idx0].rxd_info2); if ( (*rxd_info & BIT(31)) == 0 ) { hdr_len =0; if (eth_loopback_mode == 1) { if (bb == 1) { rt2880_eth_halt(rt2880_pdev); puts ("\nAbort Loopback Mode\n"); eth_loopback_mode = 0; //rt2880_eth_setup(rt2880_pdev); return (0); } continue; } else { break; } } udelay(1); #ifdef RALINK_GDMA_SCATTER_TEST_FUN if(header_payload_scatter_en == ENABLE) { length = rx_ring[rx_dma_owner_idx0].rxd_info2.PLEN1; hdr_len = rx_ring[rx_dma_owner_idx0].rxd_info2.PLEN0; } else #endif // RALINK_GDMA_SCATTER_TEST_FUN // length = rx_ring[rx_dma_owner_idx0].rxd_info2.PLEN0; if(header_payload_scatter_en == DISABLE && length == 0) { printf("\n Warring!! Packet Length has error !!,In normal mode !\n"); } #ifdef RALINK_GDMA_SCATTER_TEST_FUN if(header_payload_scatter_en == ENABLE && hdr_len == 0) { printf("\n Warring!! Packet Length has error !!,In Scatter mode !\n"); } #endif // RALINK_GDMA_SCATTER_TEST_FUN // if(eth_loopback_mode == 1) { #ifdef RALINK_GDMA_SCATTER_TEST_FUN if(header_payload_scatter_en == ENABLE) { printf("\n ===== Header len [%d] === \n",hdr_len); scatter_dst = (uchar *)KSEG1ADDR(pkthdrbuf[rx_dma_owner_idx0]); //scatter_dst[0]=0x00; //scatter_dst[1]=0x11; //scatter_dst[2]=0x22; //scatter_dst[3]=0x33; //scatter_dst[4]=0x44; //scatter_dst[5]=0x55; //print_packet(scatter_dst,hdr_len); printf("\n ===== Pay load len [%d] === \n",length); scatter_src = (uchar *)KSEG1ADDR(NetRxPackets[rx_dma_owner_idx0]); //print_packet(scatter_src,length); scatter_dst += hdr_len; memcpy(scatter_dst,scatter_src,length); length += hdr_len; rt2880_eth_send(dev, (void *)KSEG1ADDR(pkthdrbuf[rx_dma_owner_idx0]),length); } else #endif // RALINK_GDMA_SCATTER_TEST_FUN // { BUFFER_ELEM *buf; #if !defined (RT3883_FPGA_BOARD) && !defined (RT3883_ASIC_BOARD) u8 *p = (u8 *)KSEG1ADDR(NetRxPackets[rx_dma_owner_idx0]); #endif buf = rt2880_free_buf_entry_dequeue(&rt2880_free_buf_list); if(buf == NULL) { printf("\n Warrng Packet Buffer is Empty!!\n"); return (0); } //RT3883: we don't have to swap DA/SA because it is GE1<-->GE2 #if !defined (RT3883_FPGA_BOARD) && !defined (RT3883_ASIC_BOARD) //printf("\n Ready loopback,Current Buff num = %d \n",FREEBUF_OFFSET(NetRxPackets[rx_dma_owner_idx0])); if(p[0]!= 0xFF) { // save da memcpy(temp_mac,p,6); #ifdef RALINK_SWITCH_LOOPBACK_DEBUG_FUN if(!memcmp(p+6,mac_1,6)) { memcpy(p+6,mac_2,6); } else if(!memcmp(p+6,mac_2,6)) { memcpy(p+6,mac_1,6); } else if(!memcmp(p+6,mac_3,6)) { memcpy(p+6,mac_4,6); } else if(!memcmp(p+6,mac_4,6)) { memcpy(p+6,mac_3,6); } else if(!memcmp(p+6,mac_5,6)) { memcpy(p+6,mac_6,6); } else if(!memcmp(p+6,mac_6,6)) { memcpy(p+6,mac_5,6); } #endif // RALINK_SWITCH_LOOPBACK_DEBUG_FUN // //copy sa to da memcpy(p,p+6,6); memcpy(p+6,temp_mac,6); } #endif loopback_protect = 1; rt2880_eth_send(dev, (void *)KSEG1ADDR(NetRxPackets[rx_dma_owner_idx0]),length); loopback_protect = 0; NetRxPackets[rx_dma_owner_idx0] = buf->pbuf; rx_ring[rx_dma_owner_idx0].rxd_info2.LS0= 1; rx_ring[rx_dma_owner_idx0].rxd_info1.PDP0 = cpu_to_le32(phys_to_bus((u32) NetRxPackets[rx_dma_owner_idx0])); } } #ifdef RT3052_PHY_TEST else if (rt3052_phy_test == PHY_TEST_ENABLE) { // int ret; uchar* rx_buf = rx_ring[rx_dma_owner_idx0].rxd_info1.PDP0; rt3052_phy_test_ret_code = 0; rt3052_phy_test_ret_code = memcmp(&rt3052_phy_test_buf[0], rx_buf, 12);//received packet without vtag rt3052_phy_test_ret_code |= memcmp(&rt3052_phy_test_buf[16], rx_buf+12, length-12); udelay(50000);//delay to avoid receive fail if(rt3052_phy_test_debug == 1) { printf("\nRx Path len - %d, ret = %d\n", length, rt3052_phy_test_ret_code); printf("RX Packet Dump -- \n"); packet_dump(rx_buf, length); } NetReceive(NetRxPackets[rx_dma_owner_idx0], length); // printf("--- END of RX Packet Dump ---\n"); } #endif else { #ifdef RALINK_GDMA_SCATTER_TEST_FUN if(header_payload_scatter_en == ENABLE) { scatter_dst = (uchar *)KSEG1ADDR(pkthdrbuf[rx_dma_owner_idx0]); scatter_src = (uchar *)KSEG1ADDR(NetRxPackets[rx_dma_owner_idx0]); scatter_dst += hdr_len; printf("\n scatter enbale ,rcv hdr_len=%d \n",hdr_len); memcpy(scatter_dst,scatter_src,length); length += hdr_len; if(rx_ring[rx_dma_owner_idx0].rxd_info4.SP == 0) {// Packet received from CPU port printf("\n HEADER_PAYLOAD_SCATTER mode,Packet received from CPU port,plen=%d \n",length); //print_packet((void *)KSEG1ADDR(pkthdrbuf[rx_dma_owner_idx0]),length); inter_loopback_cnt++; length = inter_loopback_cnt;//for return } else NetReceive((void *)KSEG1ADDR(pkthdrbuf[rx_dma_owner_idx0]), length ); //kaiker_led_scatter_packet(); } else #endif // RALINK_GDMA_SCATTER_TEST_FUN // { #if defined (PDMA_NEW) if(rx_ring[rx_dma_owner_idx0].rxd_info4.SP == 6) #else if(rx_ring[rx_dma_owner_idx0].rxd_info4.SP == 0) #endif {// Packet received from CPU port printf("\n Normal Mode,Packet received from CPU port,plen=%d \n",length); //print_packet((void *)KSEG1ADDR(NetRxPackets[rx_dma_owner_idx0]),length); inter_loopback_cnt++; length = inter_loopback_cnt;//for return } else NetReceive((void *)KSEG1ADDR(NetRxPackets[rx_dma_owner_idx0]), length ); } } #if defined (RX_SCATTER_GATTER_DMA) rx_ring[rx_dma_owner_idx0].rxd_info2.DDONE_bit = 0; rx_ring[rx_dma_owner_idx0].rxd_info2.LS0= 0; rx_ring[rx_dma_owner_idx0].rxd_info2.PLEN0= PKTSIZE_ALIGN; #else rxd_info = (u32 *)&rx_ring[rx_dma_owner_idx0].rxd_info4; *rxd_info = 0; rxd_info = (u32 *)&rx_ring[rx_dma_owner_idx0].rxd_info2; *rxd_info = 0; rx_ring[rx_dma_owner_idx0].rxd_info2.LS0= 1; #endif /* Tell the adapter where the TX/RX rings are located. */ RALINK_REG(RX_BASE_PTR0)=phys_to_bus((u32) &rx_ring[0]); //udelay(10000); /* Move point to next RXD which wants to alloc*/ RALINK_REG(RX_CALC_IDX0)=cpu_to_le32((u32) rx_dma_owner_idx0); /* Update to Next packet point that was received. */ rx_dma_owner_idx0 = (rx_dma_owner_idx0 + 1) % NUM_RX_DESC; //printf("\n ************************************************* \n"); //printf("\n RX_CALC_IDX0=%d \n", RALINK_REG(RX_CALC_IDX0)); //printf("\n RX_DRX_IDX0 = %d \n",RALINK_REG(RX_DRX_IDX0)); //printf("\n ************************************************* \n"); #ifdef RT3052_PHY_TEST if ( rt3052_phy_test == PHY_TEST_ENABLE) { unsigned int rx_dtx = 0; rx_dtx = RALINK_REG(RX_DRX_IDX0); if ( rx_dma_owner_idx0 == rx_dtx ) { return length; } } #endif } return length; } void rt2880_eth_halt(struct eth_device* dev) { STOP_ETH(dev); //gmac_phy_switch_gear(DISABLE); //printf(" STOP_ETH \n"); //dump_reg(); } #ifdef RALINK_GDMA_STATUS_DISPLAY_FUN void kaiker_debug_show(struct eth_device* dev) { int kk; #if 1 printf("\n# rx_ring[rx_dma_owner_idx0].rxd_info2.DDONE_bit=%d ,length=%d \n",rx_ring[rx_dma_owner_idx0].rxd_info2.DDONE_bit,rx_ring[rx_dma_owner_idx0].rxd_info2.PLEN0); printf("#rx_ring[rx_dma_owner_idx0].rxd_info2.rxd_info4.IPFVLD_bit=%d \n",rx_ring[rx_dma_owner_idx0].rxd_info4.IPFVLD_bit); rx_ring[rx_dma_owner_idx0].rxd_info4.IPFVLD_bit=0; printf("\n #rx_ring[rx_dma_owner_idx0].rxd_info2.rxd_info4.L4FVLD_bit=%d \n",rx_ring[rx_dma_owner_idx0].rxd_info4.L4FVLD_bit); rx_ring[rx_dma_owner_idx0].rxd_info4.L4FVLD_bit=0; printf("\n #rx_ring[rx_dma_owner_idx0].rxd_info2.rxd_info4.IPF=%d \n",rx_ring[rx_dma_owner_idx0].rxd_info4.IPF); rx_ring[rx_dma_owner_idx0].rxd_info4.IPF = 0; printf("\n #rx_ring[rx_dma_owner_idx0].rxd_info2.rxd_info4.L4F=%d \n",rx_ring[rx_dma_owner_idx0].rxd_info4.L4F); rx_ring[rx_dma_owner_idx0].rxd_info4.L4F =0; printf("\n #rx_ring[rx_dma_owner_idx0].rxd_info2.rxd_info4.AIS=%d \n",rx_ring[rx_dma_owner_idx0].rxd_info4.AIS); printf("\n #rx_ring[rx_dma_owner_idx0].rxd_info2.rxd_info4.AI=%02X \n",rx_ring[rx_dma_owner_idx0].rxd_info4.AI); printf("\n #rx_ring[rx_dma_owner_idx0].rxd_info2.rxd_info4.FVLD=%d \n",rx_ring[rx_dma_owner_idx0].rxd_info4.FVLD); printf("\n #rx_ring[rx_dma_owner_idx0].rxd_info2.rxd_info4.FOE_Entry=%04X \n",rx_ring[rx_dma_owner_idx0].rxd_info4.FOE_Entry); #endif #if 1 for(kk=0;kk dest_mem_offset) i_diff = src_mem_offset - dest_mem_offset; else i_diff = dest_mem_offset - src_mem_offset; if (i_diff < mem_test_size) goto memtest_sram_reset; src = src_mem_offset + SRAM_BASE_MEMTEST; dest = dest_mem_offset + SRAM_BASE_MEMTEST; random_memcpy(src,dest,mem_test_size); udelay(mem_test_size); printf("\nTest Count[%d]\n",i); } /* for */ } int address_check(unsigned int src, unsigned int dest, unsigned int size) { unsigned int offset; if ( src == dest ) return 0; if ( src > dest ) offset = src - dest; else offset = dest - src; if ( offset < size ) return 0; return 1; } int ram_test_random(u32 test_times, u32 mem_base) { int i, result, fail_cnt; unsigned char *src,*dest; unsigned int mem_test_size, src_mem_offset, dest_mem_offset; unsigned int random_i, i_diff; fail_cnt = 0; for ( i = 0; i < test_times; i++) { //printf("\n Total Test num [%d]\n",i); if(kaiker_button_p()) { printf("\n--> Run %d test counts ...User Cancel memtest!!\n", i); return; } do { if (kaiker_button_p()) { printf("\n--> Run %d test counts ...User Cancel memtest!!\n", i); return; } random_i = (unsigned int)get_timer(test_times); /* step 1: decide memory size */ mem_test_size = (random_i % MEMTEST_BLOCK_SIZE); /* step 2: decide source sdram offset */ random_i = (unsigned int)get_timer(random_i); src_mem_offset = (random_i % (TEST_SIZE_OF_SDRAM-mem_test_size)); /* step 3: decide dest sdram offset */ random_i = (unsigned int)get_timer(random_i); dest_mem_offset = (random_i % (TEST_SIZE_OF_SDRAM-mem_test_size)); } while (address_check(src_mem_offset, dest_mem_offset, mem_test_size) == 0); if ( (i%2) == 0 ) { src = dest_mem_offset + mem_base; dest = src_mem_offset + SDRAM_BASE1_MEMTEST; } else { src = src_mem_offset + SDRAM_BASE1_MEMTEST; dest = dest_mem_offset + mem_base; } result = random_memcpy(src,dest,mem_test_size); if(result != 0) { printf("Random Mem Test Count[%d], %d failed\n-------\n\n",i+1, result); fail_cnt++; } // udelay(mem_test_size); } /* for */ printf("\nRandom Mem Test Count - %d, %d failed\n",i, fail_cnt); } int random_memcpy(unsigned char* p_dest, unsigned char* p_src, unsigned int length) { int i, j, k; unsigned char *pSrc = p_src; unsigned char *pDest = p_dest; if (length > TEST_SIZE_OF_SDRAM) return -1; // printf(" ... memcpy() start..."); memcpy(pDest, pSrc, length); // printf("Done\n"); j = 0; for ( i = 0; i < length; i++) { if (pDest[i] != pSrc[i]) { // printf("data error in pDest[%d], 0x%x[%d] ... pSrc[%d], 0x%x[%d]\n", i, (pDest + i), pDest[i], i, (pSrc + i), pSrc[i]); j++; } } /* for */ // printf("dest_addr src_addr size : 0x%x 0x%x %d\n\n", pDest, pSrc, length); // if ( j == 0) // printf("memory test ok!\n\n"); // else if (j != 0) { printf("src_addr: 0x%x dest_addr: 0x%x size: %d.\n", pSrc, pDest, length); // printf("memory test failed!\n\n"); // while(1); } return j; } int rt2880_memory_test(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { unsigned char *src,*dest; u32 count = 0; int choice; switch (argc) { case 1: printf("memtest usage :\n%s\n", cmdtp->usage); break; case 2: count = simple_strtoul(argv[1], NULL, 10); printf("\n Random Test [%d] times \n",count); ram_test_random(count, SDRAM_BASE_MEMTEST); break; case 3: choice = simple_strtoul(argv[1], NULL, 16); count = simple_strtoul(argv[2], NULL, 10); if (choice == 0) { printf("\n error \n"); } else if (choice == 1) { /* test sdram */ ram_test_random(count, SDRAM_BASE_MEMTEST); } else if (choice == 2) { /* test sram */ ram_test_random(count, SRAM_BASE_MEMTEST); } break; case 4: src = simple_strtoul(argv[1], NULL, 16); dest = simple_strtoul(argv[2], NULL, 16); count = simple_strtoul(argv[3], NULL, 10); random_memcpy(dest,src,count); break; default: printf("memtest input cmd error!"); break; }; return 0; } U_BOOT_CMD( memtest, 4, 1, rt2880_memory_test, "memtest - Ralink memory test !!\n", "memtest [Run Count] - Memory test with random's addr and random's size !!\n" "memtest [src address] [dest address] [test size]- Memory test with assign's addr and assign's size !!\n" ); #endif // RALINK_MEMORY_TEST_FUN // #ifdef RT2880_U_BOOT_CMD_OPEN #if defined (RT3883_FPGA_BOARD) || defined (RT3883_ASIC_BOARD) void rt3883_init_gdma(int mode) { u32 reg; u16 tmp; //mode 0: all pkts to cpu, if (mode == 0) { reg = RALINK_REG(GDMA1_FWD_CFG); reg &= (GDM_UFRC_P_CPU & GDM_BFRC_P_CPU & GDM_MFRC_P_CPU & GDM_OFRC_P_CPU); RALINK_REG(GDMA1_FWD_CFG)=cpu_to_le32((u32)reg); reg = RALINK_REG(GDMA2_FWD_CFG); reg &= (GDM_UFRC_P_CPU & GDM_BFRC_P_CPU & GDM_MFRC_P_CPU & GDM_OFRC_P_CPU); RALINK_REG(GDMA2_FWD_CFG)=cpu_to_le32((u32)reg); } //mode 1: ge1->ge2, ge2->ge1 else if (mode == 1) { reg = RALINK_REG(GDMA1_FWD_CFG); reg &= (GDM_UFRC_P_CPU & GDM_BFRC_P_CPU & GDM_MFRC_P_CPU & GDM_OFRC_P_CPU); reg |= (GDM_UFRC_P_GDMA2 | GDM_BFRC_P_GDMA2 | GDM_MFRC_P_GDMA2 | GDM_OFRC_P_GDMA2); RALINK_REG(GDMA1_FWD_CFG)=cpu_to_le32((u32)reg); reg = RALINK_REG(GDMA2_FWD_CFG); reg &= (GDM_UFRC_P_CPU & GDM_BFRC_P_CPU & GDM_MFRC_P_CPU & GDM_OFRC_P_CPU); reg |= (GDM_UFRC_P_GDMA1 | GDM_BFRC_P_GDMA1 | GDM_MFRC_P_GDMA1 | GDM_OFRC_P_GDMA1); RALINK_REG(GDMA2_FWD_CFG)=cpu_to_le32((u32)reg); } //also set GDMA my MAC tmp = (u16)rt2880_pdev->enetaddr[0]; reg = (tmp << 8) | rt2880_pdev->enetaddr[1]; RALINK_REG(GDMA1_MAC_ADRH)=reg; tmp = (u16)rt2880_pdev->enetaddr[2]; reg = (tmp << 8) | rt2880_pdev->enetaddr[3]; reg = reg << 16; tmp = (u16)rt2880_pdev->enetaddr[4]; //reg |= (tmp<<8) | rt2880_pdev->enetaddr[5]; reg |= (tmp<<8) | 1; RALINK_REG(GDMA1_MAC_ADRL)=reg; tmp = (u16)rt2880_pdev->enetaddr[0]; reg = (tmp << 8) | rt2880_pdev->enetaddr[1]; RALINK_REG(GDMA2_MAC_ADRH)=reg; tmp = (u16)rt2880_pdev->enetaddr[2]; reg = (tmp << 8) | rt2880_pdev->enetaddr[3]; reg = reg << 16; tmp = (u16)rt2880_pdev->enetaddr[4]; //reg |= (tmp<<8) | rt2880_pdev->enetaddr[5]; reg |= (tmp<<8) | 2; RALINK_REG(GDMA2_MAC_ADRL)=reg; //enable auto polling for both GE1 and GE2 reg = RALINK_REG(MDIO_CFG); reg |= 0x20000000; RALINK_REG(MDIO_CFG)=reg; #define MDIO_CFG2 RALINK_FRAME_ENGINE_BASE + 0x18 reg = RALINK_REG(MDIO_CFG2); reg |= 0x20000000; RALINK_REG(MDIO_CFG2)=reg; } void rt3883_reset_phy(void) { //Marvell phy: adj skew and reset both phy connected to ge1 and ge2 mii_mgr_write(31, 20, 0x0ce0); #ifdef RT3883_FPGA_BOARD mii_mgr_write(31, 9, 0); #endif mii_mgr_write(31, 0, 0x9140); mii_mgr_write(30, 20, 0x0ce0); #ifdef RT3883_FPGA_BOARD mii_mgr_write(30, 9, 0); #endif mii_mgr_write(30, 0, 0x9140); } int do_rt3883_cpuloopback(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { printf("RT3883 CPU loopback mode!\n"); eth_init(NULL); eth_loopback_mode = 1; rt3883_init_gdma(0); rt3883_reset_phy(); rt2880_eth_recv(rt2880_pdev); return 0; } U_BOOT_CMD( cpuloop, 1, 1, do_rt3883_cpuloopback, "cpuloop - RT3883 CPU loopback test\n", "cpuloop - RT3883 CPU loopback test\n" ); int do_rt3883_pseloopback(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { printf("RT3883 PSE loopback mode!\n"); rt3883_init_gdma(1); rt3883_reset_phy(); return 0; } U_BOOT_CMD( pseloop, 1, 1, do_rt3883_pseloopback, "pseloop - RT3883 PSE loopback test\n", "pseloop - RT3883 PSE loopback test\n" ); #endif int do_eth_loopback(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { if (eth_loopback_mode) { eth_loopback_mode=0; printf("\n Set to Normal mode ! \n"); } else { eth_init(NULL); eth_loopback_mode=1; rt2880_eth_recv(rt2880_pdev); printf("\n Set to LoopBack mode ! \n"); } return 0; } U_BOOT_CMD( loopback, 1, 1, do_eth_loopback, "loopback - Ralink eth loopback test !!\n", "kaiker,loopback - Ralink eth loopback test !!\n" ); #endif #ifdef RALINK_GDMA_STATUS_DISPLAY_FUN int rt2880_debug_show(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { kaiker_debug_show(rt2880_pdev); STOP_ETH(rt2880_pdev); puts(" STOP_ETH \n"); return 0; } U_BOOT_CMD( sdd, 1, 1, rt2880_debug_show, "sdd - Display to all DMA status !!\n", "kaiker,sdd - !!\n" ); #endif // RALINK_GDMA_STATUS_DISPLAY_FUN // #ifdef RALINK_PCI_HOST_TEST_FUN /* FUNCTION: ConvertCharToHex PURPOSE: Convert string to hex */ void ConvertCharToHex(char *s,u32 *d1) { int i; char chr; *d1=0; for (i=0; i < strlen(s); i++) { *d1 = *d1 * 16; chr = s[i]; if (chr >= '0' && chr <= '9') *d1 += chr - '0'; else if (chr >= 'a' && chr <= 'f') *d1 += chr - 'a' + 10; else if (chr >= 'A' && chr <= 'F') *d1 += chr - 'A' + 10; } } static inline u32 byte_transpose(int n,u32 v) { switch(n) { case 0: v= v & 0x000000FF; return v; case 1: v= v & 0x000000FF; v = v << 8; return v; case 2: v= v & 0x000000FF; v = v << 16; return v; case 3: v= v & 0x000000FF; v = v << 24; return v; } } static inline u8 byte_select(int n,u32 v) { switch(n) { case 0: v= v & 0x000000FF; return (u8)v; case 1: v = v & 0x0000FF00; v = v >> 8; return (u8)v; case 2: v = v & 0x00FF0000; v = v >> 16; return (u8)v; case 3: v = v & 0xFF000000; v = v >> 24; return (u8)v; } } static inline u32 halfword_transpose(int n,u32 v) { switch(n) { case 0: v= v & 0x0000FFFF; return v; case 2: v= v & 0x0000FFFF; v = v << 16; return v; } } static inline u16 halfword_select(int n,u32 v) { switch(n) { case 0: v= v & 0x0000FFFF; return (u16)v; case 2: v = v & 0xFFFF0000; v = v >> 16; return (u16)v; } } static inline u32 halfword_mask(int n,u32 v) { switch(n) { case 0: v= v & 0xFFFF0000; break; case 2: v = v & 0x0000FFFF; break; } return v; } static inline u32 byte_mask(int n,u32 v) { switch(n) { case 0: v= v & ~0x000000FF; break; case 1: v = v & ~0x0000FF00; break; case 2: v = v & ~0x00FF0000; break; case 3: v = v & ~0xFF000000; break; } return v; } //--------------------------------------------------------------------------------------------- // Function Name: MemBaseTest_8139_Byte // Description: Byte read //--------------------------------------------------------------------------------------------- #ifdef RT2880_PCI_0310 int MemBaseTest_8139_Byte(u32 iobase,u32 offset,u8 RW,u8 BW) { u8 RTL8139_value_b,ii,fail_num=0; u32 WriteValue,ReadValue; u16 halfwordvalue; u32 WriteValue_dw; u32 TestValue; u32 old_value,new_value,reg_ar; u16 RTL8139_value_w; u32 RTL8139_value_Dw; u32 memwinbase = PCI_ALLOCATE_SPACE; char writestr[10]; int byte_offset,halfword_offset; int ReturnValue; u8 byte; TestValue=0x5A5A00BC; //Test Register TSAD0~3 printf("\n iobase = 0x%08X \n",iobase); printf("\n old,offset = 0x%X\n",offset); memwinbase = memwinbase + ((offset >> 5) << 5); printf("\n memwinbase = 0x%08X \n",memwinbase); PCI_MEMBASE = memwinbase; //PCI_IOBASE = memwinbase; udelay(50000); offset = offset % 32; byte_offset = offset & 0x3; halfword_offset = offset & 0x2; offset = offset & 0xFFFFFFFC; printf("\n new,offset = 0x%X\n",offset); switch(BW) { case 1: /*byte size read/write*/ /*-----------------------*/ switch(RW) { case 1:/*Byte Read/Write*/ ReadValue = PCI_MEMWIN(offset); byte = byte_select(byte_offset,ReadValue); printf("\n kaiker,phy addr=%08X, Read value=%02X\n",memwinbase+offset ,byte); break; case 2:/*Byte write*/ printf("\n input write value:"); input_value(writestr); ConvertCharToHex(writestr,&WriteValue); WriteValue = byte_transpose(byte_offset,WriteValue); printf("\n WriteValue = %08X ,after byte_transpose\n",WriteValue); ReadValue = PCI_MEMWIN(offset); printf("\n ReadValue = %08X\n",ReadValue); ReadValue = byte_mask(byte_offset,ReadValue); printf("\n ReadValue= %08X ,after byte_mask\n",ReadValue); WriteValue = WriteValue | ReadValue; printf("\n willing WriteValue= %08X ,after byte_mask\n",WriteValue); PCI_MEMWIN(offset) = WriteValue; udelay(5000); ReadValue = PCI_MEMWIN(offset); byte = byte_select(byte_offset,ReadValue); printf("\n,phy addr=%08X,Write value=%02X\n",memwinbase+offset,byte); break; default: return 0; } /*-----------------------*/ break;/* case 1 Byte Read/Write*/ case 2: /*word size read/write*/ /*-----------------------*/ switch(RW) { case 1:/*Word Read*/ ReadValue = PCI_MEMWIN(offset); ReadValue = halfword_select(halfword_offset,ReadValue); printf("\nReg addr %8x,Read HalfWord value=%04x\n",reg_ar,ReadValue); break; case 2:/*Word write*/ printf("\n input write value:"); input_value(writestr); ConvertCharToHex(writestr,&WriteValue); WriteValue = halfword_transpose(halfword_offset,WriteValue); printf("\n WriteValue = %08X ,after halfword_transpose\n",WriteValue); ReadValue = PCI_MEMWIN(offset); printf("\n ReadValue = %08X\n",ReadValue); ReadValue = halfword_mask(halfword_offset,ReadValue); printf("\n ReadValue= %08X ,after halfword_mask\n",ReadValue); WriteValue = WriteValue | ReadValue; printf("\n willing WriteValue= %08X ,after byte_mask\n",WriteValue); PCI_MEMWIN(offset) = WriteValue; udelay(5000); ReadValue = PCI_MEMWIN(offset); halfwordvalue = halfword_select(halfword_offset,ReadValue); printf("\n,phy addr=%08X,Write value=%04X\n",memwinbase+offset,halfwordvalue); break; default: return 0; } /*-----------------------*/ break;/*case 2 Dword size read/write*/ case 3:/*Double word size read/write*/ /*-----------------------*/ switch(RW) { case 1:/*DWord Read*/ ReadValue = PCI_MEMWIN(offset); printf("\n kaiker,phy addr=%08X, Read value=%08X\n",memwinbase+offset ,ReadValue); break; case 2:/*DWord write*/ printf("\n input write value:"); input_value(writestr); ConvertCharToHex(writestr,&WriteValue); printf("\n writestr = %08X \n",WriteValue); PCI_MEMWIN(offset) = WriteValue; udelay(5000); ReadValue = PCI_MEMWIN(offset); printf("\n,phy addr=%08X,Write value=%08X\n",memwinbase+offset,ReadValue); break; default: return 0; } /*-----------------------*/ break;/*Double word size read/write */ } } #else // non RT2880_PCI_0310 // int MemBaseTest_8139_Byte(u32 iobase,u32 offset,u8 RW,u8 BW) { u8 RTL8139_value_b,ii,fail_num=0; u32 WriteValue,ReadValue; u16 halfwordvalue; u32 WriteValue_dw; u32 TestValue; u32 old_value,new_value,reg_ar; u16 RTL8139_value_w; u32 RTL8139_value_Dw; char writestr[10]; int byte_offset,halfword_offset; int ReturnValue; u8 byte; TestValue=0x5A5A00BC; udelay(50000); byte_offset = offset & 0x3; halfword_offset = offset & 0x2; offset = offset & 0xFFFFFFFC; printf("\n new,offset = 0x%X\n",offset); switch(BW) { case 1: /*byte size read/write*/ /*-----------------------*/ switch(RW) { case 1:/*Byte Read/Write*/ ReadValue = PCI_MEMWIN(offset); byte = byte_select(byte_offset,ReadValue); printf("\n kaiker,Read value=%02X\n",byte); break; case 2:/*Byte write*/ printf("\n input write value:"); input_value(writestr); ConvertCharToHex(writestr,&WriteValue); WriteValue = byte_transpose(byte_offset,WriteValue); printf("\n WriteValue = %08X ,after byte_transpose\n",WriteValue); ReadValue = PCI_MEMWIN(offset); printf("\n ReadValue = %08X\n",ReadValue); ReadValue = byte_mask(byte_offset,ReadValue); printf("\n ReadValue= %08X ,after byte_mask\n",ReadValue); WriteValue = WriteValue | ReadValue; printf("\n willing WriteValue= %08X ,after byte_mask\n",WriteValue); PCI_MEMWIN(offset) = WriteValue; udelay(5000); ReadValue = PCI_MEMWIN(offset); byte = byte_select(byte_offset,ReadValue); printf("\n,Write value=%02X\n",byte); break; default: return 0; } /*-----------------------*/ break;/* case 1 Byte Read/Write*/ case 2: /*word size read/write*/ /*-----------------------*/ switch(RW) { case 1:/*Word Read*/ ReadValue = PCI_MEMWIN(offset); ReadValue = halfword_select(halfword_offset,ReadValue); printf("\nRead HalfWord value=%04x\n",ReadValue); break; case 2:/*Word write*/ printf("\n input write value:"); input_value(writestr); ConvertCharToHex(writestr,&WriteValue); WriteValue = halfword_transpose(halfword_offset,WriteValue); printf("\n WriteValue = %08X ,after halfword_transpose\n",WriteValue); ReadValue = PCI_MEMWIN(offset); printf("\n ReadValue = %08X\n",ReadValue); ReadValue = halfword_mask(halfword_offset,ReadValue); printf("\n ReadValue= %08X ,after halfword_mask\n",ReadValue); WriteValue = WriteValue | ReadValue; printf("\n willing WriteValue= %08X ,after byte_mask\n",WriteValue); PCI_MEMWIN(offset) = WriteValue; udelay(5000); ReadValue = PCI_MEMWIN(offset); halfwordvalue = halfword_select(halfword_offset,ReadValue); printf("\nWrite value=%04X\n",halfwordvalue); break; default: return 0; } /*-----------------------*/ break;/*case 2 Dword size read/write*/ case 3:/*Double word size read/write*/ /*-----------------------*/ switch(RW) { case 1:/*DWord Read*/ ReadValue = PCI_MEMWIN(offset); printf("\n Read value=%08X\n",ReadValue); break; case 2:/*DWord write*/ printf("\n input write value:"); input_value(writestr); ConvertCharToHex(writestr,&WriteValue); printf("\n writestr = %08X \n",WriteValue); PCI_MEMWIN(offset) = WriteValue; udelay(5000); ReadValue = PCI_MEMWIN(offset); printf("\n,Write value=%08X\n",ReadValue); break; default: return 0; } /*-----------------------*/ break;/*Double word size read/write */ } } #endif // RT2880_PCI_0310 // #endif // RALINK_PCI_HOST_TEST_FUN // #if defined(RALINK_RUN_COMMAD_AT_ETH_RCV_FUN) || defined(RT2880_PCI_0310) || defined(RALINK_PCI_HOST_TEST_FUN) void input_value(u8 *str) { if (str) strcpy(console_buffer, str); else console_buffer[0] = '\0'; while(1) { if (readline ("==:", 1) > 0) { strcpy (str, console_buffer); break; } else break; } } #endif #ifdef RALINK_PCI_HOST_TEST_FUN #define PCI_BRIDGE_CONFIG_ADDR le32_to_cpu(*(volatile u_long *)(RALINK_PCI_BASE + 0x0020)) #define PCI_BRIDGE_CONFIG_DATA le32_to_cpu(*(volatile u_long *)(RALINK_PCI_BASE + 0x0024)) #define PCI_BRIDGE_CLOCK le32_to_cpu(*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x0030)) #define PCI_MEMBASE le32_to_cpu(*(volatile u_long *)(RALINK_PCI_BASE + 0x0028)) #define PCI_IOBASE le32_to_cpu(*(volatile u_long *)(RALINK_PCI_BASE + 0x002C)) #define PCI_MEMWIN(offset) le32_to_cpu(*(volatile u_long *)(RALINK_PCI_BASE + 0x10000 + offset)) #define PCI_IOWIN(offset) le32_to_cpu(*(volatile u_long *)(RALINK_PCI_BASE + 0x20000+ offset)) #define PCI_PCICFG_REG le32_to_cpu(*(volatile u_long *)RALINK_PCI_BASE) #define PCI_ARBCTL_REG le32_to_cpu(*(volatile u_long *)(RALINK_PCI_BASE + 0x0080)) int rt2880_pci_scan(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { u32 ii,jj,aa,kk,kk1,mem_ar,io_ar,offset,reg_offset,setvalue,content; u32 cpsr_flags,slot_num,Item; char soffset[3],RWselect,BWDselect,str_numeral[3],str_setvalue[10]; static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, }; u16 status; int len; PCI_PCICFG_REG = 0; PCI_ARBCTL_REG = 0x79; PCI_MEMBASE = PCI_ALLOCATE_SPACE; //PCI_IOBASE = memwinbase; kaiker_PCI_Scan_Bus_Test(); //printf("\n PCIRAW = 0x%08X \n",*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x1004)); //*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x1004) = 0xFFFFFFFF; do { RETURN_TO_MAIN_MENU: printf("------ Test AHB-PCI Bridge ------\n"); printf("<1>.Two RTL8139D NIC cards Ping Pong Test \n"); printf("<2>.Read/Write REG test \n"); printf("<0>.Exit...\n"); printf("*** Please Input the Item <0>~<4>:"); while((Item = getc())== 0); switch(Item) { /* case 1: kaiker_PCI_Bridge_Test(); break; case 2: kaiker_PCI_Scan_Bus_Test(); break; case 2: kaiker_PCI_InitPCIDevice(); break; */ case '2': /* Ulw.lw = sys_read_pci_config_word(Finded_PCIDeviceID[0].PCIDeviceID, 0x3C); // read back value printf("\n\n******8139 num1= 0x%02x:0x%02x:0x%02x:0x%02x: ***********\n",Ulw.lw_u8[3],Ulw.lw_u8[2],Ulw.lw_u8[1],Ulw.lw_u8[0]); Ulw.lw = sys_read_pci_config_word(Finded_PCIDeviceID[1].PCIDeviceID, 0x3C); // read back value printf("\n\n******8139 num2= 0x%02x:0x%02x:0x%02x:0x%02x: ***********\n",Ulw.lw_u8[3],Ulw.lw_u8[2],Ulw.lw_u8[1],Ulw.lw_u8[0]); Ulw.lw = sys_read_pci_config_word(Finded_PCIDeviceID[2].PCIDeviceID, 0x3C); // read back value printf("\n\n******PCI bridge= 0x%02x:0x%02x:0x%02x:0x%02x: ***********\n",Ulw.lw_u8[3],Ulw.lw_u8[2],Ulw.lw_u8[1],Ulw.lw_u8[0]); break; */ /***************************************/ GO_BACK: printf("\nSelect Device 1.%08x 2.%08x 3.%08x:",Finded_PCIDeviceID[0].dev_ven,Finded_PCIDeviceID[1].dev_ven,Finded_PCIDeviceID[2].dev_ven); while((ii = getc())== 0); if(ii> '3') { printf("\nDevice select error !!\n"); break; } ii = ii - 0x30; mem_ar = sys_read_pci_config_word(Finded_PCIDeviceID[ii-1].PCIDeviceID, PCI_CSH_BASE_ADDR_REG+0 ); //read back base addr io_ar=sys_read_pci_config_word(Finded_PCIDeviceID[ii-1].PCIDeviceID, PCI_CSH_BASE_ADDR_REG+4 ); //read back base addr printf("\nSelect Space 1.MEMORY 2.IO 3.Configuration :"); while((jj = getc())== 0); if(jj=='1') {/*Select memory space*/ if(mem_ar & 0x00000001)/*BAR0 is IO space*/ mem_ar=io_ar; } else if(jj=='2') {/*Selece IO space*/ if(io_ar & 0x00000001)/*BAR1 is IO space*/ mem_ar=io_ar; } else if(jj=='3') { while(1) { printf("\nSelect Register number and input read /write value\n"); printf("\nEx: The command register that write 03H: 4w3\n"); printf("\nEx: Read Status register : 6r \n"); printf("\n [ q ] go back \n"); printf("\n [ exit ] return to main menu \n"); printf(" \n :"); //scanf("%s",&lastcommand); while(1) { len = readline (":", 0); if (len > 0) { strcpy (lastcommand, console_buffer); break; } } if(lastcommand[0]=='q') goto GO_BACK; if(strcmp(lastcommand,"exit")==0) goto RETURN_TO_MAIN_MENU; for(kk=0,kk1=0;lastcommand[kk]!=0;kk++) { if(kk1>=3) break; if((lastcommand[kk]>=0x30 && lastcommand[kk]<=0x39)||(lastcommand[kk]>='a' && lastcommand[kk]<='f')||(lastcommand[kk]>='A' && lastcommand[kk]<='F')) { str_numeral[kk1]=lastcommand[kk]; str_numeral[kk1+1]=0; kk1++; } if(lastcommand[kk]=='r' || lastcommand[kk]=='R') { ConvertCharToHex(str_numeral,®_offset); content=sys_read_pci_config_word(Finded_PCIDeviceID[ii-1].PCIDeviceID, reg_offset); //read back base addr printf("\n DEV:%08X ,reg 0x%02x,value:0x%08x\n",Finded_PCIDeviceID[ii-1].PCIDeviceID,reg_offset,content); break; } else if(lastcommand[kk]=='w' || lastcommand[kk]=='W') { kk++; for(kk1=0;lastcommand[kk]!=0;kk++) { if(kk1>=8) break; if((lastcommand[kk]>=0x30 && lastcommand[kk]<=0x39)||(lastcommand[kk]>='a' && lastcommand[kk]<='f')||(lastcommand[kk]>='A' && lastcommand[kk]<='F')) { str_setvalue[kk1]=lastcommand[kk]; str_setvalue[kk1+1]=0; kk1++; } else { printf("\n syntax error !!\n"); break; } } ConvertCharToHex(str_numeral,®_offset); ConvertCharToHex(str_setvalue,&setvalue); if(reg_offset==4||reg_offset==6) sys_write_pci_config_halfword(Finded_PCIDeviceID[ii-1].PCIDeviceID,reg_offset,setvalue); else sys_write_pci_config_word(Finded_PCIDeviceID[ii-1].PCIDeviceID,reg_offset,setvalue); content=sys_read_pci_config_word(Finded_PCIDeviceID[ii-1].PCIDeviceID, reg_offset); //read back base addr printf("\n DEV:%08X ,reg 0x%02x,value:0x%08x\n",Finded_PCIDeviceID[ii-1].PCIDeviceID,reg_offset,content); break; } } } } else break; mem_ar = (mem_ar&0xfffffffe);//bit0:IO/MEM indicator while(1) { printf("\nInput Register offset (input 6. exit):"); /*Convert HEX char to decimal*/ //scanf("%s",&soffset); input_value(soffset); ConvertCharToHex(soffset,&offset); if(offset==6) break; printf("\n Input 1.Read or 2.Write:"); //scanf("%d",&RWselect); //input_value(&RWselect); //while((RWselect = getc())== 0); PCI_WAIT_INPUT_CHAR(RWselect); RWselect -= 0x30; printf("\n Input 1.Byte or 2.Word or 3.DWord:"); //scanf("%d",&BWDselect); PCI_WAIT_INPUT_CHAR(BWDselect); BWDselect -= 0x30; //BWDselect =1; MemBaseTest_8139_Byte(mem_ar,offset,RWselect,BWDselect); #if 0 for(aa=0;Finded_PCIDeviceID[aa].PCIDeviceID.Enable==1;aa++) { if(Finded_PCIDeviceID[aa].dev_ven==PCI_BRIDGE_DEVICE_VENDOR_ID) { status=sys_read_pci_config_halfword(Finded_PCIDeviceID[aa].PCIDeviceID,PCI_CSH_STATUS_REG); if((status & PCI_STATUS_PARITY_ERROR)) printf("\nThe Bridge[0x%08x] is Parity error !!\n",Finded_PCIDeviceID[aa].dev_ven); if((status & PCI_STATUS_SERR_ERROR)) printf("\nThe Bridge[0x%08x] of SERR# is Enable !!\n",Finded_PCIDeviceID[aa].dev_ven); if((status & PCI_STATUS_R_MASTER_ABORT)) printf("\n The Bridge[0x%08x] is Received master abort as master !!\n",Finded_PCIDeviceID[aa].dev_ven); if((status & PCI_STATUS_R_TARGET_ABORT)) printf("\n The Bridge[0x%08x] is Received Target abort as master !!\n",Finded_PCIDeviceID[aa].dev_ven); if((status & PCI_STATUS_S_TARGET_ABORT)) printf("\n The Bridge[0x%08x] is Signaled Target abort as target !!\n",Finded_PCIDeviceID[aa].dev_ven); if((status & PCI_STATUS_MASTER_PARITY_ERROR)) printf("\nThe Bridge[0x%08x] is Master data parity error !!\n",Finded_PCIDeviceID[aa].dev_ven); } } status=sys_read_pci_config_halfword(Finded_PCIDeviceID[ii].PCIDeviceID,PCI_CSH_STATUS_REG); if((status & PCI_STATUS_PARITY_ERROR)) printf("\n The target[0x%08x] is Parity error !!\n",Finded_PCIDeviceID[ii-1].dev_ven); if((status & PCI_STATUS_SERR_ERROR)) printf("\n The target[0x%08x] of SERR# is Enable !!\n",Finded_PCIDeviceID[ii-1].dev_ven); if((status & PCI_STATUS_R_MASTER_ABORT)) printf("\nThe target[0x%08x] is Received master abort as master !!\n",Finded_PCIDeviceID[ii-1].dev_ven); if((status & PCI_STATUS_R_TARGET_ABORT)) printf("\nThe target[0x%08x] is Received Target abort as master !!\n",Finded_PCIDeviceID[ii-1].dev_ven); if((status & PCI_STATUS_S_TARGET_ABORT)) printf("\nThe target[0x%08x] is Signaled Target abort as target !!\n",Finded_PCIDeviceID[ii-1].dev_ven); if((status & PCI_STATUS_MASTER_PARITY_ERROR)) printf("\nThe target[0x%08x] is Master data parity error !!\n",Finded_PCIDeviceID[ii-1].dev_ven); #endif } break; /***************************************/ default: printf("Exit Aridge Test ..\n"); return; } }while (Item!=0); return 0; } U_BOOT_CMD( pci, 1, 1, rt2880_pci_scan, "pci - Scan PCI bus slot and read/write Configuration space !!\n", "Ralink function create by kaiker - !!\n" ); #endif // RALINK_PCI_HOST_TEST_FUN // #ifdef RALINK_GDMA_SCATTER_TEST_FUN int set_scatter_len(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { u32 regValue; rt2880_hdrlen = simple_strtoul(argv[1], NULL, 10); if(rt2880_hdrlen == 999) { force_queue_n = 1; printf("\n Force tx DMA to Queue1 \n"); return 0; } else if(rt2880_hdrlen == 888) { force_queue_n = 0; printf("\n Force tx DMA to Queue0 \n"); return 0; } else if(rt2880_hdrlen == 777) { force_queue_n = 3; printf("\n Force tx DMA is Disable !! \n"); return 0; } while(1) { regValue = RALINK_REG(PDMA_GLO_CFG); if((regValue & RX_DMA_BUSY)) { printf("\n RX_DMA_BUSY !!! "); continue; } if((regValue & TX_DMA_BUSY)) { printf("\n TX_DMA_BUSY !!! "); continue; } break; } regValue=RALINK_REG(PDMA_GLO_CFG); udelay(100); regValue &= 0x0000FFFF; regValue |= (rt2880_hdrlen << 16); RALINK_REG(PDMA_GLO_CFG)=regValue; udelay(500); regValue=RALINK_REG(PDMA_GLO_CFG); printf("\n Set Scatter Length = %d \n",rt2880_hdrlen); printf("\n PDMA_GLO_CFG=%08X \n",regValue); return 0; } U_BOOT_CMD( hdrlen, 2, 2, set_scatter_len, "hdrlen - Specify the header segment size in byte !!\n", "hdrlen [size] - Specify the header segment size in byte !!\n" ); #endif // RALINK_GDMA_SCATTER_TEST_FUN // #ifdef RALINK_CACHE_STATE_DETECT_FUNC static inline void mips_cache_set(u32 v) { asm volatile ("mtc0 %0, $16" : : "r" (v)); } int set_cache_state(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { u32 kk; kk = simple_strtoul(argv[1], NULL, 10); mips_cache_set(kk); switch(kk) { case 0: printf("\n Set to CONF_CM_CACHABLE_NO_WA \n"); break; case 1: printf("\n Set to CONF_CM_CACHABLE_WA \n"); break; case 2: printf("\n Set to CONF_CM_UNCACHED \n"); break; case 3: printf("\n Set to CONF_CM_CACHABLE_NONCOHERENT \n"); break; case 4: printf("\n Set to CONF_CM_CACHABLE_CE \n"); break; }; return 0; } U_BOOT_CMD( cache_set, 2, 2, set_cache_state, "cache_set - Specify the header segment size in byte !!\n", "cache_set [value] - CONF_CM_CACHABLE_NO_WA 0 \n CONF_CM_CACHABLE_WA 1 \nCONF_CM_UNCACHED 2\nCONF_CM_CACHABLE_NONCOHERENT 3\nCONF_CM_CACHABLE_CE 4 \n" ); #endif // RALINK_CACHE_STATE_DETECT_FUNC // #ifdef RALINK_SEGMENT_SIZE_ALIGN_TEST_FUNC int rt2880_sdpx_16n_plus_x(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { if (argc != 2) { printf ("Usage:\n%s\n", cmdtp->usage); return ; } if(!memcmp(argv[0],"sdp.0",sizeof("sdp.0"))) { sdp0_alig_16n_x = simple_strtoul(argv[1], NULL, 10); printf("\n Set SDP0 alignment to 16N+%d\n",sdp0_alig_16n_x); } else if(!memcmp(argv[0],"sdp.1",sizeof("sdp.1"))) { sdp1_alig_16n_x = simple_strtoul(argv[1], NULL, 10); printf("\n Set SDP1 alignment to 16N+%d\n",sdp1_alig_16n_x); } return 0; } U_BOOT_CMD( sdp, 2, 2, rt2880_sdpx_16n_plus_x, "sdp - \n", "sdp.0 x x:[0,4,8,12] - set SDP0 alignment to 16N+x \n" "sdp.1 x x:[0,4,8,12] - set SDP1 alignment to 16N+x \n" ); #endif // RALINK_SEGMENT_SIZE_ALIGN_TEST_FUNC // #ifdef RALINK_INTERNAL_LOOPBACK_TEST_FUNC static int ETH_EN=0; static volatile uchar *NetTxPacket1,*NetTxPacket2,*NetTxPacket3; /* THE transmit packet */ /****************************************************************************** * * FUNCTION: Gsw_Setup_Transmit_Packet * PURPOSE: * ******************************************************************************/ int Gsw_Setup_AllOne_Transmit_Packet(struct eth_device* dev,int len,u8 patten, u8 *ptr) { u32 ii; u8 *temp_ptr; temp_ptr = ptr; // setup da ptr[0] = patten; ptr[1] = patten; ptr[2] = patten; ptr[3] = patten; ptr[4] = patten; ptr[5] = patten; ptr += 6; // setup sa // setup da ptr[0] = patten; ptr[1] = patten; ptr[2] = patten; ptr[3] = patten; ptr[4] = patten; ptr[5] = patten; ptr += 6; // setup type *ptr++ = patten; *ptr++ = patten; // setup payload for (ii = 0; ii < len; ii++) { *ptr++ = patten;//(ii + 1); } return ((int)(ptr - temp_ptr)); } /****************************************************************************** * * FUNCTION: Gsw_Setup_Transmit_Packet * PURPOSE: * ******************************************************************************/ int Gsw_Setup_Transmit_Packet(struct eth_device* dev,int len,u8 patten, u8 *ptr) { u32 ii; u8 *temp_ptr; temp_ptr = ptr; // setup da ptr[0] = 0x00; ptr[1] = 0x01; ptr[2] = 0x02; ptr[3] = 0x03; ptr[4] = 0x99; ptr[5] = patten; ptr += 6; // setup sa memset(ptr, 0, 6); memcpy(ptr, dev->enetaddr, 6); ptr += 6; // inside vlan #ifdef INSIDE_VLAN *ptr++ = 0x81; *ptr++ = 0x00; *ptr++ = 0x00; *ptr++ = 0x02; #endif // setup type *ptr++ = 0x08; *ptr++ = 0x00; // setup payload for (ii = 0; ii < len; ii++) { *ptr++ = patten;//(ii + 1); } return ((int)(ptr - temp_ptr)); } void STOP_ETHRX(struct eth_device *dev) { s32 omr; omr=RALINK_REG(PDMA_GLO_CFG); udelay(100); omr &= ~(RX_DMA_EN) ; RALINK_REG(PDMA_GLO_CFG)=omr; udelay(500); } void rt2880_internal_loopback_test(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { int rx_cnt,tx_cnt,length,valid_sent_cnt,rand_payload; ulong t_start; uint i=0; printf("\n rt2880_internal_loopback_test \n"); if (argc != 3) { printf ("Usage:\n%s\n", cmdtp->usage); return ; } if(ETH_EN == 0) { is_internal_loopback_test = 1; rt2880_eth_setup(rt2880_pdev); is_internal_loopback_test = 0; t_start = get_timer(0); printf("\n Please watting 2 Sec !!,t_start=%08X \n",t_start); while(1) { if(get_timer(t_start)>= (2 * CONFIG_SYS_HZ)) { break; } } ETH_EN = 1; // return; } NetTxPacket = NULL; if (!NetTxPacket) { int i; /* * Setup packet buffers, aligned correctly. */ NetTxPacket = &PktBuf[0] + (PKTALIGN - 1); NetTxPacket -= (ulong)NetTxPacket % PKTALIGN; printf("\n NetTxPacket = 0x%08X \n",NetTxPacket); for (i = 0; i < PKTBUFSRX; i++) { NetRxPackets[i] = KSEG1ADDR(NetTxPacket + (i+1)*PKTSIZE_ALIGN); } } STOP_ETHRX(rt2880_pdev); NetTxPacket = KSEG1ADDR(NetTxPacket) ; NetTxPacket1 = NetRxPackets[0]; NetTxPacket2 = NetRxPackets[1]; NetTxPacket3 = NetRxPackets[2]; length = simple_strtoul(argv[1], NULL, 10); rand_payload = simple_strtoul(argv[2], NULL, 10); if(rand_payload == 1) { printf("\n Random Payload\n"); } else { printf("\n All %02X patten\n",rand_payload); } //length = simple_strtoul(argv[3], NULL, 10); printf("\n length = %d \n",length); internal_loopback_test = INTERNAL_LOOPBACK_ENABLE; #if 1 //Jerry test while(!kaiker_button_p()) { if(rand_payload == 1) { length = Gsw_Setup_Transmit_Packet(rt2880_pdev,length - 14,(u8)i/*((0x30 + tx_queue_num) % 0x30)*/,NetTxPacket); if(rt2880_eth_send(rt2880_pdev,NetTxPacket,length) == -1) { printf("\n Internal loopback, Send packet is fail !! \n"); break; } i++; } else { length = Gsw_Setup_AllOne_Transmit_Packet(rt2880_pdev,length - 14,rand_payload,NetTxPacket); if(rt2880_eth_send(rt2880_pdev,NetTxPacket,length) == -1) { printf("\n Internal loopback, Send packet is fail !! \n"); break; } } } #else if(random_queue_act == ENABLE) { Gsw_Setup_Transmit_Packet(rt2880_pdev,length - 14,((0x30 + 0) % 0x30),NetTxPacket); Gsw_Setup_Transmit_Packet(rt2880_pdev,length - 14,((0x30 + 1) % 0x30),NetTxPacket1); Gsw_Setup_Transmit_Packet(rt2880_pdev,length - 14,((0x30 + 2) % 0x30),NetTxPacket2); Gsw_Setup_Transmit_Packet(rt2880_pdev,length - 14,((0x30 + 3) % 0x30),NetTxPacket3); printf("\n Created four packets for sequence queue change! \n"); //print_packet(NetTxPacket,length); //print_packet(NetTxPacket1,length); //print_packet(NetTxPacket2,length); //print_packet(NetTxPacket3,length); } else { length = Gsw_Setup_Transmit_Packet(rt2880_pdev,length - 14,((0x30 + tx_queue_num) % 0x30),NetTxPacket); } // for(i=0;i < tx_cnt ; i++) { //printf("\n Tx Count[%d]\n",i); if(random_queue_act == ENABLE) { tx_queue_num = i % 4; if(tx_queue_num == 0) { if(rt2880_eth_send(rt2880_pdev,NetTxPacket,length) == -1) { printf("\n Internal loopback, Send packet is fail !! \n"); break; } } else if(tx_queue_num == 1) { if(rt2880_eth_send(rt2880_pdev,NetTxPacket1,length) == -1) { printf("\n Internal loopback, Send packet is fail !! \n"); break; } } else if(tx_queue_num == 2) { if(rt2880_eth_send(rt2880_pdev,NetTxPacket2,length) == -1) { printf("\n Internal loopback, Send packet is fail !! \n"); break; } } else if(tx_queue_num == 3) { if(rt2880_eth_send(rt2880_pdev,NetTxPacket3,length) == -1) { printf("\n Internal loopback, Send packet is fail !! \n"); break; } } } else { length = Gsw_Setup_Transmit_Packet(rt2880_pdev,length - 14,i/*((0x30 + tx_queue_num) % 0x30)*/,NetTxPacket); if(rt2880_eth_send(rt2880_pdev,NetTxPacket,length) == -1) { printf("\n Internal loopback, Send packet is fail !! \n"); break; } } } #endif //rt2880_eth_halt(rt2880_pdev); //STOP_ETH(rt2880_pdev); internal_loopback_test = INTERNAL_LOOPBACK_DISABLE; } U_BOOT_CMD( interloopback, 3, 2, rt2880_internal_loopback_test, "interloopback - \n", "interloopback Ralink designed test !! \n" "interloopback [created packet length] [fix patten](0 or 0x2~0xFF,1:random patten)\n" ); #endif // RALINK_INTERNAL_LOOPBACK_TEST_FUNC // #ifdef RALINK_SDRAM_CONTROLLER_REFRESH_CYCLE_TEST_FUNC #define RALINK_SDRAM_CFG1 *(volatile u32 *)(RALINK_SYSCTL_BASE + 0x0304) int rt2880_auto_refresh_test(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { u32 len = 0x00100000; u32 refresh_period,tmp,t_start; int ii,kk = 2; volatile uchar *uncache_addr; if (argc != 3) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } //uncache_addr = (uchar *)(((u32)&Pkt_Buf_Pool[0] & 0x0FFFFFFF) | 0xA0000000); uncache_addr = (uchar *)(((u32)0x8a100000 & 0x0FFFFFFF) | 0xA0000000); printf("\n Test Memory Size:%d ,Address:[0x%08X] \n",len,uncache_addr); refresh_period = simple_strtoul(argv[1], NULL, 16); refresh_period &= 0x0000FFFF; kk = simple_strtoul(argv[2], NULL, 10); printf("\n Set 0x%04X clock cycles with auto refresh testing !! \n",refresh_period); for(ii=0 ; ii < len ; ii++) uncache_addr[ii] = ii % 0xFF; tmp = RALINK_SDRAM_CFG1; tmp &= 0xFFFF0000; tmp |= refresh_period; RALINK_SDRAM_CFG1 = tmp; tmp = RALINK_SDRAM_CFG1; printf("\n Set 0x%08X to RALINK_SDRAM_CFG1 \n", tmp); printf("\n Wait %d sec \n", kk); t_start = get_timer(0); while(get_timer(t_start)<= (kk * CONFIG_SYS_HZ)); printf("\n Start testing !!\n"); for(ii=0 ; ii < len ; ii++) { if(uncache_addr[ii] != ii % 0xFF) { printf("\n Fail !! addr[0x%08X],The fail's content:[%02X].The right's content:[%02X]\n", &uncache_addr[ii],uncache_addr[ii],ii % 0xFF); } } printf("\n Test finish !!\n"); printf("\n\n\n\n"); return 0; } U_BOOT_CMD( refresh, 3, 2, rt2880_auto_refresh_test, "refresh - \n", "refresh Ralink designed test !! \n" "refresh [tx counter] [created packet length]\n" ); #endif // RALINK_SDRAM_CONTROLLER_REFRESH_CYCLE_TEST_FUNC // #if defined (RALINK_GDMA_SCATTER_TEST_FUN) || defined (RALINK_GDMA_DUP_TX_RING_TEST_FUN) int rt2880_gmac_dma_test(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { if(!memcmp(argv[1],"scatter",sizeof("scatter"))) { #ifdef RALINK_GDMA_SCATTER_TEST_FUN if(!memcmp(argv[2],"off",sizeof("off"))) { printf("\n Header and payload scatter is disable !!\n"); header_payload_scatter_en = DISABLE; } else { printf("\n Header and payload scatter is Enable !!\n"); header_payload_scatter_en = ENABLE; } #endif // RALINK_GDMA_SCATTER_TEST_FUN // } else if(!memcmp(argv[1],"dup_tx_ring",sizeof("dup_tx_ring"))) { #ifdef RALINK_GDMA_DUP_TX_RING_TEST_FUN if(!memcmp(argv[2],"off",sizeof("off"))) { printf("\n dup_tx_ring is disable !!\n"); header_payload_scatter_en = DISABLE; } else { printf("\n dup_tx_ring is Enable !!\n"); header_payload_scatter_en = ENABLE; } #endif // RALINK_GDMA_DUP_TX_RING_TEST_FUN // } // *PKT_HEADER_Buf;// = (uchar *)CFG_EMBEDED_SRAM_SDP0_BUF_START; return 0; } U_BOOT_CMD( dmatest, 3, 2, rt2880_gmac_dma_test, "dmatest - \n", "dmatest scatter on/off,Header and payload scatter enable/disable \n" "dmatest [tx counter] [created packet length]\n" ); #endif // RALINK_GDMA_SCATTER_TEST_FUN #ifdef RALINK_SWITCH_DEBUG_FUN #define RALINK_VLAN_ID_BASE (RALINK_ETH_SW_BASE + 0x50) #define RALINK_VLAN_MEMB_BASE (RALINK_ETH_SW_BASE + 0x70) #define RALINK_TABLE_SEARCH (RALINK_ETH_SW_BASE + 0x24) #define RALINK_TABLE_STATUS0 (RALINK_ETH_SW_BASE + 0x28) #define RALINK_TABLE_STATUS1 (RALINK_ETH_SW_BASE + 0x2c) #define RALINK_TABLE_STATUS2 (RALINK_ETH_SW_BASE + 0x30) #define RALINK_WT_MAC_AD0 (RALINK_ETH_SW_BASE + 0x34) #define RALINK_WT_MAC_AD1 (RALINK_ETH_SW_BASE + 0x38) #define RALINK_WT_MAC_AD2 (RALINK_ETH_SW_BASE + 0x3C) #define RALINK_WT_MAC_AD2 (RALINK_ETH_SW_BASE + 0x3C) void table_dump(void) { int i, j, value, mac; int vid[16]; for (i = 0; i < 8; i++) { value = RALINK_REG(RALINK_VLAN_ID_BASE + 4*i); vid[2 * i] = value & 0xfff; vid[2 * i + 1] = (value & 0xfff000) >> 12; } RALINK_REG(RALINK_TABLE_SEARCH) = 0x1; printf("hash port(0:6) vidx vid age mac-address filt\n"); for (i = 0; i < 0x400; i++) { while(1) { value = RALINK_REG(RALINK_TABLE_STATUS0); if (value & 0x1) { //search_rdy if ((value & 0x70) == 0) { printf("found an unused entry (age = 3'b000), please check!\n"); return; } printf("%03x: ", (value >> 22) & 0x3ff); //hash_addr_lu j = (value >> 12) & 0x7f; //r_port_map printf("%c", (j & 0x01)? '1':'-'); printf("%c", (j & 0x02)? '1':'-'); printf("%c", (j & 0x04)? '1':'-'); printf("%c", (j & 0x08)? '1':'-'); printf("%c ", (j & 0x10)? '1':'-'); printf("%c", (j & 0x20)? '1':'-'); printf("%c", (j & 0x40)? '1':'-'); printf(" %2d", (value >> 7) & 0xf); //r_vid printf(" %4d", vid[(value >> 7) & 0xf]); printf(" %1d", (value >> 4) & 0x7); //r_age_field mac = RALINK_REG(RALINK_TABLE_STATUS2); printf(" %08x", mac); mac = RALINK_REG(RALINK_TABLE_STATUS1); printf("%04x", (mac & 0xffff)); printf(" %c\n", (value & 0x8)? 'y':'-'); if (value & 0x2) { printf("end of table %d\n", i); return; } break; } else if (value & 0x2) { //at_table_end printf("found the last entry %d (not ready)\n", i); return; } udelay(5000); } RALINK_REG(RALINK_TABLE_SEARCH) = 0x2; //search for next address } } void table_add(int argc, char *argv[]) { int i, j, value, is_filter; char tmpstr[9]; is_filter = (argv[1][0] == 'f')? 1 : 0; if (!argv[2] || strlen(argv[2]) != 12) { printf("MAC address format error, should be of length 12\n"); return; } strncpy(tmpstr, argv[2], 8); tmpstr[8] = '\0'; value = simple_strtoul(tmpstr, NULL, 16); RALINK_REG(RALINK_WT_MAC_AD2) = value; strncpy(tmpstr, argv[2]+8, 4); tmpstr[4] = '\0'; value = simple_strtoul(tmpstr, NULL, 16); RALINK_REG(RALINK_WT_MAC_AD1) = value; if (!argv[3] || strlen(argv[3]) != 7) { if (is_filter) argv[3] = "1111111"; else { printf("portmap format error, should be of length 7\n"); return; } } j = 0; for (i = 0; i < 7; i++) { if (argv[3][i] != '0' && argv[3][i] != '1') { printf("portmap format error, should be of combination of 0 or 1\n"); return; } j += (argv[3][i] - '0') * (1 << i); } value = j << 12; //w_port_map if (argc > 4) { j = simple_strtoul(argv[4], NULL, 0); if (j < 0 || 15 < j) { printf("wrong member index range, should be within 0~15\n"); return; } value += (j << 7); //w_index } if (argc > 5) { j = simple_strtoul(argv[5], NULL, 0); if (j < 1 || 7 < j) { printf("wrong age range, should be within 1~7\n"); return; } value += (j << 4); //w_age_field } else value += (7 << 4); //w_age_field if (is_filter) value |= (1 << 3); //sa_filter value += 1; //w_mac_cmd RALINK_REG(RALINK_WT_MAC_AD0) = value; for (i = 0; i < 20; i++) { value = RALINK_REG(RALINK_WT_MAC_AD0); if (value & 0x2) { //w_mac_done printf("done.\n"); return; } udelay(1000); } if (i == 20) printf("timeout.\n"); } void table_del(int argc, char *argv[]) { int i, j, value; char tmpstr[9]; if (!argv[2] || strlen(argv[2]) != 12) { printf("MAC address format error, should be of length 12\n"); return; } strncpy(tmpstr, argv[2], 8); tmpstr[8] = '\0'; value = simple_strtoul(tmpstr, NULL, 16); RALINK_REG(RALINK_WT_MAC_AD2) = value; strncpy(tmpstr, argv[2]+8, 4); tmpstr[4] = '\0'; value = simple_strtoul(tmpstr, NULL, 16); RALINK_REG(RALINK_WT_MAC_AD1) = value; value = 0; if (argc > 3) { j = simple_strtoul(argv[3], NULL, 0); if (j < 0 || 15 < j) { printf("wrong member index range, should be within 0~15\n"); return; } value += (j << 7); //w_index } value += 1; //w_mac_cmd RALINK_REG(RALINK_WT_MAC_AD0) = value; for (i = 0; i < 20; i++) { value = RALINK_REG(RALINK_WT_MAC_AD0); if (value & 0x2) { //w_mac_done if (argv[1] != NULL) printf("done.\n"); return; } udelay(1000); } if (i == 20) printf("timeout.\n"); } void table_clear(void) { int i, value, mac; char v[2][13]; char *argv[4]; memset(argv, 0, sizeof(v)); memset(argv, 0, sizeof(argv)); RALINK_REG(RALINK_TABLE_SEARCH) = 0x1; for (i = 0; i < 0x400; i++) { while(1) { value = RALINK_REG(RALINK_TABLE_STATUS0); if (value & 0x1) { //search_rdy if ((value & 0x70) == 0) { return; } sprintf(v[1], "%d", (value >> 7) & 0xf); mac = RALINK_REG(RALINK_TABLE_STATUS2); sprintf(v[0], "%08x", mac); mac = RALINK_REG(RALINK_TABLE_STATUS1); sprintf(v[0]+8, "%04x", (mac & 0xffff)); argv[2] = v[0]; argv[3] = v[1]; table_del(4, argv); if (value & 0x2) { return; } break; } else if (value & 0x2) { //at_table_end return; } udelay(5000); } RALINK_REG(RALINK_TABLE_SEARCH) = 0x2; //search for next address } } void vlan_dump(void) { int i, vid, value; printf("idx vid portmap\n"); for (i = 0; i < 8; i++) { vid = RALINK_REG(RALINK_VLAN_ID_BASE + 4*i); value = RALINK_REG(RALINK_VLAN_MEMB_BASE + 4*(i/2)); printf(" %2d %4d ", 2*i, vid & 0xfff); if (i%2 == 0) { printf("%c", (value & 0x00000001)? '1':'-'); printf("%c", (value & 0x00000002)? '1':'-'); printf("%c", (value & 0x00000004)? '1':'-'); printf("%c", (value & 0x00000008)? '1':'-'); printf("%c", (value & 0x00000010)? '1':'-'); printf("%c", (value & 0x00000020)? '1':'-'); printf("%c\n", (value & 0x00000040)? '1':'-'); } else { printf("%c", (value & 0x00010000)? '1':'-'); printf("%c", (value & 0x00020000)? '1':'-'); printf("%c", (value & 0x00040000)? '1':'-'); printf("%c", (value & 0x00080000)? '1':'-'); printf("%c", (value & 0x00100000)? '1':'-'); printf("%c", (value & 0x00200000)? '1':'-'); printf("%c\n", (value & 0x00400000)? '1':'-'); } printf(" %2d %4d ", 2*i+1, ((vid & 0xfff000) >> 12)); if (i%2 == 0) { printf("%c", (value & 0x00000100)? '1':'-'); printf("%c", (value & 0x00000200)? '1':'-'); printf("%c", (value & 0x00000400)? '1':'-'); printf("%c", (value & 0x00000800)? '1':'-'); printf("%c", (value & 0x00001000)? '1':'-'); printf("%c", (value & 0x00002000)? '1':'-'); printf("%c\n", (value & 0x00004000)? '1':'-'); } else { printf("%c", (value & 0x01000000)? '1':'-'); printf("%c", (value & 0x02000000)? '1':'-'); printf("%c", (value & 0x04000000)? '1':'-'); printf("%c", (value & 0x08000000)? '1':'-'); printf("%c", (value & 0x10000000)? '1':'-'); printf("%c", (value & 0x20000000)? '1':'-'); printf("%c\n", (value & 0x40000000)? '1':'-'); } } } void vlan_set(int argc, char *argv[]) { int i, j, value; int idx, vid; if (argc != 6) { printf("insufficient arguments!\n"); return; } idx = simple_strtoul(argv[3], NULL, 0); if (idx < 0 || 15 < idx) { printf("wrong member index range, should be within 0~15\n"); return; } vid = simple_strtoul(argv[4], NULL, 0); if (vid < 0 || 0xfff < vid) { printf("wrong vlan id range, should be within 0~4095\n"); return; } if (strlen(argv[5]) != 7) { printf("portmap format error, should be of length 7\n"); return; } j = 0; for (i = 0; i < 7; i++) { if (argv[5][i] != '0' && argv[5][i] != '1') { printf("portmap format error, should be of combination of 0 or 1\n"); return; } j += (argv[5][i] - '0') * (1 << i); } //set vlan identifier value = RALINK_REG(RALINK_VLAN_ID_BASE + 4*(idx/2)); if (idx % 2 == 0) { value &= 0xfff000; value |= vid; } else { value &= 0xfff; value |= (vid << 12); } RALINK_REG(RALINK_VLAN_ID_BASE + 4*(idx/2)) = value; //set vlan member value = RALINK_REG(RALINK_VLAN_MEMB_BASE + 4*(idx/4)); if (idx % 4 == 0) { value &= 0xffffff00; value |= j; } else if (idx % 4 == 1) { value &= 0xffff00ff; value |= (j << 8); } else if (idx % 4 == 2) { value &= 0xff00ffff; value |= (j << 16); } else { value &= 0x00ffffff; value |= (j << 24); } RALINK_REG(RALINK_VLAN_MEMB_BASE + 4*(idx/4)) = value; } int rt3052_switch_command(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { if (argc < 2) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } if (argc == 2) { if (!strncmp(argv[1], "dump", 5)) table_dump(); else if (!strncmp(argv[1], "clear", 6)) { table_clear(); printf("done.\n"); } else { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } } else if (!strncmp(argv[1], "add", 4)) table_add(argc, argv); else if (!strncmp(argv[1], "filt", 5)) table_add(argc, argv); else if (!strncmp(argv[1], "del", 4)) table_del(argc, argv); else if (!strncmp(argv[1], "vlan", 5)) { if (argc < 3) printf ("Usage:\n%s\n", cmdtp->usage); if (!strncmp(argv[2], "dump", 5)) vlan_dump(); else if (!strncmp(argv[2], "set", 4)) vlan_set(argc, argv); else printf ("Usage:\n%s\n", cmdtp->usage); } else { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } return 0; } U_BOOT_CMD( switch, 6, 1, rt3052_switch_command, "switch - rt3052 embedded switch command\n", "switch dump - dump switch table\n" "switch clear - clear switch table\n" "switch add [mac] [portmap] - add an entry to switch table\n" "switch add [mac] [portmap] [vlan idx] - add an entry to switch table\n" "switch add [mac] [portmap] [vlan idx] [age] - add an entry to switch table\n" "switch filt [mac] - add an SA filtering entry (with portmap 1111111) to switch table\n" "switch filt [mac] [portmap] - add an SA filtering entry to switch table\n" "switch filt [mac] [portmap] [vlan idx] - add an SA filtering entry to switch table\n" "switch filt [mac] [portmap] [vlan idx] [age] - add an SA filtering entry to switch table\n" "switch del [mac] - delete an entry from switch table\n" "switch del [mac] [vlan idx] - delete an entry from switch table\n" "switch vlan dump - dump switch table\n" "switch vlan set [vlan idx] [vid] [portmap] - set vlan id and associated member\n" ); #endif // RALINK_SWITCH_DEBUG_FUN // #ifdef RALINK_PCI_HOST_TEST_FUN //========================================================== // PCI test //========================================================== // PCI Bus MAX define #define PCIB_MAX_DEVICE_TYPE_NUM 0x13 #define PCIB_MAX_BAR_NUM 0x02 #define PCIB_MAX_BUS_NUM 0x01 //bit[23-16], #define PCIB_MAX_DEVICE_NUM 0x13 //bit[15-11] #define PCIB_MAX_FUNCTION_NUM 0x04 //bit[10-8] #define PCIB_MAX_REG_NUM 0x3c //bit[7-2] // PCIB Config define #define PCIB_CONFIG_EN 0x80000000 #define PCIB_BUS_NUM_BASE 0x10000 #define PCIB_DEV_NUM_BASE 0x800 #define PCIB_FUN_NUM_BASE 0x100 #define PCIB_REG_NUM_BASE 0x4 u32 sys_read_pci_config_word(PCIDeviceIDStruct PCIDeviceID, u32 Reg) //for Bridge only { u32 uwData,ii; PCIDeviceID.Enable = 1; #if 0 PCIDeviceID.RegNum = Reg; PCI_BRIDGE_CONFIG_ADDR= *(u32*)&PCIDeviceID; #else PCIDeviceID.RegNum = Reg>>2; PCI_BRIDGE_CONFIG_ADDR= PCIB_CONFIG_EN +PCIDeviceID.BusNum*PCIB_BUS_NUM_BASE +PCIDeviceID.DevNum*PCIB_DEV_NUM_BASE+PCIDeviceID.FunNum*PCIB_FUN_NUM_BASE +PCIDeviceID.RegNum*PCIB_REG_NUM_BASE; #endif for (ii=0;ii<1000;ii++); uwData = PCI_BRIDGE_CONFIG_DATA; return uwData; } u16 sys_read_pci_config_halfword(PCIDeviceIDStruct PCIDeviceID, u32 Reg)//for Bridge only { u32 lw; lw = sys_read_pci_config_word(PCIDeviceID, (Reg&0xfc)); switch(Reg % 4) { case 0: case 1: lw &= 0x0000FFFF; break; case 2: case 3: lw &= 0xFFFF0000; lw = lw >> 16; break; } return (u16)lw; } u8 sys_read_pci_config_byte(PCIDeviceIDStruct PCIDeviceID, u32 Reg)//for Bridge only { u32 lw; lw = sys_read_pci_config_word(PCIDeviceID, (Reg&0xfc)); switch(Reg % 4) { case 0: lw &= 0x000000FF; break; case 1: lw &= 0x0000FF00; lw = lw >> 8; break; case 2: lw &= 0x00FF0000; lw = lw >> 16; break; case 3: lw &= 0xFF000000; lw = lw >> 24; break; } return (u8)lw; } void sys_write_pci_config_word(PCIDeviceIDStruct PCIDeviceID, u32 Reg, u32 data)//for Bridge only { u32 ii; PCIDeviceID.Enable = 1; #if 0 PCIDeviceID.RegNum = (Reg&0xfc); PCI_BRIDGE_CONFIG_ADDR= *(u32 *)&PCIDeviceID; #else PCIDeviceID.RegNum = (Reg&0xfc)>>2; PCI_BRIDGE_CONFIG_ADDR= PCIB_CONFIG_EN +PCIDeviceID.BusNum*PCIB_BUS_NUM_BASE +PCIDeviceID.DevNum*PCIB_DEV_NUM_BASE+PCIDeviceID.FunNum*PCIB_FUN_NUM_BASE +PCIDeviceID.RegNum*PCIB_REG_NUM_BASE; #endif for (ii=0;ii<1000;ii++); PCI_BRIDGE_CONFIG_DATA = data; } void sys_write_pci_config_halfword(PCIDeviceIDStruct PCIDeviceID, u32 Reg, u16 data)//for Bridge only { u32 lw; lw = sys_read_pci_config_word(PCIDeviceID, (Reg&0xfc)); switch(Reg % 4) { case 0: case 1: lw &= 0xFFFF0000; lw += data; sys_write_pci_config_word(PCIDeviceID, (Reg&0xfc), lw); break; case 2: case 3: lw &= 0x0000FFFF; lw += (u32)(((u32)data) << 16); sys_write_pci_config_word(PCIDeviceID, (Reg&0xfc), lw); break; } } void sys_write_pci_config_byte(PCIDeviceIDStruct PCIDeviceID, u32 Reg, u8 data)//for Bridge only { u32 lw; lw = sys_read_pci_config_word(PCIDeviceID, (Reg&0xfc)); switch (Reg % 4) { case 0: lw &= 0xFFFFFF00; lw += data; sys_write_pci_config_word(PCIDeviceID, (Reg&0xfc), lw); break; case 1: lw &= 0xFFFF00FF; lw += (u32)(((u32)data) << 8); sys_write_pci_config_word(PCIDeviceID, (Reg&0xfc), lw); break; case 2: lw &= 0xFF00FFFF; lw += (u32)(((u32)data) << 16); sys_write_pci_config_word(PCIDeviceID, (Reg&0xfc), lw); break; case 3: lw &= 0x00FFFFFF; lw += (u32)(((u32)data) << 24); sys_write_pci_config_word(PCIDeviceID, (Reg&0xfc), lw); break; } } void kaiker_AssignPCIResource(PCIDeviceIDStruct PCIDeviceID , u32 *PciMemStart, u32 *PciIoStart) { u32 lw,ii,jj, Reg, BaseAddrReg, BaseSize; u32 dwAlignmentSize; u32 device_id; device_id = sys_read_pci_config_word(PCIDeviceID, 0x00); // read Device ID for (ii = 0 ; ii < PCIB_MAX_BAR_NUM ; ii++) //BAR_NUM:0x06 { Reg = PCI_CSH_BASE_ADDR_REG + (ii * 4); //0x10+4xi sys_write_pci_config_word(PCIDeviceID, Reg, 0xFFFFFFFF); //write 0xffffffff,then lw = sys_read_pci_config_word(PCIDeviceID, Reg); // read back value printf("\n\n******BAR%d= 0x%08x ***********\n",ii,lw); if ((lw == 0) || ((lw & 0xffffffff) == 0xffffffff)) { printf("Base Address Register %d is not exist !!\n",ii); continue; } else /* else-if */ { if ((lw & 0x01) != 0x00) /* it's IO base */ { if(device_id == PCI_BRIDGE_DEVICE_VENDOR_ID) /*If current device is PCI bridge*/ { //Open all mem space #if 1 RALINK_PCI_BAR0SETUP_ADDR = 0xFFFF0001;//Open 2G mem space RALINK_PCI_BAR1SETUP_ADDR = 0xFFFF0001;//Open 2G mem space #endif RALINK_PCI_IMBASEBAR0_ADDR = 0; RALINK_PCI_IMBASEBAR1_ADDR = 0; sys_write_pci_config_word(PCIDeviceID, Reg, SYS_DDR_SDRAM_BASE_ADDR); printf("\nSet IO base of the PCI bridge\n"); printf("\n\n******write = 0x%08x *read = 0x%08x**********\n",SYS_DDR_SDRAM_BASE_ADDR,sys_read_pci_config_word(PCIDeviceID, Reg)); } else { lw >>= 2; // 31..2:base addr. for(jj=2; jj < 32; jj++) { if (lw & 0x01 == 0x01) //[b31..b2],only 1 bit will be "1" { break; //valid bit found, } lw >>= 1; } BaseSize = 1 << jj;// size is power of 2 if (BaseSize >= PCI_IO_SPACE_ALIGNMENT) //why:0x4,??? { dwAlignmentSize = BaseSize; } else { dwAlignmentSize = PCI_IO_SPACE_ALIGNMENT;//4 } printf("This is IO Base Space Register !\n The request of size is %d bytes\n",dwAlignmentSize); if ((*PciIoStart % dwAlignmentSize) != 0) { *PciIoStart = ((*PciIoStart / dwAlignmentSize) + 1) * dwAlignmentSize; } BaseAddrReg = *PciIoStart; *PciIoStart += BaseSize; // CurrentIOStart + Current_BaseSz => NextIOStart printf("set I/O base:0x%8x\n",BaseAddrReg); sys_write_pci_config_word(PCIDeviceID, Reg, BaseAddrReg); printf("\n\n******write = 0x%08x *read = 0x%08x**********\n",BaseAddrReg,sys_read_pci_config_word(PCIDeviceID, Reg)); } }//IO base else if((lw & 0x01) != 0x01) /* it's Memory base */ { if(device_id == PCI_BRIDGE_DEVICE_VENDOR_ID)/*If current device is PCI bridge*/ { printf("\nSet Memory base of the PCI bridge\n"); sys_write_pci_config_word(PCIDeviceID, Reg, SYS_DDR_SDRAM_BASE_ADDR); printf("\n\n******write = 0x%08x *read = 0x%08x**********\n",SYS_DDR_SDRAM_BASE_ADDR,sys_read_pci_config_word(PCIDeviceID, Reg)); } else { lw >>= 4; for (jj=4; jj < 32; jj++) { if (lw & 0x01 == 0x01) { break; } lw >>= 1; } BaseSize = 1 << jj; if (BaseSize>=PCI_MEM_SPACE_ALIGNMENT) //16 { dwAlignmentSize=BaseSize; } else { dwAlignmentSize=PCI_MEM_SPACE_ALIGNMENT; } printf("This is MEMORY Base Space Register !\n The request of size is %d bytes\n",dwAlignmentSize); if ((*PciMemStart % dwAlignmentSize) != 0) { *PciMemStart = ((*PciMemStart / dwAlignmentSize) + 1) * dwAlignmentSize; } BaseAddrReg = *PciMemStart; *PciMemStart += BaseSize; printf("set MEM base :0x%8x\n",BaseAddrReg); sys_write_pci_config_word(PCIDeviceID, Reg, BaseAddrReg); printf("\n\n******write = 0x%08x *read = 0x%08x**********\n",BaseAddrReg,sys_read_pci_config_word(PCIDeviceID, Reg)); } } } } } void Init_LatTimer_CacheSize(PCIDeviceIDStruct PCIDeviceID,u32 isMaster) { u32 CMDType; PCIDeviceID.RegNum = PCI_CSH_CACHE_LINE_SIZE_REG; CMDType = sys_read_pci_config_word(PCIDeviceID, PCI_CSH_CACHE_LINE_SIZE_REG); printf(" Init_LatTimer_CacheSize is called \n\n"); printf(" CACHE_LINE_SIZE_REG default value 0x%08x\n",CMDType); CMDType=CMDType & 0xFFFF0000; // if(isMaster) // { CMDType=CMDType | 0x00000014;//Cache size CMDType=CMDType | 0x00001000;//Latency Timer // } // else // CMDType=CMDType | 0x00001000;//Latency Timer sys_write_pci_config_word(PCIDeviceID, PCI_CSH_CACHE_LINE_SIZE_REG, CMDType); CMDType = sys_read_pci_config_word(PCIDeviceID, PCI_CSH_CACHE_LINE_SIZE_REG); printf(" CACHE_LINE_SIZE_REG Set value 0x%08x\n",CMDType); } //==================================================================== // * Function Name: flib_EnablePCIDevice (0708 => ok) // * Description: 1.Read Command register byte // 2.Enable BOTH IO/MEM space response // * Input: PCIDeviceID //==================================================================== void flib_EnablePCIDevice(PCIDeviceIDStruct PCIDeviceID) { u16 CMDType; PCIDeviceID.RegNum = PCI_CSH_COMMAND_REG; CMDType = sys_read_pci_config_halfword(PCIDeviceID, PCI_CSH_COMMAND_REG); printf(" flib_EnablePCIDevice is called \n\n"); printf(" COMMAND_REG default value 0x%04x\n",CMDType); printf(" Enable PCI DEV's IO & MEM space response\n"); sys_write_pci_config_halfword(PCIDeviceID, PCI_CSH_COMMAND_REG, CMDType | PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE|PCI_CMD_MEM_WRITE_INVALIDATE|PCI_CMD_FBB_ENABLE|PCI_CMD_SERR_ENABLE| PCI_CMD_STEPPING_CONTROL|PCI_CMD_PARITY_ERR); CMDType = sys_read_pci_config_halfword(PCIDeviceID, PCI_CSH_COMMAND_REG); printf(" COMMAND_REG Set value 0x%04x\n",CMDType); } //==================================================================== // * Function Name: flib_SetPCIMaster (0708 => ok) // * Description: 1.Read Command register byte // 2.Write Back (PCI_CMD_BUS_MASTER_ENABLE) // * Input: PCIDeviceID //==================================================================== void flib_SetPCIMaster(PCIDeviceIDStruct PCIDeviceID) { u32 CMDType; PCIDeviceID.RegNum = PCI_CSH_COMMAND_REG; // printf(" flib_SetPCIMaster is called \n\n"); //` printf(" COMMAND_REG default value 0x%2x\n",CMDType); CMDType = sys_read_pci_config_byte(PCIDeviceID, PCI_CSH_COMMAND_REG); printf(" PCI BUS master mode enable..\n"); sys_write_pci_config_byte(PCIDeviceID, PCI_CSH_COMMAND_REG, CMDType | PCI_CMD_BUS_MASTER_ENABLE); } void kaiker_PCI_Bridge_Test(void) { u32 uwFAIL_CNT=0,uwReadWord,uwResult,jj,Reg; u32 M_bass_address=PCI_ALLOCATE_SPACE,IO_bass_address=PCI_ALLOCATE_SPACE; //PCIDeviceIDStruct PCIDeviceID; /* * Using Random Value to test PCI bridge interl regsiter */ printf("=>Test Internal registers...\n"); for(jj=0;Finded_PCIDeviceID[jj].PCIDeviceID.Enable==1;jj++) { printf("- Get IO/MEMORY size and allocate space to the Dev%d \n",Finded_PCIDeviceID[jj].PCIDeviceID.DevNum); kaiker_AssignPCIResource(Finded_PCIDeviceID[jj].PCIDeviceID,&M_bass_address,&IO_bass_address); } //Enable the all device and set them to master. //Add by kaiker for(jj=0;Finded_PCIDeviceID[jj].PCIDeviceID.Enable==1;jj++) { printf("EnablePCIDevice,ID=0x%08x\n",Finded_PCIDeviceID[jj].dev_ven); flib_EnablePCIDevice(Finded_PCIDeviceID[jj].PCIDeviceID); // printf("\n PCIRAW = 0x%08X \n",*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x1004)); //*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x1004) = 0xFFFFFFFF; printf("SetPCIMaster!\n"); flib_SetPCIMaster(Finded_PCIDeviceID[jj].PCIDeviceID); //printf("\n PCIRAW = 0x%08X \n",*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x1004)); //*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x1004) = 0xFFFFFFFF; printf("Init_LatTimer_CacheSize!\n"); if(Finded_PCIDeviceID[jj].dev_ven != PCI_BRIDGE_DEVICE_VENDOR_ID) { Init_LatTimer_CacheSize(Finded_PCIDeviceID[jj].PCIDeviceID,0); } else { Init_LatTimer_CacheSize(Finded_PCIDeviceID[jj].PCIDeviceID,1); } //printf("\n PCIRAW = 0x%08X \n",*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x1004)); //*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x1004) = 0xFFFFFFFF; }//mask by kaiker //Add by kaiker } void kaiker_PCI_Scan_Bus_Test(void) { u32 ii,jj,kk,ll,mm; u32 ID,TempValue; int devnum=0,find_device=0; PCI_BRIDGE_CLOCK = 0x4; //printf("\n PCIRAW = 0x%08X \n",*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x1004)); *(volatile u_long *)(RALINK_PCI_BASE + 0x0004) = 0xFFFFFFFF; //le32_to_cpu(*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x1080)) = 0; udelay(5000); //PCI Device Scan (BUS/DEVICE/FUNCTION) printf("---------------Bus/Device/Function Scan --------------------------\n"); for (ii=0;ii < PCIB_MAX_BUS_NUM; ii++) {//bus printf(" --Bus %d Scan... \n",ii); for (jj=0;jj < PCIB_MAX_DEVICE_NUM; jj++) {//dev //Read the ID to check the exist of the device(Function-0) PCI_BRIDGE_CONFIG_ADDR = PCIB_CONFIG_EN + (ii*PCIB_BUS_NUM_BASE)+(jj*PCIB_DEV_NUM_BASE); udelay(500); printf(" --PCI_BRIDGE_CONFIG_ADDR 0x%x \n",PCI_BRIDGE_CONFIG_ADDR); ID = PCI_BRIDGE_CONFIG_DATA; if((ID != 0x00000000) && (ID != 0xFFFFFFFF)) //f0 {//DEV found find_device=1; printf(" --Device %d Found... Bus %d / Dev %d /Fun 0 => ID:0x%08x \n",jj,ii,jj,ID); // Dump the Config Space of the found DEV's Function-0 printf(" DEVICE(0x%08x)'s Configuration :\n",ID); Finded_PCIDeviceID[devnum].PCIDeviceID.BusNum = ii; Finded_PCIDeviceID[devnum].PCIDeviceID.DevNum = jj; Finded_PCIDeviceID[devnum].PCIDeviceID.FunNum = 0x00; Finded_PCIDeviceID[devnum].PCIDeviceID.Enable=1; Finded_PCIDeviceID[devnum].dev_ven=ID; // kaiker_PCI_Bridge_Test(); #if 1 #if 0 for (ll=0;ll<4 /*24*/;ll++) { //for (mm=0;mm<0x10000;mm++); printf(" Value read at 0x%02x is 0x%08x\n",(ll*4),sys_read_pci_config_word(Finded_PCIDeviceID[devnum].PCIDeviceID,(ll*4))); } #endif for (ll=0;ll<24;ll++) { PCI_BRIDGE_CONFIG_ADDR= PCIB_CONFIG_EN + Finded_PCIDeviceID[devnum].PCIDeviceID.BusNum*PCIB_BUS_NUM_BASE+ Finded_PCIDeviceID[devnum].PCIDeviceID.DevNum*PCIB_DEV_NUM_BASE+ Finded_PCIDeviceID[devnum].PCIDeviceID.FunNum*PCIB_FUN_NUM_BASE+ ll*4; printf(" Value read at 0x%02x is 0x%8x\n",(ll*4),PCI_BRIDGE_CONFIG_DATA); } #endif devnum++; }//DEV found #if 1 else //f0 { printf(" --Device %d Not Found... \n",jj); } #endif }//dev }//bus printf(" --PCIB Bus Scan Finish... \n"); //printf("\n PCIRAW = 0x%08X \n",*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x1004)); //*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x1004) = 0xFFFFFFFF; /*clear remnant of devices structl */ for(;devnumusage); return 1; } rand_fix = simple_strtoul(argv[1], NULL, 10); if(rand_fix) printf("\n random mem test \n"); else printf("\n linear mem test \n"); bd = gd_data.bd; printf("\n kaiker_rt2883_mem_test ==> bd->bi_reallocate_image_addr = 0x%08X\n",bd->bi_reallocate_image_addr); printf("\n kaiker_rt2883_mem_test ==> bd->bi_total_image_size = 0x%08X\n",bd->bi_total_image_size); #if 1 test_patten_source_w = (u32 *)TEST_PATTEN_BASE_ADDR; test_patten_source_hw = (u16 *)TEST_PATTEN_BASE_ADDR; test_patten_source_b = (u8 *)TEST_PATTEN_BASE_ADDR; test_max_size = bd->bi_total_image_size & ~0xF; printf("\n Test Max Size=%d[0x%08X] \n",test_max_size,test_max_size); test_patten = random(); seg0_base_ptr_w = (volatile u32 *)SDRAM_BASE_ADDR; seg0_base_ptr_hw = (volatile u16 *)SDRAM_BASE_ADDR; seg0_base_ptr_b = (volatile u8 *)SDRAM_BASE_ADDR; seg0_end_addr = (bd->bi_reallocate_image_addr & ~0xF) - 0x10; printf("\n Kaiker Memory test !!! \n\n\n"); printf("\n memtest base addr = %08X ,end addr = %08X,image size = 0x%X \n",seg0_base_ptr_w,seg0_end_addr,test_max_size); kk = 0; if (rand_fix) { printf("\n ================== random size and random Block test =============== \n"); printf("\n base addr = %08X ,end addr = %08X,length = 0x%X \n",seg0_base_ptr_w,seg0_end_addr,test_max_size); rt2883_ram_test_random(test_max_size,(u32)seg0_base_ptr_w); return 0; } test_max_size = bd->bi_memsize - test_max_size; test_max_size = test_max_size & ~(4096 - 1); while(!kaiker_button_p()) { #if 1 test_patten = random(); kk++; printf("\n //----------------------------------------------------"); printf("\n [%d]:test_patten = [%08X] ",kk,test_patten); printf("\n //----------------------------------------------------\n"); printf("\n Start Test Seg0 Address =%08X,len=0x%08X \n",seg0_base_ptr_w,test_max_size); printf("\n End Address =%08X \n",seg0_end_addr); printf("\n Write ,32 bit:\n"); for(ii=0 ; ii< (test_max_size / 4) ;ii++) { #ifdef USE_BLOCK_PATTEN seg0_base_ptr_w[ii] = test_patten_source_w[(ii % (test_max_size /4) )]; #else seg0_base_ptr_w[ii]= test_patten + ii; #endif } printf("\n Read and compare , 32 bit :\n"); for(ii=0 ; ii< (test_max_size / 4) ;ii++) { #ifdef USE_BLOCK_PATTEN if(seg0_base_ptr_w[ii]!= test_patten_source_w[(ii % (test_max_size /4) )]) #else if(seg0_base_ptr_w[ii]!= (test_patten + ii)) #endif { printf("\n Fail addr[%08X]=%X ,true value = %X\n",&seg0_base_ptr_w[ii],seg0_base_ptr_w[ii],(test_patten + ii)); while(1); } } //------------------------------------------- printf("\n Write ,16 bit:\n"); for(ii=0 ; ii< (test_max_size / 2) ;ii++) { #ifdef USE_BLOCK_PATTEN seg0_base_ptr_hw[ii] = test_patten_source_hw[(ii % (test_max_size / 2) )]; #else seg0_base_ptr_hw[ii]= (u16)((test_patten + ii) % 0xFFFF); #endif } printf("\n Read and compare , 16 bit :\n"); for(ii=0 ; ii< (test_max_size / 2) ;ii++) { #ifdef USE_BLOCK_PATTEN if(seg0_base_ptr_hw[ii]!= test_patten_source_hw[(ii % (test_max_size /2) )]) #else if(seg0_base_ptr_hw[ii]!= (u16)((test_patten + ii) % 0xFFFF)) #endif { printf("\n Fail addr[%08X]=%X ,true value = %04X\n",&seg0_base_ptr_hw[ii],seg0_base_ptr_hw[ii],(u16)((test_patten + ii) % 0xFFFF)); while(1); } } //------------------------------------------ printf("\n Write ,8 bit:\n"); for(ii=0 ; ii< (test_max_size) ;ii++) { #ifdef USE_BLOCK_PATTEN seg0_base_ptr_b[ii]= test_patten_source_b[(ii % (test_max_size) )]; #else seg0_base_ptr_b[ii]= (u8)((test_patten + ii) % 0xFF); #endif //printf("\n Write addr[%08X] = %d\n",&seg0_base_ptr_w[ii],ii); } printf("\n Read and compare , 8 bit :\n"); for(ii=0 ; ii< (test_max_size ) ;ii++) { #ifdef USE_BLOCK_PATTEN if(seg0_base_ptr_b[ii] != test_patten_source_b[(ii % (test_max_size) )]) #else if(seg0_base_ptr_b[ii]!= (u8)((test_patten + ii) % 0xFF)) #endif { printf("\n Fail addr[%08X]=%X,true value=%X \n",&seg0_base_ptr_b[ii],seg0_base_ptr_b[ii],(u8)((test_patten + ii) % 0xFF)); while(1); } } #endif // 1 // } #endif // 1 // return 0; } U_BOOT_CMD( kaiker_memtest, 2, 1, kaiker_rt2883_mem_test, "kaiker_memtest [0:fix/1:random] - Ralink memory test !!\n", "kaiker_memtest - \n" ); #endif // RALINK_MEMORY_TEST_FUN // #ifdef RT3052_PHY_TEST /* * 1. Setup Per Port VID * P0 <-> P1 * P2 <-> P3 * P4 <-> MII(PHY) * * 2. Map port to VLAN member * * 3. Remove tag enable for each recieving port * */ void rt3052_phy_loopback_routine(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void packet_dump(unsigned char* packet, unsigned int length) { int i, j, k; k = length / 10; printf("packet dump -- %d bytes\n", length); printf("\n-----------------------------\n"); for ( i = 0; i < length; i++) { printf("0x%02x ", packet[i]); if (( i % 10 ) == 9 ) printf("\n"); } printf("\n-----------------------------\n"); } void test_packet_init() { int i; BUFFER_ELEM *buf; if(!NetTxPacket) { // initial tx and rx buffers // printf("Inital NetTxPacket...\n"); buf = rt2880_free_buf_entry_dequeue(&rt2880_free_buf_list); NetTxPacket = buf->pbuf; // printf("NetTxPacket = 0x%08x\n", NetTxPacket); for ( i = 0; i < NUM_RX_DESC; i++) { buf = rt2880_free_buf_entry_dequeue(&rt2880_free_buf_list); if ( buf == NULL) { printf("NetRxPackets[%d] --- Buffer empty\n", i); return -1; } NetRxPackets[i] = buf->pbuf; // printf("NetRxPackets[%d] = 0x%08x\n", i, NetRxPackets[i]); memset(NetRxPackets[i], 0, PKTBUFSRX); } } NetTxPacket = KSEG1ADDR(NetTxPacket); // rt2880_eth_setup(rt2880_pdev); if (!phy_init_setup) { rt2880_eth_setup(rt2880_pdev); phy_init_setup = 1; } } unsigned int rt3052_ether_setup() { int i; unsigned int length = 100; u32 mdio_value; if (!phy_init_setup) { mii_mgr_read(0, 1, &mdio_value); printf("** Port0 Reg1 mdio data is 0x%08x\n", mdio_value); phy_link_detect(); // PVID initlize for each port // port 0 -> VID 1, port 1 -> VID2 *(unsigned long *)(RALINK_ETH_SW_BASE+0x0040) = 0x00002001; // port 2 -> VID3, port 3 -> VID4 *(unsigned long *)(RALINK_ETH_SW_BASE+0x0044) = 0x00004003; // port 4-> VID5, port 5(MII Port) -> VID6 *(unsigned long *)(RALINK_ETH_SW_BASE+0x0048) = 0x00006005; // port 6 -> VID7 (CPU Port) *(unsigned long *)(RALINK_ETH_SW_BASE+0x004c) = 0x00000007; // VLAN member set *(unsigned long *)(RALINK_ETH_SW_BASE+0x0070) = 0x48444241; *(unsigned long *)(RALINK_ETH_SW_BASE+0x0074) = 0x00406050; *(unsigned long *)(RALINK_ETH_SW_BASE+0x0078) = 0x0; *(unsigned long *)(RALINK_ETH_SW_BASE+0x007c) = 0x0; *(unsigned long *)(RALINK_ETH_SW_BASE+0x0094) = 0x00007f00; *(unsigned long *)(RALINK_ETH_SW_BASE+0x0098) = 0x00007f7f; // *(unsigned long *)(RALINK_ETH_SW_BASE+0x0098) = 0x00007fff; // let switch enter force mode // -> Let Link Up and 100MB Full // *(unsigned long *)(RALINK_ETH_SW_BASE+0x0084) = 0xffffff00; mii_mgr_read(0, 1, &mdio_value); printf("++ Port0 Reg1 mdio data is 0x%08x\n", mdio_value); } #if 0 mii_mgr_read(0, 1, &mdio_value); printf("*** mdio data is 0x%08x\n", mdio_value); #endif test_packet_init(); return 1; } void rt3052_ether_loopback_send(int port_no, int send_len) { int length; int i, hdr_offset; volatile uchar *pkt; VLAN_Ethernet_t *vlan; if ( send_len < 64) send_len = 64; pkt = NetTxPacket; vlan = (VLAN_Ethernet_t *)pkt; pkt += NetSetEther(pkt, NetBcastAddr, PROT_VLAN); vlan->vet_vlan_type = htons(ETH_P_8021Q); vlan->vet_tag = htons(port_no); hdr_offset = pkt - NetTxPacket + VLAN_ETHER_HDR_SIZE; for ( i = hdr_offset; i < send_len; i++) pkt[i] = i; memcpy(rt3052_phy_test_buf, NetTxPacket, send_len); rt2880_eth_send(rt2880_pdev, NetTxPacket, send_len); #if 0 printf("------\nsend packet :\n\n"); packet_dump(NetTxPacket, send_len); #endif } void rt3052_phy_loopback_routine(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { unsigned int port_no = 0, counter = 1; unsigned int test_len; int result, i; // loopback_dump_reg(); rt3052_phy_test = PHY_TEST_ENABLE; eth_loopback_mode = 0; if (argc < 2 ) { printf("%s\n",cmdtp->usage); return; } if (argc == 2) { // rt3052_ether_setup(); result = 0; port_no = simple_strtoul(argv[1], NULL, 10); //test_len = rt2880_eth_recv(rt2880_pdev); //printf("Phy Test Start -- %d %d\n", port_no, test_len); #if 0 test_len = 64; rt3052_ether_loopback_send(port_no, test_len); test_len = rt2880_eth_recv(rt2880_pdev); #endif udelay(100000); test_len = 64; if(port_no == 2) { udelay(200000);//1-based port_no2 need additional delay } rt3052_ether_loopback_send(port_no, test_len); udelay(50000); test_len = rt2880_eth_recv(rt2880_pdev); printf("Port#%d recv len for 64bytes - %d\n",port_no, test_len); if ( test_len == 60)//switch remove vlan result++; udelay(100000); test_len = 1518; rt3052_ether_loopback_send(port_no, test_len); udelay(50000); test_len = rt2880_eth_recv(rt2880_pdev); printf("Port#%d recv len for 1518bytes - %d\n",port_no, test_len); for ( i = 0; i < 1000; i++) test_nop(); if ((test_len == 1514) && (rt3052_phy_test_ret_code ==0) ) result++; #if 0 if ( result == 2 ) printf("\n--> Loopback packet received\n"); printf("---OK\n\r"); else printf("---Fail\n\r"); // printf("\n--> error %d\n\n", result); #endif rt3052_port_test_status = result; return 0; } if (argc == 3) test_len = 64; if (argc == 4) test_len = simple_strtoul(argv[3], NULL, 10); if (test_len < 64) test_len = 64; port_no = simple_strtoul(argv[1], NULL, 10); counter = simple_strtoul(argv[2], NULL, 10); for ( i = 0; i < counter; i++) { rt3052_ether_loopback_send(port_no, test_len); test_len = rt2880_eth_recv(rt2880_pdev); printf("%d len : %d\n", i, test_len); } rt3052_phy_test = PHY_TEST_DISABLE; eth_loopback_mode = 0; // loopback_dump_reg(); } U_BOOT_CMD( phytest, 4, 1,rt3052_phy_loopback_routine, "phytest - rt3052 loopback phy test\n", "phytest usage:\n" " phytest : Port # Loopback test.\n" ); int mac_link_status_check() { u32 port_ability; int data; port_ability = *(unsigned long *)(RALINK_ETH_SW_BASE+0x0080); data = (port_ability & 0x3e000000); return data; } int phy_mdio_link_check(u32 phy_addr) { u32 mdio_value; int ret; mii_mgr_write(0, 31, 0x8000); //---> select local register mii_mgr_read(phy_addr, 1, &mdio_value); //printf("mdio_value=%x\n",mdio_value); ret = (mdio_value & 0x4); mii_mgr_write(0, 31, 0x0); //select global register if (ret!=0) return 1; else return 0; } void phy_link_detect() { int i, data, mdio_poll_count; unsigned long port_ability, mem_test_info, phy_mdio_reg; int j=0; // force_phy_an(1); mem_test_info = *(unsigned long*)(RALINK_ETH_SW_BASE+0x00dc); #define MEM_TEST_BIT (1<<6) while(!(mem_test_info & MEM_TEST_BIT)) { mem_test_info = *(unsigned long*)(RALINK_ETH_SW_BASE+0x00dc); printf("#"); } printf("Port ability - 0x%08x\n", *(unsigned long*)(RALINK_ETH_SW_BASE+0x0080)); #if 0 while (!(phy_mdio_link_check())) test_nop(); #else while (1) { test_nop(); i = phy_mdio_link_check(0); if ( i ) break; j++; if(j>1000) { printf("j=%d Timeout Port0 phy_mdio_link_check\n\r", j); break; } } #endif } /* mode: 0 - 10Mb, 1 - 100Mb */ void force_phy_an(int mode) { int i, port; unsigned long mac_port_ability; #if 0 if ( mode == 1) *(unsigned long*) (RALINK_ETH_SW_BASE+0x0084) = 0xbf80bf1f; else *(unsigned long*) (RALINK_ETH_SW_BASE+0x0084) = 0xbf80bf00; #endif mii_mgr_write(0, 31, 0x8000); //---> select local register for ( port = 0; port < 5; port++) { mii_mgr_write(port, 21, 0x6f); test_nop(); if ( mode == 1) mii_mgr_write(port, 0, 0x2100);//force 100M else mii_mgr_write(port, 0, 0x100);//force 10M test_nop(); mii_mgr_write(port, 26, 0x1203); } if ( mode == 1 ) { while(1) { test_nop(); mac_port_ability = *(unsigned long *)(RALINK_ETH_SW_BASE+0x0080); printf("-- Force 100Mb phy ...POA:0x%08x\n", mac_port_ability); if ( mac_port_ability & 0x1f ) break; } } else { while(1) { test_nop(); mac_port_ability = *(unsigned long *)(RALINK_ETH_SW_BASE+0x0080); i = ~(mac_port_ability & 0x1f); printf("-- Force 10Mb phy ...POA:0x%08x\n", mac_port_ability); if ( i != 0) break; } } for ( i = 0; i < 10; i++) test_nop(); } void test_nop() { int i=0; for(i=0; i<60; i++) { ; } } /* * RT3052/RT3352 use different GPIO ouput to idicate results */ #if defined (RT3052_ASIC_BOARD) void gpio_led_init() { // switch gpio mode from uart full to gpio *(unsigned long*)(0xb0000060) |= 0x1f; // configure uart/gpio pin to output mode *(unsigned long*)(0xb0000624) |= 0x1f80; } void gpio_led_set(unsigned long reg_val) { *(unsigned long*)(0xb0000620) = reg_val; } void light_led(int led_no) { led_no += 8; *(unsigned long*)(0xb0000620) |= (1 << led_no); } void rt3052_phy_batch(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { int j, i, result, i_success_count = 0; char phy_test_cmd[100]; uchar port_test_10M[5]; uchar port_test_100M[5]; unsigned long gpio_led, reg_counter, mdio_value; #if 1 // *(unsigned long *)(RALINK_ETH_SW_BASE+0x0084) = 0xffd01f00; gpio_led_init(); gpio_led_set(0); gpio_led_set(0x200); #endif rt3052_ether_setup(); force_phy_an(0); //force 10M before send packets printf("Port ability - 0x%08x\n", *(unsigned long*)(RALINK_ETH_SW_BASE+0x0080)); gpio_led_set(0x400); gpio_led = 0; // 10Mb Test // *(unsigned long *)(RALINK_ETH_SW_BASE+0x0084) = 0xffdf1f00; for (i = 1; i <=5; i++) { sprintf(phy_test_cmd, "phytest %d", i); run_command(phy_test_cmd, 0); // test_nop(); if (rt3052_port_test_status == 2) port_test_10M[(i-1)] = 1; else port_test_10M[(i-1)] = 0; } // display the result to console! gpio_led = 0; printf("\n"); for(i = 0; i < 5; i++) { printf("Port %d PHY Test", i); if (port_test_10M[i] == 1) { printf("...ok\n"); i_success_count++; } else { printf("...failed\n"); } } printf("\n"); //udelay(1000); if ( i_success_count == 5) gpio_led |= 0x200; gpio_led_set(gpio_led); /* force to 100M*/ force_phy_an(1); phy_link_detect(); // 100Mb Test i_success_count = 0; for (i = 1; i <=5; i++) { sprintf(phy_test_cmd, "phytest %d", i); run_command(phy_test_cmd, 0); // test_nop(); if (rt3052_port_test_status == 2) port_test_100M[(i-1)] = 1; else port_test_100M[(i-1)] = 0; } printf("\n"); for(i = 0; i < 5; i++) { printf("Port %d PHY Test", i); if (port_test_100M[i] == 1) { printf("...ok\n"); i_success_count++; } else { printf("...failed\n"); } } gpio_led_set(0); if (i_success_count == 5) { gpio_led |= 0x800; gpio_led_set(gpio_led); printf("\n** test ok**\n"); } } #elif defined (RT3352_ASIC_BOARD) void gpio_led_init() { // just switch uart full to gpio *(unsigned long*)(0xb0000060) |= 0x1c; // configure uart/gpio 9~14 pin to output mode *(unsigned long*)(0xb0000624) |= 0x7e00; } void gpio_led_set(unsigned long reg_val) { *(unsigned long*)(0xb0000620) = reg_val; } void rt3052_phy_batch(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { int j, i, result, i_success_count = 0; char phy_test_cmd[100]; uchar port_test_10M[5]; uchar port_test_100M[5]; unsigned long gpio_led, reg_counter, mdio_value; #if 1 // *(unsigned long *)(RALINK_ETH_SW_BASE+0x0084) = 0xffd01f00; gpio_led_init(); gpio_led_set(0); #endif rt3052_ether_setup(); force_phy_an(0); //force 10M before send packets printf("Port ability - 0x%08x\n", *(unsigned long*)(RALINK_ETH_SW_BASE+0x0080)); gpio_led = 0x80;//initialize gpio_led_set(gpio_led);//GPIO7 start signal // 10Mb Test // *(unsigned long *)(RALINK_ETH_SW_BASE+0x0084) = 0xffdf1f00; for (i = 1; i <=5; i++) { sprintf(phy_test_cmd, "phytest %d", i); run_command(phy_test_cmd, 0); // test_nop(); if (rt3052_port_test_status == 2) port_test_10M[(i-1)] = 1; else port_test_10M[(i-1)] = 0; } // display the result to console! printf("\n"); for(i = 0; i < 5; i++) { printf("Port %d PHY Test", i); if (port_test_10M[i] == 1) { printf("...ok\n"); i_success_count++; } else { printf("...failed\n"); } } printf("\n"); /* force to 100M*/ force_phy_an(1); phy_link_detect(); // 100Mb Test i_success_count = 0; for (i = 1; i <=5; i++) { sprintf(phy_test_cmd, "phytest %d", i); run_command(phy_test_cmd, 0); // test_nop(); if (rt3052_port_test_status == 2) port_test_100M[(i-1)] = 1; else port_test_100M[(i-1)] = 0; } printf("\n"); for(i = 0; i < 5; i++) { printf("Port %d PHY Test", i); if (port_test_100M[i] == 1) { printf("...ok\n"); i_success_count++; } else { printf("...failed\n"); } } /*test results *GPIO9 -> port0 *GPIO10 -> port1 *GPIO11 -> port2 *GPIO12 -> port3 *GPIO13 -> port4 * *GPIO14 -> all ports */ i_success_count = 0; for(i = 0; i < 5; i++) { if ((port_test_100M[i] == 1) && (port_test_10M[i] == 1)) { gpio_led |= (1 << (i+9)); i_success_count++; } } if (i_success_count == 5) { gpio_led |= (1 << 14); } //printf("gpio led is 0x%x \n\r", gpio_led); //set results to gpio gpio_led_set(gpio_led); } #endif U_BOOT_CMD( rt3052_phy, 3, 1, rt3052_phy_batch, "rt3052_phy - RT3052 phy production test\n", "rt3052_phy usage:\n" " rt3052_phy