summaryrefslogtreecommitdiffstats
path: root/target/linux/realtek/files/drivers/net/rtl819x/AsicDriver/rtl865x_asicCom.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/realtek/files/drivers/net/rtl819x/AsicDriver/rtl865x_asicCom.c')
-rw-r--r--target/linux/realtek/files/drivers/net/rtl819x/AsicDriver/rtl865x_asicCom.c162
1 files changed, 122 insertions, 40 deletions
diff --git a/target/linux/realtek/files/drivers/net/rtl819x/AsicDriver/rtl865x_asicCom.c b/target/linux/realtek/files/drivers/net/rtl819x/AsicDriver/rtl865x_asicCom.c
index d8fcf085d..341c03e66 100644
--- a/target/linux/realtek/files/drivers/net/rtl819x/AsicDriver/rtl865x_asicCom.c
+++ b/target/linux/realtek/files/drivers/net/rtl819x/AsicDriver/rtl865x_asicCom.c
@@ -1,10 +1,13 @@
/*
-* Copyright c Realtek Semiconductor Corporation, 2009
-* All rights reserved.
-*
* Program : Switch table basic operation driver
* Abstract :
* Author : hyking (hyking_liu@realsil.com.cn)
+*
+* Copyright (c) 2011 Realtek Semiconductor Corp.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
*/
#include <linux/delay.h>
@@ -17,6 +20,8 @@
#include "rtl865x_asicBasic.h"
#include "rtl865x_asicCom.h"
+
+
#define tick_Delay10ms(x) { int i=x; while(i--) __delay(5000); }
static int32 _rtl865xC_lockTLUCounter = 0;
@@ -31,12 +36,68 @@ int32 rtl8651_totalExtPortNum=0; //this replaces all RTL8651_EXTPORT_NUMBER def
int32 rtl8651_allExtPortMask=0; //this replaces all RTL8651_EXTPORTMASK defines
rtl8651_tblAsic_InitPara_t rtl8651_tblAsicDrvPara;
+#if defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E)
+int rtl8651_findAsicVlanIndexByVid(uint16 *vid)
+{
+ int i;
+ rtl865x_tblAsicDrv_vlanParam_t vlan;
+
+ for ( i = 0; i < RTL865XC_VLANTBL_SIZE; i++ )
+ {
+ if (rtl8651_getAsicVlan(i, &vlan) == SUCCESS){
+ if(*vid == vlan.vid){
+ *vid = i;
+ return SUCCESS;
+ }
+ }
+ }
+
+ return FAILED;
+}
+
+static int rtl8651_getAsicVlanIndex(rtl865xc_tblAsic_vlanTable_t *entry, uint16 *vid)
+{
+ int i;
+ int ret = FAILED;
+ rtl865x_tblAsicDrv_vlanParam_t vlan;
+
+ for ( i = 0; i < RTL865XC_VLANTBL_SIZE; i++ )
+ {
+ if ((rtl8651_getAsicVlan(i, &vlan) == SUCCESS) && (entry->vid == vlan.vid)){
+ if((entry->memberPort != vlan.memberPortMask) || (entry->egressUntag != vlan.untagPortMask) ||(entry->fid != vlan.fid)){
+ *vid = i;
+ return SUCCESS;
+ }else{
+ return FAILED;
+ }
+ }
+ }
+
+ for ( i = 0; i < RTL865XC_VLANTBL_SIZE; i++ )
+ {
+ if ( rtl8651_getAsicVlan( i, &vlan ) == FAILED )
+ break;
+ }
+
+ if(i == RTL865XC_VLANTBL_SIZE){
+ ret = FAILED; //vlan table is full
+ }else{
+ *vid = i;
+ ret = SUCCESS;
+ }
+
+ return ret;
+}
+#endif
/*=========================================
* ASIC DRIVER API: VLAN TABLE
*=========================================*/
int32 rtl8651_setAsicVlan(uint16 vid, rtl865x_tblAsicDrv_vlanParam_t *vlanp)
{
rtl865xc_tblAsic_vlanTable_t entry;
+#if defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E)
+ int flag = FAILED;
+#endif
memset(&entry,0,sizeof(entry));
if(vlanp == NULL)
@@ -50,6 +111,13 @@ int32 rtl8651_setAsicVlan(uint16 vid, rtl865x_tblAsicDrv_vlanParam_t *vlanp)
entry.memberPort = vlanp->memberPortMask & RTL8651_PHYSICALPORTMASK;
entry.egressUntag = vlanp->untagPortMask & RTL8651_PHYSICALPORTMASK;
entry.fid=vlanp->fid;
+
+#if defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E)
+ entry.vid=vid;
+ flag = rtl8651_getAsicVlanIndex(&entry, &vid);
+ if(flag == FAILED)
+ return FAILED;
+#endif
_rtl8651_forceAddAsicEntry(TYPE_VLAN_TABLE, vid, &entry);
return SUCCESS;
@@ -58,7 +126,12 @@ int32 rtl8651_setAsicVlan(uint16 vid, rtl865x_tblAsicDrv_vlanParam_t *vlanp)
int32 rtl8651_delAsicVlan(uint16 vid) {
rtl8651_tblAsic_vlanTable_t entry;
-
+#if defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E)
+ int flag = FAILED;
+ flag = rtl8651_findAsicVlanIndexByVid(&vid);
+ if(flag == FAILED)
+ return FAILED;
+#endif
memset(&entry,0,sizeof(entry));
entry.valid = 0;
return _rtl8651_forceAddAsicEntry(TYPE_VLAN_TABLE, vid, &entry);
@@ -78,6 +151,10 @@ int32 rtl8651_getAsicVlan(uint16 vid, rtl865x_tblAsicDrv_vlanParam_t *vlanp) {
vlanp->memberPortMask = (entry.extMemberPort<<RTL8651_PORT_NUMBER) | entry.memberPort;
vlanp->untagPortMask = (entry.extEgressUntag<<RTL8651_PORT_NUMBER) |entry.egressUntag;
vlanp->fid=entry.fid;
+
+#if defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E)
+ vlanp->vid=entry.vid;
+#endif
return SUCCESS;
}
@@ -185,7 +262,7 @@ int32 rtl8651_setProtocolBasedVLAN( uint32 ruleNo, uint32 port, uint8 valid, uin
vlanId = 0; // clear it for looking pretty.
}
- if ( port < RTL865XC_PORT_NUMBER )
+ if ( port < RTL8651_MAC_NUMBER )
{
// Port0 ~ Port9
addr=PBVR0_0 +(ruleNo*5*4) + ((port/2)*4) ;
@@ -661,15 +738,6 @@ int32 rtl865xC_lockSWCore(void)
WRITE_MEM32(PCRP4, ((READ_MEM32(PCRP4))&(~PauseFlowControlNway)) ); /* Jumbo Frame */
TOGGLE_BIT_IN_REG_TWICE(PCRP4,EnForceMode);
-#if 0 //def CONFIG_RTL_8196C_ESD
- {
- extern int _96c_esd_counter;
- if (_96c_esd_counter) {
- _96c_esd_counter = 1;
- }
- }
-#endif
-
if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
{
WRITE_MEM32(PCRP5, ((READ_MEM32(PCRP5))&(~PauseFlowControlNway)) ); /* Jumbo Frame */
@@ -715,15 +783,6 @@ int32 rtl865xC_lockSWCore(void)
WRITE_MEM32(PCRP4, ((READ_MEM32(PCRP4))&(~EnablePHYIf)) ); /* Jumbo Frame */
TOGGLE_BIT_IN_REG_TWICE(PCRP4,EnForceMode);
-#ifdef CONFIG_RTL_8196C_ESD
- {
- extern int _96c_esd_counter;
- if (_96c_esd_counter) {
- _96c_esd_counter = 1;
- }
- }
-#endif
-
if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
{
WRITE_MEM32(PCRP5, ((READ_MEM32(PCRP5))&(~EnablePHYIf)) ); /* Jumbo Frame */
@@ -860,7 +919,7 @@ int32 rtl8651_getChipVersion(int8 *name,uint32 size, int32 *rev)
int32 rtl8651_getChipNameID(int32 *id)
{
-#if defined(CONFIG_RTL_8196C) || defined (CONFIG_RTL_8198)
+#if defined(CONFIG_RTL_8196C) || defined (CONFIG_RTL_8198) || defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E)
*id = RTL865X_CHIP_VER_RTL8196C;
#elif defined(CONFIG_RTL8196B)
*id = RTL865X_CHIP_VER_RTL8196B;
@@ -952,7 +1011,7 @@ void rtl8651_clearRegister(void)
WRITE_MEM32(PBVR5_4, 0x00000000); /* User-defined 2 */
WRITE_MEM32(MSCR,0);
-#if defined(CONFIG_RTL_8196C) || defined(CONFIG_RTL_8198)
+#if defined(CONFIG_RTL_8196C) || defined(CONFIG_RTL_8198) || defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E)
WRITE_MEM32(PCRP0, (1 | MacSwReset));
TOGGLE_BIT_IN_REG_TWICE(PCRP0,EnForceMode);
WRITE_MEM32(PCRP1, (1 | MacSwReset));
@@ -1086,7 +1145,7 @@ int32 rtl8651_clearAsicCommTable(void)
//rtl8651_clearSpecifiedAsicTable(TYPE_L2_SWITCH_TABLE, RTL8651_L2TBL_ROW*RTL8651_L2TBL_COLUMN);
//rtl8651_clearSpecifiedAsicTable(TYPE_RATE_LIMIT_TABLE, RTL8651_RATELIMITTBL_SIZE);
rtl8651_clearSpecifiedAsicTable(TYPE_NETINTERFACE_TABLE, RTL865XC_NETINTERFACE_NUMBER);
- rtl8651_clearSpecifiedAsicTable(TYPE_VLAN_TABLE, RTL865XC_VLAN_NUMBER);
+ rtl8651_clearSpecifiedAsicTable(TYPE_VLAN_TABLE, RTL865XC_VLANTBL_SIZE);
rtl8651_clearSpecifiedAsicTable(TYPE_ACL_RULE_TABLE, RTL8651_ACLTBL_SIZE);
/*
@@ -1293,12 +1352,12 @@ void rtl865x_start(void)
REG32(CPUICR) = TXCMD | RXCMD | BUSBURST_32WORDS | MBUF_2048BYTES;
REG32(CPUIISR) = REG32(CPUIISR);
#if 1
- REG32(CPUIIMR) = RX_DONE_IE_ALL | TX_ALL_DONE_IE_ALL | LINK_CHANGE_IE;
+ REG32(CPUIIMR) = RX_DONE_IE_ALL | TX_ALL_DONE_IE_ALL | LINK_CHANGE_IE | PKTHDR_DESC_RUNOUT_IE_ALL;
#else
//REG32(CPUIIMR) = RX_DONE_IE_ALL | LINK_CHANGE_IE | PKTHDR_DESC_RUNOUT_IE_ALL | MBUF_DESC_RUNOUT_IE_ALL | TX_ALL_DONE_IE_ALL;
REG32(CPUIIMR) = RX_DONE_IE_ALL | LINK_CHANGE_IE | PKTHDR_DESC_RUNOUT_IE_ALL | MBUF_DESC_RUNOUT_IE_ALL;
#endif
- REG32(SIRR) = 1;
+ REG32(SIRR) = TRXRDY;
REG32(GIMR) |= (BSP_SW_IE);
// REG32(0xbb804508) = 0xd400f8; // adjust internal buffer threshold
// REG32(0xbb804908) = 0x00000400;/*mark_patch for correcting the Leaky bucket value*/
@@ -1431,7 +1490,7 @@ static void _rtl8651_initialRead(void) {//RTL8651 read counter for the first tim
}
}
-int32 rtl8651_returnAsicCounter(uint32 offset)
+uint32 rtl8651_returnAsicCounter(uint32 offset)
{
if(offset & 0x3)
return 0;
@@ -1442,7 +1501,12 @@ uint64 rtl865xC_returnAsicCounter64(uint32 offset)
{
if ( offset & 0x3 )
return 0;
+
+#if defined(CONFIG_RTL_8198) || defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E) || defined(CONFIG_RTL_8196C)
+ return ( READ_MEM32( MIB_COUNTER_BASE + offset ) + ( ( uint64 ) READ_MEM32( MIB_COUNTER_BASE + offset + 4 ) << 22 ) );
+#else
return ( READ_MEM32( MIB_COUNTER_BASE + offset ) + ( ( uint64 ) READ_MEM32( MIB_COUNTER_BASE + offset + 4 ) << 32 ) );
+#endif
}
int32 rtl8651_clearAsicCounter(void)
@@ -1723,10 +1787,13 @@ int32 rtl865xC_dumpAsicDiagCounter(void)
rtlglue_printf("<Port: %d>\n", i);
rtlglue_printf("Rx counters\n");
- rtlglue_printf(" Rcv %llu bytes, Drop %u pkts, CRCAlignErr %u, FragErr %u, JabberErr %u\n",
+ rtlglue_printf(" Rcv %llu bytes, Drop %u pkts,etherStatsDropEvents %u\n",
rtl865xC_returnAsicCounter64( OFFSET_IFINOCTETS_P0 + addrOffset_fromP0 ),
rtl8651_returnAsicCounter( OFFSET_DOT1DTPPORTINDISCARDS_P0 + addrOffset_fromP0 ),
+ rtl8651_returnAsicCounter(OFFSET_ETHERSTATSDROPEVENTS_P0 + addrOffset_fromP0 ));
+ rtlglue_printf(" CRCAlignErr %u, SymbolErr %u, FragErr %u, JabberErr %u\n",
rtl8651_returnAsicCounter( OFFSET_DOT3STATSFCSERRORS_P0 + addrOffset_fromP0 ),
+ rtl8651_returnAsicCounter( OFFSET_DOT3STATSSYMBOLERRORS_P0 + addrOffset_fromP0 ),
rtl8651_returnAsicCounter( OFFSET_ETHERSTATSFRAGMEMTS_P0 + addrOffset_fromP0 ),
rtl8651_returnAsicCounter( OFFSET_ETHERSTATSJABBERS_P0 + addrOffset_fromP0 ));
rtlglue_printf(" Unicast %u pkts, Multicast %u pkts, Broadcast %u pkts\n",
@@ -1935,23 +2002,38 @@ int32 rtl8651_getAsicCounter(uint32 counterIdx, rtl865x_tblAsicDrv_basicCounterP
//sync from rtl865x kernel 2.4
void FullAndSemiReset( void )
{
-#if 1//#ifdef CONFIG_RTL865XC
+#if defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E)
+ REG32(SIRR) |= FULL_RST;
+ mdelay(300);
- /* FIXME: Currently workable for FPGA, may need further modification for real chip */
+ REG32(SYS_CLK_MAG) |= CM_PROTECT;
+ REG32(SYS_CLK_MAG) &= ~CM_ACTIVE_SWCORE;
+ mdelay(300);
+
+ REG32(SYS_CLK_MAG) |= CM_ACTIVE_SWCORE;
+ REG32(SYS_CLK_MAG) &= ~CM_PROTECT;
+ mdelay(50);
- /* Perform full-reset for sw-core. */
- #ifdef CONFIG_RTL8196B_TLD
- if ((REG32(CPUSSR) & 0x0000ffff) != _MAGIC_FORM_BOOT)
- #endif
+#elif defined(CONFIG_RTL8198_REVISION_B)
+ if (REG32(BSP_REVR) >= BSP_RTL8198_REVISION_B)
{
-
+ REG32(SYS_CLK_MAG)&=(~(SYS_SW_RESET));
+ mdelay(300);
+ REG32(SYS_CLK_MAG)|=(SYS_SW_RESET);
+ mdelay(50);
+ }
+ else {
REG32(SIRR) |= FULL_RST;
tick_Delay10ms(50);
}
+#else
+ /* Perform full-reset for sw-core. */
+ REG32(SIRR) |= FULL_RST;
+ tick_Delay10ms(50);
+#endif
+ // 08-15-2012, set TRXRDY bit in rtl865x_start() in rtl865x_asicCom.c
/* Enable TRXRDY */
- REG32(SIRR) |= TRXRDY;
-
-#endif /* CONFIG_RTL865XC */
+ //REG32(SIRR) |= TRXRDY;
}