summaryrefslogtreecommitdiffstats
path: root/target/linux/realtek/files/drivers/net/rtl819x/AsicDriver/rtl865x_asicL2.c
diff options
context:
space:
mode:
authorRoman Yeryomin <roman@advem.lv>2012-09-13 00:40:35 +0300
committerRoman Yeryomin <roman@advem.lv>2013-05-26 00:44:46 +0300
commita27354c9021a8423ef8c7d2bffad49cbf639eec1 (patch)
tree2355929a4b8cf1888cd0797cfabdb42e0077c524 /target/linux/realtek/files/drivers/net/rtl819x/AsicDriver/rtl865x_asicL2.c
parent24a776baeb5d3cd903b144c89ceb11c5bc36a49e (diff)
Add realtek target files
Signed-off-by: Roman Yeryomin <roman@advem.lv>
Diffstat (limited to 'target/linux/realtek/files/drivers/net/rtl819x/AsicDriver/rtl865x_asicL2.c')
-rw-r--r--target/linux/realtek/files/drivers/net/rtl819x/AsicDriver/rtl865x_asicL2.c7197
1 files changed, 7197 insertions, 0 deletions
diff --git a/target/linux/realtek/files/drivers/net/rtl819x/AsicDriver/rtl865x_asicL2.c b/target/linux/realtek/files/drivers/net/rtl819x/AsicDriver/rtl865x_asicL2.c
new file mode 100644
index 000000000..2b6b9e9d3
--- /dev/null
+++ b/target/linux/realtek/files/drivers/net/rtl819x/AsicDriver/rtl865x_asicL2.c
@@ -0,0 +1,7197 @@
+/*
+* Copyright c Realtek Semiconductor Corporation, 2009
+* All rights reserved.
+*
+* Program : Switch table Layer2 switch driver,following features are included:
+* PHY/MII/Port/STP/QOS
+* Abstract :
+* Author : hyking (hyking_liu@realsil.com.cn)
+*/
+#include <net/rtl/rtl_types.h>
+#include <net/rtl/rtl_glue.h>
+//#include "assert.h"
+#include "rtl865x_asicBasic.h"
+#include "rtl865x_asicCom.h"
+#include "rtl865x_asicL2.h"
+#include "asicRegs.h"
+//#include "rtl_utils.h"
+#include "rtl865x_hwPatch.h"
+
+#include <linux/delay.h>
+
+#if defined(CONFIG_RTL_8198)
+#define RTL8198_EEE_MAC 1
+#endif
+
+static uint8 fidHashTable[]={0x00,0x0f,0xf0,0xff};
+
+__DRAM_FWD int32 rtl865x_wanPortMask;
+int32 rtl865x_lanPortMask = RTL865X_PORTMASK_UNASIGNED;
+
+int32 rtl865x_maxPreAllocRxSkb = RTL865X_PREALLOC_SKB_UNASIGNED;
+int32 rtl865x_rxSkbPktHdrDescNum = RTL865X_PREALLOC_SKB_UNASIGNED;
+int32 rtl865x_txSkbPktHdrDescNum = RTL865X_PREALLOC_SKB_UNASIGNED;
+int32 miiPhyAddress;
+rtl8651_tblAsic_ethernet_t rtl8651AsicEthernetTable[9];//RTL8651_PORT_NUMBER+rtl8651_totalExtPortNum
+
+#if defined(CONFIG_RTL_HW_QOS_SUPPORT)
+static uint32 _rtl865xC_QM_orgDescUsage = 0; /* Original Descriptor Usage in HW */
+#endif
+
+/* For Bandwidth control - RTL865xB Backward compatible only */
+#define _RTL865XB_BANDWIDTHCTRL_X1 (1 << 0)
+#define _RTL865XB_BANDWIDTHCTRL_X4 (1 << 1)
+#define _RTL865XB_BANDWIDTHCTRL_X8 (1 << 2)
+#define _RTL865XB_BANDWIDTHCTRL_CFGTYPE 2 /* Ingress (0) and Egress (1) : 2 types of configuration */
+static int32 _rtl865xB_BandwidthCtrlMultiplier = _RTL865XB_BANDWIDTHCTRL_X1;
+static uint32 _rtl865xB_BandwidthCtrlPerPortConfiguration[RTL8651_PORT_NUMBER][_RTL865XB_BANDWIDTHCTRL_CFGTYPE /* Ingress (0), Egress (1) */ ];
+static uint32 _rtl865xC_BandwidthCtrlNum[] = { 0, /* BW_FULL_RATE */
+ 131072, /* BW_128K */
+ 262144, /* BW_256K */
+ 524288, /* BW_512K */
+ 1048576, /* BW_1M */
+ 2097152, /* BW_2M */
+ 4194304, /* BW_4M */
+ 8388608 /* BW_8M */
+ };
+
+#define RTL865XC_INGRESS_16KUNIT 16384
+#define RTL865XC_EGRESS_64KUNIT 65535
+
+#ifdef CONFIG_RTL8196C_ETH_IOT
+extern uint32 port_link_sts, port_linkpartner_eee;
+#endif
+
+#if defined(RTL8196C_EEE_MAC)
+int eee_enabled = 1;
+void eee_phy_enable(void);
+void eee_phy_disable(void);
+void eee_phy_enable_by_port(int port);
+#elif defined(RTL8198_EEE_MAC)
+int eee_enabled = 1;
+void eee_phy_enable_98(void);
+void eee_phy_disable_98(void);
+#else
+int eee_enabled = 0;
+#endif
+
+#if defined(CONFIG_RTL_8198_NFBI_BOARD)
+#define RTL8198_NFBI_PORT5_GMII 1 //mark_nfbi , default port5 set to GMII , you can undef here to set to MII mode!!!
+//#undef RTL8198_NFBI_PORT5_GMII //mark_nfbi , default port5 set to GMII , you can undef here to set to MII mode!!!
+#endif
+
+
+#if defined(CONFIG_RTL_8198)
+
+#define PORT5_RGMII_GMII 1
+
+//static void qos_init(void);
+#endif
+
+#define QNUM_IDX_123 0
+#define QNUM_IDX_45 1
+#define QNUM_IDX_6 2
+
+static int32 _rtl865x_setQosThresholdByQueueIdx(uint32 qidx);
+
+#if 0
+static rtl865xC_outputQueuePara_t outputQueuePara[3] = {
+ {
+ 1, /* default: Bandwidth Control Include/exclude Preamble & IFG */
+ 20, /* default: Per Queue Physical Length Gap = 20 */
+ 504, /* default: Descriptor Run Out Threshold = 504 */
+ 180, /*default: System shared buffer flow control turn off threshold = 212 */
+ 196, /*default: System shared buffer flow control turn on threshold = 248 */
+ 500, /*default: system flow control turn off threshold = 500*/
+ 502, /*default: system flow control turn on threshold = 502*/
+ 330, /*default: port base flow control turn off threshold = 0xf8*/
+ 400, /*default: port base flow control turn on threshold = 0x108*/
+ 31, /* Queue-Descriptor=Based Flow Control turn off Threshold =0x14 */
+ 48, /* Queue-Descriptor=Based Flow Control turn on Threshold = 0x21 */
+ 0x03, /* Queue-Packet=Based Flow Control turn off Threshold = 0x03 */
+ 0x05 /* Queue-Packet=Based Flow Control turn on Threshold =0x05 */
+ },
+ {
+ 1, /* default: Bandwidth Control Include/exclude Preamble & IFG */
+ 20, /* default: Per Queue Physical Length Gap = 20 */
+ 504, /* default: Descriptor Run Out Threshold = 504 */
+ 120, /*default: System shared buffer flow control turn off threshold = 212 */
+ 136, /*default: System shared buffer flow control turn on threshold = 248 */
+ 330, /*default: system flow control turn off threshold = 500*/
+ 344, /*default: system flow control turn on threshold = 502*/
+ 248, /*default: port base flow control turn off threshold = 0xf8*/
+ 264, /*default: port base flow control turn on threshold = 0x108*/
+ 20, /* Queue-Descriptor=Based Flow Control turn off Threshold =0x14 */
+ 33, /* Queue-Descriptor=Based Flow Control turn on Threshold = 0x21 */
+ 0x03, /* Queue-Packet=Based Flow Control turn off Threshold = 0x03 */
+ 0x05 /* Queue-Packet=Based Flow Control turn on Threshold =0x05 */
+ },
+ {
+ 1, /* default: Bandwidth Control Include/exclude Preamble & IFG */
+ 20, /* default: Per Queue Physical Length Gap = 20 */
+ 500, /* default: Descriptor Run Out Threshold = 504 */
+ 324, /*default: System shared buffer flow control turn off threshold = 212 */
+ 340, /*default: System shared buffer flow control turn on threshold = 248 */
+ 330, /*default: system flow control turn off threshold = 500*/
+ 400, /*default: system flow control turn on threshold = 502*/
+ 240, /*default: port base flow control turn off threshold = 0xf8*/
+ 282, /*default: port base flow control turn on threshold = 0x108*/
+ 20, /* Queue-Descriptor=Based Flow Control turn off Threshold =0x14 */
+ 28, /* Queue-Descriptor=Based Flow Control turn on Threshold = 0x21 */
+ 10, /* Queue-Packet=Based Flow Control turn off Threshold = 0x03 */
+ 11 /* Queue-Packet=Based Flow Control turn on Threshold =0x05 */
+ }
+ };
+#else
+// sync from kernel 2.4 qos_init() -- 20110330
+static rtl865xC_outputQueuePara_t outputQueuePara[3] = {
+ {
+ 1, /* default: Bandwidth Control Include/exclude Preamble & IFG */
+ 0x48, /* default: Per Queue Physical Length Gap = 20 */
+ 500, /* default: Descriptor Run Out Threshold = 504 */
+ 252, /*default: System shared buffer flow control turn off threshold = 212 */
+ 310, /*default: System shared buffer flow control turn on threshold = 248 */
+ 280, /*default: system flow control turn off threshold = 500*/
+ 400, /*default: system flow control turn on threshold = 502*/
+ 258, /*default: port base flow control turn off threshold = 0xf8*/
+ 320, /*default: port base flow control turn on threshold = 0x108*/
+ 16, /* Queue-Descriptor=Based Flow Control turn off Threshold =0x14 */
+ 21, /* Queue-Descriptor=Based Flow Control turn on Threshold = 0x21 */
+ 5, /* Queue-Packet=Based Flow Control turn off Threshold = 0x03 */
+ 6 /* Queue-Packet=Based Flow Control turn on Threshold =0x05 */
+ },
+ {
+ 1, /* default: Bandwidth Control Include/exclude Preamble & IFG */
+ 0x48, /* default: Per Queue Physical Length Gap = 20 */
+ 500, /* default: Descriptor Run Out Threshold = 504 */
+ 252, /*default: System shared buffer flow control turn off threshold = 212 */
+ 310, /*default: System shared buffer flow control turn on threshold = 248 */
+ 280, /*default: system flow control turn off threshold = 500*/
+ 400, /*default: system flow control turn on threshold = 502*/
+ 258, /*default: port base flow control turn off threshold = 0xf8*/
+ 320, /*default: port base flow control turn on threshold = 0x108*/
+ 16, /* Queue-Descriptor=Based Flow Control turn off Threshold =0x14 */
+ 21, /* Queue-Descriptor=Based Flow Control turn on Threshold = 0x21 */
+ 5, /* Queue-Packet=Based Flow Control turn off Threshold = 0x03 */
+ 6 /* Queue-Packet=Based Flow Control turn on Threshold =0x05 */
+ },
+ {
+ 1, /* default: Bandwidth Control Include/exclude Preamble & IFG */
+ 0x48, /* default: Per Queue Physical Length Gap = 20 */
+ 500, /* default: Descriptor Run Out Threshold = 504 */
+ 252, /*default: System shared buffer flow control turn off threshold = 212 */
+ 310, /*default: System shared buffer flow control turn on threshold = 248 */
+ 280, /*default: system flow control turn off threshold = 500*/
+ 400, /*default: system flow control turn on threshold = 502*/
+ 258, /*default: port base flow control turn off threshold = 0xf8*/
+ 320, /*default: port base flow control turn on threshold = 0x108*/
+ 16, /* Queue-Descriptor=Based Flow Control turn off Threshold =0x14 */
+ 21, /* Queue-Descriptor=Based Flow Control turn on Threshold = 0x21 */
+ 5, /* Queue-Packet=Based Flow Control turn off Threshold = 0x03 */
+ 6 /* Queue-Packet=Based Flow Control turn on Threshold =0x05 */
+ }
+ };
+#endif
+
+static void _rtl8651_syncToAsicEthernetBandwidthControl(void);
+#if defined(CONFIG_RTL_HW_QOS_SUPPORT)
+static int32 _rtl865xC_QM_init( void );
+#endif
+
+#if defined(RTL8196C_EEE_MAC)
+// EEE PHY -- Page 4
+// register 16
+#define P4R16_eee_10_cap (1 << 13) // enable EEE 10M
+#define P4R16_eee_nway_en (1 << 12) // enable Next Page exchange in nway for EEE 100M
+#define P4R16_tx_quiet_en (1 << 9) // enable ability to turn off pow100tx when TX Quiet state
+#define P4R16_rx_quiet_en (1 << 8) // enable ability to turn off pow100rx when RX Quiet state
+
+// register 25
+#define P4R25_rg_dacquiet_en (1 << 10) // enable ability to turn off DAC when TX Quiet state
+#define P4R25_rg_ldvquiet_en (1 << 9) // enable ability to turn off line driver when TX Quiet state
+#define P4R25_rg_eeeprg_rst (1 << 6) // reset for EEE programmable finite state machine
+#define P4R25_rg_ckrsel (1 << 5) // select ckr125 as RX 125MHz clock
+#define P4R25_rg_eeeprg_en (1 << 4) // enable EEE programmable finite state machine
+
+static const unsigned short phy_data[]={
+ 0x5000, // write, address 0
+ 0x6000, // write, address 1
+ 0x7000, // write, address 2
+ 0x4000, // write, address 3
+ 0xD36C, // write, address 4
+ 0xFFFF, // write, address 5
+ 0x5060, // write, address 6
+ 0x61C5, // write, address 7
+ 0x7000, // write, address 8
+ 0x4001, // write, address 9
+ 0x5061, // write, address 10
+ 0x87F5, // write, address 11
+ 0xCE60, // write, address 12
+ 0x0026, // write, address 13
+ 0x8E03, // write, address 14
+ 0xA021, // write, address 15
+ 0x300B, // write, address 16
+ 0x58A0, // write, address 17
+ 0x629C, // write, address 18
+ 0x7000, // write, address 19
+ 0x4002, // write, address 20
+ 0x58A1, // write, address 21
+ 0x87EA, // write, address 22
+ 0xAE25, // write, address 23
+ 0xA018, // write, address 24
+ 0x3016, // write, address 25
+ 0x6894, // write, address 26
+ 0x6094, // write, address 27
+ 0x5123, // write, address 28
+ 0x63C2, // write, address 29
+ 0x5127, // write, address 30
+ 0x4003, // write, address 31
+ 0x87E0, // write, address 32
+ 0x8EF3, // write, address 33
+ 0xA10E, // write, address 34
+ 0xCC40, // write, address 35
+ 0x0007, // write, address 36
+ 0xCA40, // write, address 37
+ 0xFFE0, // write, address 38
+ 0xA202, // write, address 39
+ 0x3020, // write, address 40
+ 0x7008, // write, address 41
+ 0x3020, // write, address 42
+ 0xCC44, // write, address 43
+ 0xFFF4, // write, address 44
+ 0xCC44, // write, address 45
+ 0xFFF2, // write, address 46
+ 0x3000, // write, address 47
+ 0x5220, // write, address 48
+ 0x4004, // write, address 49
+ 0x3000, // write, address 50
+ 0x64A0, // write, address 51
+ 0x5429, // write, address 52
+ 0x4005, // write, address 53
+ 0x87CA, // write, address 54
+ 0xCE18, // write, address 55
+ 0xFFC8, // write, address 56
+ 0xCE64, // write, address 57
+ 0xFFD0, // write, address 58
+ 0x3036, // write, address 59
+ 0x65C0, // write, address 60
+ 0x50A9, // write, address 61
+ 0x4006, // write, address 62
+ 0xA3DB, // write, address 63
+ 0x303F, // write, address 64
+};
+
+static int ram_code_done=0;
+
+void set_ram_code(void)
+{
+ uint32 reg;
+ int i, len=sizeof(phy_data)/sizeof(unsigned short);
+
+ if (ram_code_done)
+ return;
+
+ rtl8651_getAsicEthernetPHYReg( 4, 0x19, &reg );
+
+ // turn on rg_eeeprg_rst
+ rtl8651_setAsicEthernetPHYReg(4, 0x19, ((reg & ~(P4R25_rg_eeeprg_en)) | P4R25_rg_eeeprg_rst));
+
+ // turn on mem_mdio_mode
+ rtl8651_setAsicEthernetPHYReg(4, 0x1c, 0x0180);
+
+ // begin to write all RAM
+ for(i=0;i<len;i++) {
+ rtl8651_setAsicEthernetPHYReg(4, 0x1d, phy_data[i]);
+ }
+
+ for(i=0;i<63;i++) {
+ rtl8651_setAsicEthernetPHYReg(4, 0x1d, 0);
+ }
+
+ // finish reading all RAM
+ // turn off mem_mdio_mode
+ rtl8651_setAsicEthernetPHYReg(4, 0x1c, 0x0080);
+
+ // turn off rg_eeeprg_rst, enable EEE programmable finite state machine
+ rtl8651_setAsicEthernetPHYReg(4, 0x19, ((reg & ~(P4R25_rg_eeeprg_rst)) | P4R25_rg_eeeprg_en));
+
+ ram_code_done = 1;
+}
+
+static const unsigned short phy_data_b[]={
+ 0x5000, // write, address 0
+ 0x6000, // write, address 1
+ 0x7000, // write, address 2
+ 0x4000, // write, address 3
+ 0x8700, // write, address 4
+ 0xD344, // write, address 5
+ 0xFFFF, // write, address 6
+ 0xCA6C, // write, address 7
+ 0xFFFD, // write, address 8
+ 0x5460, // write, address 9
+ 0x61C5, // write, address 10
+ 0x7000, // write, address 11
+ 0x4001, // write, address 12
+ 0x5461, // write, address 13
+ 0x4001, // write, address 14
+ 0x87F1, // write, address 15
+ 0xCE60, // write, address 16
+ 0x0026, // write, address 17
+ 0x8E03, // write, address 18
+ 0xA021, // write, address 19
+ 0x300F, // write, address 20
+ 0x5CA0, // write, address 21
+ 0x629C, // write, address 22
+ 0x7000, // write, address 23
+ 0x4002, // write, address 24
+ 0x5CA1, // write, address 25
+ 0x87E6, // write, address 26
+ 0xAE25, // write, address 27
+ 0xA018, // write, address 28
+ 0x301A, // write, address 29
+ 0x6E94, // write, address 30
+ 0x6694, // write, address 31
+ 0x5523, // write, address 32
+ 0x63C2, // write, address 33
+ 0x5527, // write, address 34
+ 0x4003, // write, address 35
+ 0x87DC, // write, address 36
+ 0x8EF3, // write, address 37
+ 0xA10E, // write, address 38
+ 0xCC40, // write, address 39
+ 0x0007, // write, address 40
+ 0xCA40, // write, address 41
+ 0xFFDF, // write, address 42
+ 0xA202, // write, address 43
+ 0x3024, // write, address 44
+ 0x7008, // write, address 45
+ 0x3024, // write, address 46
+ 0xCC44, // write, address 47
+ 0xFFF4, // write, address 48
+ 0xCC44, // write, address 49
+ 0xFFF2, // write, address 50
+ 0x3000, // write, address 51
+ 0x5620, // write, address 52
+ 0x4004, // write, address 53
+ 0x3000, // write, address 54
+ 0x64A0, // write, address 55
+ 0x5429, // write, address 56
+ 0x4005, // write, address 57
+ 0x87C6, // write, address 58
+ 0xCE18, // write, address 59
+ 0xFFC4, // write, address 60
+ 0xCE64, // write, address 61
+ 0xFFCF, // write, address 62
+ 0x303A, // write, address 63
+ 0x65C0, // write, address 64
+ 0x54A9, // write, address 65
+ 0x4006, // write, address 66
+ 0xA3DB, // write, address 67
+ 0x3043, // write, address 68
+};
+
+void set_ram_code_b(void)
+{
+ uint32 reg;
+ int i, len=sizeof(phy_data_b)/sizeof(unsigned short);
+
+ if (ram_code_done)
+ return;
+
+ rtl8651_getAsicEthernetPHYReg(4, 0x19, &reg );
+ rtl8651_setAsicEthernetPHYReg(4, 0x19, ((reg & ~(P4R25_rg_eeeprg_en)) | P4R25_rg_eeeprg_rst));
+ rtl8651_setAsicEthernetPHYReg(4, 0x1c, 0x0180);
+
+ for(i=0;i<len;i++) {
+ rtl8651_setAsicEthernetPHYReg(4, 0x1d, phy_data_b[i]);
+ }
+
+ rtl8651_setAsicEthernetPHYReg(4, 0x1c, 0x0080);
+ rtl8651_setAsicEthernetPHYReg(4, 0x19, ((reg & ~(P4R25_rg_eeeprg_rst)) | P4R25_rg_eeeprg_en));
+
+ ram_code_done = 1;
+}
+
+void eee_phy_enable_by_port(int port)
+{
+ uint32 reg;
+
+ // change to page 4
+ rtl8651_setAsicEthernetPHYReg(port, 31, 4);
+
+ // enable EEE N-way & set turn off power at quiet state
+ rtl8651_getAsicEthernetPHYReg( port, 16, &reg );
+ reg |= (P4R16_eee_nway_en | P4R16_tx_quiet_en | P4R16_rx_quiet_en);
+
+#ifdef CONFIG_RTL8196C_ETH_IOT
+ reg |= P4R16_eee_10_cap; // enable 10M_EEE also.
+#endif
+ rtl8651_setAsicEthernetPHYReg( port, 16, reg );
+
+ // enable EEE turn off DAC and line driver when TX Quiet state
+ rtl8651_getAsicEthernetPHYReg( port, 25, &reg );
+// reg = reg & 0xF9FF | P4R25_rg_dacquiet_en | P4R25_rg_ldvquiet_en;
+ reg |= (P4R25_rg_dacquiet_en | P4R25_rg_ldvquiet_en | P4R25_rg_eeeprg_en);
+
+ rtl8651_setAsicEthernetPHYReg( port, 25, reg );
+
+ rtl8651_setAsicEthernetPHYReg( port, 17, 0xa2a2 );
+ rtl8651_setAsicEthernetPHYReg( port, 19, 0xc5c2 );
+ rtl8651_setAsicEthernetPHYReg( port, 24, 0xc0f3 );
+
+ if ((REG32(REVR)==RTL8196C_REVISION_A) && (port==4)){
+ set_ram_code();
+ }
+ else if ((REG32(REVR) == RTL8196C_REVISION_B) && (port == 4)) {
+ set_ram_code_b();
+ }
+
+ // switch to page 0
+ rtl8651_setAsicEthernetPHYReg(port, 31, 0 );
+}
+
+void eee_phy_enable(void)
+{
+ int i;
+ uint32 reg;
+
+ // EEE PHY enable
+ for (i=0; i<MAX_PORT_NUMBER; i++)
+ {
+ // change to page 4
+ rtl8651_setAsicEthernetPHYReg(i, 31, 4);
+
+ // enable EEE N-way & set turn off power at quiet state
+ rtl8651_getAsicEthernetPHYReg( i, 16, &reg );
+ reg |= (P4R16_eee_nway_en | P4R16_tx_quiet_en | P4R16_rx_quiet_en);
+ rtl8651_setAsicEthernetPHYReg( i, 16, reg );
+
+ // enable EEE turn off DAC and line driver when TX Quiet state
+ rtl8651_getAsicEthernetPHYReg( i, 25, &reg );
+// reg = reg & 0xF9FF | P4R25_rg_dacquiet_en | P4R25_rg_ldvquiet_en;
+ reg |= (P4R25_rg_dacquiet_en | P4R25_rg_ldvquiet_en | P4R25_rg_eeeprg_en);
+ rtl8651_setAsicEthernetPHYReg( i, 25, reg );
+
+ rtl8651_setAsicEthernetPHYReg( i, 17, 0xa2a2 );
+ rtl8651_setAsicEthernetPHYReg( i, 19, 0xc5c2 );
+ rtl8651_setAsicEthernetPHYReg( i, 24, 0xc0f3 );
+
+ if ((REG32(REVR)==RTL8196C_REVISION_A) && (i==4)){
+ set_ram_code();
+ }
+ else if ((REG32(REVR) == RTL8196C_REVISION_B) && (i == 4)) {
+ set_ram_code_b();
+ }
+
+ // switch to page 0
+ rtl8651_setAsicEthernetPHYReg(i, 31, 0 );
+
+ rtl8651_restartAsicEthernetPHYNway(i+1);
+ }
+}
+
+void eee_phy_disable(void)
+{
+ int i;
+ uint32 reg;
+
+ // EEE PHY disable
+ for (i=0; i<MAX_PORT_NUMBER; i++)
+ {
+ // change to page 4
+ rtl8651_setAsicEthernetPHYReg(i, 31, 4);
+
+ // disable (EEE N-way & turn off power at quiet state)
+ rtl8651_getAsicEthernetPHYReg( i, 16, &reg );
+ reg = reg & 0xECFF;
+ rtl8651_setAsicEthernetPHYReg( i, 16, reg );
+
+ // switch to page 0
+ rtl8651_setAsicEthernetPHYReg(i, 31, 0 );
+
+ rtl8651_restartAsicEthernetPHYNway(i+1);
+ }
+
+ // EEE MAC disable
+
+}
+#endif
+
+#if defined(RTL8198_EEE_MAC)
+// EEE PHY -- Page 4
+void Set_GPHYWB(unsigned int phyid, unsigned int page, unsigned int reg, unsigned int mask, unsigned int val);
+
+void eee_phy_enable_98(void)
+{
+ int i;
+
+ for(i=0; i<5; i++)
+ REG32(PCRP0+i*4) |= (EnForceMode);
+
+ // EEE PHY enable
+ for (i=0; i<5; i++)
+ {
+ // change to page 4
+ Set_GPHYWB(i,32,27,0xffff - 0xffff,0x2fce);
+ Set_GPHYWB(i,32,21,0xffff - 0xffff,0x0100);
+ Set_GPHYWB(i,5,5,0xffff - 0xffff,0x8b84);
+ Set_GPHYWB(i,5,6,0xffff - 0xffff,0x0062);
+
+ rtl8651_restartAsicEthernetPHYNway(i+1);
+ }
+
+ for(i=0; i<5; i++)
+ REG32(PCRP0+i*4) &= ~(EnForceMode);
+}
+
+void eee_phy_disable_98(void)
+{
+ int i;
+
+ for(i=0; i<5; i++)
+ REG32(PCRP0+i*4) |= (EnForceMode);
+
+ for (i=0; i<5; i++)
+ {
+ // change to page 4
+ Set_GPHYWB(i,32,27,0xffff - 0xffff,0x2f4e);
+ Set_GPHYWB(i,32,21,0xffff - 0xffff,0x0);
+ Set_GPHYWB(i,5,5,0xffff - 0xffff,0x8b84);
+ Set_GPHYWB(i,5,6,0xffff - 0xffff,0x0042);
+
+ rtl8651_restartAsicEthernetPHYNway(i+1);
+ }
+ // EEE PHY disable
+
+ for(i=0; i<5; i++)
+ REG32(PCRP0+i*4) &= ~(EnForceMode);
+}
+#endif
+
+#ifdef CONFIG_RTL8196C_GREEN_ETHERNET
+void set_phy_pwr_save(int id, int val)
+{
+ uint32 reg_val;
+ int i, start, end;
+
+ if (id == 99)
+ { start=0; end=4; }
+ else if (id <= 4)
+ { start = end = id; }
+ else
+ return;
+ for(i=start; i<=end; i++)
+ {
+ rtl8651_getAsicEthernetPHYReg( i, 24, &reg_val);
+
+ if (val == 1)
+ rtl8651_setAsicEthernetPHYReg( i, 24, (reg_val | BIT(15)) );
+ else
+ rtl8651_setAsicEthernetPHYReg( i, 24, (reg_val & (~BIT(15))) );
+ }
+}
+#endif
+
+uint32 rtl8651_filterDbIndex(ether_addr_t * macAddr,uint16 fid)
+{
+ return ( macAddr->octet[0] ^ macAddr->octet[1] ^
+ macAddr->octet[2] ^ macAddr->octet[3] ^
+ macAddr->octet[4] ^ macAddr->octet[5] ^fidHashTable[fid]) & 0xFF;
+}
+
+int32 rtl8651_setAsicL2Table(uint32 row, uint32 column, rtl865x_tblAsicDrv_l2Param_t *l2p)
+{
+ rtl865xc_tblAsic_l2Table_t entry;
+
+ if((row >= RTL8651_L2TBL_ROW) || (column >= RTL8651_L2TBL_COLUMN) || (l2p == NULL))
+ return FAILED;
+ if(l2p->macAddr.octet[5] != ((row^(fidHashTable[l2p->fid])^ l2p->macAddr.octet[0] ^ l2p->macAddr.octet[1] ^ l2p->macAddr.octet[2] ^ l2p->macAddr.octet[3] ^ l2p->macAddr.octet[4] ) & 0xff))
+ return FAILED;
+
+ memset(&entry, 0,sizeof(entry));
+ entry.mac47_40 = l2p->macAddr.octet[0];
+ entry.mac39_24 = (l2p->macAddr.octet[1] << 8) | l2p->macAddr.octet[2];
+ entry.mac23_8 = (l2p->macAddr.octet[3] << 8) | l2p->macAddr.octet[4];
+
+
+#if 1 //chhuang: #ifdef CONFIG_RTL8650B
+ if( l2p->memberPortMask > RTL8651_PHYSICALPORTMASK) //this MAC is on extension port
+ entry.extMemberPort = (l2p->memberPortMask >>RTL8651_PORT_NUMBER);
+#endif /* CONFIG_RTL8650B */
+
+ entry.memberPort = l2p->memberPortMask & RTL8651_PHYSICALPORTMASK;
+ entry.toCPU = l2p->cpu==TRUE? 1: 0;
+ entry.isStatic = l2p->isStatic==TRUE? 1: 0;
+ entry.nxtHostFlag = l2p->nhFlag==TRUE? 1: 0;
+
+ /* RTL865xC: modification of age from ( 2 -> 3 -> 1 -> 0 ) to ( 3 -> 2 -> 1 -> 0 ). modification of granularity 100 sec to 150 sec. */
+ entry.agingTime = ( l2p->ageSec > 300 )? 0x03: ( l2p->ageSec <= 300 && l2p->ageSec > 150 )? 0x02: (l2p->ageSec <= 150 && l2p->ageSec > 0 )? 0x01: 0x00;
+
+ entry.srcBlock = (l2p->srcBlk==TRUE)? 1: 0;
+ entry.fid=l2p->fid;
+ entry.auth=l2p->auth;
+ return _rtl8651_forceAddAsicEntry(TYPE_L2_SWITCH_TABLE, row<<2 | column, &entry);
+}
+
+int32 rtl8651_delAsicL2Table(uint32 row, uint32 column)
+{
+ rtl865xc_tblAsic_l2Table_t entry;
+
+ if(row >= RTL8651_L2TBL_ROW || column >= RTL8651_L2TBL_COLUMN)
+ return FAILED;
+
+ memset(&entry,0,sizeof(entry));
+ return _rtl8651_forceAddAsicEntry(TYPE_L2_SWITCH_TABLE, row<<2 | column, &entry);
+}
+
+
+ether_addr_t cachedDA;
+static uint32 cachedMbr;
+unsigned int rtl8651_asicL2DAlookup(uint8 *dmac){
+ uint32 column;
+// rtl8651_tblAsic_l2Table_t entry;
+ rtl865xc_tblAsic_l2Table_t entry;
+
+// unsigned int row = dmac[0]^dmac[1]^dmac[2]^dmac[3]^dmac[4]^dmac[5];
+ uint32 row = rtl8651_filterDbIndex((ether_addr_t *)dmac, 0);
+ //rtlglue_printf("mac %02x %02x %02x %02x %02x %02x \n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
+
+#if 0 //chhuang:
+ //cache hit...
+ if(memcmp(&cachedDA, dmac, 6)==0)
+ return cachedMbr;
+#endif
+
+ //cache miss...
+ cachedMbr=0;
+ for(column=0;column<RTL8651_L2TBL_COLUMN; column++) {
+/* Should be fixed WRITE_MEM32(TEACR,READ_MEM32(TEACR)|0x1);ASIC patch: disable L2 Aging while reading L2 table */
+ _rtl8651_readAsicEntry(TYPE_L2_SWITCH_TABLE, row<<2 | column, &entry);
+/* WRITE_MEM32(TEACR,READ_MEM32(TEACR)&~0x1); ASIC patch: enable L2 Aging aftrer reading L2 table */
+ if(entry.agingTime == 0 && entry.isStatic == 0)
+ continue;
+ if( dmac[0]==entry.mac47_40 &&
+ dmac[1]==(entry.mac39_24>>8) &&
+ dmac[2]==(entry.mac39_24 & 0xff)&&
+ dmac[3]==(entry.mac23_8 >> 8)&&
+ dmac[4]==(entry.mac23_8 & 0xff)&&
+ dmac[5]== (row ^dmac[0]^dmac[1]^dmac[2]^dmac[3]^dmac[4])){
+
+ cachedDA=*((ether_addr_t *)dmac);
+ cachedMbr =(entry.extMemberPort<<RTL8651_PORT_NUMBER) | entry.memberPort;
+ return cachedMbr;
+ }
+ }
+ if(column==RTL8651_L2TBL_COLUMN)
+ return 0xffffffff;//can't find this MAC, broadcast it.
+ return cachedMbr;
+}
+
+
+
+int32 rtl8651_getAsicL2Table(uint32 row, uint32 column, rtl865x_tblAsicDrv_l2Param_t *l2p) {
+ rtl865xc_tblAsic_l2Table_t entry;
+
+ if((row >= RTL8651_L2TBL_ROW) || (column >= RTL8651_L2TBL_COLUMN) || (l2p == NULL))
+ return FAILED;
+
+/* RTL865XC should fix this problem.WRITE_MEM32(TEACR,READ_MEM32(TEACR)|0x1); ASIC patch: disable L2 Aging while reading L2 table */
+ _rtl8651_readAsicEntry(TYPE_L2_SWITCH_TABLE, row<<2 | column, &entry);
+ //WRITE_MEM32(TEACR,READ_MEM32(TEACR)&0x1); ASIC patch: enable L2 Aging aftrer reading L2 table */
+
+ if(entry.agingTime == 0 && entry.isStatic == 0 )
+ return FAILED;
+ l2p->macAddr.octet[0] = entry.mac47_40;
+ l2p->macAddr.octet[1] = entry.mac39_24 >> 8;
+ l2p->macAddr.octet[2] = entry.mac39_24 & 0xff;
+ l2p->macAddr.octet[3] = entry.mac23_8 >> 8;
+ l2p->macAddr.octet[4] = entry.mac23_8 & 0xff;
+ l2p->macAddr.octet[5] = row ^ l2p->macAddr.octet[0] ^ l2p->macAddr.octet[1] ^ l2p->macAddr.octet[2] ^ l2p->macAddr.octet[3] ^ l2p->macAddr.octet[4] ^(fidHashTable[entry.fid]);
+ l2p->cpu = entry.toCPU==1? TRUE: FALSE;
+ l2p->srcBlk = entry.srcBlock==1? TRUE: FALSE;
+ l2p->nhFlag = entry.nxtHostFlag==1? TRUE: FALSE;
+ l2p->isStatic = entry.isStatic==1? TRUE: FALSE;
+#if 1 //chhuang: #ifdef CONFIG_RTL8650B
+ l2p->memberPortMask = (entry.extMemberPort<<RTL8651_PORT_NUMBER) | entry.memberPort;
+#else
+ l2p->memberPortMask = entry.memberPort;
+#endif /* CONFIG_RTL8650B */
+
+ /* RTL865xC: modification of age from ( 2 -> 3 -> 1 -> 0 ) to ( 3 -> 2 -> 1 -> 0 ). modification of granularity 100 sec to 150 sec. */
+ l2p->ageSec = entry.agingTime * 150;
+
+ l2p->fid=entry.fid;
+ l2p->auth=entry.auth;
+ return SUCCESS;
+}
+
+int32 rtl8651_setAsicPortMirror(uint32 mRxMask, uint32 mTxMask,uint32 mPortMask)
+{
+ uint32 pmcr = 0;
+ pmcr = ((mTxMask<<MirrorTxPrtMsk_OFFSET)&MirrorTxPrtMsk_MASK) |
+ ((mRxMask << MirrorRxPrtMsk_OFFSET) & MirrorRxPrtMsk_MASK)|
+ ((mPortMask<<MirrorPortMsk_OFFSET) & MirrorPortMsk_MASK);
+
+ WRITE_MEM32(PMCR,pmcr);
+
+ return SUCCESS;
+}
+
+int32 rtl8651_getAsicPortMirror(uint32 *mRxMask, uint32 *mTxMask, uint32 *mPortMask)
+{
+ uint32 pmcr = READ_MEM32( PMCR );
+
+ if ( mPortMask )
+ {
+ *mPortMask = ( pmcr & MirrorPortMsk_MASK ) >> MirrorPortMsk_OFFSET;
+ }
+
+ if ( mRxMask )
+ {
+ *mRxMask = ( pmcr & MirrorRxPrtMsk_MASK ) >> MirrorRxPrtMsk_OFFSET;
+ }
+
+ if ( mTxMask )
+ {
+ *mTxMask = ( pmcr & MirrorTxPrtMsk_MASK ) >> MirrorTxPrtMsk_OFFSET;
+ }
+
+ return SUCCESS;
+}
+
+int32 rtl8651_clearAsicL2Table(void)
+{
+ rtl8651_clearSpecifiedAsicTable(TYPE_L2_SWITCH_TABLE, RTL8651_L2TBL_ROW*RTL8651_L2TBL_COLUMN);
+ rtl8651_clearSpecifiedAsicTable(TYPE_RATE_LIMIT_TABLE, RTL8651_RATELIMITTBL_SIZE);
+ return SUCCESS;
+}
+
+inline int32 convert_setAsicL2Table(uint32 row, uint32 column, ether_addr_t * mac, int8 cpu,
+ int8 srcBlk, uint32 mbr, uint32 ageSec, int8 isStatic, int8 nhFlag,int8 fid, int8 auth)
+{
+ rtl865x_tblAsicDrv_l2Param_t l2;
+
+ memset(&l2,0,sizeof(rtl865x_tblAsicDrv_l2Param_t));
+
+ l2.ageSec = ageSec;
+ l2.cpu = cpu;
+ l2.isStatic = isStatic;
+ l2.memberPortMask = mbr;
+ l2.nhFlag = nhFlag;
+ l2.srcBlk = srcBlk;
+//#ifdef RTL865XC_LAN_PORT_NUM_RESTRIT
+// if(enable4LanPortNumRestrict == TRUE)
+ l2.fid=fid;
+ l2.auth = auth;
+//#endif
+ memcpy(&l2.macAddr, mac, 6);
+ return rtl8651_setAsicL2Table(row, column, &l2);
+}
+
+/*
+ * <<RTL8651 version B Bug>>
+ * RTL8651 L2 entry bug:
+ * For each L2 entry added by driver table as a static entry, the aging time
+ * will not be updated by ASIC
+ * Bug fixed:
+ * To patch this bug, set the entry is a dynamic entry and turn on the 'nhFlag',
+ * then the aging time of this entry will be updated and once aging time expired,
+ * it won't be removed by ASIC automatically.
+ */
+int32 rtl8651_setAsicL2Table_Patch(uint32 row, uint32 column, ether_addr_t * mac, int8 cpu,
+ int8 srcBlk, uint32 mbr, uint32 ageSec, int8 isStatic, int8 nhFlag, int8 fid,int8 auth)
+{
+#if 0
+ ether_addr_t bcast_mac = { {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} };
+ ether_addr_t cpu_mac = {{0x00,0x00,0x0a,0x00,0x00,0x0f}};
+
+ /*
+ In RTL865xC, we need to turn on the CPU bit of broadcast mac to let broadcast packets being trapped to CPU.
+ */
+
+ if ( memcmp( &bcast_mac, mac, sizeof(ether_addr_t) ) == 0 || memcmp(&cpu_mac,mac,sizeof(ether_addr_t)) == 0)
+ {
+ return convert_setAsicL2Table(
+ row,
+ column,
+ mac,
+ TRUE, /* Set CPU bit to TRUE */
+ FALSE,
+ mbr,
+ 500,
+ isStatic, /* No one will be broadcast/multicast source */
+ nhFlag,/* No one will be broadcast/multicast source */
+ TRUE
+ );
+ }
+#endif
+ if(mac->octet[0]&0x1)
+ {
+ return convert_setAsicL2Table(
+ row,
+ column,
+ mac,
+ cpu,
+ FALSE,
+ mbr,
+ ageSec,
+ isStatic, /* No one will be broadcast/multicast source */
+ nhFlag, /* No one will be broadcast/multicast source */
+ fid,
+ TRUE
+ );
+ }
+ else {
+ int8 dStatic=isStatic/*, dnhFlag=(isStatic==TRUE? TRUE: FALSE)*/;
+ int8 dnhFlag = nhFlag;
+#if defined(CONFIG_RTL865X_PPTPL2TP)||defined(CONFIG_RTL865XB_PPTPL2TP)
+ extern rtl8651_tblDrv_miiTunneling_t tunnel;
+ uint32 MBR = (1 << tunnel.loopbackPort);
+ if (tunnel.valid && mbr==MBR) {
+ dStatic = TRUE;
+ dnhFlag = FALSE;
+ }
+#endif
+ return convert_setAsicL2Table(
+ row,
+ column,
+ mac,
+ cpu,
+ srcBlk,
+ mbr,
+ ageSec,
+ dStatic,
+ dnhFlag,
+ fid,
+ auth
+// FALSE, /* patch here!! always dynamic entry */
+// (isStatic==TRUE? TRUE: FALSE) /* patch here!! nhFlag always turned on if static entry*/
+ );
+ }
+}
+
+
+/*
+ * <<RTL8651 version B Bug>>
+ * RTL8651 L2 entry bug:
+ * For each L2 entry added by driver table as a static entry, the aging time
+ * will not be updated by ASIC
+ * Bug fixed:
+ * To patch this bug, set the entry as a dynamic entry and turn on the 'nhFlag',
+ * then the aging time of this entry will be updated and once aging time expired,
+ * it won't be removed by ASIC automatically.
+ */
+#if 0
+int32 rtl8651_getAsicL2Table_Patch(uint32 row, uint32 column, ether_addr_t * mac, int8 * cpu,
+ int8 * srcBlk, int8 * isStatic, uint32 * mbr, uint32 * ageSec, int8 *nhFlag)
+{
+ rtl865x_tblAsicDrv_l2Param_t l2;
+
+ int32 retval = rtl8651_getAsicL2Table(row, column, &l2);
+ if (mac) memcpy(mac, &l2.macAddr, 6);
+ if (cpu) *cpu = l2.cpu;
+ if (srcBlk) *srcBlk = l2.srcBlk;
+ if (isStatic) *isStatic = l2.isStatic;
+ if (mbr) *mbr = l2.memberPortMask;
+ if (ageSec) *ageSec = l2.ageSec;
+ if (nhFlag) *nhFlag = l2.nhFlag;
+ if (isStatic != NULL) *isStatic = TRUE; /* patch!!, always TRUE(static entry */
+ if (nhFlag != NULL) *nhFlag = FALSE; /* always false */
+ return retval;
+}
+#else
+
+int32 rtl8651_getAsicL2Table_Patch(uint32 row, uint32 column, rtl865x_tblAsicDrv_l2Param_t *asic_l2_t)
+{
+ int32 retval = rtl8651_getAsicL2Table(row, column, asic_l2_t);
+#ifdef CONFIG_RTL865XB_EXP_INVALID
+ if (retval == SUCCESS) {
+ asic_l2_t->isStatic = TRUE;
+ asic_l2_t->nhFlag = FALSE;
+ }
+#endif
+ return retval;
+}
+#endif
+
+#if !defined(CONFIG_RTL_819X)
+#define PAGE_SELECT_REGID 31
+#define PAGE_SELECT_OFFSET 0
+#define PAGE_SELECT_MASK 0xF
+#define EXTRTL_8214_REGBASE_1 CONFIG_EXTRTL8212_PHYID_P1
+#define EXTRTL_8214_REGBASE_3 CONFIG_EXTRTL8212_PHYID_P3
+static inline unsigned int rtl865x_probeP1toP4GigaPHYChip(void)
+{
+ unsigned int uid,tmp;
+ unsigned int i;
+
+ /* Read */
+ for(i=0; i<4; i++) //probe p1-p4
+ {
+ rtl8651_getAsicEthernetPHYReg( CONFIG_EXTRTL8212_PHYID_P1+i, 2, &tmp );
+ uid=tmp<<16;
+ rtl8651_getAsicEthernetPHYReg( CONFIG_EXTRTL8212_PHYID_P1+i, 3, &tmp );
+ uid=uid | tmp;
+
+ if( uid==0x001CC912 ) //0x001cc912 is 8212 two giga port , 0x001cc940 is 8214 four giga port
+ {
+ return 1;
+ }
+ else if(uid==0x001CC940)
+ {
+ //printk("Find Port1-4 8214 PHY Chip! \r\n");
+ //FixPHYChip();
+ //RstGigaPhy();
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static inline unsigned int rtl865x_probeP5GigaPHYChip(void)
+{
+ unsigned int uid,tmp;
+
+ /* Read */
+ rtl8651_getAsicEthernetPHYReg( CONFIG_EXTRTL8212_PHYID_P5, 0, &tmp );
+ rtl8651_setAsicEthernetPHYReg(CONFIG_EXTRTL8212_PHYID_P5,0x10,0x01FE);
+
+ /* Read */
+ rtl8651_getAsicEthernetPHYReg( CONFIG_EXTRTL8212_PHYID_P5, 2, &tmp );
+ uid=tmp<<16;
+ rtl8651_getAsicEthernetPHYReg( CONFIG_EXTRTL8212_PHYID_P5, 3, &tmp );
+ uid=uid | tmp;
+
+ if( uid==0x001CC912 ) //0x001cc912 is 8212 two giga port , 0x001cc940 is 8214 four giga port
+ { //printk("Find Port5 have 8211 PHY Chip! \r\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+static void rtl865x_fix8214Bug(void)
+{
+ /* 52_phy_write 0x12 9 21 0xDD0A */
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1, PAGE_SELECT_REGID, 0x0009);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1, 21, 0xDD0A);
+ /* 52_phy_write 0x13 9 21 0xDD0A */
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1+1, PAGE_SELECT_REGID, 0x0009);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1+1, 21, 0xDD0A);
+ /* 52_phy_write 0x14 8 28 0x0003 */
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3, PAGE_SELECT_REGID, 0x0008);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3, 28, 0x0003);
+
+ /* mdcmdio_cmd w 0x12 31 0x0002
+ * mdcmdio_cmd w 0x12 8 0x3672
+ * mdcmdio_cmd w 0x12 9 0x8c00
+ * mdcmdio_cmd w 0x12 12 0x5b15
+ * mdcmdio_cmd w 0x12 18 0x0edd
+ * mdcmdio_cmd w 0x12 27 0x5c5c
+ */
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1, PAGE_SELECT_REGID, 0x0002);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1, 8, 0x3672);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1, 9, 0x8c00);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1, 12, 0x5b15);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1, 18, 0x0edd);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1, 27, 0x5c5c);
+
+ /* mdcmdio_cmd w 0x13 31 0x0002
+ * mdcmdio_cmd w 0x13 8 0x3672
+ * mdcmdio_cmd w 0x13 9 0x8c00
+ * mdcmdio_cmd w 0x13 12 0x5b15
+ * mdcmdio_cmd w 0x13 18 0x0edd
+ * mdcmdio_cmd w 0x13 27 0x5c5c
+ */
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1+1, PAGE_SELECT_REGID, 0x0002);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1+1, 8, 0x3672);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1+1, 9, 0x8c00);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1+1, 12, 0x5b15);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1+1, 18, 0x0edd);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1+1, 27, 0x5c5c);
+
+ /* mdcmdio_cmd w 0x14 31 0x0002
+ * mdcmdio_cmd w 0x14 8 0x3672
+ * mdcmdio_cmd w 0x14 9 0x8c00
+ * mdcmdio_cmd w 0x14 12 0x5b15
+ * mdcmdio_cmd w 0x14 18 0x0edd
+ * mdcmdio_cmd w 0x14 27 0x5c5c
+ */
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3, PAGE_SELECT_REGID, 0x0002);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3, 8, 0x3672);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3, 9, 0x8c00);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3, 12, 0x5b15);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3, 18, 0x0edd);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3, 27, 0x5c5c);
+ /* mdcmdio_cmd w 0x15 31 0x0002
+ * mdcmdio_cmd w 0x15 8 0x3672
+ * mdcmdio_cmd w 0x15 9 0x8c00
+ * mdcmdio_cmd w 0x15 12 0x5b15
+ * mdcmdio_cmd w 0x15 18 0x0edd
+ * mdcmdio_cmd w 0x15 27 0x5c5c
+ */
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3+1, PAGE_SELECT_REGID, 0x0002);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3+1, 8, 0x3672);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3+1, 9, 0x8c00);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3+1, 12, 0x5b15);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3+1, 18, 0x0edd);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3+1, 27, 0x5c5c);
+
+ /*
+ * #RTL8214 Enable AUTO - K
+ * 52_phy_write 0x12 0 20 0x8000
+ * 52_phy_write 0x13 0 20 0x8000
+ * 52_phy_write 0x14 0 20 0x8000
+ * 52_phy_write 0x15 0 20 0x8000
+ */
+
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1, PAGE_SELECT_REGID, 0x0000);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1, 20, 0x8000);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1+1, PAGE_SELECT_REGID, 0x0000);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1+1, 20, 0x8000);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3, PAGE_SELECT_REGID, 0x0000);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3, 20, 0x8000);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3+1, PAGE_SELECT_REGID, 0x0000);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3+1, 20, 0x8000);
+
+ /*
+ * 52_phy_write 0x12 0 20 0x8040
+ * 52_phy_write 0x13 0 20 0x8040
+ * 52_phy_write 0x14 0 20 0x8040
+ * 52_phy_write 0x15 0 20 0x8040
+ */
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1, PAGE_SELECT_REGID, 0x0000);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1, 20, 0x8040);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1+1, PAGE_SELECT_REGID, 0x0000);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1+1, 20, 0x8040);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3, PAGE_SELECT_REGID, 0x0000);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3, 20, 0x8040);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3+1, PAGE_SELECT_REGID, 0x0000);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3+1, 20, 0x8040);
+ /*
+ #change to default page
+ 52_phy_read 0x12 8 0
+ */
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1, PAGE_SELECT_REGID, 0x0008);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1+1, PAGE_SELECT_REGID, 0x0008);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3, PAGE_SELECT_REGID, 0x0008);
+ rtl8651_setAsicEthernetPHYReg(EXTRTL_8214_REGBASE_3+1, PAGE_SELECT_REGID, 0x0008);
+
+#if 0
+ /* Test */
+ rtl8651_getAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1+1, PAGE_SELECT_REGID, &rData);
+ rtl8651_getAsicEthernetPHYReg(EXTRTL_8214_REGBASE_1+1, 15, &rData);
+ rtl865x_setAsicEthernetPHYPage(EXTRTL_8214_REGBASE_1+1, 8);
+ printk("*********************\nrData 0x%x\n*********************\n", rData);
+#endif
+}
+#endif
+
+static int32 _rtl8651_initAsicPara( rtl8651_tblAsic_InitPara_t *para )
+{
+ memset(&rtl8651_tblAsicDrvPara, 0, sizeof(rtl8651_tblAsic_InitPara_t));
+
+ if ( para )
+ {
+ /* Parameter != NULL, check its correctness */
+ if (para->externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT1234_RTL8212)
+ {
+ ASICDRV_ASSERT(para->externalPHYId[1] != 0);
+ ASICDRV_ASSERT(para->externalPHYId[2] != 0);
+ ASICDRV_ASSERT(para->externalPHYId[3] != 0);
+ ASICDRV_ASSERT(para->externalPHYId[4] != 0);
+ ASICDRV_ASSERT(para->externalPHYId[2] == (para->externalPHYId[1] + 1));
+ ASICDRV_ASSERT(para->externalPHYId[4] == (para->externalPHYId[3] + 1));
+ }
+ if (para->externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
+ {
+ ASICDRV_ASSERT(para->externalPHYId[5] != 0);
+ }
+
+ /* ============= Check passed : set it ============= */
+ memcpy(&rtl8651_tblAsicDrvPara, para, sizeof(rtl8651_tblAsic_InitPara_t));
+ }
+
+ return SUCCESS;
+}
+
+#if defined(CONFIG_RTL8196C_REVISION_B) || defined(CONFIG_RTL_8198)
+void Set_GPHYWB(unsigned int phyid, unsigned int page, unsigned int reg, unsigned int mask, unsigned int val)
+{
+ unsigned int data=0;
+ unsigned int wphyid=0; //start
+ unsigned int wphyid_end=1; //end
+
+ if(phyid==999)
+ { wphyid=0;
+ wphyid_end=5; //total phyid=0~4
+ }
+ else
+ { wphyid=phyid;
+ wphyid_end=phyid+1;
+ }
+
+ for(; wphyid<wphyid_end; wphyid++)
+ {
+ //change page
+ if(page>=31)
+ { rtl8651_setAsicEthernetPHYReg( wphyid, 31, 7 );
+ rtl8651_setAsicEthernetPHYReg( wphyid, 30, page );
+ }
+ else
+ {
+ rtl8651_setAsicEthernetPHYReg( wphyid, 31, page );
+ }
+
+ if(mask != 0)
+ {
+ rtl8651_getAsicEthernetPHYReg( wphyid, reg, &data);
+ data = data&mask;
+ }
+ rtl8651_setAsicEthernetPHYReg( wphyid, reg, data|val );
+
+
+ //switch to page 0
+ rtl8651_setAsicEthernetPHYReg( wphyid, 31, 0 );
+ }
+}
+#endif
+
+#ifdef CONFIG_RTL8196C_REVISION_B
+
+#ifdef CONFIG_RTL8196C_ETH_IOT
+void set_gray_code_by_port(int port)
+{
+ uint32 val;
+
+ rtl8651_setAsicEthernetPHYReg( 4, 31, 1 );
+
+ rtl8651_getAsicEthernetPHYReg( 4, 20, &val );
+ rtl8651_setAsicEthernetPHYReg( 4, 20, val + (0x1 << port) );
+
+ rtl8651_setAsicEthernetPHYReg( port, 31, 1 );
+
+ rtl8651_setAsicEthernetPHYReg( port, 19, 0x5400 );
+ if (port<4) rtl8651_setAsicEthernetPHYReg( port, 19, 0x5440 );
+ if (port<3) rtl8651_setAsicEthernetPHYReg( port, 19, 0x54c0 );
+ if (port<2) rtl8651_setAsicEthernetPHYReg( port, 19, 0x5480 );
+ if (port<1) rtl8651_setAsicEthernetPHYReg( port, 19, 0x5580 );
+
+ rtl8651_setAsicEthernetPHYReg( 4, 20, 0xb20 );
+ rtl8651_setAsicEthernetPHYReg( port, 31, 0 );
+
+ rtl8651_setAsicEthernetPHYReg( 4, 31, 0 );
+}
+#endif
+
+void Setting_RTL8196C_PHY(void)
+{
+ int i=0;
+ for(i=0; i<5; i++)
+ REG32(PCRP0+i*4) |= (EnForceMode);
+
+ /*
+ #=========ADC Bias Current =========================
+ #RG1X_P4~0 [12:10] = Reg_pi_fix [2:0], 5 ->7
+ phywb all 1 17 12-10 0x7
+ */
+ Set_GPHYWB(999, 1, 17, 0xffff-(7<<10), 0x7<<10);
+
+ /*
+ #=========patch for eee============================
+ #1. page4¡Breg24¡Glpi_rx_ti_timer_cnt change to f3
+ phywb all 4 24 7-0 0xf3
+
+ #2. page4¡Breg16¡Grg_txqt_ps_sel change to 1
+ phywb all 4 16 3 1
+ */
+ Set_GPHYWB(999, 4, 24, 0xff00, 0xf3);
+ Set_GPHYWB(999, 4, 16, 0xffff-(1<<3), 1<<3);
+ /*
+ #=========patch for IOL Tx amp.=====================
+ #<a>modify 100M DAC current default value:
+ #Port#0~#4(per port control)
+ #Page1,Reg19,bit[13:11]:
+ #original value 200uA(3b'100),--> change to 205u(3b'000) => change to 205u(3b010)
+
+ phywb all 1 19 13-11 0x2
+
+ #<b>modify bandgap voltage default value:
+ #Port#0~#4 (Global all ports contorl setting),
+ #Page1,Reg23,bit[8:6],
+
+ #original value 1.312V(3b'110),-->change to 1.212V(3b'100).
+
+ phywb all 1 23 8-6 0x4
+
+ #<c>modify TX CS cap default value:
+ #Port#0~#4 (Global all ports contorl setting),
+ #Page1,Reg18,bit[5:3],
+
+ #original value Reserved bits(3b'000),-->change to 600fF(3b'011). =>change to 750fF(3b'110)
+ phywb all 1 18 5-3 0x6
+ */
+
+ Set_GPHYWB(999, 1, 19, 0xffff-(7<<11), 0x2<<11);
+ Set_GPHYWB(999, 1, 23, 0xffff-(7<<6) , 0x4<<6);
+ Set_GPHYWB(999, 1, 18, 0xffff-(7<<3), 0x6<<3);
+
+
+ /* 20100223 from Maxod: 100M half duplex enhancement */
+ REG32(MACCR)= (REG32(MACCR) & ~CF_RXIPG_MASK) | 0x05;
+
+ /* fix the link down / link up issue with SmartBit 3101B when DUT(8196c) set to Auto-negotiation
+ and SmartBit force to 100M Full-duplex */
+ REG32(MACCR)= (REG32(MACCR) & ~SELIPG_MASK) | SELIPG_11;
+
+ /*20100222 from Anson:Switch Corner test pass setting*/
+ /*
+ REG21 default=0x2c5
+ After snr_ub(page0 reg21.7-4) = 3 and snr_lb(page0 reg21.3-0)=2 ,REG21=0x232
+ REG22 default=0x5b85
+ After adtune_lb(page0 reg22.6-4)=4 (10uA) ,REG21=0x5b45
+
+ REG0 default=0x1100
+ restart AN
+ page0 reg0.9 =1 , ,REG0=0x1300
+ */
+ //rtl8651_setAsicEthernetPHYReg( i, 0x15, 0x232 );
+ //Set_GPHYWB(999, 0, 21, 0xffff-(0xff<<0), 0x32<<0);
+ // test 96C to 96C restart AN 100 times, result is pass ==> page0 reg21.14(disable the equlizar)=1
+#ifdef CONFIG_RTL8196C_ETH_IOT
+ // enable "equalizer reset", i.e. page 0 , reg21, bit14= 0
+ Set_GPHYWB(999, 0, 21, (~0x40ff), 0x0032);
+#else
+ Set_GPHYWB(999, 0, 21, (~0x40ff), 0x4032);
+#endif
+
+ //rtl8651_setAsicEthernetPHYReg( i, 0x16, 0x5b45 );
+ //Set_GPHYWB(999, 0, 22, 0xffff-(7<<4), 0x4<<4);
+ Set_GPHYWB(999, 0, 22, 0xffff-(7<<4), 0x5<<4);
+ //rtl8651_setAsicEthernetPHYReg( i, 0x0, 0x1300 );
+ Set_GPHYWB(999, 0, 0, 0xffff-(1<<9), 0x1<<9);
+
+ /*20100225 from Anson:Switch Force cailibration
+ #change calibration update method for patch first pkt no update impedance
+ phywb all 1 29 1 0
+ #--------------Patch for impedance update fail cause rx crc error with long calbe--------
+ #Froce cailibration
+ phywb all 1 29 2 1
+ #Force impedance value = 0x8888
+ phywb all 1 28 15-0 0x8888
+ #-----------------------------------------------------------------------------------------
+ #Select clock (ckt125[4]) edge trigger mlt3[1:0] = negative for patch four corner fail issue(only tx timing)
+ phywb all 1 17 2-1 0x3
+ */
+ //Set_GPHYWB(999, 1, 29, 0xffff-(1<<1), 0x0<<1);
+ //Set_GPHYWB(999, 1, 29, 0xffff-(1<<2), 0x1<<2);
+ //Set_GPHYWB(999, 1, 28, 0xffff-(0xffff), 0x8888);
+ Set_GPHYWB(999, 1, 17, 0xffff-(3<<1), 0x3<<1);
+
+ /*20100222 from Yozen:AOI TEST pass setting*/
+ Set_GPHYWB(999, 1, 18, 0xffff-(0xffff), 0x9004);
+
+ // for "DSP recovery fail when link partner = force 100F"
+ Set_GPHYWB(999, 4, 26, 0xffff-(0xfff<<4), 0xff8<<4);
+
+ for(i=0; i<5; i++)
+ REG32(PCRP0+i*4) &= ~(EnForceMode);
+
+#ifdef CONFIG_RTL8196C_ETH_IOT
+ for(i=0; i<5; i++) {
+ set_gray_code_by_port(i);
+ }
+#endif
+ printk(" Set 8196C PHY Patch OK\n");
+
+}
+#endif
+
+#ifdef CONFIG_RTL_8198
+static const unsigned int phy_para[]={
+ //###################### PHY parameter patch ################################
+ 0x1f, 0x0005, //Page 5
+ 0x13, 0x0003, //Page 5 ########## EMA =3#############
+ //0x01, 0x0700; #Page 5 Reg 1 = 0x0700, NEC ON (20100112)
+ 0x05,0x8B82,//Page 5 Reg 5 = 0x8B82, Fix 100M re-link fail issue (20100110)
+ 0x06,0x05CB,//Page 5 Reg 6 = 0x05CB, Fix 100M re-link fail issue (20100110)
+ 0x1f,0x0002,//Page 2
+ 0x04,0x80C2,//Page 2 Reg 4 0x80C2, Fix 100M re-link fail issue (20100110)
+ 0x05,0x0938,//Page 2 Reg 5 0x0938, Disable 10M standby mode (20100112)
+
+ 0x1F,0x0003,//Page 3
+ 0x12,0xC4D2,//Page 3 Reg 18 = 0xC4D2, GAIN upper bond=24
+ 0x0D,0x0207,//Page 3 Reg 13 = 0x0207 (20100112)
+ 0x01,0x3554, //#Page 3 Reg 1 = 0x3554 (20100423)
+ 0x02,0x63E8, //#Page 3 Reg 2 = 0x63E8 (20100423)
+ 0x03,0x99C2, //#Page 3 Reg 3 = 0x99C2 (20100423)
+ 0x04,0x0113, //#Page 3 Reg 4 = 0x0113 (20100423)
+
+ 0x1f,0x0001,//Page 1
+ 0x07,0x267E,//Page 1 Reg 7 = 0x267E, Channel Gain offset (20100111)
+ 0x1C,0xE5F7,//Page 1 Reg 28 = 0xE5F7, Cable length offset (20100111)
+ 0x1B,0x0424,//Page 1 Reg 27 = 0x0424, SD threshold (20100111)
+
+ //#Add by Gary for Channel Estimation fine tune 20100430
+ //0x1f,0x0002, //# change to Page 1 (Global)
+ //0x08,0x0574, //# Page1 Reg8 (CG_INITIAL_MASTER)
+ //0x09,0x2724, //# Page1 Reg9 (CB0_INITIAL_GIGA)
+ //0x1f,0x0003, //# change to Page 3 (Global)
+ //0x1a,0x06f6, //# Page3 Reg26 (CG_INITIAL_SLAVE)
+
+ //#Add by Gary for Channel Estimation fine tune 20100430
+ //#Page1 Reg8 (CG_INITIAL_MASTER)
+ //0x1f, 0x0005,
+ //0x05, 0x83dd,
+ //0x06, 0x0574,
+ //#Page1 Reg9 (CB0_INITIAL_GIGA)
+ //0x1f, 0x0005,
+ //0x05, 0x83e0,
+ //0x06, 0x2724,
+ //#Page3 Reg26 (CG_INITIAL_SLAVE)
+ //0x1f, 0x0005,
+ //0x05, 0x843d,
+ //0x06, 0x06f6 ,
+
+ //#NC FIFO
+ 0x1f,0x0007,//ExtPage
+ 0x1e,0x0042,//ExtPage 66
+ 0x18,0x0000,//Page 66 Reg 24 = 0x0000, NC FIFO (20100111)
+ 0x1e,0x002D,//ExtPage 45
+ 0x18,0xF010,//Page 45 Reg 24 = 0xF010, Enable Giga Down Shift to 100M (20100118)
+
+ 0x1e,0x002c, //#ExtPage 44
+ 0x18,0x008B, //#Page 44 Reg 24 = 0x008B, Enable deglitch circuit (20100426)
+
+ //############################ EEE giga patch ################################
+
+ //0x1f 0x0007;
+ 0x1e,0x0028,
+ 0x16,0xf640,//phywb $phyID 40 22 15-0 0xF640
+
+ 0x1e,0x0021,
+ 0x19,0x2929,//phywb $phyID 33 25 15-0 0x2929
+
+ 0x1a,0x1005,//phywb $phyID 33 26 15-0 0x1005
+
+ 0x1e,0x0020,
+ 0x17,0x000a,//phywb $phyID 32 23 15-0 0x000a
+
+ 0x1b,0x2f4a,//Disable EEE PHY mode
+ 0x15,0x0100,//EEE ability, Disable EEEP
+
+ 0x1e,0x0040,//
+ 0x1a,0x5110,// phywb $phyID 64 26 15-0 0x5110
+ 0x18,0x0000,// programable mode
+
+ 0x1e,0x0041,//
+ 0x15,0x0e02,//phywb $phyID 65 21 15-0 0x0e02
+
+ 0x16,0x2185,//phywb $phyID 65 22 15-0 0x2185
+ 0x17,0x000c,//phywb $phyID 65 23 15-0 0x000c
+ 0x1c,0x0008,//phywb $phyID 65 28 15-0 0x0008
+ 0x1e,0x0042,//
+ 0x15,0x0d00,//phywb $phyID 66 21 15-0 0x0d00
+
+ #if 1
+ //############################ EEE Run code patch #################################
+ //###proc 67R_ram_code_20100211_inrx_uc_98_1
+ //###proc ram_code_0223_uc {} {
+ //#replace 0xfff6, lock uc ram code version!
+ 31, 0x5,
+ 5, 0xfff6,
+ 6, 0x0080,
+ 5, 0x8b6e,
+ 6, 0x0000,
+ 15, 0x0100,
+
+ //### force MDI/MDIX
+ 0x1f, 0x0007,
+ 0x1e, 0x002d,
+ 0x18, 0xf030,
+
+ //### pcs nctl patch code (0423)
+ 0x1f, 0x0007,
+ 0x1e, 0x0023,
+ 0x16, 0x0005,
+
+ //### startpoint
+ 0x15, 0x005c,
+ 0x19, 0x0068,
+ 0x15, 0x0082,
+ 0x19, 0x000a,
+ 0x15, 0x00a1,
+ 0x19, 0x0081,
+ 0x15 ,0x00af,
+ 0x19, 0x0080,
+ 0x15, 0x00d4,
+ 0x19, 0x0000,
+ 0x15, 0x00e4,
+ 0x19, 0x0081,
+ 0x15, 0x00e7,
+ 0x19, 0x0080,
+ 0x15, 0x010d,
+ 0x19, 0x0083,
+ 0x15, 0x0118,
+ 0x19, 0x0083,
+ 0x15, 0x0120,
+ 0x19, 0x0082,
+ 0x15, 0x019c,
+ 0x19, 0x0081,
+ 0x15, 0x01a4,
+ 0x19, 0x0080,
+ 0x15, 0x01cd,
+ 0x19, 0x0000,
+ 0x15, 0x01dd,
+ 0x19, 0x0081,
+ 0x15, 0x01e0,
+ 0x19, 0x0080,
+ //### endpoint
+
+ 0x16, 0x0000,
+ //### end of pcs nctl patch code
+
+ //inrx
+ 0x1f, 0x0007,
+ 0x1e, 0x0040,
+ 0x18, 0x0004,
+ 0x1f,0x0000,
+ 0x17,0x2160,
+ 0x1f,0x0007,
+ 0x1e,0x0040,
+
+ //### startpoint
+ 0x18,0x0004,
+ 0x19,0x4000,
+ 0x18,0x0014,
+ 0x19,0x7f00,
+ 0x18,0x0024,
+ 0x19,0x0000,
+ 0x18,0x0034,
+ 0x19,0x0100,
+ 0x18,0x0044,
+ 0x19,0xe000,
+ 0x18,0x0054,
+ 0x19,0x0000,
+ 0x18,0x0064,
+ 0x19,0x0000,
+ 0x18,0x0074,
+ 0x19,0x0000,
+ 0x18,0x0084,
+ 0x19,0x0400,
+ 0x18,0x0094,
+ 0x19,0x8000,
+ 0x18,0x00a4,
+ 0x19,0x7f00,
+ 0x18,0x00b4,
+ 0x19,0x4000,
+ 0x18,0x00c4,
+ 0x19,0x2000,
+ 0x18,0x00d4,
+ 0x19,0x0100,
+ 0x18,0x00e4,
+ 0x19,0x8400,
+ 0x18,0x00f4,
+ 0x19,0x7a00,
+ 0x18,0x0104,
+ 0x19,0x4000,
+ 0x18,0x0114,
+ 0x19,0x3f00,
+ 0x18,0x0124,
+ 0x19,0x0100,
+ 0x18,0x0134,
+ 0x19,0x7800,
+ 0x18,0x0144,
+ 0x19,0x0000,
+ 0x18,0x0154,
+ 0x19,0x0000,
+ 0x18,0x0164,
+ 0x19,0x0000,
+ 0x18,0x0174,
+ 0x19,0x0400,
+ 0x18,0x0184,
+ 0x19,0x8000,
+ 0x18,0x0194,
+ 0x19,0x7f00,
+ 0x18,0x01a4,
+ 0x19,0x8300,
+ 0x18,0x01b4,
+ 0x19,0x8300,
+ 0x18,0x01c4,
+ 0x19,0xe200,
+ 0x18,0x01d4,
+ 0x19,0x0a00,
+ 0x18,0x01e4,
+ 0x19,0x8800,
+ 0x18,0x01f4,
+ 0x19,0x0300,
+ 0x18,0x0204,
+ 0x19,0xe100,
+ 0x18,0x0214,
+ 0x19,0x4600,
+ 0x18,0x0224,
+ 0x19,0x4000,
+ 0x18,0x0234,
+ 0x19,0x7f00,
+ 0x18,0x0244,
+ 0x19,0x0000,
+ 0x18,0x0254,
+ 0x19,0x0100,
+ 0x18,0x0264,
+ 0x19,0x4000,
+ 0x18,0x0274,
+ 0x19,0x3e00,
+ 0x18,0x0284,
+ 0x19,0x0000,
+ 0x18,0x0294,
+ 0x19,0xe000,
+ 0x18,0x02a4,
+ 0x19,0x1200,
+ 0x18,0x02b4,
+ 0x19,0x8000,
+ 0x18,0x02c4,
+ 0x19,0x7f00,
+ 0x18,0x02d4,
+ 0x19,0x8900,
+ 0x18,0x02e4,
+ 0x19,0x8300,
+ 0x18,0x02f4,
+ 0x19,0xe000,
+ 0x18,0x0304,
+ 0x19,0x0000,
+ 0x18,0x0314,
+ 0x19,0x4000,
+ 0x18,0x0324,
+ 0x19,0x7f00,
+ 0x18,0x0334,
+ 0x19,0x0000,
+ 0x18,0x0344,
+ 0x19,0x2000,
+ 0x18,0x0354,
+ 0x19,0x4000,
+ 0x18,0x0364,
+ 0x19,0x3e00,
+ 0x18,0x0374,
+ 0x19,0xfd00,
+ 0x18,0x0384,
+ 0x19,0x0000,
+ 0x18,0x0394,
+ 0x19,0x1200,
+ 0x18,0x03a4,
+ 0x19,0xab00,
+ 0x18,0x03b4,
+ 0x19,0x0c00,
+ 0x18,0x03c4,
+ 0x19,0x0600,
+ 0x18,0x03d4,
+ 0x19,0xa000,
+ 0x18,0x03e4,
+ 0x19,0x3d00,
+ 0x18,0x03f4,
+ 0x19,0xfb00,
+ 0x18,0x0404,
+ 0x19,0xe000,
+ 0x18,0x0414,
+ 0x19,0x0000,
+ 0x18,0x0424,
+ 0x19,0x4000,
+ 0x18,0x0434,
+ 0x19,0x7f00,
+ 0x18,0x0444,
+ 0x19,0x0000,
+ 0x18,0x0454,
+ 0x19,0x0100,
+ 0x18,0x0464,
+ 0x19,0x4000,
+ 0x18,0x0474,
+ 0x19,0xc600,
+ 0x18,0x0484,
+ 0x19,0xff00,
+ 0x18,0x0494,
+ 0x19,0x0000,
+ 0x18,0x04a4,
+ 0x19,0x1000,
+ 0x18,0x04b4,
+ 0x19,0x0200,
+ 0x18,0x04c4,
+ 0x19,0x7f00,
+ 0x18,0x04d4,
+ 0x19,0x4000,
+ 0x18,0x04e4,
+ 0x19,0x7f00,
+ 0x18,0x04f4,
+ 0x19,0x0200,
+ 0x18,0x0504,
+ 0x19,0x0200,
+ 0x18,0x0514,
+ 0x19,0x5200,
+ 0x18,0x0524,
+ 0x19,0xc400,
+ 0x18,0x0534,
+ 0x19,0x7400,
+ 0x18,0x0544,
+ 0x19,0x0000,
+ 0x18,0x0554,
+ 0x19,0x1000,
+ 0x18,0x0564,
+ 0x19,0xbc00,
+ 0x18,0x0574,
+ 0x19,0x0600,
+ 0x18,0x0584,
+ 0x19,0xfe00,
+ 0x18,0x0594,
+ 0x19,0x4000,
+ 0x18,0x05a4,
+ 0x19,0x7f00,
+ 0x18,0x05b4,
+ 0x19,0x0000,
+ 0x18,0x05c4,
+ 0x19,0x0a00,
+ 0x18,0x05d4,
+ 0x19,0x5200,
+ 0x18,0x05e4,
+ 0x19,0xe400,
+ 0x18,0x05f4,
+ 0x19,0x3c00,
+ 0x18,0x0604,
+ 0x19,0x0000,
+ 0x18,0x0614,
+ 0x19,0x1000,
+ 0x18,0x0624,
+ 0x19,0x8a00,
+ 0x18,0x0634,
+ 0x19,0x7f00,
+ 0x18,0x0644,
+ 0x19,0x4000,
+ 0x18,0x0654,
+ 0x19,0x7f00,
+ 0x18,0x0664,
+ 0x19,0x0100,
+ 0x18,0x0674,
+ 0x19,0x2000,
+ 0x18,0x0684,
+ 0x19,0x0000,
+ 0x18,0x0694,
+ //### 0x2219:0x4600 =>0xe600 #0309
+ 0x19,0xe600,
+ 0x18,0x06a4,
+ //### 0x2219:0xfc00 =>0xff00 #0309
+ 0x19,0xff00,
+ 0x18,0x06b4,
+ 0x19,0x0000,
+ 0x18,0x06c4,
+ 0x19,0x5000,
+ 0x18,0x06d4,
+ 0x19,0x9d00,
+ 0x18,0x06e4,
+ 0x19,0xff00,
+ 0x18,0x06f4,
+ 0x19,0x4000,
+ 0x18,0x0704,
+ 0x19,0x7f00,
+ 0x18,0x0714,
+ 0x19,0x0000,
+ 0x18,0x0724,
+ 0x19,0x2000,
+ 0x18,0x0734,
+ 0x19,0x0000,
+ 0x18,0x0744,
+ 0x19,0xe600,
+ 0x18,0x0754,
+ 0x19,0xff00,
+ 0x18,0x0764,
+ 0x19,0x0000,
+ 0x18,0x0774,
+ 0x19,0x5000,
+ 0x18,0x0784,
+ 0x19,0x8500,
+ 0x18,0x0794,
+ 0x19,0x7f00,
+ 0x18,0x07a4,
+ 0x19,0xac00,
+ 0x18,0x07b4,
+ 0x19,0x0800,
+ 0x18,0x07c4,
+ 0x19,0xfc00,
+ 0x18,0x07d4,
+ 0x19,0x4000,
+ 0x18,0x07e4,
+ 0x19,0x7f00,
+ 0x18,0x07f4,
+ 0x19,0x0400,
+ 0x18,0x0804,
+ 0x19,0x0200,
+ 0x18,0x0814,
+ 0x19,0x0000,
+ 0x18,0x0824,
+ 0x19,0xff00,
+ 0x18,0x0834,
+ 0x19,0x7f00,
+ 0x18,0x0844,
+ 0x19,0x0000,
+ 0x18,0x0854,
+ 0x19,0x4200,
+ 0x18,0x0864,
+ 0x19,0x0500,
+ 0x18,0x0874,
+ 0x19,0x9000,
+ 0x18,0x0884,
+ 0x19,0x8000,
+ 0x18,0x0894,
+ 0x19,0x7d00,
+ 0x18,0x08a4,
+ 0x19,0x8c00,
+ 0x18,0x08b4,
+ 0x19,0x8300,
+ 0x18,0x08c4,
+ 0x19,0xe000,
+ 0x18,0x08d4,
+ 0x19,0x0000,
+ 0x18,0x08e4,
+ 0x19,0x4000,
+ 0x18,0x08f4,
+ 0x19,0x0400,
+ 0x18,0x0904,
+ 0x19,0xff00,
+ 0x18,0x0914,
+ 0x19,0x0500,
+ 0x18,0x0924,
+ 0x19,0x8500,
+ 0x18,0x0934,
+ 0x19,0x8c00,
+ 0x18,0x0944,
+ 0x19,0xfa00,
+ 0x18,0x0954,
+ 0x19,0xe000,
+ 0x18,0x0964,
+ 0x19,0x0000,
+ 0x18,0x0974,
+ 0x19,0x4000,
+ 0x18,0x0984,
+ 0x19,0x5f00,
+ 0x18,0x0994,
+ 0x19,0x0400,
+ 0x18,0x09a4,
+ 0x19,0x0000,
+ 0x18,0x09b4,
+ 0x19,0xfe00,
+ 0x18,0x09c4,
+ 0x19,0x7300,
+ 0x18,0x09d4,
+ 0x19,0x0d00,
+ 0x18,0x09e4,
+ 0x19,0x0300,
+ 0x18,0x09f4,
+ 0x19,0x4000,
+ 0x18,0x0a04,
+ 0x19,0x2000,
+ 0x18,0x0a14,
+ 0x19,0x0000,
+ 0x18,0x0a24,
+ 0x19,0x0400,
+ 0x18,0x0a34,
+ 0x19,0xda00,
+ 0x18,0x0a44,
+ 0x19,0x0600,
+ 0x18,0x0a54,
+ 0x19,0x7d00,
+ 0x18,0x0a64,
+ 0x19,0x4000,
+ 0x18,0x0a74,
+ 0x19,0x5f00,
+ 0x18,0x0a84,
+ 0x19,0x0400,
+ 0x18,0x0a94,
+ 0x19,0x0000,
+ 0x18,0x0aa4,
+ 0x19,0x0000,
+ 0x18,0x0ab4,
+ 0x19,0x7300,
+ 0x18,0x0ac4,
+ 0x19,0x0d00,
+ 0x18,0x0ad4,
+ 0x19,0x0300,
+ 0x18,0x0ae4,
+ 0x19,0x0400,
+ 0x18,0x0af4,
+ 0x19,0xce00,
+ 0x18,0x0b04,
+ 0x19,0x0900,
+ 0x18,0x0b14,
+ 0x19,0x9d00,
+ 0x18,0x0b24,
+ 0x19,0x0800,
+ 0x18,0x0b34,
+ 0x19,0x9000,
+ 0x18,0x0b44,
+ 0x19,0x0700,
+ 0x18,0x0b54,
+ 0x19,0x7900,
+ 0x18,0x0b64,
+ 0x19,0x4000,
+ 0x18,0x0b74,
+ 0x19,0x7f00,
+ 0x18,0x0b84,
+ 0x19,0x0400,
+ 0x18,0x0b94,
+ 0x19,0x0000,
+ 0x18,0x0ba4,
+ 0x19,0x0000,
+ 0x18,0x0bb4,
+ 0x19,0x0400,
+ 0x18,0x0bc4,
+ 0x19,0x7300,
+ 0x18,0x0bd4,
+ 0x19,0x0d00,
+ 0x18,0x0be4,
+ 0x19,0x0100,
+ 0x18,0x0bf4,
+ 0x19,0x0900,
+ 0x18,0x0c04,
+ 0x19,0x8e00,
+ 0x18,0x0c14,
+ 0x19,0x0800,
+ 0x18,0x0c24,
+ 0x19,0x7d00,
+ 0x18,0x0c34,
+ 0x19,0x4000,
+ 0x18,0x0c44,
+ 0x19,0x7f00,
+ 0x18,0x0c54,
+ 0x19,0x0000,
+ 0x18,0x0c64,
+ 0x19,0x0000,
+ 0x18,0x0c74,
+ 0x19,0x0200,
+ 0x18,0x0c84,
+ 0x19,0x0000,
+ 0x18,0x0c94,
+ 0x19,0x7000,
+ 0x18,0x0ca4,
+ 0x19,0x0c00,
+ 0x18,0x0cb4,
+ 0x19,0x0100,
+ 0x18,0x0cc4,
+ 0x19,0x0900,
+ 0x18,0x0cd4,
+ 0x19,0x7f00,
+ 0x18,0x0ce4,
+ 0x19,0x4000,
+ 0x18,0x0cf4,
+ 0x19,0x7f00,
+ 0x18,0x0d04,
+ 0x19,0x3400,
+ 0x18,0x0d14,
+ 0x19,0x8300,
+ 0x18,0x0d24,
+ 0x19,0x8200,
+ 0x18,0x0d34,
+ 0x19,0x0000,
+ 0x18,0x0d44,
+ 0x19,0x7000,
+ 0x18,0x0d54,
+ 0x19,0x0d00,
+ 0x18,0x0d64,
+ 0x19,0x0100,
+ 0x18,0x0d74,
+ 0x19,0x0f00,
+ 0x18,0x0d84,
+ 0x19,0x7f00,
+ 0x18,0x0d94,
+ 0x19,0x9a00,
+ 0x18,0x0da4,
+ 0x19,0x7d00,
+ 0x18,0x0db4,
+ 0x19,0x4000,
+ 0x18,0x0dc4,
+ 0x19,0x7f00,
+ 0x18,0x0dd4,
+ 0x19,0x1400,
+ 0x18,0x0de4,
+ 0x19,0x0000,
+ 0x18,0x0df4,
+ 0x19,0x8200,
+ 0x18,0x0e04,
+ 0x19,0x0000,
+ 0x18,0x0e14,
+ 0x19,0x7000,
+ 0x18,0x0e24,
+ 0x19,0x0f00,
+ 0x18,0x0e34,
+ 0x19,0x0100,
+ 0x18,0x0e44,
+ 0x19,0x9b00,
+ 0x18,0x0e54,
+ 0x19,0x7f00,
+ 0x18,0x0e64,
+ 0x19,0x4000,
+ 0x18,0x0e74,
+ 0x19,0x1f00,
+ 0x18,0x0e84,
+ 0x19,0x0200,
+ 0x18,0x0e94,
+ 0x19,0x0600,
+ 0x18,0x0ea4,
+ 0x19,0x7100,
+ 0x18,0x0eb4,
+ 0x19,0x1d00,
+ 0x18,0x0ec4,
+ 0x19,0x0100,
+ 0x18,0x0ed4,
+ 0x19,0x4000,
+ 0x18,0x0ee4,
+ 0x19,0x1f00,
+ 0x18,0x0ef4,
+ 0x19,0x0200,
+ 0x18,0x0f04,
+ 0x19,0x0600,
+ 0x18,0x0f14,
+ 0x19,0x7100,
+ 0x18,0x0f24,
+ 0x19,0x0d00,
+ 0x18,0x0f34,
+ 0x19,0x0100,
+ 0x18,0x0f44,
+ 0x19,0x4000,
+ 0x18,0x0f54,
+ 0x19,0x1f00,
+ 0x18,0x0f64,
+ 0x19,0x0200,
+ 0x18,0x0f74,
+ 0x19,0x0600,
+ 0x18,0x0f84,
+ 0x19,0x7100,
+ 0x18,0x0f94,
+ 0x19,0x0d00,
+ 0x18,0x0fa4,
+ 0x19,0x0100,
+ 0x18,0x0fb4,
+ 0x19,0x4000,
+ 0x18,0x0fc4,
+ 0x19,0x1f00,
+ 0x18,0x0fd4,
+ 0x19,0x0200,
+ 0x18,0x0fe4,
+ 0x19,0x0600,
+ 0x18,0x0ff4,
+ 0x19,0x7100,
+ 0x18,0x1004,
+ 0x19,0x0d00,
+ 0x18,0x1014,
+ 0x19,0x0100,
+ 0x18,0x1024,
+ 0x19,0x4000,
+ 0x18,0x1034,
+ 0x19,0x1f00,
+ 0x18,0x1044,
+ 0x19,0x0200,
+ 0x18,0x1054,
+ 0x19,0x0600,
+ 0x18,0x1064,
+ 0x19,0x7100,
+ 0x18,0x1074,
+ 0x19,0x0d00,
+ 0x18,0x1084,
+ 0x19,0x0100,
+ 0x18,0x1094,
+ 0x19,0x4000,
+ 0x18,0x10a4,
+ 0x19,0x1f00,
+ 0x18,0x10b4,
+ 0x19,0x0200,
+ 0x18,0x10c4,
+ 0x19,0x0600,
+ 0x18,0x10d4,
+ 0x19,0x7100,
+ 0x18,0x10e4,
+ 0x19,0x0d00,
+ 0x18,0x10f4,
+ 0x19,0x0100,
+ 0x18,0x1104,
+ 0x19,0x4000,
+ 0x18,0x1114,
+ 0x19,0x7f00,
+ 0x18,0x1124,
+ 0x19,0x0400,
+ 0x18,0x1134,
+ 0x19,0x9000,
+ 0x18,0x1144,
+ 0x19,0x0200,
+ 0x18,0x1154,
+ 0x19,0x0600,
+ 0x18,0x1164,
+ 0x19,0x7300,
+ 0x18,0x1174,
+ 0x19,0x0d00,
+ 0x18,0x1184,
+ 0x19,0x0100,
+ 0x18,0x1194,
+ 0x19,0x0b00,
+ 0x18,0x11a4,
+ 0x19,0x9500,
+ 0x18,0x11b4,
+ 0x19,0x9400,
+ 0x18,0x11c4,
+ 0x19,0x0400,
+ 0x18,0x11d4,
+ 0x19,0x4000,
+ 0x18,0x11e4,
+ 0x19,0x4000,
+ 0x18,0x11f4,
+ 0x19,0x0500,
+ 0x18,0x1204,
+ 0x19,0x8000,
+ 0x18,0x1214,
+ 0x19,0x7800,
+ 0x18,0x1224,
+ 0x19,0x4000,
+ 0x18,0x1234,
+ 0x19,0x7f00,
+ 0x18,0x1244,
+ 0x19,0x0400,
+ 0x18,0x1254,
+ 0x19,0x0000,
+ 0x18,0x1264,
+ 0x19,0x0200,
+ 0x18,0x1274,
+ 0x19,0x0000,
+ 0x18,0x1284,
+ 0x19,0x7000,
+ 0x18,0x1294,
+ 0x19,0x0f00,
+ 0x18,0x12a4,
+ 0x19,0x0100,
+ 0x18,0x12b4,
+ 0x19,0x9b00,
+ 0x18,0x12c4,
+ 0x19,0x7f00,
+ 0x18,0x12d4,
+ 0x19,0xe100,
+ 0x18,0x12e4,
+ 0x19,0x1000,
+ 0x18,0x12f4,
+ 0x19,0x4000,
+ 0x18,0x1304,
+ 0x19,0x7f00,
+ 0x18,0x1314,
+ 0x19,0x0500,
+ 0x18,0x1324,
+ 0x19,0x0000,
+ 0x18,0x1334,
+ 0x19,0x0000,
+ 0x18,0x1344,
+ 0x19,0x0600,
+ 0x18,0x1354,
+ 0x19,0x7300,
+ 0x18,0x1364,
+ 0x19,0x0d00,
+ 0x18,0x1374,
+ 0x19,0x0100,
+ 0x18,0x1384,
+ 0x19,0x0400,
+ 0x18,0x1394,
+ 0x19,0x0600,
+ 0x18,0x13a4,
+ 0x19,0x4000,
+ 0x18,0x13b4,
+ 0x19,0x4000,
+ 0x18,0x13c4,
+ 0x19,0x0400,
+ 0x18,0x13d4,
+ 0x19,0xe000,
+ 0x18,0x13e4,
+ 0x19,0x7d00,
+ 0x18,0x13f4,
+ 0x19,0x0500,
+ 0x18,0x1404,
+ 0x19,0x7800,
+ 0x18,0x1414,
+ 0x19,0x4000,
+ 0x18,0x1424,
+ 0x19,0x4000,
+ 0x18,0x1434,
+ 0x19,0x0400,
+ 0x18,0x1444,
+ 0x19,0xe000,
+ 0x18,0x1454,
+ 0x19,0x9700,
+ 0x18,0x1464,
+ 0x19,0x4000,
+ 0x18,0x1474,
+ 0x19,0x7f00,
+ 0x18,0x1484,
+ 0x19,0x0000,
+ 0x18,0x1494,
+ 0x19,0x0100,
+ 0x18,0x14a4,
+ 0x19,0x4400,
+ 0x18,0x14b4,
+ 0x19,0x0000,
+ 0x18,0x14c4,
+ 0x19,0x0000,
+ 0x18,0x14d4,
+ 0x19,0x0000,
+ 0x18,0x14e4,
+ 0x19,0x4000,
+ 0x18,0x14f4,
+ 0x19,0x8000,
+ 0x18,0x1504,
+ 0x19,0x7f00,
+ 0x18,0x1514,
+ 0x19,0x4000,
+ 0x18,0x1524,
+ 0x19,0x3f00,
+ 0x18,0x1534,
+ 0x19,0x0400,
+ 0x18,0x1544,
+ 0x19,0x5000,
+ 0x18,0x1554,
+ 0x19,0xf800,
+ 0x18,0x1564,
+ 0x19,0x0000,
+ 0x18,0x1574,
+ 0x19,0xe000,
+ 0x18,0x1584,
+ 0x19,0x4000,
+ 0x18,0x1594,
+ 0x19,0x8000,
+ 0x18,0x15a4,
+ 0x19,0x7f00,
+ 0x18,0x15b4,
+ 0x19,0x8900,
+ 0x18,0x15c4,
+ 0x19,0x8300,
+ 0x18,0x15d4,
+ 0x19,0xe000,
+ 0x18,0x15e4,
+ 0x19,0x0000,
+ 0x18,0x15f4,
+ 0x19,0x4000,
+ 0x18,0x1604,
+ 0x19,0x7f00,
+ 0x18,0x1614,
+ 0x19,0x0200,
+ 0x18,0x1624,
+ 0x19,0x1000,
+ 0x18,0x1634,
+ 0x19,0x0000,
+ 0x18,0x1644,
+ 0x19,0xfc00,
+ 0x18,0x1654,
+ 0x19,0xfd00,
+ 0x18,0x1664,
+ 0x19,0x0000,
+ 0x18,0x1674,
+ 0x19,0x4000,
+ 0x18,0x1684,
+ 0x19,0xbc00,
+ 0x18,0x1694,
+ 0x19,0x0e00,
+ 0x18,0x16a4,
+ 0x19,0xfe00,
+ 0x18,0x16b4,
+ 0x19,0x8a00,
+ 0x18,0x16c4,
+ 0x19,0x8300,
+ 0x18,0x16d4,
+ 0x19,0xe000,
+ 0x18,0x16e4,
+ 0x19,0x0000,
+ 0x18,0x16f4,
+ 0x19,0x4000,
+ 0x18,0x1704,
+ 0x19,0x7f00,
+ 0x18,0x1714,
+ 0x19,0x0100,
+ 0x18,0x1724,
+ 0x19,0xff00,
+ 0x18,0x1734,
+ 0x19,0x0000,
+ 0x18,0x1744,
+ //### 0x2219 : 0xfc00 ##0309
+ 0x19,0xfc00,
+ 0x18,0x1754,
+ //### 0x2219 : 0xff00 ##0309
+ 0x19,0xff00,
+ 0x18,0x1764,
+ 0x19,0x0000,
+ 0x18,0x1774,
+ 0x19,0x4000,
+ 0x18,0x1784,
+ 0x19,0x9d00,
+ 0x18,0x1794,
+ 0x19,0xff00,
+ 0x18,0x17a4,
+ 0x19,0x4000,
+ 0x18,0x17b4,
+ 0x19,0x7f00,
+ 0x18,0x17c4,
+ 0x19,0x0000,
+ 0x18,0x17d4,
+ 0x19,0xff00,
+ 0x18,0x17e4,
+ 0x19,0x0000,
+ 0x18,0x17f4,
+ 0x19,0xfc00,
+ 0x18,0x1804,
+ 0x19,0xff00,
+ 0x18,0x1814,
+ 0x19,0x0000,
+ 0x18,0x1824,
+ 0x19,0x4000,
+ 0x18,0x1834,
+ 0x19,0x8900,
+ 0x18,0x1844,
+ 0x19,0x8300,
+ 0x18,0x1854,
+ 0x19,0xe000,
+ 0x18,0x1864,
+ 0x19,0x0000,
+ 0x18,0x1874,
+ 0x19,0xac00,
+ 0x18,0x1884,
+ 0x19,0x0800,
+ 0x18,0x1894,
+ 0x19,0xfa00,
+ 0x18,0x18a4,
+ 0x19,0x4000,
+ 0x18,0x18b4,
+ 0x19,0x7f00,
+ 0x18,0x18c4,
+ 0x19,0x0400,
+ 0x18,0x18d4,
+ 0x19,0x0200,
+ 0x18,0x18e4,
+ 0x19,0x0000,
+ 0x18,0x18f4,
+ 0x19,0xfd00,
+ 0x18,0x1904,
+ 0x19,0x7f00,
+ 0x18,0x1914,
+ 0x19,0x0000,
+ 0x18,0x1924,
+ 0x19,0x4000,
+ 0x18,0x1934,
+ 0x19,0x0500,
+ 0x18,0x1944,
+ 0x19,0x9000,
+ 0x18,0x1954,
+ 0x19,0x8000,
+ 0x18,0x1964,
+ 0x19,0x7d00,
+ 0x18,0x1974,
+ 0x19,0x8c00,
+ 0x18,0x1984,
+ 0x19,0x8300,
+ 0x18,0x1994,
+ 0x19,0xe000,
+ 0x18,0x19a4,
+ 0x19,0x0000,
+ 0x18,0x19b4,
+ 0x19,0x4000,
+ 0x18,0x19c4,
+ 0x19,0x0400,
+ 0x18,0x19d4,
+ 0x19,0xff00,
+ 0x18,0x19e4,
+ 0x19,0x0500,
+ 0x18,0x19f4,
+ 0x19,0x8500,
+ 0x18,0x1a04,
+ 0x19,0x8c00,
+ 0x18,0x1a14,
+ 0x19,0xfa00,
+ 0x18,0x1a24,
+ 0x19,0xe000,
+ 0x18,0x1a34,
+ 0x19,0x0000,
+ 0x18,0x1a44,
+ 0x19,0x4000,
+ 0x18,0x1a54,
+ 0x19,0x5f00,
+ 0x18,0x1a64,
+ 0x19,0x0400,
+ 0x18,0x1a74,
+ 0x19,0x0000,
+ 0x18,0x1a84,
+ 0x19,0xfc00,
+ 0x18,0x1a94,
+ 0x19,0x7300,
+ 0x18,0x1aa4,
+ 0x19,0x0d00,
+ 0x18,0x1ab4,
+ 0x19,0x0100,
+ 0x18,0x1ac4,
+ 0x19,0x4000,
+ 0x18,0x1ad4,
+ 0x19,0x2000,
+ 0x18,0x1ae4,
+ 0x19,0x0000,
+ 0x18,0x1af4,
+ 0x19,0x0400,
+ 0x18,0x1b04,
+ 0x19,0xda00,
+ 0x18,0x1b14,
+ 0x19,0x0600,
+ 0x18,0x1b24,
+ 0x19,0x7d00,
+ 0x18,0x1b34,
+ 0x19,0x4000,
+ 0x18,0x1b44,
+ 0x19,0x5f00,
+ 0x18,0x1b54,
+ 0x19,0x0400,
+ 0x18,0x1b64,
+ 0x19,0x0000,
+ 0x18,0x1b74,
+ 0x19,0x0000,
+ 0x18,0x1b84,
+ 0x19,0x7300,
+ 0x18,0x1b94,
+ 0x19,0x0d00,
+ 0x18,0x1ba4,
+ 0x19,0x0100,
+ 0x18,0x1bb4,
+ 0x19,0x0400,
+ 0x18,0x1bc4,
+ 0x19,0xce00,
+ 0x18,0x1bd4,
+ 0x19,0x0800,
+ 0x18,0x1be4,
+ 0x19,0x9200,
+ 0x18,0x1bf4,
+ 0x19,0x0900,
+ 0x18,0x1c04,
+ 0x19,0x9b00,
+ 0x18,0x1c14,
+ 0x19,0x0700,
+ 0x18,0x1c24,
+ 0x19,0x7900,
+ 0x18,0x1c34,
+ 0x19,0x4000,
+ 0x18,0x1c44,
+ 0x19,0x7f00,
+ 0x18,0x1c54,
+ 0x19,0x0400,
+ 0x18,0x1c64,
+ 0x19,0x0000,
+ 0x18,0x1c74,
+ 0x19,0x0000,
+ 0x18,0x1c84,
+ 0x19,0x0400,
+ 0x18,0x1c94,
+ 0x19,0x7300,
+ 0x18,0x1ca4,
+ 0x19,0x0d00,
+ 0x18,0x1cb4,
+ 0x19,0x0100,
+ 0x18,0x1cc4,
+ 0x19,0x0900,
+ 0x18,0x1cd4,
+ 0x19,0x8e00,
+ 0x18,0x1ce4,
+ 0x19,0x0800,
+ 0x18,0x1cf4,
+ 0x19,0x7d00,
+ 0x18,0x1d04,
+ 0x19,0x4000,
+ 0x18,0x1d14,
+ 0x19,0x7f00,
+ 0x18,0x1d24,
+ 0x19,0x0000,
+ 0x18,0x1d34,
+ 0x19,0x0000,
+ 0x18,0x1d44,
+ 0x19,0x0000,
+ 0x18,0x1d54,
+ 0x19,0x0000,
+ 0x18,0x1d64,
+ 0x19,0x7000,
+ 0x18,0x1d74,
+ 0x19,0x0c00,
+ 0x18,0x1d84,
+ 0x19,0x0100,
+ 0x18,0x1d94,
+ 0x19,0x0900,
+ 0x18,0x1da4,
+ 0x19,0x7f00,
+ 0x18,0x1db4,
+ 0x19,0x4000,
+ 0x18,0x1dc4,
+ 0x19,0x7f00,
+ 0x18,0x1dd4,
+ 0x19,0x0400,
+ 0x18,0x1de4,
+ 0x19,0x0000,
+ 0x18,0x1df4,
+ 0x19,0x0000,
+ 0x18,0x1e04,
+ 0x19,0x0000,
+ 0x18,0x1e14,
+ 0x19,0x7000,
+ 0x18,0x1e24,
+ 0x19,0x0d00,
+ 0x18,0x1e34,
+ 0x19,0x0100,
+ 0x18,0x1e44,
+ 0x19,0x0b00,
+ 0x18,0x1e54,
+ 0x19,0x7f00,
+ 0x18,0x1e64,
+ 0x19,0x9a00,
+ 0x18,0x1e74,
+ 0x19,0x7f00,
+ 0x18,0x1e84,
+ 0x19,0x4000,
+ 0x18,0x1e94,
+ 0x19,0x7f00,
+ 0x18,0x1ea4,
+ 0x19,0x0400,
+ 0x18,0x1eb4,
+ 0x19,0x0000,
+ 0x18,0x1ec4,
+ 0x19,0x0000,
+ 0x18,0x1ed4,
+ 0x19,0x0000,
+ 0x18,0x1ee4,
+ 0x19,0x7100,
+ 0x18,0x1ef4,
+ 0x19,0x0d00,
+ 0x18,0x1f04,
+ 0x19,0x0100,
+ 0x18,0x1f14,
+ 0x19,0x9400,
+ 0x18,0x1f24,
+ 0x19,0x7f00,
+ 0x18,0x1f34,
+ 0x19,0x4000,
+ 0x18,0x1f44,
+ 0x19,0x7f00,
+ 0x18,0x1f54,
+ 0x19,0x0500,
+ 0x18,0x1f64,
+ 0x19,0x0000,
+ 0x18,0x1f74,
+ 0x19,0x0000,
+ 0x18,0x1f84,
+ 0x19,0x0000,
+ 0x18,0x1f94,
+ 0x19,0x7300,
+ 0x18,0x1fa4,
+ 0x19,0x0d00,
+ 0x18,0x1fb4,
+ 0x19,0x0100,
+ 0x18,0x1fc4,
+ 0x19,0x0500,
+ 0x18,0x1fd4,
+ 0x19,0x8800,
+ 0x18,0x1fe4,
+ 0x19,0x0400,
+ 0x18,0x1ff4,
+ 0x19,0x7d00,
+ 0x18,0x2004,
+ 0x19,0x4000,
+ 0x18,0x2014,
+ 0x19,0x4000,
+ 0x18,0x2024,
+ 0x19,0x0400,
+ 0x18,0x2034,
+ 0x19,0xe100,
+ 0x18,0x2044,
+ 0x19,0x8a00,
+ 0x18,0x2054,
+ 0x19,0x4000,
+ 0x18,0x2064,
+ 0x19,0x4000,
+ 0x18,0x2074,
+ 0x19,0x0400,
+ 0x18,0x2084,
+ 0x19,0xe100,
+ 0x18,0x2094,
+ 0x19,0xa400,
+ 0x18,0x20a4,
+ 0x19,0x4000,
+ 0x18,0x20b4,
+ 0x19,0x7f00,
+ 0x18,0x20c4,
+ 0x19,0x0000,
+ 0x18,0x20d4,
+ 0x19,0x0100,
+ 0x18,0x20e4,
+ 0x19,0x4000,
+ 0x18,0x20f4,
+ 0x19,0x3e00,
+ 0x18,0x2104,
+ 0x19,0x0000,
+ 0x18,0x2114,
+ 0x19,0xe000,
+ 0x18,0x2124,
+ 0x19,0x1200,
+ 0x18,0x2134,
+ 0x19,0x8000,
+ 0x18,0x2144,
+ 0x19,0x7f00,
+ 0x18,0x2154,
+ 0x19,0x8900,
+ 0x18,0x2164,
+ 0x19,0x8300,
+ 0x18,0x2174,
+ 0x19,0xe000,
+ 0x18,0x2184,
+ 0x19,0x0000,
+ 0x18,0x2194,
+ 0x19,0x4000,
+ 0x18,0x21a4,
+ 0x19,0x7f00,
+ 0x18,0x21b4,
+ 0x19,0x0000,
+ 0x18,0x21c4,
+ 0x19,0x2000,
+ 0x18,0x21d4,
+ 0x19,0x4000,
+ 0x18,0x21e4,
+ 0x19,0x3e00,
+ 0x18,0x21f4,
+ 0x19,0xff00,
+ 0x18,0x2204,
+ 0x19,0x0000,
+ 0x18,0x2214,
+ 0x19,0x1200,
+ 0x18,0x2224,
+ 0x19,0x8000,
+ 0x18,0x2234,
+ 0x19,0x7f00,
+ 0x18,0x2244,
+ 0x19,0x8600,
+ 0x18,0x2254,
+ 0x19,0x8500,
+ 0x18,0x2264,
+ 0x19,0x8900,
+ 0x18,0x2274,
+ 0x19,0xfd00,
+ 0x18,0x2284,
+ 0x19,0xe000,
+ 0x18,0x2294,
+ 0x19,0x0000,
+ 0x18,0x22a4,
+ 0x19,0x9500,
+ 0x18,0x22b4,
+ 0x19,0x0400,
+ 0x18,0x22c4,
+ 0x19,0x4000,
+ 0x18,0x22d4,
+ 0x19,0x4000,
+ 0x18,0x22e4,
+ 0x19,0x1000,
+ 0x18,0x22f4,
+ 0x19,0x4000,
+ 0x18,0x2304,
+ 0x19,0x3f00,
+ 0x18,0x2314,
+ 0x19,0x0200,
+ 0x18,0x2324,
+ 0x19,0x4000,
+ 0x18,0x2334,
+ 0x19,0x3700,
+ 0x18,0x2344,
+ 0x19,0x7f00,
+ 0x18,0x2354,
+ 0x19,0x0000,
+ 0x18,0x2364,
+ 0x19,0x0200,
+ 0x18,0x2374,
+ 0x19,0x0200,
+ 0x18,0x2384,
+ 0x19,0x9000,
+ 0x18,0x2394,
+ 0x19,0x8000,
+ 0x18,0x23a4,
+ 0x19,0x7d00,
+ 0x18,0x23b4,
+ 0x19,0x8900,
+ 0x18,0x23c4,
+ 0x19,0x8300,
+ 0x18,0x23d4,
+ 0x19,0xe000,
+ 0x18,0x23e4,
+ 0x19,0x0000,
+ 0x18,0x23f4,
+ 0x19,0x4000,
+ 0x18,0x2404,
+ 0x19,0x0400,
+ 0x18,0x2414,
+ 0x19,0xff00,
+ 0x18,0x2424,
+ 0x19,0x0200,
+ 0x18,0x2434,
+ 0x19,0x8500,
+ 0x18,0x2444,
+ 0x19,0x8900,
+ 0x18,0x2454,
+ 0x19,0xfa00,
+ 0x18,0x2464,
+ 0x19,0xe000,
+ 0x18,0x2474,
+ 0x19,0x0000,
+ 0x18,0x2484,
+ 0x19,0x4000,
+ 0x18,0x2494,
+ 0x19,0x7f00,
+ 0x18,0x24a4,
+ 0x19,0x0000,
+ 0x18,0x24b4,
+ 0x19,0x0000,
+ 0x18,0x24c4,
+ 0x19,0x4000,
+ 0x18,0x24d4,
+ 0x19,0x3700,
+ 0x18,0x24e4,
+ 0x19,0x7300,
+ 0x18,0x24f4,
+ 0x19,0x0500,
+ 0x18,0x2504,
+ 0x19,0x0200,
+ 0x18,0x2514,
+ 0x19,0x0100,
+ 0x18,0x2524,
+ 0x19,0xd800,
+ 0x18,0x2534,
+ 0x19,0x0400,
+ 0x18,0x2544,
+ 0x19,0x7d00,
+ 0x18,0x2554,
+ 0x19,0x4000,
+ 0x18,0x2564,
+ 0x19,0x7f00,
+ 0x18,0x2574,
+ 0x19,0x0000,
+ 0x18,0x2584,
+ 0x19,0x0000,
+ 0x18,0x2594,
+ 0x19,0x4000,
+ 0x18,0x25a4,
+ 0x19,0x0000,
+ 0x18,0x25b4,
+ 0x19,0x7200,
+ 0x18,0x25c4,
+ 0x19,0x0400,
+ 0x18,0x25d4,
+ 0x19,0x0000,
+ 0x18,0x25e4,
+ 0x19,0x0800,
+ 0x18,0x25f4,
+ 0x19,0x7f00,
+ 0x18,0x2604,
+ 0x19,0x4000,
+ 0x18,0x2614,
+ 0x19,0x7f00,
+ 0x18,0x2624,
+ 0x19,0x0000,
+ 0x18,0x2634,
+ 0x19,0x0000,
+ 0x18,0x2644,
+ 0x19,0xc000,
+ 0x18,0x2654,
+ 0x19,0x0000,
+ 0x18,0x2664,
+ 0x19,0x7200,
+ 0x18,0x2674,
+ 0x19,0x0500,
+ 0x18,0x2684,
+ 0x19,0x0000,
+ 0x18,0x2694,
+ 0x19,0x0400,
+ 0x18,0x26a4,
+ 0x19,0xeb00,
+ 0x18,0x26b4,
+ 0x19,0x8400,
+ 0x18,0x26c4,
+ 0x19,0x7d00,
+ 0x18,0x26d4,
+ 0x19,0x4000,
+ 0x18,0x26e4,
+ 0x19,0x7f00,
+ 0x18,0x26f4,
+ 0x19,0x0000,
+ 0x18,0x2704,
+ 0x19,0x0000,
+ 0x18,0x2714,
+ 0x19,0x4000,
+ 0x18,0x2724,
+ 0x19,0x0000,
+ 0x18,0x2734,
+ 0x19,0x7200,
+ 0x18,0x2744,
+ 0x19,0x0700,
+ 0x18,0x2754,
+ 0x19,0x0000,
+ 0x18,0x2764,
+ 0x19,0x0400,
+ 0x18,0x2774,
+ 0x19,0xde00,
+ 0x18,0x2784,
+ 0x19,0x9b00,
+ 0x18,0x2794,
+ 0x19,0x7d00,
+ 0x18,0x27a4,
+ 0x19,0x4000,
+ 0x18,0x27b4,
+ 0x19,0x7f00,
+ 0x18,0x27c4,
+ 0x19,0x0000,
+ 0x18,0x27d4,
+ 0x19,0x9000,
+ 0x18,0x27e4,
+ 0x19,0x4000,
+ 0x18,0x27f4,
+ 0x19,0x0400,
+ 0x18,0x2804,
+ 0x19,0x7300,
+ 0x18,0x2814,
+ 0x19,0x1500,
+ 0x18,0x2824,
+ 0x19,0x0000,
+ 0x18,0x2834,
+ 0x19,0x0400,
+ 0x18,0x2844,
+ 0x19,0xd100,
+ 0x18,0x2854,
+ 0x19,0x9400,
+ 0x18,0x2864,
+ 0x19,0x9200,
+ 0x18,0x2874,
+ 0x19,0x8000,
+ 0x18,0x2884,
+ 0x19,0x7b00,
+ 0x18,0x2894,
+ 0x19,0x4000,
+ 0x18,0x28a4,
+ 0x19,0x7f00,
+ 0x18,0x28b4,
+ 0x19,0x0000,
+ 0x18,0x28c4,
+ 0x19,0x0000,
+ 0x18,0x28d4,
+ 0x19,0x4000,
+ 0x18,0x28e4,
+ 0x19,0x0000,
+ 0x18,0x28f4,
+ 0x19,0x7200,
+ 0x18,0x2904,
+ 0x19,0x0700,
+ 0x18,0x2914,
+ 0x19,0x0000,
+ 0x18,0x2924,
+ 0x19,0x0400,
+ 0x18,0x2934,
+ 0x19,0xc200,
+ 0x18,0x2944,
+ 0x19,0x9b00,
+ 0x18,0x2954,
+ 0x19,0x7d00,
+ 0x18,0x2964,
+ 0x19,0xe200,
+ 0x18,0x2974,
+ 0x19,0x7a00,
+ 0x18,0x2984,
+ 0x19,0x4000,
+ 0x18,0x2994,
+ 0x19,0x7f00,
+ 0x18,0x29a4,
+ 0x19,0x0000,
+ 0x18,0x29b4,
+ 0x19,0x0000,
+ 0x18,0x29c4,
+ 0x19,0x4000,
+ 0x18,0x29d4,
+ 0x19,0x3700,
+ 0x18,0x29e4,
+ 0x19,0x7300,
+ 0x18,0x29f4,
+ 0x19,0x0500,
+ 0x18,0x2a04,
+ 0x19,0x0000,
+ 0x18,0x2a14,
+ 0x19,0x0100,
+ 0x18,0x2a24,
+ 0x19,0x0300,
+ 0x18,0x2a34,
+ 0x19,0xe200,
+ 0x18,0x2a44,
+ 0x19,0x2a00,
+ 0x18,0x2a54,
+ 0x19,0x0200,
+ 0x18,0x2a64,
+ 0x19,0x7b00,
+ 0x18,0x2a74,
+ 0x19,0xe200,
+ 0x18,0x2a84,
+ 0x19,0x4800,
+ //### endpoint
+
+ 0x1f,0x0000,
+ 0x17,0x2100,
+ 0x1f,0x0007,
+ 0x1e,0x0040,
+ 0x18,0x0000,
+ //### end of inrx dspctl patch code
+
+ //### inrx eyesch patch code
+ 0x1f,0x0007,
+ 0x1e,0x0042,
+ 0x15,0x0f00,
+ 0x1f,0x0000,
+ 0x17,0x2160,
+ 0x1f,0x0001,
+ 0x10,0xf25e,
+ 0x1f,0x0007,
+ 0x1e,0x0042,
+
+ //### startpoint
+ 0x15,0x0f00,
+ 0x16,0x7408,
+ 0x15,0x0e00,
+ 0x15,0x0f00,
+ 0x15,0x0f01,
+ 0x16,0x4000,
+ 0x15,0x0e01,
+ 0x15,0x0f01,
+ 0x15,0x0f02,
+ 0x16,0x9400,
+ 0x15,0x0e02,
+ 0x15,0x0f02,
+ 0x15,0x0f03,
+ 0x16,0x7408,
+ 0x15,0x0e03,
+ 0x15,0x0f03,
+ 0x15,0x0f04,
+ 0x16,0x4008,
+ 0x15,0x0e04,
+ 0x15,0x0f04,
+ 0x15,0x0f05,
+ 0x16,0x9400,
+ 0x15,0x0e05,
+ 0x15,0x0f05,
+ 0x15,0x0f06,
+ 0x16,0x0803,
+ 0x15,0x0e06,
+ 0x15,0x0f06,
+ //### endpoint
+
+ 0x1f, 0x0001,
+ 0x10, 0xf05e,
+ 0x1f, 0x0007,
+ 0x1e, 0x0042,
+ 0x15,0x0d00,
+ 0x15,0x0100,
+ 0x1f,0x0000,
+ 0x17,0x2100,
+ //### end of inrx eyesch patch code
+
+ //### release MDI/MDIX force mode
+ 0x1f, 0x0007,
+ 0x1e, 0x002d,
+ 0x18, 0xf010,
+
+ //### uc patch code (20110103 add foce giga mode)
+ 0x1f,0x0005,
+ //### startpoint
+
+ 5, 0x8000,
+ 6, 0xeeff,
+ 6, 0xfc8b,
+ 6, 0xeeff,
+ 6, 0xfda0,
+ 6, 0x0280,
+ 6, 0x33f7,
+ 6, 0x00e0,
+ 6, 0xfff7,
+ 6, 0xa080,
+ 6, 0x02ae,
+ 6, 0xf602,
+ 6, 0x842b,
+ 6, 0x0201,
+ 6, 0x4802,
+ 6, 0x015b,
+ 6, 0x0280,
+ 6, 0xabe0,
+ 6, 0x8b8c,
+ 6, 0xe18b,
+ 6, 0x8d1e,
+ 6, 0x01e1,
+ 6, 0x8b8e,
+ 6, 0x1e01,
+ 6, 0xa000,
+ 6, 0xe4ae,
+ 6, 0xd8bf,
+ 6, 0x846c,
+ 6, 0xd785,
+ 6, 0x80d0,
+ 6, 0x6c02,
+ 6, 0x28b4,
+ 6, 0xeee1,
+ 6, 0x4477,
+ 6, 0xeee1,
+ 6, 0x4565,
+ 6, 0xee8b,
+ 6, 0x85c2,
+ 6, 0xee8a,
+ 6, 0xe86e,
+ 6, 0xee85,
+ 6, 0x7100,
+ 6, 0xee85,
+ 6, 0x7200,
+ 6, 0xee85,
+ 6, 0x7302,
+ 6, 0xee85,
+ 6, 0x7a03,
+ 6, 0xee85,
+ 6, 0x7bb8,
+ 6, 0xee85,
+ 6, 0x7400,
+ 6, 0xee85,
+ 6, 0x7500,
+ 6, 0xee85,
+ 6, 0x7000,
+ 6, 0xd407,
+ 6, 0xf7e4,
+ 6, 0x8b96,
+ 6, 0xe58b,
+ 6, 0x97d4,
+ 6, 0x0802,
+ 6, 0xe48b,
+ 6, 0x94e5,
+ 6, 0x8b95,
+ 6, 0xd100,
+ 6, 0xbf84,
+ 6, 0x5d02,
+ 6, 0x2959,
+ 6, 0xbf8b,
+ 6, 0x88ec,
+ 6, 0x0019,
+ 6, 0xa98b,
+ 6, 0x90f9,
+ 6, 0xeeff,
+ 6, 0xf600,
+ 6, 0xeeff,
+ 6, 0xf7fc,
+ 6, 0xe0e1,
+ 6, 0x40e1,
+ 6, 0xe141,
+ 6, 0xf72f,
+ 6, 0xf628,
+ 6, 0xe4e1,
+ 6, 0x40e5,
+ 6, 0xe141,
+ 6, 0x04f8,
+ 6, 0xe08b,
+ 6, 0x8ead,
+ 6, 0x2017,
+ 6, 0xf620,
+ 6, 0xe48b,
+ 6, 0x8e02,
+ 6, 0x25da,
+ 6, 0x0226,
+ 6, 0xb402,
+ 6, 0x8169,
+ 6, 0x0202,
+ 6, 0x3402,
+ 6, 0x82b1,
+ 6, 0x0283,
+ 6, 0x4ae0,
+ 6, 0x8b8e,
+ 6, 0xad23,
+ 6, 0x05f6,
+ 6, 0x23e4,
+ 6, 0x8b8e,
+ 6, 0xe08b,
+ 6, 0x8ead,
+ 6, 0x2408,
+ 6, 0xf624,
+ 6, 0xe48b,
+ 6, 0x8e02,
+ 6, 0x277d,
+ 6, 0xe08b,
+ 6, 0x8ead,
+ 6, 0x260b,
+ 6, 0xf626,
+ 6, 0xe48b,
+ 6, 0x8e02,
+ 6, 0x056e,
+ 6, 0x021c,
+ 6, 0x9a02,
+ 6, 0x80fb,
+ 6, 0x0281,
+ 6, 0x55fc,
+ 6, 0x04f8,
+ 6, 0xe08b,
+ 6, 0x83ad,
+ 6, 0x2321,
+ 6, 0xe0e0,
+ 6, 0x22e1,
+ 6, 0xe023,
+ 6, 0xad29,
+ 6, 0x20e0,
+ 6, 0x8b83,
+ 6, 0xad21,
+ 6, 0x06e1,
+ 6, 0x8b84,
+ 6, 0xad28,
+ 6, 0x3ce0,
+ 6, 0x8b85,
+ 6, 0xad21,
+ 6, 0x06e1,
+ 6, 0x8b84,
+ 6, 0xad29,
+ 6, 0x30bf,
+ 6, 0x3144,
+ 6, 0x0228,
+ 6, 0xe8ae,
+ 6, 0x28ee,
+ 6, 0x8ae2,
+ 6, 0x00ee,
+ 6, 0x8ae3,
+ 6, 0x00ee,
+ 6, 0x8ae4,
+ 6, 0x00ee,
+ 6, 0x8ae5,
+ 6, 0x00ee,
+ 6, 0x8b72,
+ 6, 0x00e0,
+ 6, 0x8b83,
+ 6, 0xad21,
+ 6, 0x08e0,
+ 6, 0x8b84,
+ 6, 0xf620,
+ 6, 0xe48b,
+ 6, 0x84bf,
+ 6, 0x3147,
+ 6, 0x0228,
+ 6, 0xe8fc,
+ 6, 0x04f8,
+ 6, 0xe0e0,
+ 6, 0x38e1,
+ 6, 0xe039,
+ 6, 0xac2e,
+ 6, 0x08ee,
+ 6, 0xe08e,
+ 6, 0x36ee,
+ 6, 0xe08f,
+ 6, 0x20fc,
+ 6, 0x04f8,
+ 6, 0xfaef,
+ 6, 0x69e0,
+ 6, 0x8b85,
+ 6, 0xad21,
+ 6, 0x39e0,
+ 6, 0xe022,
+ 6, 0xe1e0,
+ 6, 0x2358,
+ 6, 0xc059,
+ 6, 0x021e,
+ 6, 0x01e1,
+ 6, 0x8b72,
+ 6, 0x1f10,
+ 6, 0x9e26,
+ 6, 0xe48b,
+ 6, 0x72ad,
+ 6, 0x211d,
+ 6, 0xe18b,
+ 6, 0x84f7,
+ 6, 0x29e5,
+ 6, 0x8b84,
+ 6, 0xac27,
+ 6, 0x0dac,
+ 6, 0x2605,
+ 6, 0x0204,
+ 6, 0xa2ae,
+ 6, 0x0d02,
+ 6, 0x820c,
+ 6, 0xae08,
+ 6, 0x0282,
+ 6, 0x38ae,
+ 6, 0x0302,
+ 6, 0x81b1,
+ 6, 0xef96,
+ 6, 0xfefc,
+ 6, 0x04d1,
+ 6, 0x00bf,
+ 6, 0x845d,
+ 6, 0x0229,
+ 6, 0x59d1,
+ 6, 0x03bf,
+ 6, 0x316b,
+ 6, 0x0229,
+ 6, 0x59d1,
+ 6, 0x00bf,
+ 6, 0x316e,
+ 6, 0x0229,
+ 6, 0x59d1,
+ 6, 0x00bf,
+ 6, 0x8463,
+ 6, 0x0229,
+ 6, 0x59d1,
+ 6, 0x0fbf,
+ 6, 0x3162,
+ 6, 0x0229,
+ 6, 0x59d1,
+ 6, 0x01bf,
+ 6, 0x3165,
+ 6, 0x0229,
+ 6, 0x59d1,
+ 6, 0x01bf,
+ 6, 0x3168,
+ 6, 0x0229,
+ 6, 0x59e0,
+ 6, 0x8b85,
+ 6, 0xad24,
+ 6, 0x0ed1,
+ 6, 0x00bf,
+ 6, 0x3177,
+ 6, 0xad23,
+ 6, 0x03bf,
+ 6, 0x317a,
+ 6, 0x0229,
+ 6, 0x59e0,
+ 6, 0x8b83,
+ 6, 0xad22,
+ 6, 0x08d1,
+ 6, 0x00bf,
+ 6, 0x315c,
+ 6, 0x0229,
+ 6, 0x5904,
+ 6, 0xd102,
+ 6, 0xbf31,
+ 6, 0x6b02,
+ 6, 0x2959,
+ 6, 0xd106,
+ 6, 0xbf31,
+ 6, 0x6202,
+ 6, 0x2959,
+ 6, 0xd107,
+ 6, 0xbf31,
+ 6, 0x6502,
+ 6, 0x2959,
+ 6, 0xd107,
+ 6, 0xbf31,
+ 6, 0x6802,
+ 6, 0x2959,
+ 6, 0xd101,
+ 6, 0xbf84,
+ 6, 0x5d02,
+ 6, 0x2959,
+ 6, 0x0282,
+ 6, 0x7104,
+ 6, 0xd102,
+ 6, 0xbf31,
+ 6, 0x6b02,
+ 6, 0x2959,
+ 6, 0xd101,
+ 6, 0xbf84,
+ 6, 0x5d02,
+ 6, 0x2959,
+ 6, 0xd011,
+ 6, 0x0228,
+ 6, 0x0459,
+ 6, 0x03ef,
+ 6, 0x01d1,
+ 6, 0x00a0,
+ 6, 0x0002,
+ 6, 0xd101,
+ 6, 0xbf31,
+ 6, 0x6e02,
+ 6, 0x2959,
+ 6, 0xd111,
+ 6, 0xad20,
+ 6, 0x020c,
+ 6, 0x11ad,
+ 6, 0x2102,
+ 6, 0x0c12,
+ 6, 0xbf84,
+ 6, 0x6302,
+ 6, 0x2959,
+ 6, 0x04f8,
+ 6, 0xe08b,
+ 6, 0x85ad,
+ 6, 0x2437,
+ 6, 0xe0ea,
+ 6, 0xcae1,
+ 6, 0xeacb,
+ 6, 0xad29,
+ 6, 0x2ee0,
+ 6, 0xeacc,
+ 6, 0xe1ea,
+ 6, 0xcdad,
+ 6, 0x2925,
+ 6, 0xe0e0,
+ 6, 0x08e1,
+ 6, 0xe009,
+ 6, 0xad20,
+ 6, 0x1ce0,
+ 6, 0xe00a,
+ 6, 0xe1e0,
+ 6, 0x0bad,
+ 6, 0x2013,
+ 6, 0xd103,
+ 6, 0xbf31,
+ 6, 0x77e0,
+ 6, 0x8b85,
+ 6, 0xad23,
+ 6, 0x05d1,
+ 6, 0x01bf,
+ 6, 0x317a,
+ 6, 0x0229,
+ 6, 0x59fc,
+ 6, 0x04f8,
+ 6, 0xf9fb,
+ 6, 0xe08b,
+ 6, 0x85ad,
+ 6, 0x2522,
+ 6, 0xe0e0,
+ 6, 0x22e1,
+ 6, 0xe023,
+ 6, 0xe2e0,
+ 6, 0x36e3,
+ 6, 0xe037,
+ 6, 0x5ac4,
+ 6, 0x0d01,
+ 6, 0x5802,
+ 6, 0x1e20,
+ 6, 0xe385,
+ 6, 0x71ac,
+ 6, 0x3160,
+ 6, 0xac3a,
+ 6, 0x08ac,
+ 6, 0x3e26,
+ 6, 0xae67,
+ 6, 0xaf83,
+ 6, 0x46ad,
+ 6, 0x3761,
+ 6, 0xe085,
+ 6, 0x7210,
+ 6, 0xe485,
+ 6, 0x72e1,
+ 6, 0x8573,
+ 6, 0x1b10,
+ 6, 0x9e02,
+ 6, 0xae51,
+ 6, 0xd100,
+ 6, 0xbf84,
+ 6, 0x6002,
+ 6, 0x2959,
+ 6, 0xee85,
+ 6, 0x7200,
+ 6, 0xae43,
+ 6, 0xad36,
+ 6, 0x27e0,
+ 6, 0x857a,
+ 6, 0xe185,
+ 6, 0x7bef,
+ 6, 0x74e0,
+ 6, 0x8574,
+ 6, 0xe185,
+ 6, 0x751b,
+ 6, 0x749e,
+ 6, 0x2e14,
+ 6, 0xe485,
+ 6, 0x74e5,
+ 6, 0x8575,
+ 6, 0xef74,
+ 6, 0xe085,
+ 6, 0x7ae1,
+ 6, 0x857b,
+ 6, 0x1b47,
+ 6, 0x9e0f,
+ 6, 0xae19,
+ 6, 0xee85,
+ 6, 0x7400,
+ 6, 0xee85,
+ 6, 0x7500,
+ 6, 0xae0f,
+ 6, 0xac39,
+ 6, 0x0cd1,
+ 6, 0x01bf,
+ 6, 0x8460,
+ 6, 0x0229,
+ 6, 0x59ee,
+ 6, 0x8572,
+ 6, 0x00e6,
+ 6, 0x8571,
+ 6, 0xfffd,
+ 6, 0xfc04,
+ 6, 0xf8e0,
+ 6, 0x8b85,
+ 6, 0xad27,
+ 6, 0x30e0,
+ 6, 0xe036,
+ 6, 0xe1e0,
+ 6, 0x37e1,
+ 6, 0x8570,
+ 6, 0x1f10,
+ 6, 0x9e23,
+ 6, 0xe485,
+ 6, 0x70ac,
+ 6, 0x200b,
+ 6, 0xac21,
+ 6, 0x0dac,
+ 6, 0x250f,
+ 6, 0xac27,
+ 6, 0x11ae,
+ 6, 0x1202,
+ 6, 0x8383,
+ 6, 0xae0d,
+ 6, 0x0283,
+ 6, 0x88ae,
+ 6, 0x0802,
+ 6, 0x838f,
+ 6, 0xae03,
+ 6, 0x0283,
+ 6, 0xa2fc,
+ 6, 0x04ee,
+ 6, 0x8576,
+ 6, 0x0004,
+ 6, 0x0283,
+ 6, 0xaf02,
+ 6, 0x83f2,
+ 6, 0x04f8,
+ 6, 0xf9e0,
+ 6, 0x8b87,
+ 6, 0xad26,
+ 6, 0x08d1,
+ 6, 0x01bf,
+ 6, 0x8469,
+ 6, 0x0229,
+ 6, 0x59fd,
+ 6, 0xfc04,
+ 6, 0x0284,
+ 6, 0x1304,
+ 6, 0xee85,
+ 6, 0x7600,
+ 6, 0xee85,
+ 6, 0x7702,
+ 6, 0x04f8,
+ 6, 0xf9e0,
+ 6, 0x8b85,
+ 6, 0xad26,
+ 6, 0x38d0,
+ 6, 0x0b02,
+ 6, 0x2804,
+ 6, 0x5882,
+ 6, 0x7882,
+ 6, 0x9f2d,
+ 6, 0xe085,
+ 6, 0x76e1,
+ 6, 0x8577,
+ 6, 0x1f10,
+ 6, 0x9eb5,
+ 6, 0x10e4,
+ 6, 0x8576,
+ 6, 0xe0e0,
+ 6, 0x00e1,
+ 6, 0xe001,
+ 6, 0xf727,
+ 6, 0xe4e0,
+ 6, 0x00e5,
+ 6, 0xe001,
+ 6, 0xe2e0,
+ 6, 0x20e3,
+ 6, 0xe021,
+ 6, 0xad30,
+ 6, 0xf7f6,
+ 6, 0x27e4,
+ 6, 0xe000,
+ 6, 0xe5e0,
+ 6, 0x01fd,
+ 6, 0xfc04,
+ 6, 0xf8fa,
+ 6, 0xef69,
+ 6, 0xe08b,
+ 6, 0x86ad,
+ 6, 0x2212,
+ 6, 0xe0e0,
+ 6, 0x14e1,
+ 6, 0xe015,
+ 6, 0xad26,
+ 6, 0x89e1,
+ 6, 0x8578,
+ 6, 0xbf84,
+ 6, 0x6602,
+ 6, 0x2959,
+ 6, 0xef96,
+ 6, 0xfefc,
+ 6, 0x04f8,
+ 6, 0xfaef,
+ 6, 0x69e0,
+ 6, 0x8b86,
+ 6, 0xad22,
+ 6, 0x09e1,
+ 6, 0x8579,
+ 6, 0xbf84,
+ 6, 0x6602,
+ 6, 0x2959,
+ 6, 0xef96,
+ 6, 0xfefc,
+ 6, 0x04f8,
+ 6, 0xfaef,
+ 6, 0x69e0,
+ 6, 0x8b86,
+ 6, 0xac20,
+ 6, 0x1abf,
+ 6, 0x8580,
+ 6, 0xd06c,
+ 6, 0x0228,
+ 6, 0xbbe0,
+ 6, 0xe0e4,
+ 6, 0xe1e0,
+ 6, 0xe558,
+ 6, 0x0668,
+ 6, 0xc0d1,
+ 6, 0xd2e4,
+ 6, 0xe0e4,
+ 6, 0xe5e0,
+ 6, 0xe5ef,
+ 6, 0x96fe,
+ 6, 0xfc04,
+ 6, 0xa0e0,
+ 6, 0xeaf0,
+ 6, 0xe07c,
+ 6, 0x55e2,
+ 6, 0x3211,
+ 6, 0xe232,
+ 6, 0x88e2,
+ 6, 0x0070,
+ 6, 0xe426,
+ 6, 0x70e0,
+ 6, 0x7699,
+ 6, 0xe000,
+ 6, 0x2508,
+ 6, 0x0726,
+ 6, 0x4072,
+ 6, 0x2726,
+ 6, 0x7e28,
+ 6, 0x04b7,
+ 6, 0x2925,
+ 6, 0x762a,
+ 6, 0x68e5,
+ 6, 0x2bad,
+ 6, 0x002c,
+ 6, 0xdbf0,
+ 6, 0x2d67,
+ 6, 0xbb2e,
+ 6, 0x7b0f,
+ 6, 0x2f73,
+ 6, 0x6531,
+ 6, 0xaccc,
+ 6, 0x3223,
+ 6, 0x0033,
+ 6, 0x2d17,
+ 6, 0x347f,
+ 6, 0x5235,
+ 6, 0x1000,
+ 6, 0x3606,
+ 6, 0x0037,
+ 6, 0x0cc0,
+ 6, 0x387f,
+ 6, 0xce3c,
+ 6, 0xe5f7,
+ 6, 0x3d3d,
+ 6, 0xa465,
+ 6, 0x303e,
+ 6, 0x6700,
+ 6, 0x5369,
+ 6, 0xd20f,
+ 6, 0x6a01,
+ 6, 0x2c6c,
+ 6, 0x2b13,
+ 6, 0x6ee1,
+ 6, 0x006f,
+ 6, 0x12f7,
+ 6, 0x7100,
+ 6, 0x6b73,
+ 6, 0x06eb,
+ 6, 0x7494,
+ 6, 0xc776,
+ 6, 0x980a,
+ 6, 0x7750,
+ 6, 0x0078,
+ 6, 0x8a15,
+ 6, 0x797f,
+ 6, 0x6f7a,
+ 6, 0x06a6,
+ //### endpoint
+
+ //#unlock uc ramcode version
+ 5, 0xe142,
+ 6, 0x0701,
+ 5, 0xe140,
+ 6, 0x0405,
+ 15, 0x0000,
+
+ //### end of uc patch code
+ //#Enable negear EEE Nway ability autooff
+ 0x1f,0x0005,
+ 0x05,0x8b84,
+ 0x06,0x0026,
+ 0x1f,0x0000,
+
+ //#lpi patch code-maxod-20110103
+ 31, 0x0007,
+ 30, 0x0023,
+ 22, 0x0006,
+ //#quiet time to 22ms
+ 21, 0x147,
+ 25, 0x96,
+ //#lpi_tx_wake_timer to 1.3us
+ 21, 0x16d,
+ 25, 0x26,
+ 22, 0x0002,
+ 31, 0x0000,
+
+ //#Add by Gary for Channel Estimation fine tune 20100430
+ //#Page1 Reg8 (CG_INITIAL_MASTER)
+ 0x1f, 0x0005,
+ 0x05, 0x83dd,
+ 0x06, 0x0574,
+ //#Page1 Reg9 (CB0_INITIAL_GIGA)
+ 0x1f, 0x0005,
+ 0x05, 0x83e0,
+ 0x06, 0x2724,
+ //#Page3 Reg26 (CG_INITIAL_SLAVE)
+ 0x1f, 0x0005,
+ 0x05, 0x843d,
+ 0x06, 0x06f6 ,
+
+ 0x1f, 0x0000,
+ #endif
+};
+
+static const unsigned int default_val[]={
+ 999,0x1f,0x0002,
+
+ 2,0x11,0x7e00,
+
+ 3,0x1f,0x0002,
+ 3,0x17,0xff00,
+ 3,0x18,0x0005,
+ 3,0x19,0x0005,
+ 3,0x1a,0x0005,
+ 3,0x1b,0x0005,
+ 3,0x1c,0x0005,
+
+ 4,0x1f,0x0002,
+ 4,0x13,0x00aa,
+ 4,0x14,0x00aa,
+ 4,0x15,0x00aa,
+ 4,0x16,0x00aa,
+ 4,0x17,0x00aa,
+ 4,0x18,0x0f0a,
+ 4,0x19,0x50ab,
+ 4,0x1a,0x0000,
+ 4,0x1b,0x0f0f,
+
+ 999,0x1f,0x0000,
+};
+
+void Setting_RTL8198_GPHY(void)
+{
+ int i=0, port =0, len=0;
+
+ for(i=0; i<5; i++)
+ REG32(PCRP0+i*4) |= (EnForceMode);
+
+ if (REG32(BSP_REVR) == BSP_RTL8198_REVISION_A)
+ {
+ /*
+ #Access command format: phywb {all: phyID=0,1,2,3,4} {page} {RegAddr} {Bit location} {Bit value}
+ #when writing gpage 72, must do mdcmdio_cmd write $phyID 31 0x7, then mdcmdio_cmd write $phyID 30 $PageNum
+ phywb all 72 21 15-0 0x7092
+ phywb all 72 22 15-0 0x7092
+ phywb all 72 23 15-0 0x7092
+ phywb all 72 24 15-0 0x7092
+ phywb all 72 25 15-0 0x7092
+ phywb all 72 26 15-0 0x7092
+ */
+
+ // Set_GPHYWB(3, 2, 20, 0, 0x2000);
+
+ Set_GPHYWB(999, 72, 21, 0, 0x7092);
+ Set_GPHYWB(999, 72, 22, 0, 0x7092);
+ Set_GPHYWB(999, 72, 23, 0, 0x7092);
+ Set_GPHYWB(999, 72, 24, 0, 0x7092);
+ Set_GPHYWB(999, 72, 25, 0, 0x7092);
+ Set_GPHYWB(999, 72, 26, 0, 0x7092);
+
+ /*
+ set PageNum 2; #All of GPHY register in the Page#2
+ #Array format = {{PhyID List1} {RegAddr1 RegData1 RegAddr2 RegData2}, ...}
+
+ set AFE_Reg {{0 1 2 3 4} { 0 0x0000 1 0x065a 2 0x8c01 3 0x0428 4 0x80c8 5 0x0978 6 0x0678 7 0x3620 8 0x0000 9 0x0007 10 0x0000}
+ {2} {11 0x0063 12 0xeb65 13 0x51d1 14 0x5dcb 15 0x3044 16 0x1000 17 0x7e00 18 0x0000}
+ {3} {19 0x3d22 20 0x2000 21 0x6040 22 0x0000 23 0xff00 24 0x0005 25 0x0005 26 0x0005 27 0x0005 28 0x0005}
+ {4} {19 0x00aa 20 0x00aa 21 0x00aa 22 0x00aa 23 0x00aa 24 0x0f0a 25 0x5050 26 0x0000 27 0x0f0f }}
+ */
+
+ //phyid=all
+ Set_GPHYWB(999, 2, 0, 0, 0x0000);
+ Set_GPHYWB(999, 2, 1, 0, 0x065a);
+ Set_GPHYWB(999, 2, 2, 0, 0x8c01);
+ Set_GPHYWB(999, 2, 3, 0, 0x0428);
+ Set_GPHYWB(999, 2, 4, 0, 0x80c8);
+ Set_GPHYWB(999, 2, 5, 0, 0x0978);
+ Set_GPHYWB(999, 2, 6, 0, 0x0678);
+ Set_GPHYWB(999, 2, 7, 0, 0x3620);
+ Set_GPHYWB(999, 2, 8, 0, 0x0000);
+ Set_GPHYWB(999, 2, 9, 0, 0x0007);
+ Set_GPHYWB(999, 2, 10, 0, 0x0000);
+
+ //phyid=2
+ Set_GPHYWB( 2, 2, 11, 0, 0x0063);
+ Set_GPHYWB( 2, 2, 12, 0, 0xeb65);
+ Set_GPHYWB( 2, 2, 13, 0, 0x51d1);
+ Set_GPHYWB( 2, 2, 14, 0, 0x5dcb);
+ Set_GPHYWB( 2, 2, 15, 0, 0x3044);
+ Set_GPHYWB( 2, 2, 16, 0, 0x1000);
+ Set_GPHYWB( 2, 2, 17, 0, 0x7e00);
+ Set_GPHYWB( 2, 2, 18, 0, 0x0000);
+
+ //phyid=3
+ Set_GPHYWB( 3, 2, 19, 0, 0x3d22);
+ Set_GPHYWB( 3, 2, 20, 0, 0x2000);
+ Set_GPHYWB( 3, 2, 21, 0, 0x6040);
+ Set_GPHYWB( 3, 2, 22, 0, 0x0000);
+ Set_GPHYWB( 3, 2, 23, 0, 0xff00);
+ Set_GPHYWB( 3, 2, 24, 0, 0x0005);
+ Set_GPHYWB( 3, 2, 25, 0, 0x0005);
+ Set_GPHYWB( 3, 2, 26, 0, 0x0005);
+ Set_GPHYWB( 3, 2, 27, 0, 0x0005);
+ Set_GPHYWB( 3, 2, 28, 0, 0x0005);
+
+ //phyid=4
+ Set_GPHYWB( 4, 2, 19, 0, 0x00aa);
+ Set_GPHYWB( 4, 2, 20, 0, 0x00aa);
+ Set_GPHYWB( 4, 2, 21, 0, 0x00aa);
+ Set_GPHYWB( 4, 2, 22, 0, 0x00aa);
+ Set_GPHYWB( 4, 2, 23, 0, 0x00aa);
+ Set_GPHYWB( 4, 2, 24, 0, 0x0f0a);
+ Set_GPHYWB( 4, 2, 25, 0, 0x5050);
+ Set_GPHYWB( 4, 2, 26, 0, 0x0000);
+ Set_GPHYWB( 4, 2, 27, 0, 0x0f0f);
+
+ /*
+ #=========== INRX Para. =================================
+
+ phywb all 0 21 0x1006
+ #dfse_mode[15:14]=3(full), Fine tune aagc_lvl_fnet[10:0]
+ phywb all 1 12 15-0 0xdbf0
+
+ #cb0_i_giga[12:0]
+ phywb all 1 9 15-0 0x2576
+ phywb all 1 7 15-0 0x287E
+ phywb all 1 10 15-0 0x68E5
+ phywb all 1 29 15-0 0x3DA4
+ phywb all 1 28 15-0 0xE7F7
+ phywb all 1 20 15-0 0x7F52
+ phywb all 1 24 15-0 0x7FCE
+ phywb all 1 8 15-0 0x04B7
+ phywb all 1 6 15-0 0x4072
+ phywb all 1 16 15-0 0xF05E
+ phywb all 1 27 15-0 0xB414
+ */
+
+ Set_GPHYWB( 999, 1, 12, 0, 0xdbf0);
+
+ Set_GPHYWB( 999, 1, 9, 0, 0x2576);
+ Set_GPHYWB( 999, 1, 7, 0, 0x287E);
+ Set_GPHYWB( 999, 1, 10, 0, 0x68E5);
+ Set_GPHYWB( 999, 1, 29, 0, 0x3DA4);
+ Set_GPHYWB( 999, 1, 28, 0, 0xE7F7);
+ Set_GPHYWB( 999, 1, 20, 0, 0x7F52);
+ Set_GPHYWB( 999, 1, 24, 0, 0x7FCE);
+ Set_GPHYWB( 999, 1, 8, 0, 0x04B7);
+ Set_GPHYWB( 999, 1, 6, 0, 0x4072);
+ Set_GPHYWB( 999, 1, 16, 0, 0xF05E);
+ Set_GPHYWB( 999, 1, 27, 0, 0xB414);
+
+ /*
+ #=========== Cable Test =================================
+
+ phywb all 3 26 15-0 0x06A6
+ phywb all 3 16 15-0 0xF05E
+ phywb all 3 19 15-0 0x06EB
+ phywb all 3 18 15-0 0xF4D2
+ phywb all 3 14 15-0 0xE120
+ phywb all 3 0 15-0 0x7C00
+
+ phywb all 3 2 15-0 0x5FD0
+ phywb all 3 13 15-0 0x0207
+
+ #disable jabber detect
+ phywb all 0 16 15-0 0x05EF
+
+ #Patch for EEE GMII issue
+ phywb all 32 26 15-0 0x0103
+ phywb all 32 22 15-0 0x0004
+ */
+ Set_GPHYWB( 999, 3, 26, 0, 0x06A6);
+ Set_GPHYWB( 999, 3, 16, 0, 0xF05E);
+ Set_GPHYWB( 999, 3, 19, 0, 0x06EB);
+ Set_GPHYWB( 999, 3, 18, 0, 0xF4D2);
+ Set_GPHYWB( 999, 3, 14, 0, 0xE120);
+ Set_GPHYWB( 999, 3, 00, 0, 0x7C00);
+
+ Set_GPHYWB( 999, 3, 02, 0, 0x5FD0);
+ Set_GPHYWB( 999, 3, 13, 0, 0x0207);
+
+ Set_GPHYWB( 999, 0, 16, 0, 0x05EF);
+
+ Set_GPHYWB( 999, 3, 26, 0, 0x0103);
+ Set_GPHYWB( 999, 3, 22, 0, 0x0004);
+
+ /*
+ disable aldps_en, for power measurement
+ hywb all 44 21 15-0 0x0350
+ */
+ Set_GPHYWB( 999, 44, 21, 0, 0x0350);
+ }
+ else
+ {
+ len=sizeof(default_val)/sizeof(unsigned int);
+ for(i=0;i<len;i=i+3)
+ {
+
+ if(default_val[i]==999)
+ {
+ for(port=0; port<5; port++)
+ rtl8651_setAsicEthernetPHYReg(port, default_val[i+1], default_val[i+2]);
+ }
+ else
+ {
+ port=default_val[i];
+ rtl8651_setAsicEthernetPHYReg(port, default_val[i+1], default_val[i+2]);
+ }
+ }
+ len=sizeof(phy_para)/sizeof(unsigned int);
+ for(port=0; port<5; port++)
+ {
+ for(i=0;i<len;i=i+2)
+ {
+ rtl8651_setAsicEthernetPHYReg(port, phy_para[i], phy_para[i+1]);
+ }
+ }
+ Set_GPHYWB( 999, 5, 5, 0, 0x8b84);
+ Set_GPHYWB( 999, 5, 6, 0, 0x0006);
+ Set_GPHYWB( 999, 2, 8, 0, 0x0020);
+
+ // for the IOT issue with IC+ when EEE N-way.
+ Set_GPHYWB( 999, 172, 24, 0, 0x0006);
+
+#ifdef CONFIG_RTL_8198_ESD
+ Set_GPHYWB(999, 44, 27, 0xffff-(0xf<<12), 0x4<<12);
+#endif
+ }
+
+ for(i=0; i<5; i++)
+ REG32(PCRP0+i*4) &= ~(EnForceMode);
+
+ printk("==Set GPHY Parameter OK\n");
+}
+
+int rtl8198_force_giga(int port)
+{
+ if (port < 0 || port > 4)
+ return 0;
+
+ REG32(PCRP0+ port*4) |= (EnForceMode);
+
+ rtl8651_setAsicEthernetPHYReg(port, 31, 0x5);
+ rtl8651_setAsicEthernetPHYReg(port, 5, 0x8b86);
+ rtl8651_setAsicEthernetPHYReg(port, 6, 0x0040);
+ rtl8651_setAsicEthernetPHYReg(port, 31, 0x0);
+
+ REG32(PCRP0+ port*4) = REG32(PCRP0+ port*4) & ~(EnForceMode | NwayAbility100MF | NwayAbility100MH | NwayAbility10MF | NwayAbility10MH); // disable Nway 10/100 ability
+
+ rtl8651_restartAsicEthernetPHYNway(port);
+ return 0;
+}
+
+int rtl8198_disable_force(int port)
+{
+ if (port < 0 || port > 4)
+ return 0;
+
+ REG32(PCRP0+ port*4) |= (EnForceMode);
+
+ rtl8651_setAsicEthernetPHYReg(port, 31, 0x5);
+ rtl8651_setAsicEthernetPHYReg(port, 5, 0x8b86);
+ rtl8651_setAsicEthernetPHYReg(port, 6, 0x0000);
+ rtl8651_setAsicEthernetPHYReg(port, 31, 0x0);
+
+ REG32(PCRP0+ port*4) = (REG32(PCRP0+ port*4) & ~(EnForceMode)) | NwayAbility100MF | NwayAbility100MH | NwayAbility10MF | NwayAbility10MH; // enable Nway 10/100 ability
+
+ rtl8651_restartAsicEthernetPHYNway(port);
+ return 0;
+}
+
+#if defined(PORT5_RGMII_GMII)
+unsigned int ExtP5GigaPhyMode=0;
+void ProbeP5GigaPHYChip(void)
+{
+ unsigned int uid,tmp;
+ unsigned int i;
+
+ //printk("In Setting port5 \r\n");
+
+ //REG32(0xB8000010)=0x01FFFCB9;
+
+ for(i=0; i<=5; i++)
+ REG32(PCRP0+i*4) |= (EnForceMode);
+
+
+ /* Read */
+ rtl8651_setAsicEthernetPHYReg(GIGA_P5_PHYID,0x10,0x01FE);
+ rtl8651_getAsicEthernetPHYReg(GIGA_P5_PHYID, 0, &tmp );
+
+ //printk("Read port5 phyReg0= 0x%x \r\n",tmp);
+
+ rtl8651_getAsicEthernetPHYReg( GIGA_P5_PHYID, 2, &tmp );
+ //printk("Read port5 UPChipID= 0x%x \r\n",tmp);
+ uid=tmp<<16;
+ rtl8651_getAsicEthernetPHYReg( GIGA_P5_PHYID, 3, &tmp );
+ //printk("Read port5 downChipID= 0x%x \r\n",tmp);
+ uid=uid | tmp;
+
+ if( uid==0x001CC912 ) //0x001cc912 is 8212 two giga port , 0x001cc940 is 8214 four giga port
+ {
+ //printk("Find Port5 have 8211 PHY Chip! \r\n");
+ ExtP5GigaPhyMode=1;
+ //return 1;
+ }
+ else
+ {
+ //printk("NO Find Port5 8211 PHY Chip! \r\n");
+ //ExtP5GigaPhyMode=0;
+ //return 1;
+ }
+ for(i=0; i<=5; i++)
+ REG32(PCRP0+i*4) &= ~(EnForceMode);
+
+}
+#endif
+#endif
+
+int32 rtl865x_platform_check(void)
+{
+ uint32 bondOptReg=0;
+ bondOptReg=REG32(0xB800000C);
+ if(((bondOptReg&0x0F)!=0x7) && ((bondOptReg&0x0F)!=0x9))
+ {
+ printk("current chip doesn't supported,system halt...\n");
+ while(1);
+ }
+
+ return SUCCESS;
+}
+
+/*patch for LED showing*/
+#define BICOLOR_LED 1
+/*=========================================
+ * init Layer2 Asic
+ * rtl865x_initAsicL2 mainly configure basic&L2 Asic.
+ * =========================================*/
+int32 rtl865x_initAsicL2(rtl8651_tblAsic_InitPara_t *para)
+{
+ int32 index;
+
+#ifdef BICOLOR_LED
+#if defined (CONFIG_RTL_8196C) || defined(CONFIG_RTL_8198)
+#else
+ unsigned int hw_val;
+#endif
+#endif
+
+#ifdef CONFIG_RTL8196C_ETH_IOT
+ port_link_sts = 0;
+ port_linkpartner_eee = 0;
+#endif
+
+ //bond check
+ //rtl865x_platform_check();
+
+/*==============================
+ *port
+ ==============================*/
+//#ifdef CONFIG_RTL8214_SUPPORT /* Replaced by auto-detect */
+#ifndef CONFIG_RTL_819X
+// rtl865x_wanPortMask = RTL865X_PORTMASK_UNASIGNED;
+ if (rtl865x_probeP5GigaPHYChip())
+ {
+ para->externalPHYProperty |= RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B;
+ para->externalPHYId[5] = CONFIG_EXTRTL8212_PHYID_P5;
+
+#if defined(CONFIG_RTL8186_KB)
+ /* wan/lan port mask if the RTL8186_KB defined */
+ rtl865x_wanPortMask = 0x2; /* port 1 */
+ rtl865x_lanPortMask = 0x1dd; /* port 5/2/3/4/6/7/8 */
+#else
+ rtl865x_wanPortMask = 0x20; /* port 5 */
+ rtl865x_lanPortMask = 0x1de; /* port 1/2/3/4/6/7/8 */
+#endif
+ }
+
+ if (rtl865x_probeP1toP4GigaPHYChip())
+ {
+ para->externalPHYProperty |= RTL8651_TBLASIC_EXTPHYPROPERTY_PORT1234_RTL8212;
+ para->externalPHYId[1] = CONFIG_EXTRTL8212_PHYID_P1;
+ para->externalPHYId[2] = CONFIG_EXTRTL8212_PHYID_P1+1;
+ para->externalPHYId[3] = CONFIG_EXTRTL8212_PHYID_P3;
+ para->externalPHYId[4] = CONFIG_EXTRTL8212_PHYID_P3+1;
+ }
+#endif
+
+ if ((rtl865x_probeSdramSize())>(16<<20))
+ {
+#if !defined(CONFIG_RTL_819X)
+ rtl865x_fix8214Bug();
+ rtl865x_maxPreAllocRxSkb = 256;
+ rtl865x_rxSkbPktHdrDescNum = 512;
+ rtl865x_txSkbPktHdrDescNum = 1024;
+#endif
+ }
+
+
+#if defined(RTL865X_TEST)
+ char chipVersion[16];
+ int rev;
+
+ /* _rtl8651_mapToVirtualRegSpace(); to be removed */
+ rtl8651_getChipVersion(chipVersion, sizeof(chipVersion), &rev);
+ memset(pVirtualSWReg,0, VIRTUAL_SWCORE_REG_SIZE);
+ memset(pVirtualSysReg,0, VIRTUAL_SYSTEM_REG_SIZE);
+ memset(pVirtualHsb,0, HSB_SIZE);
+ memset(pVirtualHsa,0, HSA_SIZE);
+ memset(pVirtualSWTable,0,VIRTUAL_SWCORE_TBL_SIZE);
+ memset(pVirtualMIIRegs,0,sizeof(pVirtualMIIRegs));
+ rtl8651_setChipVersion(chipVersion, &rev);
+
+#elif 0 && defined(RTL865X_MODEL_USER) /* map to real reg space will cause VSV test crash in model code mode. */
+#if defined(VSV)||defined(MIILIKE)
+ _rtl8651_mapToRealRegSpace();
+#else
+ _rtl8651_mapToVirtualRegSpace(); /* for cleshell.c:main() only ! */
+ modelIcSetDefaultValue();
+#endif
+#elif defined(RTL865X_MODEL_KERNEL)
+#endif
+
+ ASICDRV_INIT_CHECK(_rtl8651_initAsicPara(para));
+
+ rtl8651_getChipVersion(RtkHomeGatewayChipName, sizeof(RtkHomeGatewayChipName), &RtkHomeGatewayChipRevisionID);
+ rtl8651_getChipNameID(&RtkHomeGatewayChipNameID);
+
+#ifndef RTL865X_TEST
+ rtlglue_printf("chip name: %s, chip revid: %d\n", RtkHomeGatewayChipName, RtkHomeGatewayChipRevisionID);
+#endif
+
+ if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT1234_RTL8212)
+ {
+
+ printk("\nEnable Port1~Port4 GigaPort.\n\n");
+ /* Patch for 'RGMII port does not get descritpors'. Set to MII PHY mode first and later we'll change to RGMII mode again. */
+ rtl865xC_setAsicEthernetMIIMode(0, LINK_MII_PHY);
+
+ /*
+ # According to Hardware SD: David & Maxod,
+
+ Set Port5_GMII Configuration Register.
+ - RGMII Output Timing compensation control : 0 ns
+ - RGMII Input Timing compensation control : 0 ns
+ */
+ rtl865xC_setAsicEthernetRGMIITiming(0, RGMII_TCOMP_0NS, RGMII_RCOMP_0NS);
+
+ /* Set P1 - P4 to SerDes Interface. */
+ WRITE_MEM32(PITCR, Port4_TypeCfg_SerDes | Port3_TypeCfg_SerDes | Port2_TypeCfg_SerDes | Port1_TypeCfg_SerDes );
+ }
+ else if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
+ {
+ /* Patch for 'RGMII port does not get descritpors'. Set to MII PHY mode first and later we'll change to RGMII mode again. */
+ rtl865xC_setAsicEthernetMIIMode(RTL8651_MII_PORTNUMBER, LINK_MII_PHY);
+
+ /*
+ # According to Hardware SD: David & Maxod,
+
+ Set Port5_GMII Configuration Register.
+ - RGMII Output Timing compensation control : 0 ns
+ - RGMII Input Timing compensation control : 0 ns
+ */
+ rtl865xC_setAsicEthernetRGMIITiming(RTL8651_MII_PORTNUMBER, RGMII_TCOMP_0NS, RGMII_RCOMP_0NS);
+ }
+
+#ifdef CONFIG_RTL8196C_REVISION_B
+ if (REG32(REVR) == RTL8196C_REVISION_B)
+ Setting_RTL8196C_PHY();
+
+#elif defined(CONFIG_RTL_8198)
+#if 0//def PORT5_RGMII_GMII
+ ProbeP5GigaPHYChip();
+#endif
+ Setting_RTL8198_GPHY();
+
+#endif
+
+#ifdef CONFIG_8198_PORT5_RGMII
+ {
+ /* define GPIO port */
+ enum GPIO_PORT
+ {
+ GPIO_PORT_A = 0,
+ GPIO_PORT_B,
+ GPIO_PORT_C,
+ GPIO_PORT_D,
+ GPIO_PORT_E,
+ GPIO_PORT_F,
+ GPIO_PORT_G,
+ GPIO_PORT_H,
+ GPIO_PORT_I,
+ GPIO_PORT_MAX,
+ };
+
+ #define REG_IOCFG_GPIO 0x00000018
+
+ extern int32 smi_init(uint32 port, uint32 pinSCK, uint32 pinSDA);
+ extern int RTL8370_init(void);
+
+ // set to GPIO mode
+ REG32(PIN_MUX_SEL) |= (REG_IOCFG_GPIO);
+
+
+ WRITE_MEM32(PABCD_CNR, READ_MEM32(PABCD_CNR) & (~(0x0000000C))); //set GPIO pin
+ WRITE_MEM32(PABCD_DIR, READ_MEM32(PABCD_DIR) | ((0x0000000C))); //output pin
+
+ smi_init(GPIO_PORT_A, 3, 2);
+
+ RTL8370_init();
+ }
+#endif
+
+ /* 2006.12.12
+ We turn on bit.10 (ENATT2LOG).
+
+ * Current implementation of unnumbered pppoe in multiple session
+ When wan type is multiple-session, and one session is unnumbered pppoe, WAN to unnumbered LAN is RP --> NPI.
+ And user adds ACL rule to trap dip = unnumbered LAN to CPU.
+
+ However, when pktOpApp of this ACL rule is set, it seems that this toCPU ACL does not work.
+ Therefore, we turn on this bit (ENATT2LOG) to trap pkts (WAN --> unnumbered LAN) to CPU.
+
+ */
+ WRITE_MEM32( SWTCR1, READ_MEM32( SWTCR1 ) | EnNATT2LOG );
+
+ /*
+ * Turn on ENFRAG2ACLPT for Rate Limit. For those packets which need to be trapped to CPU, we turn on
+ * this bit to tell ASIC ACL and Protocol Trap to process these packets. If this bit is not turnned on, packets
+ * which need to be trapped to CPU will not be processed by ASIC ACL and Protocol Trap.
+ * NOTE: If this bit is turned on, the backward compatible will disable.
+ * - chhuang
+ */
+ WRITE_MEM32( SWTCR1, READ_MEM32( SWTCR1 ) | ENFRAGTOACLPT );
+
+#ifdef CONFIG_RTL865X_LIGHT_ROMEDRV
+ WRITE_MEM32( SWTCR1, READ_MEM32( SWTCR1 ) | L4EnHash1 ); /*Turn on Napt Enhanced hash1*/
+#endif
+
+ /*
+ * Cannot turn on EnNAP8651B due to:
+ * If turn on, NAT/LP/ServerPort will reference nexthop. This will result in referecing wrong L2 entry when
+ * the destination host is in the same subnet as WAN.
+ */
+
+
+ /*Although chip is in 8650 compatible mode,
+ some 865XB features are independent to compatibility register*/
+ /*Initialize them here if needed*/
+
+ {
+ int rev;
+ char chipVersion[16];
+ rtl8651_getChipVersion(chipVersion, sizeof(chipVersion), &rev);
+ if(chipVersion[strlen(chipVersion)-1]=='B'
+ || chipVersion[strlen(chipVersion) - 1] == 'C' )
+ {
+ rtl8651_totalExtPortNum=3; //this replaces all RTL8651_EXTPORT_NUMBER defines
+ rtl8651_allExtPortMask = 0x7<<RTL8651_MAC_NUMBER; //this replaces all RTL8651_EXTPORTMASK defines
+#if !defined(RTL865X_TEST) && !defined(RTL865X_MODEL_USER)
+ rtl8651_asicEthernetCableMeterInit();
+#endif
+ }
+
+ }
+ //Disable layer2, layer3 and layer4 function
+ //Layer 2 enabled automatically when a VLAN is added
+ //Layer 3 enabled automatically when a network interface is added.
+ //Layer 4 enabled automatically when an IP address is setup.
+ rtl8651_setAsicOperationLayer(1);
+ rtl8651_clearAsicCommTable();
+ rtl8651_clearAsicL2Table();
+ //rtl8651_clearAsicAllTable();//MAY BE OMITTED. FULL_RST clears all tables already.
+ rtl8651_setAsicSpanningEnable(FALSE);
+
+#ifdef RTL865XB_URL_FILTER
+ WRITE_MEM32( SWTCR1, READ_MEM32( SWTCR1 ) | EN_51B_CPU_REASON ); /* Use 8650B's new reason bit definition. */
+#endif
+
+#if !defined(RTL865X_TEST) && !defined(RTL865X_MODEL_USER)
+ //mark_issue
+ //WRITE_MEM32(0xbd012064,READ_MEM32(0xbd012064)|0xf0000000);//Enable Lexra bus timeout interrupt and timeout limit
+ #if 0
+ // shliu: Why we set PORT5_PHY_CONTROL to value "0x2c7"?? Should set "0x2c2"?!
+ WRITE_MEM32(0xbc800020,0x000002c7);
+ WRITE_MEM32(0xbc800008,0xbc8020a0);
+ WRITE_MEM32(0xbc800000,0x00000009);
+ #endif
+#endif
+
+ /* Init PHY LED style */
+#ifdef BICOLOR_LED
+
+#ifdef CONFIG_RTL_819X
+#if defined(CONFIG_RTL8186_KB) && defined(CONFIG_RTL8186_KB_N)
+ hw_val = read_gpio_hw_setting();
+ REG32(PIN_MUX_SEL) =0x0fffff80;/*For Belkin_n board, not for demo board*/
+ REG32(LEDCREG)=0;
+#else
+#if defined (CONFIG_RTL_8196C) || defined(CONFIG_RTL_8198)
+#else
+ hw_val = read_gpio_hw_setting();
+ REG32(PIN_MUX_SEL) =0x00000380;
+ REG32(LEDCREG)=0;
+#endif
+#endif
+#else
+ hw_val = read_gpio_hw_setting();
+ if (hw_val == 0x2 || hw_val == 0x3 || hw_val == 0x6 || hw_val == 0x7) // LED in matrix mode
+ {
+ REG32(LEDCREG) = 0x155500;
+ }
+ REG32(TCR0) = 0x000002c2;
+ REG32(SWTAA) = PORT5_PHY_CONTROL;
+ REG32(SWTACR) = ACTION_START | CMD_FORCE;
+ while ( (REG32(SWTACR) & ACTION_MASK) != ACTION_DONE ); /* Wait for command done */
+#endif
+
+#else
+#if 0
+ #if defined(BICOLOR_LED_VENDOR_BXXX)
+ REG32(LEDCR) |= 0x00080000;
+
+ REG32(PABCNR) &= ~0xc01f0000; /* set port a-7/6 & port b-4/3/2/1/0 to gpio */
+ REG32(PABDIR) |= 0x401f0000; /* set port a-6 & port b-4/3/2/1/0 gpio direction-output */
+ REG32(PABDIR) &= ~0x80000000; /* set port a-7 gpio direction-input */
+ #else /* BICOLOR_LED_VENDOR_BXXX */
+ REG32(LEDCR) = 0x00000000;
+ REG32(TCR0) = 0x000002c7;
+ REG32(SWTAA) = PORT5_PHY_CONTROL;
+ REG32(SWTACR) = ACTION_START | CMD_FORCE;
+ while ( (REG32(SWTACR) & ACTION_MASK) != ACTION_DONE ); /* Wait for command done */
+ #endif /* BICOLOR_LED_VENDOR_BXXX */
+#endif
+#endif
+ //MAC Control (0xBC803000)
+/* WRITE_MEM32(MACCR,READ_MEM32(MACCR)&~DIS_IPG);//Set IFG range as 96+-4bit time*/
+ WRITE_MEM32(MACCR,READ_MEM32(MACCR)&~NORMAL_BACKOFF);//Normal backoff
+ WRITE_MEM32(MACCR,READ_MEM32(MACCR)&~BACKOFF_EXPONENTIAL_3);//Exponential parameter is 9
+ WRITE_MEM32(MACCR,READ_MEM32(MACCR)|INFINITE_PAUSE_FRAMES);//send pause frames infinitely.
+ WRITE_MEM32(MACCR,READ_MEM32(MACCR)|DIS_MASK_CGST);
+
+ miiPhyAddress = -1; /* not ready to use mii port 5 */
+
+ memset( &rtl8651AsicEthernetTable[0], 0, ( RTL8651_PORT_NUMBER + rtl8651_totalExtPortNum ) * sizeof(rtl8651_tblAsic_ethernet_t) );
+ /* Record the PHYIDs of physical ports. Default values are 0. */
+ rtl8651AsicEthernetTable[0].phyId = 0; /* Default value of port 0's embedded phy id -- 0 */
+ rtl8651AsicEthernetTable[0].isGPHY = FALSE;
+
+ if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT1234_RTL8212)
+ {
+ rtl8651AsicEthernetTable[1].phyId = rtl8651_tblAsicDrvPara.externalPHYId[1];
+ rtl8651AsicEthernetTable[2].phyId = rtl8651_tblAsicDrvPara.externalPHYId[2];
+ rtl8651AsicEthernetTable[3].phyId = rtl8651_tblAsicDrvPara.externalPHYId[3];
+ rtl8651AsicEthernetTable[4].phyId = rtl8651_tblAsicDrvPara.externalPHYId[4];
+ rtl8651AsicEthernetTable[1].isGPHY = TRUE;
+ rtl8651AsicEthernetTable[2].isGPHY = TRUE;
+ rtl8651AsicEthernetTable[3].isGPHY = TRUE;
+ rtl8651AsicEthernetTable[4].isGPHY = TRUE;
+ } else
+ { /* USE internal 10/100 PHY */
+ rtl8651AsicEthernetTable[1].phyId = 1; /* Default value of port 1's embedded phy id -- 1 */
+ rtl8651AsicEthernetTable[2].phyId = 2; /* Default value of port 2's embedded phy id -- 2 */
+ rtl8651AsicEthernetTable[3].phyId = 3; /* Default value of port 3's embedded phy id -- 3 */
+ rtl8651AsicEthernetTable[4].phyId = 4; /* Default value of port 4's embedded phy id -- 4 */
+ rtl8651AsicEthernetTable[1].isGPHY = FALSE;
+ rtl8651AsicEthernetTable[2].isGPHY = FALSE;
+ rtl8651AsicEthernetTable[3].isGPHY = FALSE;
+ rtl8651AsicEthernetTable[4].isGPHY = FALSE;
+ }
+
+ if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
+ {
+ rtl8651AsicEthernetTable[RTL8651_MII_PORTNUMBER].phyId = rtl8651_tblAsicDrvPara.externalPHYId[5];
+ rtl8651AsicEthernetTable[RTL8651_MII_PORTNUMBER].isGPHY = TRUE;
+ rtl8651_setAsicEthernetMII( rtl8651AsicEthernetTable[RTL8651_MII_PORTNUMBER].phyId,
+ P5_LINK_RGMII,
+ TRUE );
+ }
+
+#if 0
+ WRITE_MEM32(PCRP0, (rtl8651AsicEthernetTable[0].phyId<<ExtPHYID_OFFSET)|AcptMaxLen_16K|EnablePHYIf ); /* Jumbo Frame */
+ WRITE_MEM32(PCRP1, (rtl8651AsicEthernetTable[1].phyId<<ExtPHYID_OFFSET)|AcptMaxLen_16K|EnablePHYIf ); /* Jumbo Frame */
+ WRITE_MEM32(PCRP2, (rtl8651AsicEthernetTable[2].phyId<<ExtPHYID_OFFSET)|AcptMaxLen_16K|EnablePHYIf ); /* Jumbo Frame */
+ WRITE_MEM32(PCRP3, (rtl8651AsicEthernetTable[3].phyId<<ExtPHYID_OFFSET)|AcptMaxLen_16K|EnablePHYIf ); /* Jumbo Frame */
+ WRITE_MEM32(PCRP4, (rtl8651AsicEthernetTable[4].phyId<<ExtPHYID_OFFSET)|AcptMaxLen_16K|EnablePHYIf ); /* Jumbo Frame */
+
+ if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
+ {
+ WRITE_MEM32(PCRP5, (rtl8651AsicEthernetTable[5].phyId<<ExtPHYID_OFFSET)|AcptMaxLen_16K|EnablePHYIf ); /* Jumbo Frame */
+ }
+
+#if 0 /* No need to set PHYID of port 6. Just use ASIC default value. */
+ /* Due to MSb of phyid has been added an inverter in b-cut,
+ * although we want to set 6(0b00110) as phyid, we have to write 22(0b10110) instead. */
+ WRITE_MEM32( PCRP6, ( 22 << ExtPHYID_OFFSET ) | AcptMaxLen_16K | EnablePHYIf );
+#endif
+ if(RTL865X_PHY6_DSP_BUG)
+ WRITE_MEM32(PCRP6, (6<<ExtPHYID_OFFSET)|AcptMaxLen_16K|EnablePHYIf );
+ /* Set PHYID 6 to PCRP6. (By default, PHYID of PCRP6 is 0. It will collide with PHYID of port 0. */
+#endif
+
+
+
+/* WRITE_MEM32(MACCR,READ_MEM32(MACCR)&~(EN_FX_P4 | EN_FX_P3 | EN_FX_P2 | EN_FX_P1 | EN_FX_P0));//Disable FX mode (UTP mode)*/
+ /* Initialize MIB counters */
+ rtl8651_clearAsicCounter();
+
+ rtl865xC_setNetDecisionPolicy( NETIF_VLAN_BASED ); /* Net interface Multilayer-Decision-Based Control -- Set to VLAN-Based mode. */
+ //rtl865xC_setNetDecisionPolicy( NETIF_PORT_BASED ); /* Net interface Multilayer-Decision-Based Control -- Set to port-Based mode. */
+ //WRITE_MEM32(PLITIMR,0);
+
+ /*FIXME:Hyking init in Layer4 2*/
+ //WRITE_MEM32(SWTCR0,READ_MEM32(SWTCR0)&~NAPTR_NOT_FOUND_DROP);//When reverse NAPT entry not found, CPU process it.
+ //rtl8651_setAsicNaptAutoAddDelete(FALSE, TRUE);
+ WRITE_MEM32( VCR0, READ_MEM32( VCR0 ) & (~EN_ALL_PORT_VLAN_INGRESS_FILTER) ); /* Disable VLAN ingress filter of all ports */ /* Please reference to the maintis bug 2656# */
+ /*WRITE_MEM32( VCR0, READ_MEM32( VCR0 ) & (~EN_ALL_PORT_VLAN_INGRESS_FILTER) );*/ /* Enable VLAN ingress filter of all ports */
+ WRITE_MEM32(SWTCR0,READ_MEM32(SWTCR0)&~WAN_ROUTE_MASK);//Set WAN route toEnable (Allow traffic from WAN port to WAN port)
+ WRITE_MEM32(SWTCR0,READ_MEM32(SWTCR0)|NAPTF2CPU);//When packet destination to switch. Just send to CPU
+ WRITE_MEM32(SWTCR0,(READ_MEM32(SWTCR0)&(~LIMDBC_MASK))|LIMDBC_VLAN);//When packet destination to switch. Just send to CPU
+
+ /*FIXME:Hyking init in Layer3 1*/
+ //rtl8651_setAsicMulticastEnable(TRUE); /* Enable multicast table */
+
+ /* Enable unknown unicast / multicast packet to be trapped to CPU. */
+// WRITE_MEM32( FFCR, READ_MEM32( FFCR ) | EN_UNUNICAST_TOCPU );
+ WRITE_MEM32( FFCR, READ_MEM32( FFCR ) & ~EN_UNUNICAST_TOCPU );
+ WRITE_MEM32( FFCR, READ_MEM32( FFCR ) | EN_UNMCAST_TOCPU );
+/* WRITE_MEM32(SWTMCR,READ_MEM32(SWTMCR)&~MCAST_TO_CPU);*/
+/* WRITE_MEM32(SWTMCR,READ_MEM32(SWTMCR)|EN_BCAST);//Enable special broadcast handling*/
+/* WRITE_MEM32(SWTMCR,READ_MEM32(SWTMCR)&~BCAST_TO_CPU);//When EN_BCAST enables, this bit is invalid*/
+/* WRITE_MEM32(SWTMCR,READ_MEM32(SWTMCR)&~BRIDGE_PKT_TO_CPU);//Current no bridge protocol is supported*/
+
+ /*FIXME:Hyking init in Layer3 1*/
+ //WRITE_MEM32(ALECR, READ_MEM32(ALECR)|(uint32)EN_PPPOE);//enable PPPoE auto encapsulation
+ WRITE_MEM32(CSCR,READ_MEM32(CSCR)&~ALLOW_L2_CHKSUM_ERR);//Don't allow chcksum error pkt be forwarded.
+
+ WRITE_MEM32(CSCR,READ_MEM32(CSCR)&~ALLOW_L3_CHKSUM_ERR);
+ WRITE_MEM32(CSCR,READ_MEM32(CSCR)&~ALLOW_L4_CHKSUM_ERR);
+ WRITE_MEM32(CSCR,READ_MEM32(CSCR)|EN_ETHER_L3_CHKSUM_REC); //Enable L3 checksum Re-calculation
+ WRITE_MEM32(CSCR,READ_MEM32(CSCR)|EN_ETHER_L4_CHKSUM_REC); //Enable L4 checksum Re-calculation
+
+/* WRITE_MEM32(MISCCR,READ_MEM32(MISCCR)&~FRAG2CPU);//IP fragment packet does not need to send to CPU when initial ASIC
+ WRITE_MEM32(MISCCR,READ_MEM32(MISCCR)&~MULTICAST_L2_MTU_MASK);
+ WRITE_MEM32(MISCCR,READ_MEM32(MISCCR)|(1522&MULTICAST_L2_MTU_MASK));//Multicast packet layer2 size 1522 at most*/
+ /* follow RTL865xB's convention, we use 1522 as default multicast MTU */
+
+ /*FIXME:Hyking init in Layer3 1*/
+ //rtl8651_setAsicMulticastMTU(1522);
+
+ //Set all Protocol-Based Reg. to 0
+
+ for (index=0;index<32;index++)
+ WRITE_MEM32(PBVCR0+index*4, 0x00000000);
+ //Enable TTL-1
+ /*FIXME:Hyking init in Layer3 1*/
+ //WRITE_MEM32(TTLCR,READ_MEM32(TTLCR)|(uint32)EN_TTL1);//Don't hide this router. enable TTL-1 when routing on this gateway.
+
+
+ for (index=0; index<RTL8651_PORT_NUMBER+rtl8651_totalExtPortNum; index++) {
+
+
+
+ if( rtl8651_setAsicMulticastSpanningTreePortState(index, RTL8651_PORTSTA_FORWARDING))
+ return FAILED;
+
+ rtl865xC_setAsicSpanningTreePortState(index, RTL8651_PORTSTA_FORWARDING);
+
+ rtl8651_setAsicEthernetBandwidthControl(index, TRUE, RTL8651_BC_FULL);
+ rtl8651_setAsicEthernetBandwidthControl(index, FALSE, RTL8651_BC_FULL);
+ }
+
+ /* Enable TX/RX After ALL ASIC configurations are done */
+ WRITE_MEM32( SIRR, READ_MEM32(SIRR)| TRXRDY );
+
+ /* Initiate Bandwidth control backward compatible mode : Set all of them to FULL-Rate */
+ {
+ int32 portIdx, typeIdx;
+ _rtl865xB_BandwidthCtrlMultiplier = _RTL865XB_BANDWIDTHCTRL_X1;
+ for ( portIdx = 0 ; portIdx < RTL8651_PORT_NUMBER ; portIdx ++ )
+ {
+ for ( typeIdx = 0 ; typeIdx < _RTL865XB_BANDWIDTHCTRL_CFGTYPE ; typeIdx ++ )
+ {
+ _rtl865xB_BandwidthCtrlPerPortConfiguration[portIdx][typeIdx] = BW_FULL_RATE;
+ }
+ }
+ /* Sync the configuration to ASIC */
+ _rtl8651_syncToAsicEthernetBandwidthControl();
+ }
+
+
+
+ /* ==================================================================================================
+ Embedded PHY patch -- According to the designer, internal PHY's parameters need to be adjusted.
+ ================================================================================================== */
+ if(RTL865X_PHY6_DSP_BUG) /*modified by Mark*/
+ {
+ rtl8651_setAsicEthernetPHYReg( 6, 9, 0x0505 );
+ rtl8651_setAsicEthernetPHYReg( 6, 4, 0x1F10 );
+ rtl8651_setAsicEthernetPHYReg( 6, 0, 0x1200 );
+ }
+
+ /* ===============================
+ =============================== */
+ {
+ uint32 port;
+ uint32 maxPort;
+
+ maxPort = (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)?
+ RTL8651_MAC_NUMBER:
+ RTL8651_PHY_NUMBER;
+
+#ifdef CONFIG_RTL_EEE_DISABLED
+ eee_enabled = 0;
+#endif
+
+ for ( port = 0 ; port < maxPort ; port ++ )
+ {
+
+#if defined(RTL8196C_EEE_MAC)
+ if (eee_enabled) {
+ uint32 reg;
+ eee_phy_enable_by_port(port);
+
+ if (REG32(REVR) == RTL8196C_REVISION_B) {
+ // enable EEE MAC
+ reg = REG32(EEECR);
+// REG32(EEECR) = (reg & ~(0x1f << (port * 5)) )
+// | ((FRC_P0_EEE_100|EN_P0_TX_EEE|EN_P0_RX_EEE) << (port * 5));
+ REG32(EEECR) = (reg & ~(0x1f << (port * 5)) )
+ | ((EN_P0_TX_EEE|EN_P0_RX_EEE) << (port * 5));
+
+ }
+ }
+#endif
+ rtl8651_setAsicFlowControlRegister(port, TRUE);
+ rtl865xC_setAsicPortPauseFlowControl(port, TRUE, TRUE);
+ }
+
+ #if defined(CONFIG_RTL_8196C)
+ if (eee_enabled == 0) {
+ REG32(EEECR) = 0;
+ }
+ #elif defined(CONFIG_RTL_8198)
+ if (eee_enabled) {
+ eee_phy_enable_98();
+ }
+ else {
+ eee_phy_disable_98();
+ }
+ #endif
+ }
+
+
+
+ /* ===============================
+ (1) Handling port 0.
+ =============================== */
+ rtl8651_restartAsicEthernetPHYNway(0); /* Restart N-way of port 0 to let embedded phy patch take effect. */
+
+ /* ===============================
+ (2) Handling port 1 - port 4.
+ =============================== */
+ if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT1234_RTL8212)
+ {
+
+ } else
+ {
+ /* Restart N-way of port 1 - port 4 to let embedded phy patch take effect. */
+ {
+ uint32 port;
+
+ /* Restart N-way of port 1 - port 4 */
+ for ( port = 1; port < RTL8651_PHY_NUMBER; port++ )
+ {
+ rtl8651_restartAsicEthernetPHYNway(port);
+ }
+ }
+ }
+
+ /* ===============================
+ (3) Handling port 5.
+ =============================== */
+
+
+ /* =====================
+ QoS-related patch
+ ===================== */
+ {
+ #define DEFAULT_ILB_UBOUND 0x3FBE /*added by Mark for suggested Leacky Bucket value*/
+ #define DEFAULT_ILB_LBOUND 0x3FBC
+
+ uint32 token, tick, hiThreshold,i;
+ rtl8651_getAsicLBParameter( &token, &tick, &hiThreshold );
+ hiThreshold = 0x400; /* New default vlue. */
+ rtl8651_setAsicLBParameter( token, tick, hiThreshold );
+ /*Mantis(2307): Ingress leaky bucket need to be initized with suggested value . added by mark*/
+ WRITE_MEM32( ILBPCR1, DEFAULT_ILB_UBOUND << UpperBound_OFFSET | DEFAULT_ILB_LBOUND << LowerBound_OFFSET );
+ for(i=0;i<=(RTL8651_PHY_NUMBER/2);i++) /*Current Token Register is 2 bytes per port*/
+ WRITE_MEM32( ILB_CURRENT_TOKEN + 4*i , DEFAULT_ILB_UBOUND << UpperBound_OFFSET | DEFAULT_ILB_UBOUND );
+
+ }
+
+ #if defined(CONFIG_RTL_HW_QOS_SUPPORT)
+ /* Initiate Queue Management system */
+ _rtl865xC_QM_init();
+ #endif
+
+ /*
+ Init QUEUE Number configuration for RTL865xC : For Port 0~5 and CPU Port - All ports have 1 queue for each.
+ */
+ {
+#if 1
+ /* The default value was just as same as what we want */
+ rtl865xC_lockSWCore();
+
+ /* Enable Flow Control for each QUEUE / Port */
+ {
+ int32 port, queue;
+
+ for ( port = PHY0 ; port <= CPU ; port ++ )
+ {
+ /* Set the Ingress & Egress bandwidth control NO LIMIT */
+ /* Has been done by _rtl8651_syncToAsicEthernetBandwidthControl() */
+ /*
+ rtl8651_setAsicPortIngressBandwidth(port, (IBWC_ODDPORT_MASK>>IBWC_ODDPORT_OFFSET));
+ rtl8651_setAsicPortEgressBandwidth(port, (APR_MASK>>APR_OFFSET));
+ */
+
+ /*
+ Init QUEUE Number configuration for RTL865xC : For Port 0~5 and CPU Port - All ports have 1 queue for each.
+ */
+ rtl8651_setAsicOutputQueueNumber(port, 1 /* According to DataSheet of QNUMCR : All ports use 1 queue by default */);
+
+ for ( queue = QUEUE0 ; queue <= QUEUE5 ; queue ++ )
+ {
+ rtl8651_setAsicQueueFlowControlConfigureRegister( port, queue, TRUE);
+ #if 0
+ /* Please keep the queue setting as above.
+ * Default set queue FC disable will corrupt wlan<->lan performance
+ * 2011/01/10 ZhaoBo
+ */
+ rtl8651_setAsicQueueFlowControlConfigureRegister( port, queue, FALSE);
+ #endif
+ }
+ }
+ }
+
+ rtl865xC_waitForOutputQueueEmpty();
+ rtl8651_resetAsicOutputQueue();
+ rtl865xC_unLockSWCore();
+#endif
+
+ /* DSP bug (PHY-ID for DSP controller is set same as PHY 0 ) in RTL865xC A-Cut */
+ if(RTL865X_PHY6_DSP_BUG)
+ /* correct the default value of input queue flow control threshold */
+ WRITE_MEM32( IQFCTCR, 0xC8 << IQ_DSC_FCON_OFFSET | 0x96 << IQ_DSC_FCOFF_OFFSET );
+
+ if ( RTL865X_IQFCTCR_DEFAULT_VALUE_BUG )
+ {
+ rtl8651_setAsicSystemInputFlowControlRegister(0xc8, 0x96); /* Configure the ASIC Input Queue Flow control threshold to the default value ( ASIC default value is opposite from correct ) */
+ }
+
+ }
+
+ /* set default include IFG */
+ WRITE_MEM32( QOSFCR, BC_withPIFG_MASK);
+
+ {
+ rtl8651_setAsicPriorityDecision(2, 1, 1, 1, 1);
+
+ WRITE_MEM32(PBPCR, 0);
+ /* Set the threshold value for qos sytem */
+ _rtl865x_setQosThresholdByQueueIdx(QNUM_IDX_123);
+
+ /* clear dscp priority assignment, otherwise, pkt with dscp value 0 will be assign priority 1 */
+ WRITE_MEM32(DSCPCR0,0);
+ WRITE_MEM32(DSCPCR1,0);
+ WRITE_MEM32(DSCPCR2,0);
+ WRITE_MEM32(DSCPCR3,0);
+ WRITE_MEM32(DSCPCR4,0);
+ WRITE_MEM32(DSCPCR5,0);
+ WRITE_MEM32(DSCPCR6,0);
+ }
+
+
+#if defined(RTL865X_TEST) || defined(RTL865X_MODEL_USER)
+#if defined(VERA)||defined(VSV)||defined(MIILIKE)
+ /* To speed up vera, we ignore set NAPT default value. */
+#else
+ /* ICMP Table: Set collision bit to 1 */
+ memset( &naptIcmp, 0, sizeof(naptIcmp) );
+ naptIcmp.isCollision = 1;
+ for(flowTblIdx=0; flowTblIdx<RTL8651_ICMPTBL_SIZE; flowTblIdx++)
+ rtl8651_setAsicNaptIcmpTable( TRUE, flowTblIdx, &naptIcmp );
+#endif
+#endif
+
+#if 1
+#if defined(CONFIG_RTL_8198_NFBI_BOARD)
+ //WRITE_MEM32(PIN_MUX_SEL_2, 0); //for led control
+
+ REG32(PCRP0) &= (0xFFFFFFFF-(0x00000000|MacSwReset));
+ REG32(PCRP1) &= (0xFFFFFFFF-(0x00000000|MacSwReset));
+ REG32(PCRP2) &= (0xFFFFFFFF-(0x00000000|MacSwReset));
+ REG32(PCRP3) &= (0xFFFFFFFF-(0x00000000|MacSwReset));
+ REG32(PCRP4) &= (0xFFFFFFFF-(0x00000000|MacSwReset));
+ REG32(PCRP5) &= (0xFFFFFFFF-(0x00000000|MacSwReset));
+
+ REG32(PCRP0) = REG32(PCRP0) | (0 << ExtPHYID_OFFSET) | EnablePHYIf | MacSwReset;
+ REG32(PCRP1) = REG32(PCRP1) | (1 << ExtPHYID_OFFSET) | EnablePHYIf | MacSwReset;
+ REG32(PCRP2) = REG32(PCRP2) | (2 << ExtPHYID_OFFSET) | EnablePHYIf | MacSwReset;
+ REG32(PCRP3) = REG32(PCRP3) | (3 << ExtPHYID_OFFSET) | EnablePHYIf | MacSwReset;
+ REG32(PCRP4) = REG32(PCRP4) | (4 << ExtPHYID_OFFSET) | EnablePHYIf | MacSwReset;
+
+ //port5 STP forwarding?
+ REG32(PITCR) = REG32(PITCR) & 0xFFFFF3FF; //configure port 5 to be a MII interface
+ rtl865xC_setAsicEthernetMIIMode(5, LINK_MII_PHY); //port 5 MII PHY mode
+ REG32(P5GMIICR) = REG32(P5GMIICR) | 0x40; //Conf_done=1
+
+#if defined(RTL8198_NFBI_PORT5_GMII) //GMII mode
+ #define GMII_PIN_MUX 0xc0
+ REG32(PIN_MUX_SEL)= REG32(PIN_MUX_SEL)&(~(GMII_PIN_MUX));
+ REG32(PCRP5) = 0 | (0x10<<ExtPHYID_OFFSET) |
+ EnForceMode| ForceLink|ForceSpeed1000M|ForceDuplex |
+ MIIcfg_RXER | EnablePHYIf | MacSwReset;
+#else //MII mode
+ REG32(PCRP5) = 0 | (0x10<<ExtPHYID_OFFSET) |
+ EnForceMode| ForceLink|ForceSpeed100M |ForceDuplex |
+ MIIcfg_RXER | EnablePHYIf | MacSwReset;
+#endif
+
+#elif defined(CONFIG_RTL_8198)
+ #define GMII_PIN_MUX 0xf00
+ #if defined(CONFIG_8198_PORT5_GMII) || defined(CONFIG_8198_PORT5_RGMII)
+ REG32(PIN_MUX_SEL)= REG32(PIN_MUX_SEL)&(~(GMII_PIN_MUX));
+ #endif
+ //WRITE_MEM32(PIN_MUX_SEL_2, 0);
+
+ WRITE_MEM32(PCRP0, READ_MEM32(PCRP0) & ~MacSwReset);
+ WRITE_MEM32(PCRP1, READ_MEM32(PCRP1) & ~MacSwReset);
+ WRITE_MEM32(PCRP2, READ_MEM32(PCRP2) & ~MacSwReset);
+ WRITE_MEM32(PCRP3, READ_MEM32(PCRP3) & ~MacSwReset);
+ WRITE_MEM32(PCRP4, READ_MEM32(PCRP4) & ~MacSwReset);
+
+ WRITE_MEM32(PCRP0, READ_MEM32(PCRP0) | ((0<<ExtPHYID_OFFSET)|EnablePHYIf|MacSwReset) ); /* Jumbo Frame */
+ WRITE_MEM32(PCRP1, READ_MEM32(PCRP1) | ((1<<ExtPHYID_OFFSET)|EnablePHYIf|MacSwReset) ); /* Jumbo Frame */
+ WRITE_MEM32(PCRP2, READ_MEM32(PCRP2) | ((2<<ExtPHYID_OFFSET)|EnablePHYIf|MacSwReset) ); /* Jumbo Frame */
+ WRITE_MEM32(PCRP3, READ_MEM32(PCRP3) | ((3<<ExtPHYID_OFFSET)|EnablePHYIf|MacSwReset) ); /* Jumbo Frame */
+ WRITE_MEM32(PCRP4, READ_MEM32(PCRP4) | ((4<<ExtPHYID_OFFSET)|EnablePHYIf|MacSwReset) ); /* Jumbo Frame */
+
+#if defined(PORT5_RGMII_GMII)
+ if(ExtP5GigaPhyMode)
+ {
+ REG32(PCRP5) &= (0x83FFFFFF-(0x00000000|MacSwReset));
+ REG32(PCRP5) = REG32(PCRP5) | (GIGA_P5_PHYID << ExtPHYID_OFFSET) | EnablePHYIf | MacSwReset | 1<<20;
+ REG32(P5GMIICR) = REG32(P5GMIICR) | Conf_done ;//| P5txdely;
+ }
+#endif
+#if defined(CONFIG_8198_PORT5_GMII)
+ REG32(PITCR) = REG32(PITCR) & 0xFFFFF3FF; //configure port 5 to be a MII interface
+ rtl865xC_setAsicEthernetMIIMode(5, LINK_MII_MAC); //port 5 GMII/MII MAC auto mode
+ REG32(P5GMIICR) = REG32(P5GMIICR) | 0x40; //Conf_done=1
+ REG32(PCRP5) = 0 | (0x5<<ExtPHYID_OFFSET) | //JSW@20100309:For external 8211BN GMII ,PHYID must be 5
+ EnForceMode| ForceLink|ForceSpeed1000M |ForceDuplex |
+ MIIcfg_RXER | EnablePHYIf | MacSwReset;
+#elif defined(CONFIG_8198_PORT5_RGMII)
+ REG32(PITCR) = REG32(PITCR) & 0xFFFFF3FF; //configure port 5 to be a MII interface
+ rtl865xC_setAsicEthernetMIIMode(5, LINK_RGMII); //port 5 GMII/MII MAC auto mode
+
+ REG32(P5GMIICR) = REG32(P5GMIICR) | Conf_done;
+ REG32(PCRP5) = 0 | (0x5<<ExtPHYID_OFFSET) | //JSW@20100309:For external 8211BN GMII ,PHYID must be 5
+ EnForceMode| ForceLink|ForceSpeed1000M |ForceDuplex |
+ MIIcfg_RXER | EnablePHYIf | MacSwReset;
+#endif
+ WRITE_MEM32(PCRP0,(REG32(PCRP0) & (0xFFFFFFFF-(MacSwReset))));
+ WRITE_MEM32(PCRP0,(REG32(PCRP0) | (0 << ExtPHYID_OFFSET) | EnablePHYIf |MacSwReset));
+
+#ifdef CONFIG_RTL_8197B
+ /* disable MAC Gbe ability/Gbe 1000F ability of PHY. */
+ WRITE_MEM32(PCRP0, READ_MEM32(PCRP0) & ~NwayAbility1000MF);
+ WRITE_MEM32(PCRP1, READ_MEM32(PCRP1) & ~NwayAbility1000MF);
+ WRITE_MEM32(PCRP2, READ_MEM32(PCRP2) & ~NwayAbility1000MF);
+ WRITE_MEM32(PCRP3, READ_MEM32(PCRP3) & ~NwayAbility1000MF);
+ WRITE_MEM32(PCRP4, READ_MEM32(PCRP4) & ~NwayAbility1000MF);
+ Set_GPHYWB(999, 0, 9, 0, 0);
+#endif
+
+#elif defined(CONFIG_RTL_8196C)
+ WRITE_MEM32(PCRP0, (READ_MEM32(PCRP0)&(0xFFFFFFFF-(0x00400000|MacSwReset))) );
+ TOGGLE_BIT_IN_REG_TWICE(PCRP0,EnForceMode);
+
+ WRITE_MEM32(PCRP1, (READ_MEM32(PCRP1)&(0xFFFFFFFF-(0x00400000|MacSwReset))) );
+ TOGGLE_BIT_IN_REG_TWICE(PCRP1,EnForceMode);
+ WRITE_MEM32(PCRP2, (READ_MEM32(PCRP2)&(0xFFFFFFFF-(0x00400000|MacSwReset))) );
+ TOGGLE_BIT_IN_REG_TWICE(PCRP2,EnForceMode);
+ WRITE_MEM32(PCRP3, (READ_MEM32(PCRP3)&(0xFFFFFFFF-(0x00400000|MacSwReset))) );
+ TOGGLE_BIT_IN_REG_TWICE(PCRP3,EnForceMode);
+ WRITE_MEM32(PCRP4, (READ_MEM32(PCRP4)&(0xFFFFFFFF-(0x00400000|MacSwReset))) );
+ TOGGLE_BIT_IN_REG_TWICE(PCRP4,EnForceMode);
+
+ WRITE_MEM32(PCRP0, (READ_MEM32(PCRP0)|(rtl8651AsicEthernetTable[0].phyId<<ExtPHYID_OFFSET)|EnablePHYIf|MacSwReset ) ); /* Jumbo Frame */
+ TOGGLE_BIT_IN_REG_TWICE(PCRP0,EnForceMode);
+ WRITE_MEM32(PCRP1, (READ_MEM32(PCRP1)|(rtl8651AsicEthernetTable[1].phyId<<ExtPHYID_OFFSET)|EnablePHYIf|MacSwReset ) ); /* Jumbo Frame */
+ TOGGLE_BIT_IN_REG_TWICE(PCRP1,EnForceMode);
+ WRITE_MEM32(PCRP2, (READ_MEM32(PCRP2)|(rtl8651AsicEthernetTable[2].phyId<<ExtPHYID_OFFSET)|EnablePHYIf|MacSwReset ) ); /* Jumbo Frame */
+ TOGGLE_BIT_IN_REG_TWICE(PCRP2,EnForceMode);
+ WRITE_MEM32(PCRP3, (READ_MEM32(PCRP3)|(rtl8651AsicEthernetTable[3].phyId<<ExtPHYID_OFFSET)|EnablePHYIf|MacSwReset ) ); /* Jumbo Frame */
+ TOGGLE_BIT_IN_REG_TWICE(PCRP3,EnForceMode);
+ WRITE_MEM32(PCRP4, (READ_MEM32(PCRP4)|(rtl8651AsicEthernetTable[4].phyId<<ExtPHYID_OFFSET)|EnablePHYIf|MacSwReset ) ); /* Jumbo Frame */
+ TOGGLE_BIT_IN_REG_TWICE(PCRP4,EnForceMode);
+#else
+ WRITE_MEM32(PCRP0, (READ_MEM32(PCRP0)|(rtl8651AsicEthernetTable[0].phyId<<ExtPHYID_OFFSET)|EnablePHYIf ) ); /* Jumbo Frame */
+ WRITE_MEM32(PCRP1, (READ_MEM32(PCRP1)|(rtl8651AsicEthernetTable[1].phyId<<ExtPHYID_OFFSET)|EnablePHYIf ) ); /* Jumbo Frame */
+ WRITE_MEM32(PCRP2, (READ_MEM32(PCRP2)|(rtl8651AsicEthernetTable[2].phyId<<ExtPHYID_OFFSET)|EnablePHYIf ) ); /* Jumbo Frame */
+ WRITE_MEM32(PCRP3, (READ_MEM32(PCRP3)|(rtl8651AsicEthernetTable[3].phyId<<ExtPHYID_OFFSET)|EnablePHYIf ) ); /* Jumbo Frame */
+ WRITE_MEM32(PCRP4, (READ_MEM32(PCRP4)|(rtl8651AsicEthernetTable[4].phyId<<ExtPHYID_OFFSET)|EnablePHYIf ) ); /* Jumbo Frame */
+#endif
+
+
+ if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
+ {
+ WRITE_MEM32(PCRP5, ( (READ_MEM32(PCRP5))|(rtl8651AsicEthernetTable[5].phyId<<ExtPHYID_OFFSET)|EnablePHYIf ) ); /* Jumbo Frame */
+ }
+
+#if 0 /* No need to set PHYID of port 6. Just use ASIC default value. */
+ /* Due to MSb of phyid has been added an inverter in b-cut,
+ * although we want to set 6(0b00110) as phyid, we have to write 22(0b10110) instead. */
+ WRITE_MEM32( PCRP6, (READ_MEM32(PCRP6)|( 22 << ExtPHYID_OFFSET ) | AcptMaxLen_16K | EnablePHYIf );
+#endif
+ if(RTL865X_PHY6_DSP_BUG)
+ WRITE_MEM32(PCRP6, (READ_MEM32(PCRP6)|(6<<ExtPHYID_OFFSET)|EnablePHYIf ) );
+ /* Set PHYID 6 to PCRP6. (By default, PHYID of PCRP6 is 0. It will collide with PHYID of port 0. */
+#endif
+
+#if defined(CONFIG_RTL865X_DIAG_LED)
+ /* diagnosis led (gpio-porta-6) on */
+ /* pull high by set portA-0(bit 30) as gpio-output-1, meaning: diag led OFF */
+ REG32(PABDAT) |= 0x40000000;
+#endif /* CONFIG_RTL865X_DIAG_LED */
+
+#if !defined(CONFIG_RTL_8196C) && !defined(CONFIG_RTL_8198)
+ REG32(MDCIOCR) = 0x96181441; // enable Giga port 8211B LED
+#endif
+
+ /*disable pattern match*/
+ {
+ int pnum;
+ for(pnum=0;pnum<RTL8651_PORT_NUMBER;pnum++)
+ {
+ rtl8651_setAsicPortPatternMatch(pnum, 0, 0, 0x2);
+ }
+ }
+
+#if defined(CONFIG_RTL_8196C)
+ //enable RTL8196C 10M power saving mode
+ {
+ int tmp,idx;
+
+ for(idx=0;idx<MAX_PORT_NUMBER;idx++) {
+ rtl8651_getAsicEthernetPHYReg( idx, 0x18, &tmp );
+#ifdef CONFIG_RTL8196C_GREEN_ETHERNET
+ tmp |= BIT(15); //enable power saving mode
+#else
+ tmp &= ~BIT(15); //disable power saving mode
+#endif
+ rtl8651_setAsicEthernetPHYReg( idx, 0x18, tmp );
+ }
+ }
+ REG32(MPMR) |= PM_MODE_ENABLE_AUTOMATIC_POWER_DOWN;
+
+// #define PIN_MUX_SEL 0xb8000040
+ // Configure LED-SIG0/LED-SIG1/LED-SIG2/LED-SIG3/LED-PHASE0/LED-PHASE1/LED-PHASE2/LED-PHASE3 PAD as LED-SW
+
+#ifndef CONFIG_POCKET_ROUTER_SUPPORT
+ REG32(PIN_MUX_SEL) &= ~(0xFFFF);
+#endif
+
+#if defined(PATCH_GPIO_FOR_LED)
+ REG32(PIN_MUX_SEL) |= (0xFFFF);
+#endif
+
+#endif // end of defined(CONFIG_RTL_8196C)
+
+#if defined(CONFIG_RTL_8198)
+ REG32(MPMR) |= PM_MODE_ENABLE_AUTOMATIC_POWER_DOWN;
+#endif
+
+ return SUCCESS;
+}
+
+int32 rtl8651_setAsicPortPatternMatch(uint32 port, uint32 pattern, uint32 patternMask, int32 operation) {
+ //not for ext port
+ if(port>=RTL8651_PORT_NUMBER)
+ return FAILED;
+
+ if(pattern==0&&patternMask==0){
+ //bit 0~13 is reseved...
+ //if((READ_MEM32(PPMAR)&0x2000)==0) //system pattern match not enabled.
+ //return SUCCESS;
+ WRITE_MEM32(PPMAR,READ_MEM32(PPMAR)&~(1<<(port+26)));
+ if((READ_MEM32(PPMAR)&0xfc000000)==0)
+ WRITE_MEM32(PPMAR,READ_MEM32(PPMAR)&~(1<<13)); //turn off system pattern match switch.
+
+ return SUCCESS;
+ }
+ if(operation>3)
+ return FAILED; //valid operations: 0(drop), 1(mirror to cpu),2(fwd to cpu), 3(to mirror port)
+ WRITE_MEM32(PPMAR,READ_MEM32(PPMAR)|((1<<(port+26))|(1<<13))); //turn on system pattern match and turn on pattern match on indicated port.
+ WRITE_MEM32(PPMAR,(READ_MEM32(PPMAR) & (~(0x3<<(14+2*port))))|(operation<<(14+2*port))); //specify operation
+ WRITE_MEM32(PATP0+4*port,pattern);
+ WRITE_MEM32(MASKP0+4*port,patternMask);
+ return SUCCESS;
+}
+
+int32 rtl8651_getAsicPortPatternMatch(uint32 port, uint32 *pattern, uint32 *patternMask, int32 *operation)
+{
+ //not for ext port
+ if(port>=RTL8651_PORT_NUMBER)
+ return FAILED;
+ if(((READ_MEM32(PPMAR)& (1<<13))==0)||((READ_MEM32(PPMAR)& (1<<(26+port)))==0))
+ return FAILED;
+ if(pattern)
+ *pattern=READ_MEM32(PATP0+4*port);
+ if(patternMask)
+ *patternMask=READ_MEM32(MASKP0+4*port);
+ if(operation)
+ *operation=(READ_MEM32(PPMAR)>>(14+2*port))&0x3;
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl8651_setAsicSpanningEnable | Enable/disable ASIC spanning tree support
+@parm int8 | spanningTreeEnabled | TRUE to indicate spanning tree is enabled; FALSE to indicate spanning tree is disabled.
+@rvalue SUCCESS | Success
+@comm
+Global switch to enable or disable ASIC spanning tree support.
+If ASIC spanning tree support is enabled, further configuration would be refered by ASIC to prcoess packet forwarding / MAC learning.
+If ASIC spanning tree support is disabled, all MAC learning and packet forwarding would be done regardless of port state.
+Note that the configuration does not take effect for spanning tree BPDU CPU trapping. It is set in <p rtl8651_setAsicResvMcastAddrToCPU()>.
+@xref <p rtl8651_setAsicMulticastSpanningTreePortState()>, <p rtl865xC_setAsicSpanningTreePortState()>, <p rtl8651_getAsicMulticastSpanningTreePortState()>, <p rtl865xC_getAsicSpanningTreePortState()>
+ */
+int32 rtl8651_setAsicSpanningEnable(int8 spanningTreeEnabled)
+{
+ if(spanningTreeEnabled == TRUE)
+ {
+ WRITE_MEM32(MSCR,READ_MEM32(MSCR)|(EN_STP));
+ WRITE_MEM32(RMACR ,READ_MEM32(RMACR)|MADDR00);
+
+ }else
+ {
+ WRITE_MEM32(MSCR,READ_MEM32(MSCR)&~(EN_STP));
+ WRITE_MEM32(RMACR, READ_MEM32(RMACR)&~MADDR00);
+
+ }
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl8651_getAsicSpanningEnable | Getting the ASIC spanning tree support status
+@parm int8* | spanningTreeEnabled | The pointer to get the status of ASIC spanning tree configuration status.
+@rvalue FAILED | Failed
+@rvalue SUCCESS | Success
+@comm
+Get the ASIC global switch to enable or disable ASIC spanning tree support.
+The switch can be set by calling <p rtl8651_setAsicSpanningEnable()>
+@xref <p rtl8651_setAsicSpanningEnable()>, <p rtl8651_setAsicMulticastSpanningTreePortState()>, <p rtl865xC_setAsicSpanningTreePortState()>, <p rtl8651_getAsicMulticastSpanningTreePortState()>, <p rtl865xC_getAsicSpanningTreePortState()>
+ */
+int32 rtl8651_getAsicSpanningEnable(int8 *spanningTreeEnabled)
+{
+ if(spanningTreeEnabled == NULL)
+ return FAILED;
+ *spanningTreeEnabled = (READ_MEM32(MSCR)&(EN_STP)) == (EN_STP)? TRUE: FALSE;
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl865xC_setAsicSpanningTreePortState | Configure Spanning Tree Protocol Port State
+@parm uint32 | port | port number under consideration
+@parm uint32 | portState | Spanning tree port state: RTL8651_PORTSTA_DISABLED, RTL8651_PORTSTA_BLOCKING, RTL8651_PORTSTA_LISTENING, RTL8651_PORTSTA_LEARNING, RTL8651_PORTSTA_FORWARDING
+@rvalue SUCCESS | Success
+@rvalue FAILED | Failed
+@comm
+Config IEEE 802.1D spanning tree port sate into ASIC.
+ */
+int32 rtl865xC_setAsicSpanningTreePortState(uint32 port, uint32 portState)
+{
+ uint32 offset = port * 4;
+
+ if ( port >= RTL865XC_PORT_NUMBER )
+ return FAILED;
+
+ switch(portState)
+ {
+ case RTL8651_PORTSTA_DISABLED:
+ WRITE_MEM32( PCRP0 + offset, ( READ_MEM32( PCRP0 + offset ) & (~STP_PortST_MASK) ) | STP_PortST_DISABLE );
+ break;
+ case RTL8651_PORTSTA_BLOCKING:
+ case RTL8651_PORTSTA_LISTENING:
+ WRITE_MEM32( PCRP0 + offset, ( READ_MEM32( PCRP0 + offset ) & (~STP_PortST_MASK) ) | STP_PortST_BLOCKING );
+ break;
+ case RTL8651_PORTSTA_LEARNING:
+ WRITE_MEM32( PCRP0 + offset, ( READ_MEM32( PCRP0 + offset ) & (~STP_PortST_MASK) ) | STP_PortST_LEARNING );
+ break;
+ case RTL8651_PORTSTA_FORWARDING:
+ WRITE_MEM32( PCRP0 + offset, ( READ_MEM32( PCRP0 + offset ) & (~STP_PortST_MASK) ) | STP_PortST_FORWARDING );
+ break;
+ default:
+ return FAILED;
+ }
+
+ TOGGLE_BIT_IN_REG_TWICE(PCRP0 + offset, EnForceMode);
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl865xC_getAsicSpanningTreePortState | Retrieve Spanning Tree Protocol Port State
+@parm uint32 | port | port number under consideration
+@parm uint32 | portState | pointer to memory to store the port state
+@rvalue SUCCESS | Success
+@rvalue FAILED | Failed
+@comm
+Possible spanning tree port state: RTL8651_PORTSTA_DISABLED, RTL8651_PORTSTA_BLOCKING, RTL8651_PORTSTA_LISTENING, RTL8651_PORTSTA_LEARNING, RTL8651_PORTSTA_FORWARDING
+ */
+int32 rtl865xC_getAsicSpanningTreePortState(uint32 port, uint32 *portState)
+{
+ uint32 reg;
+ uint32 offset = port * 4;
+
+ if ( port >= RTL865XC_PORT_NUMBER || portState == NULL )
+ return FAILED;
+
+ reg = ( READ_MEM32( PCRP0 + offset ) & STP_PortST_MASK );
+
+ switch(reg)
+ {
+ case STP_PortST_DISABLE:
+ *portState = RTL8651_PORTSTA_DISABLED;
+ break;
+ case STP_PortST_BLOCKING:
+ *portState = RTL8651_PORTSTA_BLOCKING;
+ break;
+ case STP_PortST_LEARNING:
+ *portState = RTL8651_PORTSTA_LEARNING;
+ break;
+ case STP_PortST_FORWARDING:
+ *portState = RTL8651_PORTSTA_FORWARDING;
+ break;
+ default:
+ return FAILED;
+ }
+ return SUCCESS;
+
+}
+
+/*
+@func int32 | rtl8651_setAsicMulticastSpanningTreePortState | Configure Multicast Spanning Tree Protocol Port State
+@parm uint32 | port | port number under consideration
+@parm uint32 | portState | Spanning tree port state: RTL8651_PORTSTA_DISABLED, RTL8651_PORTSTA_BLOCKING, RTL8651_PORTSTA_LISTENING, RTL8651_PORTSTA_LEARNING, RTL8651_PORTSTA_FORWARDING
+@rvalue SUCCESS | Success
+@rvalue FAILED | Failed
+@comm
+In RTL865xC platform, Multicast spanning tree configuration is set by this API.
+@xref <p rtl865xC_setAsicSpanningTreePortState()>
+ */
+int32 rtl8651_setAsicMulticastSpanningTreePortState(uint32 port, uint32 portState)
+{
+#if 0 //Note: 96C/98 have remove these bits!!!
+ uint32 offset = port * 4;
+
+ if ( port >= RTL865XC_PORT_NUMBER )
+ {
+ return FAILED;
+ }
+
+ switch(portState)
+ {
+ case RTL8651_PORTSTA_DISABLED:
+ WRITE_MEM32( PCRP0 + offset, ( READ_MEM32( PCRP0 + offset ) & (~IPMSTP_PortST_MASK) ) | IPMSTP_PortST_DISABLE );
+ break;
+ case RTL8651_PORTSTA_BLOCKING:
+ case RTL8651_PORTSTA_LISTENING:
+ WRITE_MEM32( PCRP0 + offset, ( READ_MEM32( PCRP0 + offset ) & (~IPMSTP_PortST_MASK) ) | IPMSTP_PortST_BLOCKING );
+ break;
+ case RTL8651_PORTSTA_LEARNING:
+ WRITE_MEM32( PCRP0 + offset, ( READ_MEM32( PCRP0 + offset ) & (~IPMSTP_PortST_MASK) ) | IPMSTP_PortST_LEARNING );
+ break;
+ case RTL8651_PORTSTA_FORWARDING:
+ WRITE_MEM32( PCRP0 + offset, ( READ_MEM32( PCRP0 + offset ) & (~IPMSTP_PortST_MASK) ) | IPMSTP_PortST_FORWARDING );
+ break;
+ default:
+ return FAILED;
+ }
+
+ TOGGLE_BIT_IN_REG_TWICE(PCRP0 + offset,EnForceMode);
+#endif
+
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl8651_getAsicMulticastSpanningTreePortState | Retrieve Spanning Tree Protocol Port State
+@parm uint32 | port | port number under consideration
+@parm uint32 | portState | pointer to memory to store the port state
+@rvalue SUCCESS | Success
+@rvalue FAILED | Failed
+@comm
+In RTL865xC platform, Multicast spanning tree configuration is gotten by this API.
+@xref <p rtl865xC_getAsicSpanningTreePortState()>
+ */
+int32 rtl8651_getAsicMulticastSpanningTreePortState(uint32 port, uint32 *portState)
+{
+ uint32 reg;
+ uint32 offset = port * 4;
+
+ if ( port >= RTL865XC_PORT_NUMBER || portState == NULL )
+ return FAILED;
+
+ reg = ( READ_MEM32( PCRP0 + offset ) & IPMSTP_PortST_MASK );
+
+ switch(reg)
+ {
+ case IPMSTP_PortST_DISABLE:
+ *portState = RTL8651_PORTSTA_DISABLED;
+ break;
+ case IPMSTP_PortST_BLOCKING:
+ *portState = RTL8651_PORTSTA_BLOCKING;
+ break;
+ case IPMSTP_PortST_LEARNING:
+ *portState = RTL8651_PORTSTA_LEARNING;
+ break;
+ case IPMSTP_PortST_FORWARDING:
+ *portState = RTL8651_PORTSTA_FORWARDING;
+ break;
+ default:
+ return FAILED;
+ }
+ return SUCCESS;
+}
+
+/*=========================================
+ * ASIC DRIVER API: MDC/MDIO Control
+ *=========================================*/
+
+int32 rtl8651_getAsicEthernetPHYReg(uint32 phyId, uint32 regId, uint32 *rData)
+{
+ uint32 status;
+
+ WRITE_MEM32( MDCIOCR, COMMAND_READ | ( phyId << PHYADD_OFFSET ) | ( regId << REGADD_OFFSET ) );
+
+#if defined(CONFIG_RTL_8198)
+ if (REG32(REVR) == BSP_RTL8198_REVISION_A)
+ mdelay(10);
+#elif defined(CONFIG_RTL8196C_REVISION_B)
+ if (REG32(REVR) == RTL8196C_REVISION_A)
+ mdelay(10); //wei add, for 8196C revision A. mdio data read will delay 1 mdc clock.
+#endif
+
+ do { status = READ_MEM32( MDCIOSR ); } while ( ( status & MDC_STATUS ) != 0 );
+
+ status &= 0xffff;
+ *rData = status;
+
+ return SUCCESS;
+}
+
+int32 rtl8651_setAsicEthernetPHYReg(uint32 phyId, uint32 regId, uint32 wData)
+{
+ WRITE_MEM32( MDCIOCR, COMMAND_WRITE | ( phyId << PHYADD_OFFSET ) | ( regId << REGADD_OFFSET ) | wData );
+
+ while( ( READ_MEM32( MDCIOSR ) & MDC_STATUS ) != 0 ); /* wait until command complete */
+
+ return SUCCESS;
+}
+
+int32 rtl8651_getAsicEthernetPHYStatus(uint32 port, uint32 *rData)
+{
+ uint32 statCtrlReg1, phyid;
+
+ /* port number validation */
+ if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
+ {
+ if ( port > RTL8651_MAC_NUMBER )
+ {
+ return FAILED;
+ }
+ } else
+ {
+ if ( port > RTL8651_PHY_NUMBER )
+ {
+ return FAILED;
+ }
+ }
+
+ /* PHY id determination */
+ phyid = rtl8651AsicEthernetTable[port].phyId;
+
+ /* read current PHY reg 1*/
+ rtl8651_getAsicEthernetPHYReg( phyid, 1, &statCtrlReg1 );
+
+ /*assign value*/
+ *rData=statCtrlReg1;
+ return SUCCESS;
+}
+
+int32 rtl8651_restartAsicEthernetPHYNway(uint32 port)
+{
+ uint32 statCtrlReg0, phyid;
+
+ /* port number validation */
+ if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
+ {
+ if ( port > RTL8651_MAC_NUMBER )
+ {
+ return FAILED;
+ }
+ } else
+ {
+ if ( port > RTL8651_PHY_NUMBER )
+ {
+ return FAILED;
+ }
+ }
+
+ /* PHY id determination */
+ phyid = rtl8651AsicEthernetTable[port].phyId;
+
+ /* read current PHY reg 0 */
+ rtl8651_getAsicEthernetPHYReg( phyid, 0, &statCtrlReg0 );
+
+ /* enable 'restart Nway' bit */
+ statCtrlReg0 |= RESTART_AUTONEGO;
+
+ /* write PHY reg 0 */
+ rtl8651_setAsicEthernetPHYReg( phyid, 0, statCtrlReg0 );
+
+ return SUCCESS;
+}
+
+int32 rtl8651_setAsicEthernetPHYPowerDown( uint32 port, uint32 pwrDown )
+{
+ uint32 statCtrlReg0, phyid;
+
+ /* port number validation */
+ if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
+ {
+ if ( port > RTL8651_MAC_NUMBER )
+ {
+ return FAILED;
+ }
+ } else
+ {
+ if ( port > RTL8651_PHY_NUMBER )
+ {
+ return FAILED;
+ }
+ }
+
+ /* PHY id determination */
+ phyid = rtl8651AsicEthernetTable[port].phyId;
+
+ /* read current PHY reg 0 value */
+ rtl8651_getAsicEthernetPHYReg( phyid, 0, &statCtrlReg0 );
+
+ if ( pwrDown ){
+ REG32(PCRP0+port*4) |= EnForceMode;
+ REG32(PCRP0+port*4) &= ~ForceLink;
+ statCtrlReg0 |= POWER_DOWN;
+ }
+ else{
+ REG32(PCRP0+port*4) &= ~EnForceMode;
+ statCtrlReg0 &= ~POWER_DOWN;
+ }
+ /* write PHY reg 0 */
+ rtl8651_setAsicEthernetPHYReg( phyid, 0, statCtrlReg0 );
+
+ return SUCCESS;
+
+}
+
+int32 rtl8651_setAsicEthernetPHYAdvCapality(uint32 port, uint32 capality)
+{
+ uint32 statCtrlReg4, phyid;
+
+ /* port number validation */
+ if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
+ {
+ if ( port > RTL8651_MAC_NUMBER )
+ {
+ return FAILED;
+ }
+ } else
+ {
+ if ( port > RTL8651_PHY_NUMBER )
+ {
+ return FAILED;
+ }
+ }
+
+ /* PHY id determination */
+ phyid = rtl8651AsicEthernetTable[port].phyId;
+
+ /* read current PHY reg 4 value */
+ rtl8651_getAsicEthernetPHYReg( phyid, 4, &statCtrlReg4);
+
+ /*Clear Duplex and Speed bits*/
+ statCtrlReg4 &= ~(0xF<<5);
+
+ if (capality & (1<<DUPLEX_100M))
+ {
+ statCtrlReg4 |= (1<<8);
+ }
+ if (capality & (1<<HALF_DUPLEX_100M))
+ {
+ statCtrlReg4 |= (1<<7);
+ }
+ if (capality & (1<<DUPLEX_10M))
+ {
+ statCtrlReg4 |= (1<<6);
+ }
+ if (capality & (1<<HALF_DUPLEX_10M))
+ {
+ statCtrlReg4 |= (1<<5);
+ }
+ if(capality & (1<<PORT_AUTO))
+ {
+ /*Set All Duplex and Speed All Supported*/
+ statCtrlReg4 |=(0xF <<5);
+ }
+
+ /* write PHY reg 4 */
+ rtl8651_setAsicEthernetPHYReg( phyid, 4, statCtrlReg4 );
+
+ return SUCCESS;
+}
+int32 rtl8651_setAsicEthernetPHYSpeed( uint32 port, uint32 speed )
+{
+ uint32 statCtrlReg0, phyid;
+
+ /* port number validation */
+ if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
+ {
+ if ( port > RTL8651_MAC_NUMBER )
+ {
+ return FAILED;
+ }
+ } else
+ {
+ if ( port > RTL8651_PHY_NUMBER )
+ {
+ return FAILED;
+ }
+ }
+
+ /* PHY id determination */
+ phyid = rtl8651AsicEthernetTable[port].phyId;
+
+ /* read current PHY reg 0 value */
+ rtl8651_getAsicEthernetPHYReg( phyid, 0, &statCtrlReg0 );
+
+ if (0 == speed )
+ {
+ /*10M*/
+ statCtrlReg0 &= ~SPEED_SELECT_100M;
+ }
+ else if (1 == speed)
+ {
+ /*100M*/
+ statCtrlReg0 |= SPEED_SELECT_100M;
+ }
+ else if(2 == speed)
+ {
+ /*1000M*/
+ }
+
+ /* write PHY reg 0 */
+ rtl8651_setAsicEthernetPHYReg( phyid, 0, statCtrlReg0 );
+
+ return SUCCESS;
+
+}
+
+int32 rtl8651_setAsicEthernetPHYDuplex( uint32 port, uint32 duplex )
+{
+ uint32 statCtrlReg0, phyid;
+
+ /* port number validation */
+ if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
+ {
+ if ( port > RTL8651_MAC_NUMBER )
+ {
+ return FAILED;
+ }
+ } else
+ {
+ if ( port > RTL8651_PHY_NUMBER )
+ {
+ return FAILED;
+ }
+ }
+
+ /* PHY id determination */
+ phyid = rtl8651AsicEthernetTable[port].phyId;
+
+ /* read current PHY reg 0 value */
+ rtl8651_getAsicEthernetPHYReg( phyid, 0, &statCtrlReg0 );
+
+ if ( duplex )
+ statCtrlReg0 |= SELECT_FULL_DUPLEX;
+ else
+ statCtrlReg0 &= ~SELECT_FULL_DUPLEX;
+
+ /* write PHY reg 0 */
+ rtl8651_setAsicEthernetPHYReg( phyid, 0, statCtrlReg0 );
+
+ return SUCCESS;
+
+}
+
+int32 rtl8651_setAsicEthernetPHYAutoNeg( uint32 port, uint32 autoneg)
+{
+ uint32 statCtrlReg0, phyid;
+
+ /* port number validation */
+ if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
+ {
+ if ( port > RTL8651_MAC_NUMBER )
+ {
+ return FAILED;
+ }
+ } else
+ {
+ if ( port > RTL8651_PHY_NUMBER )
+ {
+ return FAILED;
+ }
+ }
+
+ /* PHY id determination */
+ phyid = rtl8651AsicEthernetTable[port].phyId;
+
+ /* read current PHY reg 0 value */
+ rtl8651_getAsicEthernetPHYReg( phyid, 0, &statCtrlReg0 );
+
+ if (autoneg)
+ statCtrlReg0 |= ENABLE_AUTONEGO;
+ else
+ statCtrlReg0 &= ~ENABLE_AUTONEGO;
+
+ /* write PHY reg 0 */
+ rtl8651_setAsicEthernetPHYReg( phyid, 0, statCtrlReg0 );
+
+ return SUCCESS;
+
+}
+
+int32 rtl865xC_setAsicPortPauseFlowControl(uint32 port, uint8 rxEn, uint8 txEn)
+{
+ uint32 offset = port<<2;
+ uint32 pauseFC = 0;
+
+ if(rxEn!=0)
+ pauseFC |= PauseFlowControlDtxErx;
+ if(txEn!=0)
+ pauseFC |= PauseFlowControlEtxDrx;
+
+ WRITE_MEM32(PCRP0+offset, (~(PauseFlowControl_MASK)&(READ_MEM32(PCRP0+offset)))|pauseFC);
+
+ TOGGLE_BIT_IN_REG_TWICE(PCRP0 + offset,EnForceMode);
+ return SUCCESS;
+}
+
+int32 rtl865xC_getAsicPortPauseFlowControl(uint32 port, uint8 *rxEn, uint8 *txEn)
+{
+ uint32 offset = port<<2;
+ uint32 pauseFC = 0;
+
+ pauseFC = ((PauseFlowControl_MASK)&(READ_MEM32(PCRP0+offset)));
+
+ if (pauseFC&PauseFlowControlDtxErx)
+ *rxEn = TRUE;
+
+ if (pauseFC&PauseFlowControlEtxDrx)
+ *txEn = TRUE;
+
+ return SUCCESS;
+}
+
+
+int32 rtl8651_asicEthernetCableMeterInit(void)
+{
+ rtlglue_printf("NOT YET\n");
+
+#if 0
+ uint32 old_value;
+ //set PHY6 Reg0 TxD latch internal clock phase
+ WRITE_MEM32(SWTAA, 0xbc8020c0);
+ WRITE_MEM32(TCR0,0x56);
+ WRITE_MEM32(SWTACR,ACTION_START | CMD_FORCE);
+ #ifndef RTL865X_TEST
+ while ( (READ_MEM32(SWTACR) & ACTION_MASK) != ACTION_DONE );//Wait for command done
+#endif /* RTL865X_TEST */
+ //set PHY7 Reg 5
+ WRITE_MEM32(SWTAA, 0xbc8020f4);
+ WRITE_MEM32(TCR0,0x4b68);
+ WRITE_MEM32(SWTACR,ACTION_START | CMD_FORCE);
+ #ifndef RTL865X_TEST
+ while ( (READ_MEM32(SWTACR) & ACTION_MASK) != ACTION_DONE );//Wait for command done
+#endif /* RTL865X_TEST */
+ //set PHY7 Reg 6
+ WRITE_MEM32(SWTAA, 0xbc8020f8);
+ WRITE_MEM32(TCR0,0x0380);
+ WRITE_MEM32(SWTACR,ACTION_START | CMD_FORCE);
+ #ifndef RTL865X_TEST
+ while ( (READ_MEM32(SWTACR) & ACTION_MASK) != ACTION_DONE );//Wait for command done
+#endif /* RTL865X_TEST */
+ old_value=READ_MEM32(0xbc8020fc);
+ //set PHY7 Reg 7
+ WRITE_MEM32(SWTAA, 0xbc8020fc);
+ WRITE_MEM32(TCR0,old_value|0x300);
+ WRITE_MEM32(SWTACR,ACTION_START | CMD_FORCE);
+ #ifndef RTL865X_TEST
+ while ( (READ_MEM32(SWTACR) & ACTION_MASK) != ACTION_DONE );//Wait for command done
+#endif /* RTL865X_TEST */
+#endif
+return SUCCESS;
+}
+
+
+/*=========================================
+ * ASIC DRIVER API: ETHERNET MII
+ *=========================================*/
+int32 rtl865xC_setAsicEthernetMIIMode(uint32 port, uint32 mode)
+{
+ if ( port != 0 && port != RTL8651_MII_PORTNUMBER )
+ return FAILED;
+ if ( mode != LINK_RGMII && mode != LINK_MII_MAC && mode != LINK_MII_PHY )
+ return FAILED;
+
+ if ( port == 0 )
+ {
+ /* MII port MAC interface mode configuration */
+ WRITE_MEM32( P0GMIICR, ( READ_MEM32( P0GMIICR ) & ~CFG_GMAC_MASK ) | ( mode << LINKMODE_OFFSET ) );
+ }
+ else
+ {
+ /* MII port MAC interface mode configuration */
+ WRITE_MEM32( P5GMIICR, ( READ_MEM32( P5GMIICR ) & ~CFG_GMAC_MASK ) | ( mode << LINKMODE_OFFSET ) );
+ }
+ return SUCCESS;
+
+}
+
+int32 rtl865xC_setAsicEthernetRGMIITiming(uint32 port, uint32 Tcomp, uint32 Rcomp)
+{
+ if ( port != 0 && port != RTL8651_MII_PORTNUMBER )
+ return FAILED;
+ if ( Tcomp < RGMII_TCOMP_0NS || Tcomp > RGMII_TCOMP_7NS || Rcomp < RGMII_RCOMP_0NS || Rcomp > RGMII_RCOMP_2DOT5NS )
+ return FAILED;
+
+ if ( port == 0 )
+ {
+ WRITE_MEM32(P0GMIICR, ( ( ( READ_MEM32(P0GMIICR) & ~RGMII_TCOMP_MASK ) | Tcomp ) & ~RGMII_RCOMP_MASK ) | Rcomp );
+ }
+ else
+ {
+ WRITE_MEM32(P5GMIICR, ( ( ( READ_MEM32(P5GMIICR) & ~RGMII_TCOMP_MASK ) | Tcomp ) & ~RGMII_RCOMP_MASK ) | Rcomp );
+ }
+
+ return SUCCESS;
+}
+
+/* For backward-compatible issue, this API is used to set MII port 5. */
+int32 rtl8651_setAsicEthernetMII(uint32 phyAddress, int32 mode, int32 enabled)
+{
+ /* Input validation */
+ if ( phyAddress < 0 || phyAddress > 31 )
+ return FAILED;
+ if ( mode != P5_LINK_RGMII && mode != P5_LINK_MII_MAC && mode != P5_LINK_MII_PHY )
+ return FAILED;
+
+ /* Configure driver level information about mii port 5 */
+ if ( enabled )
+ {
+ if ( miiPhyAddress >= 0 && miiPhyAddress != phyAddress )
+ return FAILED;
+
+ miiPhyAddress = phyAddress;
+ }
+ else
+ {
+ miiPhyAddress = -1;
+ }
+
+ /* MII port MAC interface mode configuration */
+ WRITE_MEM32( P5GMIICR, ( READ_MEM32( P5GMIICR ) & ~CFG_GMAC_MASK ) | ( mode << P5_LINK_OFFSET ) );
+
+ return SUCCESS;
+}
+
+int32 rtl8651_getAsicEthernetMII(uint32 *phyAddress)
+{
+ *phyAddress=miiPhyAddress;
+ return SUCCESS;
+}
+
+
+/*=========================================
+ * ASIC DRIVER API: Packet Scheduling Control Register
+ *=========================================*/
+/*
+@func int32 | rtl8651_setAsicPriorityDecision | set priority selection
+@parm uint32 | portpri | output queue decision priority assign for Port Based Priority.
+@parm uint32 | dot1qpri | output queue decision priority assign for 1Q Based Priority.
+@parm uint32 | dscppri | output queue decision priority assign for DSCP Based Priority
+@parm uint32 | aclpri | output queue decision priority assign for ACL Based Priority.
+@parm uint32 | natpri | output queue decision priority assign for NAT Based Priority.
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_setAsicPriorityDecision( uint32 portpri, uint32 dot1qpri, uint32 dscppri, uint32 aclpri, uint32 natpri )
+{
+ /* Invalid input parameter */
+ if ((portpri < 0) || (portpri > 0xF) || (dot1qpri < 0) || (dot1qpri > 0xF) ||
+ (dscppri < 0) || (dscppri > 0xF) || (aclpri < 0) || (aclpri > 0xF) ||
+ (natpri < 0) || (natpri > 0xF))
+ return FAILED;
+
+ WRITE_MEM32(QIDDPCR, (portpri << PBP_PRI_OFFSET) | (dot1qpri << BP8021Q_PRI_OFFSET) |
+ (dscppri << DSCP_PRI_OFFSET) | (aclpri << ACL_PRI_OFFSET) |
+ (natpri << NAPT_PRI_OFFSET));
+
+ return SUCCESS;
+}
+
+int32 rtl8651_setAsicQueueFlowControlConfigureRegister(enum PORTID port, enum QUEUEID queue, uint32 enable)
+{
+ switch (port)
+ {
+ case PHY0:
+ WRITE_MEM32(FCCR0, (READ_MEM32(FCCR0) & ~(0x1<<(queue+Q_P0_EN_FC_OFFSET))) | (enable << (queue+Q_P0_EN_FC_OFFSET))); break;
+ case PHY1:
+ WRITE_MEM32(FCCR0, (READ_MEM32(FCCR0) & ~(0x1<<(queue+Q_P1_EN_FC_OFFSET))) | (enable << (queue+Q_P1_EN_FC_OFFSET))); break;
+ case PHY2:
+ WRITE_MEM32(FCCR0, (READ_MEM32(FCCR0) & ~(0x1<<(queue+Q_P2_EN_FC_OFFSET))) | (enable << (queue+Q_P2_EN_FC_OFFSET))); break;
+ case PHY3:
+ WRITE_MEM32(FCCR0, (READ_MEM32(FCCR0) & ~(0x1<<(queue+Q_P3_EN_FC_OFFSET))) | (enable << (queue+Q_P3_EN_FC_OFFSET))); break;
+ case PHY4:
+ WRITE_MEM32(FCCR1, (READ_MEM32(FCCR1) & ~(0x1<<(queue+Q_P4_EN_FC_OFFSET))) | (enable << (queue+Q_P4_EN_FC_OFFSET))); break;
+ case PHY5:
+ WRITE_MEM32(FCCR1, (READ_MEM32(FCCR1) & ~(0x1<<(queue+Q_P5_EN_FC_OFFSET))) | (enable << (queue+Q_P5_EN_FC_OFFSET))); break;
+ case CPU:
+ WRITE_MEM32(FCCR1, (READ_MEM32(FCCR1) & ~(0x1<<(queue+Q_P6_EN_FC_OFFSET))) | (enable << (queue+Q_P6_EN_FC_OFFSET))); break;
+ default:
+ return FAILED;
+ }
+
+ return SUCCESS;
+}
+
+int32 rtl8651_getAsicQueueFlowControlConfigureRegister(enum PORTID port, enum QUEUEID queue, uint32 *enable)
+{
+ if (enable != NULL)
+ {
+ switch (port)
+ {
+ case PHY0:
+ *enable = (READ_MEM32(FCCR0) & (0x1<<(queue+Q_P0_EN_FC_OFFSET))) >> (queue+Q_P0_EN_FC_OFFSET); break;
+ case PHY1:
+ *enable = (READ_MEM32(FCCR0) & (0x1<<(queue+Q_P1_EN_FC_OFFSET))) >> (queue+Q_P1_EN_FC_OFFSET); break;
+ case PHY2:
+ *enable = (READ_MEM32(FCCR0) & (0x1<<(queue+Q_P2_EN_FC_OFFSET))) >> (queue+Q_P2_EN_FC_OFFSET); break;
+ case PHY3:
+ *enable = (READ_MEM32(FCCR0) & (0x1<<(queue+Q_P3_EN_FC_OFFSET))) >> (queue+Q_P3_EN_FC_OFFSET); break;
+ case PHY4:
+ *enable = (READ_MEM32(FCCR1) & (0x1<<(queue+Q_P4_EN_FC_OFFSET))) >> (queue+Q_P4_EN_FC_OFFSET); break;
+ case PHY5:
+ *enable = (READ_MEM32(FCCR1) & (0x1<<(queue+Q_P5_EN_FC_OFFSET))) >> (queue+Q_P5_EN_FC_OFFSET); break;
+ case CPU:
+ *enable = (READ_MEM32(FCCR1) & (0x1<<(queue+Q_P6_EN_FC_OFFSET))) >> (queue+Q_P6_EN_FC_OFFSET); break;
+ default:
+ return FAILED;
+ }
+ }
+
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl8651_setAsicLBParameter | set Leaky Bucket Paramters
+@parm uint32 | token | Token is used for adding budget in each time slot.
+@parm uint32 | tick | Tick is used for time slot size slot.
+@parm uint32 | hiThreshold | leaky bucket token high-threshold register
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_setAsicLBParameter( uint32 token, uint32 tick, uint32 hiThreshold )
+{
+ WRITE_MEM32( ELBPCR, (READ_MEM32(ELBPCR) & ~(Token_MASK | Tick_MASK)) | (token << Token_OFFSET) | (tick << Tick_OFFSET));
+ WRITE_MEM32( ELBTTCR, (READ_MEM32(ELBTTCR) & ~0xFFFF/*L2_MASK*/) | (hiThreshold << L2_OFFSET));
+ WRITE_MEM32( ILBPCR2, (READ_MEM32(ILBPCR2) & ~(ILB_feedToken_MASK|ILB_Tick_MASK)) | (token << ILB_feedToken_OFFSET) | (tick << ILB_Tick_OFFSET) );
+ return SUCCESS;
+}
+
+
+/*
+@func int32 | rtl8651_getAsicLBParameter | get Leaky Bucket Paramters
+@parm uint32* | pToken | pointer to return token
+@parm uint32* | pTick | pointer to return tick
+@parm uint32* | pHiThreshold | pointer to return hiThreshold
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_getAsicLBParameter( uint32* pToken, uint32* pTick, uint32* pHiThreshold )
+{
+ uint32 regValue;
+
+ regValue = READ_MEM32(ELBPCR);
+
+ if (pToken != NULL)
+ *pToken = (regValue & Token_MASK) >> Token_OFFSET;
+ if (pTick != NULL)
+ *pTick = (regValue & Tick_MASK) >> Tick_OFFSET;
+ if (pHiThreshold != NULL)
+ *pHiThreshold = (READ_MEM32(ELBTTCR) & 0xFF) >> L2_OFFSET;
+
+ return SUCCESS;
+}
+
+
+/*
+@func int32 | rtl8651_setAsicQueueRate | set per queue rate
+@parm enum PORTID | port | the port number
+@parm enum QUEUEID | queueid | the queue ID wanted to set
+@parm uint32 | pprTime | Peak Packet Rate (in times of APR). 0~6: PPR = (2^pprTime)*apr. 7: disable PPR
+@parm uint32 | aprBurstSize | Bucket Burst Size of Average Packet Rate (unit: 1KByte). 0xFF: disable
+@parm uint32 | apr | Average Packet Rate (unit: 64Kbps). 0x3FFF: unlimited rate
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_setAsicQueueRate( enum PORTID port, enum QUEUEID queueid, uint32 pprTime, uint32 aprBurstSize, uint32 apr )
+{
+ uint32 reg1, regValue;
+
+ if ((port < PHY0) || (port > CPU) || (queueid < QUEUE0) || (queueid > QUEUE5))
+ return FAILED;
+
+ reg1 = P0Q0RGCR + (port * 0x18) + (queueid * 0x4); /* offset to get corresponding register */
+
+ regValue = READ_MEM32(reg1) & ~(PPR_MASK | L1_MASK | APR_MASK);
+ regValue |= ((pprTime << PPR_OFFSET) | (aprBurstSize << L1_OFFSET) | (apr << APR_OFFSET));
+ WRITE_MEM32( reg1, regValue);
+ return SUCCESS;
+}
+
+
+/*
+@func int32 | rtl8651_getAsicQueueRate | get per queue rate configuration
+@parm enum PORTID | port | the port number
+@parm enum QUEUEID | queueid | the queue ID wanted to set
+@parm uint32* | pPprTime | pointer to Peak Packet Rate (in times of APR). 0~6: PPR = (2^pprTime)*apr. 7: disable PPR
+@parm uint32* | pAprBurstSize | pointer to APR Burst Size (unit: 1KBytes). 0xff: disable
+@parm uint32* | pApr | pointer to Average Packet Rate (unit: 64Kbps). 0x3FFF: unlimited rate
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_getAsicQueueRate( enum PORTID port, enum QUEUEID queueid, uint32* pPprTime, uint32* pAprBurstSize, uint32* pApr )
+{
+ uint32 reg1, regValue;
+
+ if ((port < PHY0) || (port > CPU) || (queueid < QUEUE0) || (queueid > QUEUE5))
+ return FAILED;
+
+ reg1 = P0Q0RGCR + (port * 0x18) + (queueid * 0x4); /* offset to get corresponding register */
+ regValue = READ_MEM32(reg1);
+
+ if (pPprTime != NULL)
+ *pPprTime = (regValue & PPR_MASK) >> PPR_OFFSET;
+ if (pAprBurstSize != NULL)
+ *pAprBurstSize = (regValue & L1_MASK) >> L1_OFFSET;
+ if (pApr != NULL)
+ *pApr = (regValue & APR_MASK) >> APR_OFFSET;
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl8651_setAsicPortIngressBandwidth | set per-port total ingress bandwidth
+@parm enum PORTID | port | the port number
+@parm uint32 | bandwidth | the total ingress bandwidth (unit: 16Kbps), 0:disable
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_setAsicPortIngressBandwidth( enum PORTID port, uint32 bandwidth)
+{
+ uint32 reg1;
+
+ /* For ingress bandwidth control, its only for PHY0 to PHY5 */
+ if ((port < PHY0) || (port > PHY5))
+ return FAILED;
+
+ reg1 = IBCR0 + ((port / 2) * 0x04); /* offset to get corresponding register */
+
+ if ( port % 2)
+ { /* ODD-port */
+ WRITE_MEM32( reg1, ((READ_MEM32(reg1) & ~(IBWC_ODDPORT_MASK)) | ((bandwidth << IBWC_ODDPORT_OFFSET) & IBWC_ODDPORT_MASK)));
+ } else
+ { /* EVEN-port */
+ WRITE_MEM32( reg1, ((READ_MEM32(reg1) & ~(IBWC_EVENPORT_MASK)) | ((bandwidth << IBWC_EVENPORT_OFFSET) & IBWC_EVENPORT_MASK)));
+ }
+
+
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl8651_getAsicPortIngressBandwidth | get per-port total ingress bandwidth
+@parm enum PORTID | port | the port number
+@parm uint32* | pBandwidth | pointer to the returned total ingress bandwidth (unit: 16Kbps), 0:disable
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_getAsicPortIngressBandwidth( enum PORTID port, uint32* pBandwidth )
+{
+ uint32 reg1, regValue;
+
+ /* For ingress bandwidth control, its only for PHY0 to PHY5 */
+ if ((port < PHY0) || (port > PHY5))
+ return FAILED;
+
+ reg1 = IBCR0 + ((port / 2) * 0x04); /* offset to get corresponding register */
+
+ regValue = READ_MEM32(reg1);
+
+ if (pBandwidth != NULL)
+ {
+ *pBandwidth = (port % 2)?
+ /* Odd port */((regValue & IBWC_ODDPORT_MASK) >> IBWC_ODDPORT_OFFSET):
+ /* Even port */((regValue & IBWC_EVENPORT_MASK) >> IBWC_EVENPORT_OFFSET);
+ }
+
+ return SUCCESS;
+}
+
+
+/*
+@func int32 | rtl8651_setAsicPortEgressBandwidth | set per-port total egress bandwidth
+@parm enum PORTID | port | the port number
+@parm uint32 | bandwidth | the total egress bandwidth (unit: 64kbps). 0x3FFF: disable
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_setAsicPortEgressBandwidth( enum PORTID port, uint32 bandwidth )
+{
+ uint32 reg1;
+
+ if ((port < PHY0) || (port > CPU))
+ return FAILED;
+
+ reg1 = WFQRCRP0 + (port * 0xC); /* offset to get corresponding register */
+ WRITE_MEM32( reg1, (READ_MEM32(reg1) & ~(APR_MASK)) | (bandwidth << APR_OFFSET));
+
+ return SUCCESS;
+}
+
+
+/*
+@func int32 | rtl8651_getAsicPortEgressBandwidth | get per-port total egress bandwidth
+@parm enum PORTID | port | the port number
+@parm uint32* | pBandwidth | pointer to the returned total egress bandwidth (unit: 64kbps). 0x3FFF: disable
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_getAsicPortEgressBandwidth( enum PORTID port, uint32* pBandwidth )
+{
+ uint32 reg1, regValue;
+
+ if ((port < PHY0) || (port > CPU))
+ return FAILED;
+
+ reg1 = WFQRCRP0 + (port * 0xC); /* offset to get corresponding register */
+ regValue = READ_MEM32(reg1);
+
+ if (pBandwidth != NULL)
+ *pBandwidth = (regValue & APR_MASK) >> APR_OFFSET;
+
+ return SUCCESS;
+}
+
+
+/*
+@func int32 | rtl8651_setAsicQueueWeight | set WFQ weighting
+@parm enum PORTID | port | the port number
+@parm enum QUEUEID | queueid | the queue ID wanted to set
+@parm enum QUEUETYPE | queueType | the specified queue type
+@parm uint32 | weight | the weight value wanted to set (valid:0~127)
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_setAsicQueueWeight( enum PORTID port, enum QUEUEID queueid, enum QUEUETYPE queueType, uint32 weight )
+{
+ uint32 reg1, regOFFSET, regValue;
+
+ if ((port < PHY0) || (port > CPU) || (queueid < QUEUE0) || (queueid > QUEUE5))
+ return FAILED;
+ if ((queueType < STR_PRIO) || (queueType > WFQ_PRIO))
+ return FAILED;
+
+ reg1 = WFQWCR0P0 + (port * 0xC) + ((queueid >> 2) * 0x4); /* offset to get corresponding register */
+ regOFFSET = (queueid % 4) * 0x8; /* used to offset register value */
+
+ regValue = READ_MEM32(reg1) & ~((WEIGHT0_MASK | SCHE0_MASK) << regOFFSET);
+ regValue |= ((queueType << (SCHE0_OFFSET + regOFFSET)) | (weight << (WEIGHT0_OFFSET + regOFFSET)));
+ WRITE_MEM32( reg1, regValue);
+ return SUCCESS;
+}
+
+
+/*
+@func int32 | rtl8651_getAsicQueueWeight | get WFQ weighting
+@parm enum PORTID | port | the port number
+@parm enum QUEUEID | queueid | the queue ID wanted to set
+@parm enum QUEUETYPE* | pQueueType | pointer to the returned queue type
+@parm uint32* | pWeight | pointer to the returned weight value
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_getAsicQueueWeight( enum PORTID port, enum QUEUEID queueid, enum QUEUETYPE *pQueueType, uint32 *pWeight )
+{
+ uint32 reg1, regOFFSET, regValue;
+
+ if ((port < PHY0) || (port > CPU) || (queueid < QUEUE0) || (queueid > QUEUE5))
+ return FAILED;
+
+ reg1 = WFQWCR0P0 + (port * 0xC) + ((queueid >> 2) * 0x4); /* offset to get corresponding register */
+ regOFFSET = (queueid % 4) * 0x8; /* used to offset register value */
+ regValue = READ_MEM32(reg1);
+
+ if (pQueueType != NULL)
+ *pQueueType = ((regValue & (SCHE0_MASK << regOFFSET)) >> SCHE0_OFFSET) >> regOFFSET;
+ if (pWeight != NULL)
+ *pWeight = ((regValue & (WEIGHT0_MASK << regOFFSET)) >> WEIGHT0_OFFSET) >> regOFFSET;
+
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl8651_setAsicOutputQueueNumber | set output queue number for a specified port
+@parm enum PORTID | port | the port number (valid: physical ports(0~5) and CPU port(6) )
+@parm enum QUEUENUM | qnum | the output queue number
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_setAsicOutputQueueNumber( enum PORTID port, enum QUEUENUM qnum )
+{
+ /* Invalid input parameter */
+
+ enum QUEUENUM orgQnum;
+
+ if ((port < PHY0) || (port > CPU) || (qnum < QNUM1) || (qnum > QNUM6))
+ return FAILED;
+
+ orgQnum = (READ_MEM32(QNUMCR) >> (3*port)) & 0x7;
+ WRITE_MEM32(QNUMCR, (READ_MEM32(QNUMCR) & ~(0x7 << (3*port))) | (qnum << (3*port)));
+
+ if (qnum==6)
+ {
+ if (orgQnum!=6)
+ _rtl865x_setQosThresholdByQueueIdx(QNUM_IDX_6);
+ }
+ else if (qnum>3)
+ {
+ if((orgQnum==6)||orgQnum<4)
+ _rtl865x_setQosThresholdByQueueIdx(QNUM_IDX_45);
+ }
+ else
+ {
+ if(orgQnum>3)
+ _rtl865x_setQosThresholdByQueueIdx(QNUM_IDX_123);
+ }
+
+ return SUCCESS;
+}
+
+
+/*
+@func int32 | rtl8651_getAsicOutputQueueNumber | get output queue number for a specified port
+@parm enum PORTID | port | the port number (valid: physical ports(0~5) and CPU port(6) )
+@parm enum QUEUENUM | qnum | the output queue number
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_getAsicOutputQueueNumber( enum PORTID port, enum QUEUENUM *qnum )
+{
+ /* Invalid input parameter */
+ if ((port < PHY0) || (port > CPU))
+ return FAILED;
+
+ if (qnum != NULL)
+ *qnum = (READ_MEM32(QNUMCR) >> (3*port)) & 0x7;
+
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl8651_setAsicPriorityToQIDMappingTable | set user priority to QID mapping table parameter
+@parm enum QUEUENUM | qnum | the output queue number
+@parm enum PRIORITYVALUE | priority | priority
+@parm enum QUEUEID | qid | queue ID
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_setAsicPriorityToQIDMappingTable( enum QUEUENUM qnum, enum PRIORITYVALUE priority, enum QUEUEID qid )
+{
+ /* Invalid input parameter */
+ if ((priority < PRI0) || (priority > PRI7))
+ return FAILED;
+ if ((qid < QUEUE0) || (qid > QUEUE5))
+ return FAILED;
+
+ switch (qnum)
+ {
+ case QNUM1:
+ WRITE_MEM32(UPTCMCR0, (READ_MEM32(UPTCMCR0) & ~(0x7 << (priority*3))) | (qid << (priority*3))); break;
+ case QNUM2:
+ WRITE_MEM32(UPTCMCR1, (READ_MEM32(UPTCMCR1) & ~(0x7 << (priority*3))) | (qid << (priority*3))); break;
+ case QNUM3:
+ WRITE_MEM32(UPTCMCR2, (READ_MEM32(UPTCMCR2) & ~(0x7 << (priority*3))) | (qid << (priority*3))); break;
+ case QNUM4:
+ WRITE_MEM32(UPTCMCR3, (READ_MEM32(UPTCMCR3) & ~(0x7 << (priority*3))) | (qid << (priority*3))); break;
+ case QNUM5:
+ WRITE_MEM32(UPTCMCR4, (READ_MEM32(UPTCMCR4) & ~(0x7 << (priority*3))) | (qid << (priority*3))); break;
+ case QNUM6:
+ WRITE_MEM32(UPTCMCR5, (READ_MEM32(UPTCMCR5) & ~(0x7 << (priority*3))) | (qid << (priority*3))); break;
+ default:
+ return FAILED;
+ }
+
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl8651_setAsicCPUPriorityToQIDMappingTable | set user priority to QID mapping table parameter based on destination port & priority information
+@parm enum PORTID | port | the destination port
+@parm enum PRIORITYVALUE | priority | priority
+@parm enum QUEUEID | qid | queue ID
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_setAsicCPUPriorityToQIDMappingTable( enum PORTID port, enum PRIORITYVALUE priority, enum QUEUEID qid )
+{
+ uint32 reg;
+ /* Invalid input parameter */
+ if ((priority < PRI0) || (priority > PRI7))
+ return FAILED;
+ if ((qid < QUEUE0) || (qid > QUEUE5))
+ return FAILED;
+ if (port<CPU || port>MULTEXT)
+ return FAILED;
+
+ reg = (uint32)(((uint32*)CPUQIDMCR0) + (port-CPU));
+
+ WRITE_MEM32(reg, (READ_MEM32(reg) & ~(0x7 << (priority<<2))) | (qid << (priority<<2)));
+
+ return SUCCESS;
+}
+
+
+int32 rtl8651_setAsicSystemBasedFlowControlRegister(uint32 sharedON, uint32 sharedOFF, uint32 fcON, uint32 fcOFF, uint32 drop)
+{
+ /* Invalid input parameter */
+ if ((sharedON > (SDC_FCON_MASK >> SDC_FCON_OFFSET)) ||
+ (sharedOFF > (S_DSC_FCOFF_MASK >> S_DSC_FCOFF_OFFSET)) ||
+ (fcON > ((S_Max_SBuf_FCON_MASK >> S_Max_SBuf_FCON_OFFSET))) ||
+ (fcOFF > (S_Max_SBuf_FCOFF_MASK >> S_Max_SBuf_FCOFF_OFFSET)) ||
+ (drop > (S_DSC_RUNOUT_MASK >> S_DSC_RUNOUT_OFFSET)))
+ return FAILED;
+
+ WRITE_MEM32(SBFCR0, (READ_MEM32(SBFCR0) & ~(S_DSC_RUNOUT_MASK)) | (drop << S_DSC_RUNOUT_OFFSET));
+ WRITE_MEM32(SBFCR1, (READ_MEM32(SBFCR1) & ~(S_DSC_FCON_MASK | S_DSC_FCOFF_MASK)) | ( fcON<< S_DSC_FCON_OFFSET) | (fcOFF << S_DSC_FCOFF_OFFSET));
+ WRITE_MEM32(SBFCR2, (READ_MEM32(SBFCR2) & ~(S_Max_SBuf_FCON_MASK | S_Max_SBuf_FCOFF_MASK)) | (sharedON << S_Max_SBuf_FCON_OFFSET) | (sharedOFF << S_Max_SBuf_FCOFF_OFFSET));
+ return SUCCESS;
+}
+
+int32 rtl8651_setAsicQueueDescriptorBasedFlowControlRegister(enum PORTID port, enum QUEUEID queue, uint32 fcON, uint32 fcOFF)
+{
+ /* Invalid input parameter */
+ if ((port < PHY0) || (port > CPU))
+ return FAILED;
+
+ if ((fcON > (QG_DSC_FCON_MASK >> QG_DSC_FCON_OFFSET)) ||
+ (fcOFF > (QG_DSC_FCOFF_MASK >> QG_DSC_FCOFF_OFFSET)))
+ return FAILED;
+
+
+ switch (queue)
+ {
+ case QUEUE0:
+ WRITE_MEM32((QDBFCRP0G0+(port*0xC)), (READ_MEM32(QDBFCRP0G0+(port*0xC)) & ~(QG_DSC_FCON_MASK | QG_DSC_FCOFF_MASK)) | (fcON << QG_DSC_FCON_OFFSET) | (fcOFF << QG_DSC_FCOFF_OFFSET));
+ break;
+ case QUEUE1:
+ case QUEUE2:
+ case QUEUE3:
+ case QUEUE4:
+ WRITE_MEM32((QDBFCRP0G1+(port*0xC)), (READ_MEM32(QDBFCRP0G1+(port*0xC)) & ~(QG_DSC_FCON_MASK | QG_DSC_FCOFF_MASK)) | (fcON << QG_DSC_FCON_OFFSET) | (fcOFF << QG_DSC_FCOFF_OFFSET));
+ break;
+ case QUEUE5:
+ WRITE_MEM32((QDBFCRP0G2+(port*0xC)), (READ_MEM32(QDBFCRP0G2+(port*0xC)) & ~(QG_DSC_FCON_MASK | QG_DSC_FCOFF_MASK)) | (fcON << QG_DSC_FCON_OFFSET) | (fcOFF << QG_DSC_FCOFF_OFFSET));
+ break;
+ default:
+ return FAILED;
+ }
+ return SUCCESS;
+}
+
+int32 rtl8651_setAsicQueuePacketBasedFlowControlRegister(enum PORTID port, enum QUEUEID queue, uint32 fcON, uint32 fcOFF)
+{
+ /* Invalid input parameter */
+ if ((port < PHY0) || (port > CPU))
+ return FAILED;
+
+ if ((fcON > (QG_QLEN_FCON_MASK>> QG_QLEN_FCON_OFFSET)) ||
+ (fcOFF > (QG_QLEN_FCOFF_MASK >> QG_QLEN_FCOFF_OFFSET)))
+ return FAILED;
+
+ switch (queue)
+ {
+ case QUEUE0:
+ WRITE_MEM32((QPKTFCRP0G0+(port*0xC)), (READ_MEM32(QPKTFCRP0G0+(port*0xC)) & ~(QG_QLEN_FCON_MASK | QG_QLEN_FCOFF_MASK)) | (fcON << QG_QLEN_FCON_OFFSET) | (fcOFF << QG_QLEN_FCOFF_OFFSET));
+ break;
+ case QUEUE1:
+ case QUEUE2:
+ case QUEUE3:
+ case QUEUE4:
+ WRITE_MEM32((QPKTFCRP0G1+(port*0xC)), (READ_MEM32(QPKTFCRP0G1+(port*0xC)) & ~(QG_QLEN_FCON_MASK | QG_QLEN_FCOFF_MASK)) | (fcON << QG_QLEN_FCON_OFFSET) | (fcOFF << QG_QLEN_FCOFF_OFFSET));
+ break;
+ case QUEUE5:
+ WRITE_MEM32((QPKTFCRP0G2+(port*0xC)), (READ_MEM32(QPKTFCRP0G2+(port*0xC)) & ~(QG_QLEN_FCON_MASK | QG_QLEN_FCOFF_MASK)) | (fcON << QG_QLEN_FCON_OFFSET) | (fcOFF << QG_QLEN_FCOFF_OFFSET));
+ break;
+ default:
+ return FAILED;
+ }
+
+ return SUCCESS;
+}
+
+int32 rtl8651_setAsicPortBasedFlowControlRegister(enum PORTID port, uint32 fcON, uint32 fcOFF)
+{
+ /* Invalid input parameter */
+ if ((fcON > (P_MaxDSC_FCON_MASK >> P_MaxDSC_FCON_OFFSET)) ||
+ (fcOFF > (P_MaxDSC_FCOFF_MASK >> P_MaxDSC_FCOFF_OFFSET)))
+ return FAILED;
+
+ switch (port)
+ {
+ case PHY0:
+ WRITE_MEM32(PBFCR0, (READ_MEM32(PBFCR0) & ~(P_MaxDSC_FCON_MASK | P_MaxDSC_FCOFF_MASK)) | (fcON << P_MaxDSC_FCON_OFFSET) | (fcOFF << P_MaxDSC_FCOFF_OFFSET)); break;
+ case PHY1:
+ WRITE_MEM32(PBFCR1, (READ_MEM32(PBFCR1) & ~(P_MaxDSC_FCON_MASK | P_MaxDSC_FCOFF_MASK)) | (fcON << P_MaxDSC_FCON_OFFSET) | (fcOFF << P_MaxDSC_FCOFF_OFFSET)); break;
+ case PHY2:
+ WRITE_MEM32(PBFCR2, (READ_MEM32(PBFCR2) & ~(P_MaxDSC_FCON_MASK | P_MaxDSC_FCOFF_MASK)) | (fcON << P_MaxDSC_FCON_OFFSET) | (fcOFF << P_MaxDSC_FCOFF_OFFSET)); break;
+ case PHY3:
+ WRITE_MEM32(PBFCR3, (READ_MEM32(PBFCR3) & ~(P_MaxDSC_FCON_MASK | P_MaxDSC_FCOFF_MASK)) | (fcON << P_MaxDSC_FCON_OFFSET) | (fcOFF << P_MaxDSC_FCOFF_OFFSET)); break;
+ case PHY4:
+ WRITE_MEM32(PBFCR4, (READ_MEM32(PBFCR4) & ~(P_MaxDSC_FCON_MASK | P_MaxDSC_FCOFF_MASK)) | (fcON << P_MaxDSC_FCON_OFFSET) | (fcOFF << P_MaxDSC_FCOFF_OFFSET)); break;
+ case PHY5:
+ WRITE_MEM32(PBFCR5, (READ_MEM32(PBFCR5) & ~(P_MaxDSC_FCON_MASK | P_MaxDSC_FCOFF_MASK)) | (fcON << P_MaxDSC_FCON_OFFSET) | (fcOFF << P_MaxDSC_FCOFF_OFFSET)); break;
+ case CPU:
+ WRITE_MEM32(PBFCR6, (READ_MEM32(PBFCR6) & ~(P_MaxDSC_FCON_MASK | P_MaxDSC_FCOFF_MASK)) | (fcON << P_MaxDSC_FCON_OFFSET) | (fcOFF << P_MaxDSC_FCOFF_OFFSET)); break;
+ default:
+ return FAILED;
+ }
+
+ return SUCCESS;
+}
+
+int32 rtl8651_setAsicPerQueuePhysicalLengthGapRegister(uint32 gap)
+{
+ /* Invalid input parameter */
+ if (gap > (QLEN_GAP_MASK >> QLEN_GAP_OFFSET))
+ return FAILED;
+
+ WRITE_MEM32(PQPLGR, (READ_MEM32(PQPLGR) & ~(QLEN_GAP_MASK)) | (gap << QLEN_GAP_OFFSET));
+ return SUCCESS;
+}
+
+
+static int32 _rtl865x_setQosThresholdByQueueIdx(uint32 qidx)
+{
+ /* Set the threshold value for qos sytem */
+ int32 retval;
+ int32 i,j;
+
+ printk("Set threshould idx %d\n", qidx);
+ retval = rtl8651_setAsicSystemBasedFlowControlRegister(outputQueuePara[qidx].systemSBFCON, outputQueuePara[qidx].systemSBFCOFF, outputQueuePara[qidx].systemFCON, outputQueuePara[qidx].systemFCOFF, outputQueuePara[qidx].drop);
+ if (retval!= SUCCESS)
+ {
+ rtlglue_printf("Set System Base Flow Control Para Error.\n");
+ return retval;
+ }
+
+ for(i =0; i < RTL8651_OUTPUTQUEUE_SIZE; i++)
+ {
+ retval = rtl8651_setAsicQueueDescriptorBasedFlowControlRegister(0, i, outputQueuePara[qidx].queueDescFCON, outputQueuePara[qidx].queueDescFCOFF);
+ if (retval!= SUCCESS)
+ {
+ rtlglue_printf("Set Queue Descriptor Base Flow Control Para Error.\n");
+ return retval;
+ }
+ for(j=1;j<=CPU;j++)
+ rtl8651_setAsicQueueDescriptorBasedFlowControlRegister(PHY0+j, i, outputQueuePara[qidx].queueDescFCON, outputQueuePara[qidx].queueDescFCOFF);
+
+
+ retval = rtl8651_setAsicQueuePacketBasedFlowControlRegister(0, i, outputQueuePara[qidx].queuePktFCON, outputQueuePara[qidx].queuePktFCOFF);
+ if (retval!= SUCCESS)
+ {
+ rtlglue_printf("Set Queue Packet Base Flow Control Para Error.\n");
+ return retval;
+ }
+ for(j=1;j<=CPU;j++)
+ rtl8651_setAsicQueuePacketBasedFlowControlRegister(PHY0+j, i, outputQueuePara[qidx].queuePktFCON, outputQueuePara[qidx].queuePktFCOFF);
+
+ }
+
+ retval = rtl8651_setAsicPortBasedFlowControlRegister(0, outputQueuePara[qidx].portFCON, outputQueuePara[qidx].portFCOFF);
+ if (retval!= SUCCESS)
+ {
+ rtlglue_printf("Set Port Base Flow Control Para Error.\n");
+ return retval;
+ }
+ for(j=1;j<=CPU;j++)
+ rtl8651_setAsicPortBasedFlowControlRegister(PHY0+j, outputQueuePara[qidx].portFCON, outputQueuePara[qidx].portFCOFF);
+
+ retval = rtl8651_setAsicPerQueuePhysicalLengthGapRegister(outputQueuePara[qidx].gap);
+ if (retval!= SUCCESS)
+ {
+ rtlglue_printf("Set Queue Physical Lenght Gap Reg Error.\n");
+ return retval;
+ }
+
+ return SUCCESS;
+}
+
+#if defined(CONFIG_RTL_HW_QOS_SUPPORT)
+static int32 _rtl865xC_QM_init( void )
+{
+#if defined(RTL865X_TEST) || defined(RTL865X_MODEL_USER) || defined(RTL865X_MODEL_KERNEL)
+#else
+ uint32 originalDescGetReady;
+ int32 cnt;
+
+ rtlglue_printf("Start to initiate QM\n");
+
+ /*
+ 1. Get the original decriptor usage for QM.
+ */
+ rtl865xC_lockSWCore();
+
+ _rtl865xC_QM_orgDescUsage = 0; /* by default, set it to 0 */
+
+ do
+ {
+ int32 idx;
+
+ originalDescGetReady = TRUE; /* by default, set it to TRUE */
+ cnt = 0;
+
+ for ( idx = 0 ; idx < RTL865XC_QM_DESC_READROBUSTPARAMETER ; idx ++ )
+ {
+ uint32 currentDescUsage;
+
+ currentDescUsage = (READ_MEM32( GDSR0 ) & USEDDSC_MASK) >> USEDDSC_OFFSET;
+ if ( ( currentDescUsage == 0 /* It's impossible */ ) ||
+ (( _rtl865xC_QM_orgDescUsage != 0 ) &&
+ ( currentDescUsage != _rtl865xC_QM_orgDescUsage) ) )
+ {
+ rtlglue_printf("INIT swCore descriptor count Failed : (%d [%d])\n", currentDescUsage, _rtl865xC_QM_orgDescUsage);
+ originalDescGetReady = FALSE;
+ } else
+ {
+ _rtl865xC_QM_orgDescUsage = currentDescUsage;
+ }
+ }
+ cnt++;
+ } while ( originalDescGetReady != TRUE && cnt< 200000);
+
+ if (_rtl865xC_QM_orgDescUsage<12)
+ _rtl865xC_QM_orgDescUsage = 12;
+
+ rtl865xC_unLockSWCore();
+#endif
+ return SUCCESS;
+}
+#endif
+
+/*
+@func int32 | rtl865xC_waitForOutputQueueEmpty | wait until output queue empty
+@rvalue SUCCESS |
+@comm
+ The function will not return until all the output queue is empty.
+ */
+int32 rtl865xC_waitForOutputQueueEmpty(void)
+{
+#if defined(CONFIG_RTL_HW_QOS_SUPPORT)
+ int32 currentDescUsage;
+ int32 cnt, i;
+
+ #if defined(CONFIG_RTL_8196C)
+ while((READ_MEM32(LAGCR1)&OUTPUTQUEUE_STAT_MASK_CR1)!=OUTPUTQUEUE_STAT_MASK_CR1);
+ #else
+ while ( ((READ_MEM32(LAGCR0)&OUTPUTQUEUE_STAT_MASK_CR0)^OUTPUTQUEUE_STAT_MASK_CR0) ||
+ ((READ_MEM32(LAGCR1)&OUTPUTQUEUE_STAT_MASK_CR1)^OUTPUTQUEUE_STAT_MASK_CR1) );
+ #endif
+
+ /* There are something wrong when check the input queue is empty or not */
+ currentDescUsage = (READ_MEM32( GDSR0 ) & USEDDSC_MASK) >> USEDDSC_OFFSET;
+ cnt = (currentDescUsage-_rtl865xC_QM_orgDescUsage)<<10;
+ i = 0;
+ while ( ((currentDescUsage = ((READ_MEM32( GDSR0 ) & USEDDSC_MASK) >> USEDDSC_OFFSET)) > _rtl865xC_QM_orgDescUsage) && (i<cnt) )
+ {
+#if 0
+ if (net_ratelimit() && i<120)
+ rtlglue_printf("Waiting for input queue empty. ==> currently used %d.\n", (currentDescUsage-_rtl865xC_QM_orgDescUsage));
+#else
+ ; /* do nothing */
+#endif
+ i++;
+ }
+#endif
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl8651_resetAsicOutputQueue | reset output queue
+@rvalue SUCCESS |
+@comm
+ When reset is done, all queue pointer will be reset to the initial base address.
+ */
+
+ int32 rtl8651_resetAsicOutputQueue(void)
+ {
+ uint32 i;
+ uint32 scr, pauseTicks;
+
+ WRITE_MEM32(QRR, 0x0);
+ scr = (REG32(SCCR) & 0x00000070) >> 4;
+ switch( scr )
+ {
+ case 0: pauseTicks = 12500000; break;
+ case 1: pauseTicks = 25000000; break;
+ case 2: pauseTicks = 31250000; break;
+ case 3: pauseTicks = 32500000; break;
+ case 4: pauseTicks = 33750000; break;
+ case 5: pauseTicks = 35000000; break;
+ case 6: pauseTicks = 36250000; break;
+ case 7: pauseTicks = 37500000; break;
+ default:pauseTicks = 25000000; break;
+ }
+ /* waiting 500ms */
+
+ pauseTicks = pauseTicks<<2;
+
+ for(i=pauseTicks;i<0;i--)
+ {
+ i = i;
+ }
+
+ WRITE_MEM32(QRR, 0x1);
+
+ for(i=pauseTicks;i<0;i--)
+ {
+ i = i;
+ }
+
+ WRITE_MEM32(QRR, 0x0);
+
+ return SUCCESS;
+ }
+
+
+/*
+ * _rtl8651_syncToAsicEthernetBandwidthControl()
+ *
+ * Sync SW bandwidth control () configuration to ASIC:
+ *
+ *
+ * _rtl865xB_BandwidthCtrlPerPortConfiguration -----> Translate from RTL865xB Index to ACTUAL
+ * token count in RTL865xC
+ * |
+ * ---------
+ * |
+ * _rtl865xB_BandwidthCtrlMultiplier ---- Translate using ---->*
+ * RTL865xB's mechanism |
+ * |
+ * ---------------------
+ * |
+ * -- > Actual Token count which need to set to ASIC.
+ * => Set it to ASIC if value in SW is different from ASIC.
+ *
+*/
+static void _rtl8651_syncToAsicEthernetBandwidthControl(void)
+{
+ uint32 port;
+ uint32 cfgTypeIdx;
+ int32 retval;
+
+ for ( port = 0 ; port < RTL8651_PORT_NUMBER ; port ++ )
+ {
+ for ( cfgTypeIdx = 0 ; cfgTypeIdx < _RTL865XB_BANDWIDTHCTRL_CFGTYPE ; cfgTypeIdx ++ )
+ {
+ uint32 currentSwBandwidthCtrlBasicSetting;
+ uint32 currentSwBandwidthCtrlMultiplier;
+ uint32 currentSwBandwidthCtrlSetting;
+ uint32 currentAsicBandwidthCtrlSetting;
+
+ /*
+ We would check for rate and _rtl865xB_BandwidthCtrlMultiplier for the rate-multiply.
+
+ In RTL865xB, the bits definition is as below.
+
+ SWTECR
+
+ bit 14(x8) bit 15 (x4) Result
+ =============================================
+ 0 0 x1
+ 0 1 x4
+ 1 0 x8
+ 1 1 x8
+ */
+ if (_rtl865xB_BandwidthCtrlMultiplier & _RTL865XB_BANDWIDTHCTRL_X8)
+ { /* case {b'10, b'11} */
+ currentSwBandwidthCtrlMultiplier = 8;
+ } else if ( _rtl865xB_BandwidthCtrlMultiplier & _RTL865XB_BANDWIDTHCTRL_X4)
+ { /* case {b'01} */
+ currentSwBandwidthCtrlMultiplier = 4;
+ } else
+ { /* case {b'00} */
+ currentSwBandwidthCtrlMultiplier = 1;
+ }
+
+ /* Calculate Current SW configuration : 0 : Full Rate */
+ /* Mix BASIC setting and Multiplier -> to get the ACTUAL bandwidth setting */
+
+ currentSwBandwidthCtrlBasicSetting = ((_rtl865xC_BandwidthCtrlNum[_rtl865xB_BandwidthCtrlPerPortConfiguration[port][cfgTypeIdx]])*(currentSwBandwidthCtrlMultiplier));
+ currentSwBandwidthCtrlSetting = (cfgTypeIdx == 0)?
+ /* Ingress */
+ (((currentSwBandwidthCtrlBasicSetting%RTL865XC_INGRESS_16KUNIT)<(RTL865XC_INGRESS_16KUNIT>>1))?(currentSwBandwidthCtrlBasicSetting/RTL865XC_INGRESS_16KUNIT):((currentSwBandwidthCtrlBasicSetting/RTL865XC_INGRESS_16KUNIT)+1)):
+ /* Egress */
+ (((currentSwBandwidthCtrlBasicSetting%RTL865XC_EGRESS_64KUNIT)<(RTL865XC_EGRESS_64KUNIT>>1))?(currentSwBandwidthCtrlBasicSetting/RTL865XC_EGRESS_64KUNIT):((currentSwBandwidthCtrlBasicSetting/RTL865XC_EGRESS_64KUNIT)+1));
+
+ /* Get Current ASIC configuration */
+ retval = (cfgTypeIdx == 0)?
+ /* Ingress */
+ (rtl8651_getAsicPortIngressBandwidth( port,
+ &currentAsicBandwidthCtrlSetting)):
+ /* Egress */
+ (rtl8651_getAsicPortEgressBandwidth( port,
+ &currentAsicBandwidthCtrlSetting));
+
+ if ( retval != SUCCESS )
+ {
+ assert(0);
+ goto out;
+ }
+
+ /* SYNC configuration to HW if the configuration is different */
+ if ( (!( (currentSwBandwidthCtrlSetting) == 0 && (currentAsicBandwidthCtrlSetting == 0x3fff) ) /* for FULL Rate case */) ||
+ ( currentSwBandwidthCtrlSetting != currentAsicBandwidthCtrlSetting ))
+ {
+#if 0
+ if (cfgTypeIdx==0)
+ {
+ rtlglue_printf("set ingress bandwidth port %d, %d.\n", port, (currentSwBandwidthCtrlSetting == 0)?
+ (0 /* For Ingress Bandwidth control, 0 means "disabled" */):
+ (currentSwBandwidthCtrlSetting));
+ }
+ else
+ {
+ rtlglue_printf("set ingress bandwidth port %d, %d.\n", port, (currentSwBandwidthCtrlSetting == 0)?
+ (0x3fff /* For Egress Bandwidth control, 0x3fff means "disabled" */):
+ (currentSwBandwidthCtrlSetting));
+ }
+#endif
+ retval = (cfgTypeIdx == 0)?
+ /* Ingress */
+ (rtl8651_setAsicPortIngressBandwidth( port,
+ (currentSwBandwidthCtrlSetting == 0)?
+ (0 /* For Ingress Bandwidth control, 0 means "disabled" */):
+ (currentSwBandwidthCtrlSetting)) ):
+ /* Egress */
+ (rtl8651_setAsicPortEgressBandwidth( port,
+ (currentSwBandwidthCtrlSetting == 0)?
+ (0x3fff /* For Egress Bandwidth control, 0x3fff means "disabled" */):
+ (currentSwBandwidthCtrlSetting)) );
+
+ if ( retval != SUCCESS )
+ {
+ assert(0);
+ goto out;
+ }
+ }
+
+ }
+ }
+out:
+ return;
+}
+
+
+/*
+@func int32 | rtl8651_setAsicEthernetBandwidthControl | set ASIC per-port total ingress bandwidth
+@parm uint32 | port | the port number
+@parm int8 | input | Ingress or egress control to <p port>
+@parm uint32 | rate | rate to set.
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+The <p rate> can be set to several different values:
+BW_FULL_RATE
+BW_128K
+BW_256K
+BW_512K
+BW_1M
+BW_2M
+BW_4M
+BW_8M
+
+Note: This function is backward compatible to RTL865xB.
+ */
+int32 rtl8651_setAsicEthernetBandwidthControl(uint32 port, int8 input, uint32 rate)
+{
+ uint32 *currentConfig_p;
+
+ if ( port >= RTL8651_PORT_NUMBER )
+ {
+ goto err;
+ }
+
+ switch ( rate )
+ {
+ case BW_FULL_RATE:
+ case BW_128K:
+ case BW_256K:
+ case BW_512K:
+ case BW_1M:
+ case BW_2M:
+ case BW_4M:
+ case BW_8M:
+ break;
+ default:
+ goto err;
+ }
+
+ currentConfig_p = &(_rtl865xB_BandwidthCtrlPerPortConfiguration[port][(input)?0 /* Ingress */:1 /* Egress */]);
+
+ /* We just need to re-config HW when it's updated */
+ if ( *currentConfig_p != rate )
+ {
+ /* Update configuration table */
+ *currentConfig_p = rate;
+
+ /* sync the configuration to ASIC */
+ _rtl8651_syncToAsicEthernetBandwidthControl();
+ }
+
+ return SUCCESS;
+err:
+ return FAILED;
+}
+
+
+int32 rtl8651_setAsicFlowControlRegister(uint32 port, uint32 enable)
+{
+ uint32 phyid, statCtrlReg4;
+
+ if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
+ {
+ if ( port > RTL8651_MAC_NUMBER )
+ {
+ return FAILED;
+ }
+ } else
+ {
+ if ( port > RTL8651_PHY_NUMBER )
+ {
+ return FAILED;
+ }
+ }
+ /* phy id determination */
+ phyid = rtl8651AsicEthernetTable[port].phyId;
+
+ /* Read */
+ rtl8651_getAsicEthernetPHYReg( phyid, 4, &statCtrlReg4 );
+
+ if ( enable && ( statCtrlReg4 & CAPABLE_PAUSE ) == 0 )
+ {
+ statCtrlReg4 |= CAPABLE_PAUSE;
+ }
+ else if ( enable == 0 && ( statCtrlReg4 & CAPABLE_PAUSE ) )
+ {
+ statCtrlReg4 &= ~CAPABLE_PAUSE;
+ }
+ else
+ return SUCCESS; /* The configuration does not change. Do nothing. */
+
+ rtl8651_setAsicEthernetPHYReg( phyid, 4, statCtrlReg4 );
+
+ /* restart N-way. */
+ rtl8651_restartAsicEthernetPHYNway(port);
+
+ return SUCCESS;
+}
+
+int32 rtl8651_getAsicFlowControlRegister(uint32 port, uint32 *enable)
+{
+ uint32 phyid, statCtrlReg4;
+
+ if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
+ {
+ if ( port > RTL8651_MAC_NUMBER )
+ {
+ return FAILED;
+ }
+ } else
+ {
+ if ( port > RTL8651_PHY_NUMBER )
+ {
+ return FAILED;
+ }
+ }
+ /* phy id determination */
+ phyid = rtl8651AsicEthernetTable[port].phyId;
+
+ /* Read */
+ rtl8651_getAsicEthernetPHYReg( phyid, 4, &statCtrlReg4 );
+
+ *enable = ( statCtrlReg4 & CAPABLE_PAUSE )? TRUE: FALSE;
+
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl8651_setAsicSystemInputFlowControlRegister | Set System input queue flow control register
+@parm uint32 | fcON | Threshold for Flow control OFF
+@parm uint32 | fcOFF | Threshold for Flow control ON
+@rvalue SUCCESS |
+@comm
+Set input-queue flow control threshold on RTL865xC platform.
+ */
+int32 rtl8651_setAsicSystemInputFlowControlRegister(uint32 fcON, uint32 fcOFF)
+{
+ /* Check the correctness */
+ if ( (fcON > ( IQ_DSC_FCON_MASK >> IQ_DSC_FCON_OFFSET )) ||
+ (fcOFF > ( IQ_DSC_FCOFF_MASK >> IQ_DSC_FCOFF_OFFSET )) )
+ {
+ return FAILED;
+ }
+
+ /* Write the flow control threshold value into ASIC */
+ WRITE_MEM32( IQFCTCR,
+ ( (READ_MEM32(IQFCTCR) & ~(IQ_DSC_FCON_MASK | IQ_DSC_FCOFF_MASK)) |
+ (fcON << IQ_DSC_FCON_OFFSET) |
+ (fcOFF << IQ_DSC_FCOFF_OFFSET)) );
+ return SUCCESS;
+}
+/*
+@func int32 | rtl8651_getAsicSystemInputFlowControlRegister | Get System input queue flow control register
+@parm uint32* | fcON | pointer to get Threshold for Flow control OFF
+@parm uint32* | fcOFF | pointer to get Threshold for Flow control ON
+@rvalue SUCCESS |
+@comm
+Set input-queue flow control threshold on RTL865xC platform.
+ */
+int32 rtl8651_getAsicSystemInputFlowControlRegister(uint32 *fcON, uint32 *fcOFF)
+{
+ uint32 iqfctcr;
+
+ iqfctcr = READ_MEM32( IQFCTCR );
+
+ if ( fcON )
+ {
+ *fcON = ( iqfctcr & IQ_DSC_FCON_MASK ) >> IQ_DSC_FCON_OFFSET;
+ }
+
+ if ( fcOFF )
+ {
+ *fcOFF = ( iqfctcr & IQ_DSC_FCOFF_MASK ) >> IQ_DSC_FCOFF_OFFSET;
+ }
+
+ return SUCCESS;
+}
+
+
+int32 rtl865xC_setAsicEthernetForceModeRegs(uint32 port, uint32 enForceMode, uint32 forceLink, uint32 forceSpeed, uint32 forceDuplex)
+{
+ uint32 offset = port * 4;
+ uint32 PCR = READ_MEM32( PCRP0 + offset );
+
+ if (rtl8651_tblAsicDrvPara.externalPHYProperty & RTL8651_TBLASIC_EXTPHYPROPERTY_PORT5_RTL8211B)
+ {
+ if ( port > RTL8651_MAC_NUMBER )
+ {
+ return FAILED;
+ }
+ } else
+ {
+ if ( port > RTL8651_PHY_NUMBER )
+ {
+ return FAILED;
+ }
+ }
+
+ PCR &= ~EnForceMode;
+ PCR &= ~ForceLink;
+ PCR &= ~ForceSpeedMask;
+ PCR &= ~ForceDuplex;
+
+ if ( enForceMode )
+ {
+ PCR |= EnForceMode;
+
+#if defined(CONFIG_RTL_8196C) || defined(CONFIG_RTL_8198)
+ //ForceMode with polling link status, disable Auto-Negotiation but polling phy's link status
+ PCR |= PollLinkStatus;
+#endif
+
+ if ( forceLink )
+ PCR |= ForceLink;
+
+ if ( forceSpeed == 2 )
+ PCR |= ForceSpeed1000M;
+ else if ( forceSpeed == 1 )
+ PCR |= ForceSpeed100M;
+ else
+ PCR |= ForceSpeed10M;
+
+ if ( forceDuplex )
+ PCR |= ForceDuplex;
+ }
+
+ WRITE_MEM32( PCRP0 + offset, PCR );
+ mdelay(10);
+ TOGGLE_BIT_IN_REG_TWICE(PCRP0 + offset,EnForceMode);
+ return SUCCESS;
+
+}
+
+
+#define MULTICAST_STORM_CONTROL 1
+#define BROADCAST_STORM_CONTROL 2
+#define RTL865XC_MAXALLOWED_BYTECOUNT 30360 /* Used for BSCR in RTL865xC. Means max allowable byte count for 10Mbps port */
+
+static int32 rtl865xC_setBrdcstStormCtrlRate(uint32 percentage)
+{
+ uint32 rate = RTL865XC_MAXALLOWED_BYTECOUNT * percentage / 100;
+
+ WRITE_MEM32( BSCR, rate );
+ return SUCCESS;
+}
+
+
+static int32 rtl8651_perPortStormControl(uint32 type, uint32 portNum, uint32 enable)
+{
+ uint32 regAddress;
+ uint32 oldRegValue;
+ uint32 newRegValue;
+ uint32 totalExtPortNum=3;
+
+ if(portNum>=RTL8651_PORT_NUMBER + totalExtPortNum)
+ {
+ rtlglue_printf("wrong port number\n");
+ return FAILED;
+ }
+
+ regAddress=PCRP0 + portNum * 4;
+
+ oldRegValue=READ_MEM32(regAddress);
+
+ newRegValue=oldRegValue;
+
+ if((type & BROADCAST_STORM_CONTROL) !=0)
+ {
+ if(enable == TRUE)
+ {
+ newRegValue = newRegValue |ENBCSC |BCSC_ENBROADCAST;
+ }
+
+ if(enable==FALSE)
+ {
+ newRegValue = newRegValue & (~BCSC_ENBROADCAST);
+ }
+
+ }
+
+ if((type & MULTICAST_STORM_CONTROL) !=0)
+ {
+ if(enable == TRUE)
+ {
+ newRegValue = newRegValue | ENBCSC |BCSC_ENMULTICAST;
+ }
+
+ if(enable==FALSE)
+ {
+ newRegValue = newRegValue & (~BCSC_ENMULTICAST);
+ }
+
+ }
+
+ if((newRegValue & (BCSC_ENMULTICAST |BCSC_ENBROADCAST ))==0)
+ {
+ /*no needn't storm control*/
+ newRegValue = newRegValue & (~ENBCSC);
+ }
+
+ if(newRegValue!=oldRegValue)
+ {
+ WRITE_MEM32(regAddress, newRegValue);
+ }
+
+ TOGGLE_BIT_IN_REG_TWICE(regAddress,EnForceMode);
+
+ return SUCCESS;
+
+
+}
+
+int32 rtl865x_setStormControl(uint32 type,uint32 enable,uint32 percentage)
+{
+ uint32 port;
+ uint32 totalExtPortNum=3;
+ for ( port = 0; port < RTL8651_PORT_NUMBER + totalExtPortNum; port++ )
+ {
+ if(enable==TRUE)
+ {
+ /*speed unit Mbps*/
+ if(percentage>100)
+ {
+ rtl865xC_setBrdcstStormCtrlRate(100);
+ }
+ else
+ {
+ rtl865xC_setBrdcstStormCtrlRate(percentage);
+ }
+
+ rtl8651_perPortStormControl(type, port, TRUE);
+ }
+ else
+ {
+ rtl865xC_setBrdcstStormCtrlRate(100);
+ rtl8651_perPortStormControl(type, port, FALSE);
+
+ }
+
+ }
+
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl8651_setAsic802D1xMacBaseAbility | set 802.1x mac based ability
+@parm enum PORTID | port | the port number (physical port: 0~5, extension port: 6~8)
+@parm uint32* | isEnable | 1: enabled, 0: disabled.
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_setAsic802D1xMacBaseAbility( enum PORTID port, uint32 isEnable )
+{
+ /* Invalid input parameter */
+ if ((port < PHY0) || (port > EXT2))
+ return FAILED;
+
+ /* Invalid input parameter */
+ if ((isEnable != TRUE) && (isEnable != FALSE))
+ return FAILED;
+
+ switch (port)
+ {
+ case PHY0:
+ WRITE_MEM32(DOT1XMACCR, isEnable == TRUE ? (READ_MEM32(DOT1XMACCR) | ( Dot1xMAC_P0En)):
+ (READ_MEM32(DOT1XMACCR) & ~( Dot1xMAC_P0En)));
+ break;
+
+ case PHY1:
+ WRITE_MEM32(DOT1XMACCR, isEnable == TRUE ? (READ_MEM32(DOT1XMACCR) | ( Dot1xMAC_P1En)):
+ (READ_MEM32(DOT1XMACCR) & ~( Dot1xMAC_P1En)));
+ break;
+
+ case PHY2:
+ WRITE_MEM32(DOT1XMACCR, isEnable == TRUE ? (READ_MEM32(DOT1XMACCR) | ( Dot1xMAC_P2En)):
+ (READ_MEM32(DOT1XMACCR) & ~( Dot1xMAC_P2En)));
+ break;
+
+ case PHY3:
+ WRITE_MEM32(DOT1XMACCR, isEnable == TRUE ? (READ_MEM32(DOT1XMACCR) | ( Dot1xMAC_P3En)):
+ (READ_MEM32(DOT1XMACCR) & ~( Dot1xMAC_P3En)));
+ break;
+
+ case PHY4:
+ WRITE_MEM32(DOT1XMACCR, isEnable == TRUE ? (READ_MEM32(DOT1XMACCR) | ( Dot1xMAC_P4En)):
+ (READ_MEM32(DOT1XMACCR) & ~( Dot1xMAC_P4En)));
+ break;
+
+ case PHY5:
+ WRITE_MEM32(DOT1XMACCR, isEnable == TRUE ? (READ_MEM32(DOT1XMACCR) | ( Dot1xMAC_P5En)):
+ (READ_MEM32(DOT1XMACCR) & ~( Dot1xMAC_P5En)));
+ break;
+
+ case CPU:
+ WRITE_MEM32(DOT1XMACCR, isEnable == TRUE ? (READ_MEM32(DOT1XMACCR) | ( Dot1xMAC_P6En)):
+ (READ_MEM32(DOT1XMACCR) & ~( Dot1xMAC_P6En)));
+ break;
+
+ case EXT1:
+ WRITE_MEM32(DOT1XMACCR, isEnable == TRUE ? (READ_MEM32(DOT1XMACCR) | ( Dot1xMAC_P7En)):
+ (READ_MEM32(DOT1XMACCR) & ~( Dot1xMAC_P7En)));
+ break;
+
+ case EXT2:
+ WRITE_MEM32(DOT1XMACCR, isEnable == TRUE ? (READ_MEM32(DOT1XMACCR) | ( Dot1xMAC_P8En)):
+ (READ_MEM32(DOT1XMACCR) & ~( Dot1xMAC_P8En)));
+ break;
+
+ case EXT3:
+ return FAILED;
+
+ case MULTEXT:
+ return FAILED;
+
+ }
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl8651_setAsic802D1xMacBaseDirection | set 802.1x mac based direction
+@parm enum uint32 | dir | OperCOnntrolledDirections for MAC-Based ACCESS Control. 0:BOTH, 1:IN
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_setAsic802D1xMacBaseDirection(int32 dir)
+{
+
+
+ /* Invalid input parameter */
+ if ((dir != Dot1xMAC_OPDIR_IN) && (dir != Dot1xMAC_OPDIR_BOTH))
+ {
+ return FAILED;
+ }
+
+ if(dir == Dot1xMAC_OPDIR_IN)
+ {
+ WRITE_MEM32(DOT1XMACCR,(READ_MEM32(DOT1XMACCR)) |Dot1xMAC_OPDIR);
+ }
+ else
+ {
+ WRITE_MEM32(DOT1XMACCR,(READ_MEM32(DOT1XMACCR)) &(~Dot1xMAC_OPDIR));
+ }
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl8651_setAsicGuestVlanProcessControl | set guest vlan process control
+@parm enum uint32 | process |default process for unauthenticated client (00~11)<<12
+@rvalue SUCCESS
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_setAsicGuestVlanProcessControl( uint32 process)
+{
+ /* Invalid input parameter */
+ if((process < Dot1xUNAUTHBH_DROP) || (process > Dot1xUNAUTHBH_RESERVED))
+ return FAILED;
+
+ WRITE_MEM32(GVGCR, ((READ_MEM32(GVGCR)) & 0x0fff) | process);
+
+ return SUCCESS;
+}
+
+#if defined(CONFIG_RTL_QOS_8021P_SUPPORT)
+/*
+@func int32 | rtl8651_setAsicDot1qAbsolutelyPriority | set 802.1Q absolutely priority
+@parm enum PRIORITYVALUE | srcpriority | priority value
+@parm enum PRIORITYVALUE | priority | absolute priority value
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_setAsicDot1qAbsolutelyPriority( enum PRIORITYVALUE srcpriority, enum PRIORITYVALUE priority )
+{
+ /* Invalid input parameter */
+ if ((srcpriority < PRI0) || (srcpriority > PRI7) || (priority < PRI0) || (priority > PRI7))
+ return FAILED;
+
+ switch (srcpriority)
+ {
+ case PRI0:
+ WRITE_MEM32(LPTM8021Q, (READ_MEM32(LPTM8021Q) & ~(EN_8021Q2LTMPRI0_MASK)) | (priority << EN_8021Q2LTMPRI0)); break;
+ case PRI1:
+ WRITE_MEM32(LPTM8021Q, (READ_MEM32(LPTM8021Q) & ~(EN_8021Q2LTMPRI1_MASK)) | (priority << EN_8021Q2LTMPRI1)); break;
+ case PRI2:
+ WRITE_MEM32(LPTM8021Q, (READ_MEM32(LPTM8021Q) & ~(EN_8021Q2LTMPRI2_MASK)) | (priority << EN_8021Q2LTMPRI2)); break;
+ case PRI3:
+ WRITE_MEM32(LPTM8021Q, (READ_MEM32(LPTM8021Q) & ~(EN_8021Q2LTMPRI3_MASK)) | (priority << EN_8021Q2LTMPRI3)); break;
+ case PRI4:
+ WRITE_MEM32(LPTM8021Q, (READ_MEM32(LPTM8021Q) & ~(EN_8021Q2LTMPRI4_MASK)) | (priority << EN_8021Q2LTMPRI4)); break;
+ case PRI5:
+ WRITE_MEM32(LPTM8021Q, (READ_MEM32(LPTM8021Q) & ~(EN_8021Q2LTMPRI5_MASK)) | (priority << EN_8021Q2LTMPRI5)); break;
+ case PRI6:
+ WRITE_MEM32(LPTM8021Q, (READ_MEM32(LPTM8021Q) & ~(EN_8021Q2LTMPRI6_MASK)) | (priority << EN_8021Q2LTMPRI6)); break;
+ case PRI7:
+ WRITE_MEM32(LPTM8021Q, (READ_MEM32(LPTM8021Q) & ~(EN_8021Q2LTMPRI7_MASK)) | (priority << EN_8021Q2LTMPRI7)); break;
+ }
+
+ return SUCCESS;
+}
+
+
+/*
+@func int32 | rtl8651_getAsicDot1qAbsolutelyPriority | get 802.1Q absolutely priority
+@parm enum PRIORITYVALUE | srcpriority | priority value
+@parm enum PRIORITYVALUE* | pPriority | pPriority will return the absolute priority value
+@rvalue SUCCESS |
+@rvalue FAILED | invalid parameter
+@comm
+ */
+int32 rtl8651_getAsicDot1qAbsolutelyPriority( enum PRIORITYVALUE srcpriority, enum PRIORITYVALUE *pPriority )
+{
+
+ /* Invalid input parameter */
+ if ((srcpriority < PRI0) || (srcpriority > PRI7))
+ return FAILED;
+
+ if (pPriority != NULL)
+ {
+ switch (srcpriority)
+ {
+ case PRI0:
+ *pPriority = (READ_MEM32(LPTM8021Q) & EN_8021Q2LTMPRI0_MASK) >> EN_8021Q2LTMPRI0; break;
+ case PRI1:
+ *pPriority = (READ_MEM32(LPTM8021Q) & EN_8021Q2LTMPRI1_MASK) >> EN_8021Q2LTMPRI1; break;
+ case PRI2:
+ *pPriority = (READ_MEM32(LPTM8021Q) & EN_8021Q2LTMPRI2_MASK) >> EN_8021Q2LTMPRI2; break;
+ case PRI3:
+ *pPriority = (READ_MEM32(LPTM8021Q) & EN_8021Q2LTMPRI3_MASK) >> EN_8021Q2LTMPRI3; break;
+ case PRI4:
+ *pPriority = (READ_MEM32(LPTM8021Q) & EN_8021Q2LTMPRI4_MASK) >> EN_8021Q2LTMPRI4; break;
+ case PRI5:
+ *pPriority = (READ_MEM32(LPTM8021Q) & EN_8021Q2LTMPRI5_MASK) >> EN_8021Q2LTMPRI5; break;
+ case PRI6:
+ *pPriority = (READ_MEM32(LPTM8021Q) & EN_8021Q2LTMPRI6_MASK) >> EN_8021Q2LTMPRI6; break;
+ case PRI7:
+ *pPriority = (READ_MEM32(LPTM8021Q) & EN_8021Q2LTMPRI7_MASK) >> EN_8021Q2LTMPRI7; break;
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+/*
+@func int32 | rtl8651_flushAsicDot1qAbsolutelyPriority | set 802.1Q absolutely priority the default value 0
+@parm void
+@rvalue SUCCESS |
+@comm
+ */
+int32 rtl8651_flushAsicDot1qAbsolutelyPriority(void)
+{
+ WRITE_MEM32(LPTM8021Q, 0);
+ return SUCCESS;
+}
+#endif
+
+#ifdef CONFIG_RTL_LINKCHG_PROCESS
+/*
+@func int32 | rtl8651_updateAsicLinkAggregatorLMPR | Arrange the table which maps hashed index to port.
+@parm uint32 | portMask | Specify the port mask for the aggregator.
+@rvalue SUCCESS | Update the mapping table successfully.
+@rvalue FAILED | When the port mask is invalid, return FAILED
+@comm
+RTL865x provides an aggregator port. This API updates the table which maps hashed index to port.
+If portmask = 0: clear all aggregation port mappings.
+Rearrange policy is round-robin. ie. if port a,b,c is in portmask, then hash block 0~7's port number is a,b,c,a,b,c,a,b
+*/
+int32 rtl8651_updateAsicLinkAggregatorLMPR(int32 portmask)
+{
+ uint32 hIdx, portIdx, reg;
+
+ /* Clear all mappings */
+ WRITE_MEM32( LAGHPMR0, 0 );
+
+ if ( portmask == 0 )
+ {
+ return SUCCESS;
+ }
+
+ reg = 0;
+ portIdx = 0;
+ for ( hIdx = 0; hIdx < RTL865XC_LAGHASHIDX_NUMBER; hIdx++ )
+ {
+ while ( ( ( 1 << portIdx ) & portmask ) == 0 ) /* Don't worry about infinite loop because portmask won't be 0. */
+ {
+ portIdx = ( portIdx + 1 ) % ( RTL8651_PORT_NUMBER + rtl8651_totalExtPortNum );
+ }
+
+ reg |= ( portIdx << ( hIdx * LAG_HASHIDX_BITNUM ) );
+ portIdx = ( portIdx + 1 ) % ( RTL8651_PORT_NUMBER + rtl8651_totalExtPortNum );
+ }
+
+ WRITE_MEM32( LAGHPMR0, reg );
+ return SUCCESS;
+}
+
+
+
+static uint32 _rtl8651_findAsicLinkupPortmask(uint32 portMask)
+{
+ uint32 port, lnkUp_portMask = portMask;
+ for ( port = 0; port < RTL8651_PORT_NUMBER + rtl8651_totalExtPortNum; port++ )
+ {
+ if ( ( portMask & ( 1 << port ) ) && (rtl8651AsicEthernetTable[port].linkUp == FALSE) )
+ {
+ lnkUp_portMask &= ~( 1 << port );
+ }
+ }
+ return lnkUp_portMask;
+}
+
+int32 rtl8651_setAsicEthernetLinkStatus(uint32 port, int8 linkUp)
+{
+ int8 notify;
+ uint32 portmask;
+
+ if (port >= (RTL8651_PORT_NUMBER+rtl8651_totalExtPortNum))
+ {
+ return FAILED;
+ }
+
+ notify = (rtl8651AsicEthernetTable[port].linkUp != ((linkUp==TRUE)? TRUE: FALSE))?TRUE:FALSE;
+
+
+ rtl8651AsicEthernetTable[port].linkUp = (linkUp == TRUE)? TRUE: FALSE;
+
+ /*
+ If the specified port is a member of the aggregator,
+ update the table which maps hashed index to the port
+ because the member port of the aggregator link changes.
+ */
+ portmask = READ_MEM32( LAGCR0 ) & TRUNKMASK_MASK;
+ if ( portmask & ( 1 << port ) )
+ {
+ /* Find the link-up portmask */
+ uint32 lnkUp_portMask = _rtl8651_findAsicLinkupPortmask(portmask);
+ rtl8651_updateAsicLinkAggregatorLMPR( lnkUp_portMask );
+ }
+
+ return SUCCESS;
+}
+#endif
+
+#if defined (CONFIG_RTL_ENABLE_RATELIMIT_TABLE)
+int32 rtl8651_setAsicRateLimitTable(uint32 index, rtl865x_tblAsicDrv_rateLimitParam_t *rateLimit_t)
+{
+ rtl8651_tblAsic_rateLimitTable_t entry;
+
+ if (rateLimit_t == NULL || index >= RTL8651_RATELIMITTBL_SIZE)
+ return FAILED;
+ memset(&entry,0,sizeof(rtl8651_tblAsic_rateLimitTable_t));
+ entry.maxToken = rateLimit_t->maxToken&0xFFFFFF;
+ entry.refill = rateLimit_t->refill_number&0xFFFFFF;
+ entry.refillTime = rateLimit_t->t_intervalUnit&0x3F;
+ entry.refillRemainTime = rateLimit_t->t_remainUnit&0x3F;
+ entry.token = rateLimit_t->token&0xFFFFFF;
+ return _rtl8651_forceAddAsicEntry(TYPE_RATE_LIMIT_TABLE, index, &entry);
+}
+
+
+int32 rtl8651_delAsicRateLimitTable(uint32 index)
+{
+ rtl8651_tblAsic_rateLimitTable_t entry;
+
+ if (index >= RTL8651_RATELIMITTBL_SIZE)
+ return FAILED;
+ memset(&entry,0,sizeof(rtl8651_tblAsic_rateLimitTable_t));
+ return _rtl8651_forceAddAsicEntry(TYPE_RATE_LIMIT_TABLE, index, &entry);
+}
+
+
+int32 rtl8651_getAsicRateLimitTable(uint32 index, rtl865x_tblAsicDrv_rateLimitParam_t *rateLimit_t)
+{
+ rtl8651_tblAsic_rateLimitTable_t entry;
+
+ if (rateLimit_t == NULL || index >= RTL8651_RATELIMITTBL_SIZE)
+ return FAILED;
+ _rtl8651_readAsicEntry(TYPE_RATE_LIMIT_TABLE, index, &entry);
+ if (entry.refillTime == 0)
+ return FAILED;
+ rateLimit_t->token = entry.token & 0xFFFFFF;
+ rateLimit_t->maxToken = entry.maxToken & 0xFFFFFF;
+ rateLimit_t->t_remainUnit = entry.refillRemainTime&0x3F;
+ rateLimit_t->t_intervalUnit = entry.refillTime&0x3F;
+ rateLimit_t->refill_number = entry.refill&0xFFFFFF;
+ return SUCCESS;
+}
+#endif
+#ifdef CONFIG_RTK_VOIP_QOS
+/*
+ * @func int32 | rtl8651_setAsicDscpPriority | set DSCP-based priority
+ * @parm uint32 | dscp | DSCP value
+ * @parm enum PRIORITYVALUE | priority | priority value
+ * @rvalue SUCCESS |
+ * @rvalue FAILED | invalid parameter
+ * @comm
+ * */
+int32 rtl8651_setAsicDscpPriority( uint32 dscp, enum PRIORITYVALUE priority )
+{
+ /* Invalid input parameter */
+ if ((dscp < 0) || (dscp > 63))
+ return FAILED;
+ if ((priority < PRI0) || (priority > PRI7))
+ return FAILED;
+
+ if ((0 <= dscp) && (dscp <= 9))
+ WRITE_MEM32(DSCPCR0, (READ_MEM32(DSCPCR0) & ~(0x7 << (dscp*3))) | (priority << (dscp*3)));
+ else if ((10 <= dscp) && (dscp <= 19))
+ WRITE_MEM32(DSCPCR1, (READ_MEM32(DSCPCR1) & ~(0x7 << ((dscp%10)*3))) | (priority << ((dscp%10)*3)));
+ else if ((20 <= dscp) && (dscp <= 29))
+ WRITE_MEM32(DSCPCR2, (READ_MEM32(DSCPCR2) & ~(0x7 << ((dscp%10)*3))) | (priority << ((dscp%10)*3)));
+ else if ((30 <= dscp) && (dscp <= 39))
+ WRITE_MEM32(DSCPCR3, (READ_MEM32(DSCPCR3) & ~(0x7 << ((dscp%10)*3))) | (priority << ((dscp%10)*3)));
+ else if ((40 <= dscp) && (dscp <= 49))
+ WRITE_MEM32(DSCPCR4, (READ_MEM32(DSCPCR4) & ~(0x7 << ((dscp%10)*3))) | (priority << ((dscp%10)*3)));
+ else if ((50 <= dscp) && (dscp <= 59))
+ WRITE_MEM32(DSCPCR5, (READ_MEM32(DSCPCR5) & ~(0x7 << ((dscp%10)*3))) | (priority << ((dscp%10)*3)));
+ else if ((60 <= dscp) && (dscp <= 63))
+ WRITE_MEM32(DSCPCR6, (READ_MEM32(DSCPCR6) & ~(0x7 << ((dscp%10)*3))) | (priority << ((dscp%10)*3)));
+
+ return SUCCESS;
+}
+
+
+/*
+ * @func int32 | rtl8651_setAsicDscpPriority | set DSCP-based priority
+ * @parm uint32 | dscp | DSCP value
+ * @parm enum PRIORITYVALUE* | pPriority | pPriority will return the priority of the specified DSCP
+ * @rvalue SUCCESS |
+ * @rvalue FAILED | invalid parameter
+ * @comm
+ * */
+int32 rtl8651_getAsicDscpPriority( uint32 dscp, enum PRIORITYVALUE *pPriority )
+{
+ /* Invalid input parameter */
+ if ((dscp < 0) || (dscp > 63))
+ return FAILED;
+
+ if (pPriority != NULL)
+ {
+ if ((0 <= dscp) && (dscp <= 9))
+ *pPriority = (READ_MEM32(DSCPCR0) & (0x7 << (dscp*3))) >> (dscp*3);
+ else if ((10 <= dscp) && (dscp <= 19))
+ *pPriority = (READ_MEM32(DSCPCR1) & (0x7 << ((dscp%10)*3))) >> ((dscp%10)*3);
+ else if ((20 <= dscp) && (dscp <= 29))
+ *pPriority = (READ_MEM32(DSCPCR2) & (0x7 << ((dscp%10)*3))) >> ((dscp%10)*3);
+ else if ((30 <= dscp) && (dscp <= 39))
+ *pPriority = (READ_MEM32(DSCPCR3) & (0x7 << ((dscp%10)*3))) >> ((dscp%10)*3);
+ else if ((40 <= dscp) && (dscp <= 49))
+ *pPriority = (READ_MEM32(DSCPCR4) & (0x7 << ((dscp%10)*3))) >> ((dscp%10)*3);
+ else if ((50 <= dscp) && (dscp <= 59))
+ *pPriority = (READ_MEM32(DSCPCR5) & (0x7 << ((dscp%10)*3))) >> ((dscp%10)*3);
+ else if ((60 <= dscp) && (dscp <= 63))
+ *pPriority = (READ_MEM32(DSCPCR6) & (0x7 << ((dscp%10)*3))) >> ((dscp%10)*3);
+ }
+
+ return SUCCESS;
+}
+
+int32 rtl8651_reset_dscp_priority(void)
+{
+ //clear dscp priority assignment, otherwise pkt with dscp value 0 will be assign priority 1
+ WRITE_MEM32(DSCPCR0,0);
+ WRITE_MEM32(DSCPCR1,0);
+ WRITE_MEM32(DSCPCR2,0);
+ WRITE_MEM32(DSCPCR3,0);
+ WRITE_MEM32(DSCPCR4,0);
+ WRITE_MEM32(DSCPCR5,0);
+ WRITE_MEM32(DSCPCR6,0);
+ return 0;
+}
+int32 rtl8651_cpu_tx_fc(int enable)
+{
+ if(enable)
+ REG32(PSRP6_RW) |= 0x40;
+ else
+ REG32(PSRP6_RW) &= 0xffffffbf;
+ return 0;
+}
+int32 rtl8651_setQueueNumber(int port, int qnum)
+{
+ rtl865xC_lockSWCore();
+ rtl8651_setAsicOutputQueueNumber(port, qnum);
+ rtl865xC_waitForOutputQueueEmpty();
+ rtl8651_resetAsicOutputQueue();
+ rtl865xC_unLockSWCore();
+ return SUCCESS;
+}
+#endif
+#ifdef CONFIG_RTK_VOIP_PORT_LINK
+int rtl8651_getAsicEthernetLinkStatus(uint32 port, int8 *linkUp)
+{
+
+ int status = READ_MEM32( PSRP0 + port * 4 );
+
+ if(status & PortStatusLinkUp)
+ *linkUp = TRUE;
+ else
+ *linkUp = FALSE;
+
+
+ return SUCCESS;
+}
+#endif