Initial AR9341 support, some changes in makefiles, athrs27 driver
authorPiotr Dymacz <pepe2k@gmail.com>
Tue, 17 Dec 2013 22:11:42 +0000 (23:11 +0100)
committerPiotr Dymacz <pepe2k@gmail.com>
Tue, 17 Dec 2013 22:11:42 +0000 (23:11 +0100)
Makefile
u-boot/Makefile
u-boot/board/ar7240/common/athrs27_phy.c [new file with mode: 0755]
u-boot/board/ar7240/common/athrs27_phy.h [new file with mode: 0755]
u-boot/board/ar7240/common/lowlevel_init_934x.S
u-boot/board/ar7240/db12x/Makefile
u-boot/cpu/mips/ar7240/ag934x.c
u-boot/cpu/mips/ar7240/ag934x_phy.h
u-boot/include/configs/ar7240.h
u-boot/include/configs/db12x.h

index 34dac2da21c900e6c4e6b5525aa2f15467a1fe00..a994b8211a6da29d8a4ad8b71a9c8ee5a158f998 100755 (executable)
--- a/Makefile
+++ b/Makefile
@@ -90,8 +90,19 @@ tplink_mr3220_v2:
 tplink_wdr3600_43x0:   export UBOOT_FILE_NAME=uboot_for_tp-link_tl-wdr3600-43x0
 tplink_wdr3600_43x0:   export MAX_UBOOT_SIZE=64
 tplink_wdr3600_43x0:   export COMPRESSED_UBOOT=1
+tplink_wdr3600_43x0:   export ETH_CONFIG=_s17
 tplink_wdr3600_43x0:
-       @cd $(BUILD_TOPDIR)/u-boot/ && $(MAKECMD) db12x_config
+       @cd $(BUILD_TOPDIR)/u-boot/ && $(MAKECMD) wdr3600_43x0_config
+       @cd $(BUILD_TOPDIR)/u-boot/ && $(MAKECMD) ENDIANNESS=-EB V=1 all
+       @cp $(BUILD_TOPDIR)/u-boot/tuboot.bin $(BUILD_TOPDIR)/bin/temp.bin
+       @make show_size
+
+tplink_wr841n_v8:      export UBOOT_FILE_NAME=uboot_for_tp-link_tl-wr841n_v8
+tplink_wr841n_v8:      export MAX_UBOOT_SIZE=64
+tplink_wr841n_v8:      export COMPRESSED_UBOOT=1
+tplink_wr841n_v8:      export ETH_CONFIG=_s27
+tplink_wr841n_v8:
+       @cd $(BUILD_TOPDIR)/u-boot/ && $(MAKECMD) wr841n_v8_config
        @cd $(BUILD_TOPDIR)/u-boot/ && $(MAKECMD) ENDIANNESS=-EB V=1 all
        @cp $(BUILD_TOPDIR)/u-boot/tuboot.bin $(BUILD_TOPDIR)/bin/temp.bin
        @make show_size
index f253bb5ab4bba460b357c59a7654bd59675ca9fb..b067643a040027491111ef1462e68b4960e2204f 100755 (executable)
@@ -267,13 +267,8 @@ unconfig:
 #########################################################################
 ## MIPS32 AR7100 (24K)
 #########################################################################
-
-hornet_common_config :
+common_config :
        @ >include/config.h
-       @echo "#define CONFIG_AR7240                        1" >> include/config.h
-       @echo "#define CONFIG_MACH_HORNET                   1" >> include/config.h
-       @echo "#define CONFIG_HORNET_1_1_WAR                1" >> include/config.h
-       @echo "#define NEW_DDR_TAP_CAL                      1" >> include/config.h
 
 ifdef CONFIG_BOOTDELAY
        @echo "#define CONFIG_BOOTDELAY "$(CONFIG_BOOTDELAY)   >> include/config.h
@@ -293,6 +288,12 @@ endif
        # don't show info about console (in, out, err...)
        @echo "#define CFG_CONSOLE_INFO_QUIET"                 >> include/config.h
 
+hornet_common_config : common_config
+       @echo "#define CONFIG_AR7240                        1" >> include/config.h
+       @echo "#define CONFIG_MACH_HORNET                   1" >> include/config.h
+       @echo "#define CONFIG_HORNET_1_1_WAR                1" >> include/config.h
+       @echo "#define NEW_DDR_TAP_CAL                      1" >> include/config.h
+
 wr703n_config : unconfig hornet_common_config
        @echo '======= Configuring for TP-Link TL-WR703N at:' `date` '======='
        @echo "#define CONFIG_FOR_TPLINK_WR703N_V1          1" >> include/config.h
@@ -469,37 +470,35 @@ carambola2_config : unconfig hornet_common_config
        
        @./mkconfig -a ap121 mips mips ap121 ar7240 ar7240
 
-db12x_config : unconfig
-       @echo '======= Configuring for TP-Link TL-WDR3600/43x0 at:' `date` '======='
-       @ >include/config.h
-       @echo "#define CONFIG_WASP_SUPPORT                  1" >> include/config.h
-       @echo "#undef CFG_ATHRS26_PHY"                         >> include/config.h
-       @echo "#define DDR2_32BIT_SUPPORT                   1" >> include/config.h
-       @echo "#define CONFIG_AG7240_GE0_IS_CONNECTED       1" >> include/config.h
+wasp_common_config : common_config
        @echo "#define CONFIG_AR7240                        1" >> include/config.h
        @echo "#define CONFIG_WASP                          1" >> include/config.h
+       @echo "#define CONFIG_WASP_SUPPORT                  1" >> include/config.h
 
-ifdef CONFIG_BOOTDELAY
-       @echo "#define CONFIG_BOOTDELAY "$(CONFIG_BOOTDELAY)   >> include/config.h
-endif
-
-       @echo "#define CONFIG_DELAY_TO_AUTORUN_HTTPD        3" >> include/config.h
-       @echo "#define CONFIG_DELAY_TO_AUTORUN_CONSOLE      5" >> include/config.h
-       @echo "#define CONFIG_DELAY_TO_AUTORUN_NETCONSOLE   7" >> include/config.h
-
-       # max delay time for button pressing
-       @echo "#define CONFIG_MAX_BUTTON_PRESSING          10" >> include/config.h
-
-       # don't show info about console (in, out, err...)
-       @echo "#define CFG_CONSOLE_INFO_QUIET"                 >> include/config.h
-
-       @echo "#define CONFIG_ATHRS17_PHY                   1" >> include/config.h
+wdr3600_43x0_config : unconfig wasp_common_config
+       @echo '======= Configuring for TP-Link TL-WDR3600/43x0 at:' `date` '======='
+       @echo "#define CONFIG_FOR_TPLINK_WDR3600_WDR43X0_V1 1" >> include/config.h
+       @echo "#define DDR2_32BIT_SUPPORT                   1" >> include/config.h
+       @echo "#define CFG_ATHRS17_PHY                      1" >> include/config.h
        @echo "#define CFG_AG7240_NMACS                     1" >> include/config.h
+       @echo "#define CFG_DUAL_PHY_SUPPORT                 1" >> include/config.h
        @echo "#define DEFAULT_FLASH_SIZE_IN_MB             8" >> include/config.h
        @echo "#define BOARD_CUSTOM_STRING                  \"DB120 (AR9344) U-Boot for TL-WDR3600/43x0\"" >> include/config.h
 
        @./mkconfig -a db12x mips mips db12x ar7240 ar7240
 
+wr841n_v8_config : unconfig wasp_common_config
+       @echo '======= Configuring for TP-Link TL-WR841N/D at:' `date` '======='
+       @echo "#define CONFIG_FOR_TPLINK_WR841N_V8          1" >> include/config.h
+       @echo "#define CONFIG_AP123                         1" >> include/config.h
+       @echo "#define DDR2_32BIT_SUPPORT                   1" >> include/config.h
+       @echo "#define CFG_ATHRS27_PHY                      1" >> include/config.h
+       @echo "#define CFG_AG7240_NMACS                     2" >> include/config.h
+       @echo "#define DEFAULT_FLASH_SIZE_IN_MB             4" >> include/config.h
+       @echo "#define BOARD_CUSTOM_STRING                  \"AP123 (AR9341) U-Boot for TL-WR841N/D v8\"" >> include/config.h
+
+       @./mkconfig -a db12x mips mips db12x ar7240 ar7240
+
 #########################################################################
 #########################################################################
 #########################################################################
diff --git a/u-boot/board/ar7240/common/athrs27_phy.c b/u-boot/board/ar7240/common/athrs27_phy.c
new file mode 100755 (executable)
index 0000000..0793f29
--- /dev/null
@@ -0,0 +1,865 @@
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright © 2007 Atheros Communications, Inc.,  All Rights Reserved.
+ */
+
+/*
+ * Manage the atheros ethernet PHY.
+ *
+ * All definitions in this file are operating system independent!
+ */
+
+#include <config.h>
+#include <linux/types.h>
+#include <common.h>
+#include <miiphy.h>
+#include "phy.h"
+#include <asm/addrspace.h>
+#include "ar7240_soc.h"
+#include "athrs27_phy.h"
+
+/* PHY selections and access functions */
+
+typedef enum {
+    PHY_SRCPORT_INFO,
+    PHY_PORTINFO_SIZE,
+} PHY_CAP_TYPE;
+
+typedef enum {
+    PHY_SRCPORT_NONE,
+    PHY_SRCPORT_VLANTAG,
+    PHY_SRCPORT_TRAILER,
+} PHY_SRCPORT_TYPE;
+
+#define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)
+#define DRV_MSG(x,a,b,c,d,e,f)
+#define DRV_PRINT(DBG_SW,X)
+
+#define ATHR_LAN_PORT_VLAN          1
+#define ATHR_WAN_PORT_VLAN          2
+#define ENET_UNIT_LAN 1
+#define ENET_UNIT_WAN 0
+
+#define TRUE    1
+#define FALSE   0
+
+#define ATHR_PHY0_ADDR   0x0
+#define ATHR_PHY1_ADDR   0x1
+#define ATHR_PHY2_ADDR   0x2
+#define ATHR_PHY3_ADDR   0x3
+#define ATHR_PHY4_ADDR   0x4
+
+#define MODULE_NAME "ATHRS27"
+
+/*
+ * Track per-PHY port information.
+ */
+
+
+typedef struct {
+    BOOL   isEnetPort;       /* normal enet port */
+    BOOL   isPhyAlive;       /* last known state of link */
+    int    ethUnit;          /* MAC associated with this phy port */
+    uint32_t phyBase;
+    uint32_t phyAddr;          /* PHY registers associated with this phy port */
+    uint32_t VLANTableSetting; /* Value to be written to VLAN table */
+} athrPhyInfo_t;
+
+/*
+ * Per-PHY information, indexed by PHY unit number.
+ */
+static athrPhyInfo_t athrPhyInfo[] = {
+
+    {TRUE,   /* port 1 -- LAN port 1 */
+     FALSE,
+     ENET_UNIT_LAN,
+     0,
+     ATHR_PHY0_ADDR,
+     ATHR_LAN_PORT_VLAN
+    },
+
+    {TRUE,   /* port 2 -- LAN port 2 */
+     FALSE,
+     ENET_UNIT_LAN,
+     0,
+     ATHR_PHY1_ADDR,
+     ATHR_LAN_PORT_VLAN
+    },
+
+    {TRUE,   /* port 3 -- LAN port 3 */
+     FALSE,
+     ENET_UNIT_LAN,
+     0,
+     ATHR_PHY2_ADDR,
+     ATHR_LAN_PORT_VLAN
+    },
+
+
+   {TRUE,   /* port 4 --  LAN port 4 */
+     FALSE,
+     ENET_UNIT_LAN,
+     0,
+     ATHR_PHY3_ADDR,
+     ATHR_LAN_PORT_VLAN   /* Send to all ports */
+    },
+
+    {TRUE,  /* port 5 -- WAN Port 5 */
+     FALSE,
+     ENET_UNIT_WAN,
+     0,
+     ATHR_PHY4_ADDR,
+     ATHR_LAN_PORT_VLAN    /* Send to all ports */
+    },
+
+    {FALSE,   /* port 0 -- cpu port 0 */
+     TRUE,
+     ENET_UNIT_LAN,
+     0,
+     0x00,
+     ATHR_LAN_PORT_VLAN
+    },
+
+};
+
+
+#define ATHR_GLOBALREGBASE    0
+
+#define ATHR_PHY_MAX 5
+
+/* Range of valid PHY IDs is [MIN..MAX] */
+#define ATHR_ID_MIN 0
+#define ATHR_ID_MAX (ATHR_PHY_MAX-1)
+
+
+/* Convenience macros to access myPhyInfo */
+#define ATHR_IS_ENET_PORT(phyUnit) (athrPhyInfo[phyUnit].isEnetPort)
+#define ATHR_IS_PHY_ALIVE(phyUnit) (athrPhyInfo[phyUnit].isPhyAlive)
+#define ATHR_ETHUNIT(phyUnit) (athrPhyInfo[phyUnit].ethUnit)
+#define ATHR_PHYBASE(phyUnit) (athrPhyInfo[phyUnit].phyBase)
+#define ATHR_PHYADDR(phyUnit) (athrPhyInfo[phyUnit].phyAddr)
+#define ATHR_VLAN_TABLE_SETTING(phyUnit) (athrPhyInfo[phyUnit].VLANTableSetting)
+
+
+#define ATHR_IS_ETHUNIT(phyUnit, ethUnit) \
+            (ATHR_IS_ENET_PORT(phyUnit) &&        \
+            ATHR_ETHUNIT(phyUnit) == (ethUnit))
+
+#define ATHR_IS_WAN_PORT(phyUnit) (!(ATHR_ETHUNIT(phyUnit)==ENET_UNIT_LAN))
+
+/* Forward references */
+BOOL athrs27_phy_is_link_alive(int phyUnit);
+uint32_t athrs27_reg_read(uint32_t reg_addr);
+void athrs27_reg_write(uint32_t reg_addr, uint32_t reg_val);
+unsigned int s27_rd_phy(unsigned int phy_addr, unsigned int reg_addr);
+void s27_wr_phy(unsigned int phy_addr, unsigned int reg_addr, unsigned int write_data);
+
+
+void athrs27_powersave_off(int phy_addr)
+{
+    s27_wr_phy(phy_addr,ATHR_DEBUG_PORT_ADDRESS,0x29);
+    s27_wr_phy(phy_addr,ATHR_DEBUG_PORT_DATA,0x36c0);
+
+}
+void athrs27_sleep_off(int phy_addr)
+{
+    s27_wr_phy(phy_addr,ATHR_DEBUG_PORT_ADDRESS,0xb);
+    s27_wr_phy(phy_addr,ATHR_DEBUG_PORT_DATA,0x3c00);
+}
+
+void athrs27_force_100M(int phyAddr,int duplex)
+{
+   /*
+    *  Force MDI and MDX to alternate ports 
+    *  Phy 0,2 and 4 -- MDI
+    *  Phy 1 and 3 -- MDX
+    */
+
+    if(phyAddr%2) {
+        s27_wr_phy(phyAddr,ATHR_PHY_FUNC_CONTROL,0x820);
+    }
+    else {
+        s27_wr_phy(phyAddr,ATHR_PHY_FUNC_CONTROL,0x800);
+    }
+
+    s27_wr_phy(phyAddr,0x1d,0x29);
+    s27_wr_phy(phyAddr,0x1e,0x0);
+    s27_wr_phy(phyAddr,0x10,0xc60);
+    s27_wr_phy(phyAddr,ATHR_PHY_CONTROL,(0xa000|(duplex << 8)));
+}
+
+void athrs27_force_10M(int phyAddr,int duplex)
+{
+
+    athrs27_powersave_off(phyAddr);
+    athrs27_sleep_off(phyAddr);
+
+    s27_wr_phy(phyAddr,ATHR_PHY_CONTROL,(0x8000 |(duplex << 8)));
+}
+
+int athrs27_reg_init(void)
+{
+#if S27_PHY_DEBUG
+    uint32_t rd_val;
+#endif
+
+    /* if using header for register configuration, we have to     */
+    /* configure s27 register after frame transmission is enabled */
+    athrs27_reg_rmw(0x8,(1<<28));  /* Set WAN port is connected to GE0 */
+
+#if defined(S27_FORCE_100M)
+    athrs27_force_100M(ATHR_PHY4_ADDR,1);
+#elif  defined(S27_FORCE_10M)
+    athrs27_force_10M(ATHR_PHY4_ADDR,1);
+#else
+    s27_wr_phy(ATHR_PHY4_ADDR,ATHR_PHY_CONTROL,0x9000);
+
+#endif
+#ifdef S27_PHY_DEBUG
+    printf(MODULE_NAME":OPERATIONAL_MODE_REG0:%x\n",athrs27_reg_read(OPERATIONAL_MODE_REG0));
+    printf(MODULE_NAME":REG 0x4-->:%x\n",athrs27_reg_read(0x4));
+    printf(MODULE_NAME":REG 0x2c-->:%x\n",athrs27_reg_read(0x2c));
+    printf(MODULE_NAME":REG 0x8-->:%x\n",athrs27_reg_read(0x8));
+#endif
+
+    return 0;
+}
+int athrs27_reg_init_lan(void)
+{
+    int i = 60;
+#if S26_PHY_DEBUG
+    uint32_t rd_val;
+#endif
+    int       phyUnit;
+    uint32_t  phyBase = 0;
+    BOOL      foundPhy = FALSE;
+    uint32_t  phyAddr = 0;
+
+
+    /* reset switch */
+    printf(MODULE_NAME ": resetting s27\n");
+    athrs27_reg_write(0x0, athrs27_reg_read(0x0)|0x80000000);
+
+    while(i--) {
+        sysMsDelay(100);
+        if(!(athrs27_reg_read(0x0)&0x80000000))
+            break;
+    }
+    printf(MODULE_NAME ": s27 reset done\n");
+    athrs27_reg_write(PORT_STATUS_REGISTER0,0x4e);
+
+    athrs27_reg_rmw(OPERATIONAL_MODE_REG0,(1<<6));  /* Set GMII mode */
+
+    if (is_emu() || is_wasp()) {
+       athrs27_reg_rmw(0x2c,((1<<26)| (1<<16) | 0x1)); /* FiX ME: EBU debug */
+    }
+
+    for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
+
+        foundPhy = TRUE;
+        phyBase = ATHR_PHYBASE(phyUnit);
+        phyAddr = ATHR_PHYADDR(phyUnit);
+
+#if defined(S27_FORCE_100M)
+        athrs27_force_100M(phyAddr,1);
+#elif defined(S27_FORCE_10M)
+        athrs27_force_10M(phyAddr,1);
+#else
+        s27_wr_phy(phyAddr,ATHR_PHY_CONTROL,0x9000);
+#endif
+
+#if S27_PHY_DEBUG
+        rd_val = s27_rd_phy(phyAddr,ATHR_PHY_FUNC_CONTROL);
+        printf("S27 ATHR_PHY_FUNC_CONTROL (%d):%x\n",phyAddr,rd_val);
+        rd_val = s27_rd_phy(phyAddr,ATHR_PHY_ID1);
+        printf("S27 PHY ID  (%d) :%x\n",phyAddr, rd_val);
+        rd_val = s27_rd_phy(phyAddr,ATHR_PHY_SPEC_STATUS);
+        printf("S27 PHY CTRL  (%d) :%x\n",phyAddr, rd_val);
+        rd_val = s27_rd_phy(phyAddr,ATHR_PHY_STATUS);
+        printf("S27 ATHR PHY STATUS  (%d) :%x\n",phyAddr, rd_val);
+#endif
+    }
+
+    /* 
+     * status[1:0]=2'h2;   - (0x10 - 1000 Mbps , 0x01 - 100Mbps, 0x0 - 10 Mbps)
+     * status[2]=1'h1;     - Tx Mac En
+     * status[3]=1'h1;     - Rx Mac En
+     * status[4]=1'h1;     - Tx Flow Ctrl En
+     * status[5]=1'h1;     - Rx Flow Ctrl En
+     * status[6]=1'h1;     - Duplex Mode
+     */
+    athrs27_reg_write(PORT_STATUS_REGISTER1, 0x200);  /* LAN - 1 */
+    athrs27_reg_write(PORT_STATUS_REGISTER2, 0x200);  /* LAN - 2 */
+    athrs27_reg_write(PORT_STATUS_REGISTER3, 0x200);  /* LAN - 3 */
+    athrs27_reg_write(PORT_STATUS_REGISTER4, 0x200);  /* LAN - 4 */
+
+    if (is_emu()) {
+        athrs27_reg_write(PORT_STATUS_REGISTER1, 0x4C);  /* LAN - 1 */
+        athrs27_reg_write(PORT_STATUS_REGISTER2, 0x4c);  /* LAN - 2 */
+        athrs27_reg_write(PORT_STATUS_REGISTER3, 0x4c);  /* LAN - 3 */
+        athrs27_reg_write(PORT_STATUS_REGISTER4, 0x4c);  /* LAN - 4 */
+    }
+
+    /* QM Control */
+    athrs27_reg_write(0x38, 0xc000050e);
+
+    /*
+     * status[11]=1'h0;    - CPU Disable
+     * status[7] = 1'b1;   - Learn One Lock
+     * status[14] = 1'b0;  - Learn Enable
+     */
+#ifdef ATHEROS_HEADER_EN
+    athrs27_reg_write(PORT_CONTROL_REGISTER0, 0x4804);
+#else
+   /* Atheros Header Disable */
+    athrs27_reg_write(PORT_CONTROL_REGISTER0, 0x4004);
+#endif
+
+    /* Tag Priority Mapping */
+    athrs27_reg_write(0x70, 0xfa50);
+
+    /* Enable ARP packets to CPU port */
+    athrs27_reg_write(S27_ARL_TBL_CTRL_REG,(athrs27_reg_read(S27_ARL_TBL_CTRL_REG) | 0x100000));
+
+   /* Enable Broadcast packets to CPU port */
+    athrs27_reg_write(S27_FLD_MASK_REG,(athrs27_reg_read(S27_FLD_MASK_REG) |
+                           S27_ENABLE_CPU_BROADCAST | S27_ENABLE_CPU_BCAST_FWD ));
+
+    return 0;
+}
+
+/******************************************************************************
+*
+* athrs27_phy_is_link_alive - test to see if the specified link is alive
+*
+* RETURNS:
+*    TRUE  --> link is alive
+*    FALSE --> link is down
+*/
+BOOL
+athrs27_phy_is_link_alive(int phyUnit)
+{
+    uint16_t phyHwStatus;
+    uint32_t phyBase;
+    uint32_t phyAddr;
+
+    phyBase = ATHR_PHYBASE(phyUnit);
+    phyAddr = ATHR_PHYADDR(phyUnit);
+    phyHwStatus = s27_rd_phy(phyAddr, ATHR_PHY_SPEC_STATUS);
+
+    if (phyHwStatus & ATHR_STATUS_LINK_PASS)
+        return TRUE;
+
+    return FALSE;
+}
+
+/******************************************************************************
+*
+* athrs27_phy_setup - reset and setup the PHY associated with
+* the specified MAC unit number.
+*   
+* Resets the associated PHY port.
+*   
+* RETURNS:
+*    TRUE  --> associated PHY is alive
+*    FALSE --> no LINKs on this ethernet unit
+*/
+BOOL
+athrs27_phy_setup(int ethUnit)
+{
+    int       phyUnit;
+    uint16_t  phyHwStatus;
+    uint16_t  timeout;
+    int       liveLinks = 0;
+    uint32_t  phyBase = 0;
+    BOOL      foundPhy = FALSE;
+    uint32_t  phyAddr = 0;
+//#if S27_PHY_DEBUG
+    uint32_t  rd_val = 0;
+//#endif
+    uint32_t  ar7240_revid;
+
+
+    /* See if there's any configuration data for this enet */
+    /* start auto negogiation on each phy */
+    for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
+
+        foundPhy = TRUE;
+        phyBase = ATHR_PHYBASE(phyUnit);
+        phyAddr = ATHR_PHYADDR(phyUnit);
+
+        if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
+            continue;
+        }
+        if (!is_emu()) {
+           s27_wr_phy(phyAddr, ATHR_AUTONEG_ADVERT,ATHR_ADVERTISE_ALL);
+
+           s27_wr_phy(phyAddr, ATHR_PHY_CONTROL,ATHR_CTRL_AUTONEGOTIATION_ENABLE
+                         | ATHR_CTRL_SOFTWARE_RESET);
+        }
+        else  {
+               printf("############ is emulation ############\n");
+
+           if(ATHR_ETHUNIT(phyUnit) == ENET_UNIT_WAN) {
+               s27_wr_phy(phyAddr, ATHR_AUTONEG_ADVERT,ATHR_ADVERTISE_ALL);
+               s27_wr_phy(phyAddr,0x9, 0x0); //donot advertise 1000Mbps mode
+               s27_wr_phy(phyAddr, ATHR_PHY_CONTROL,0x0);
+               s27_wr_phy(phyAddr, ATHR_PHY_CONTROL,ATHR_CTRL_AUTONEGOTIATION_ENABLE
+                         | ATHR_CTRL_SOFTWARE_RESET);
+           }
+           else { 
+
+               s27_wr_phy(phyAddr, ATHR_AUTONEG_ADVERT,(ATHR_ADVERTISE_ASYM_PAUSE | ATHR_ADVERTISE_PAUSE |
+                            ATHR_ADVERTISE_10HALF | ATHR_ADVERTISE_10FULL));
+               s27_wr_phy(phyAddr,0x9, 0x0); //donot advertise 1000Mbps mode
+               s27_wr_phy(phyAddr, ATHR_PHY_CONTROL,0x0);
+               s27_wr_phy(phyAddr, ATHR_PHY_CONTROL,ATHR_CTRL_AUTONEGOTIATION_ENABLE
+                         | ATHR_CTRL_SOFTWARE_RESET);
+           }
+       }
+       rd_val = s27_rd_phy(phyAddr,ATHR_PHY_CONTROL);
+       printf("%s ATHR_PHY_CONTROL %d: 0x%x\n",__func__,phyAddr,rd_val);
+       rd_val = s27_rd_phy(phyAddr,ATHR_PHY_SPEC_STATUS);
+       printf("%s ATHR_PHY_SPEC_STAUS %d: 0x%x\n",__func__,phyAddr,rd_val);
+    }
+    if (!foundPhy) {
+        return FALSE; /* No PHY's configured for this ethUnit */
+    }
+
+    /*
+     * After the phy is reset, it takes a little while before
+     * it can respond properly.
+     */
+    if (ethUnit == ENET_UNIT_LAN)
+        sysMsDelay(100);       // changed by lsz, sysMsDelay(1000);
+    else
+        sysMsDelay(300);       // changed by lsz, sysMsDelay(3000);
+
+    /*
+     * Wait up to 3 seconds for ALL associated PHYs to finish
+     * autonegotiation.  The only way we get out of here sooner is
+     * if ALL PHYs are connected AND finish autonegotiation.
+     */
+    for (phyUnit=0; (phyUnit < ATHR_PHY_MAX) /*&& (timeout > 0) */; phyUnit++) {
+        if (ATHR_ETHUNIT(phyUnit) == ENET_UNIT_WAN)
+            continue;
+
+        timeout=20;
+        for (;;) {
+            phyHwStatus =  s27_rd_phy(phyAddr, ATHR_PHY_CONTROL);
+
+            if (ATHR_RESET_DONE(phyHwStatus)) {
+                DRV_PRINT(DRV_DEBUG_PHYSETUP,
+                          ("Port %d, Neg Success\n", phyUnit));
+                break;
+            }
+            if (timeout == 0) {
+                DRV_PRINT(DRV_DEBUG_PHYSETUP,
+                          ("Port %d, Negogiation timeout\n", phyUnit));
+                break;
+            }
+            if (--timeout == 0) {
+                DRV_PRINT(DRV_DEBUG_PHYSETUP,
+                          ("Port %d, Negogiation timeout\n", phyUnit));
+                break;
+            }
+
+            sysMsDelay(150);
+        }
+        /* fix IOT */
+        s27_wr_phy(phyUnit, 29, 0x14);
+        s27_wr_phy(phyUnit, 30, 0x1352);
+
+#ifdef S27_VER_1_0
+        /* turn off power saving */
+        s27_wr_phy(phyUnit, 29, 41);
+        s27_wr_phy(phyUnit, 30, 0);
+        printf("def_ S27_VER_1_0\n");
+#endif
+    }
+
+    /*
+     * All PHYs have had adequate time to autonegotiate.
+     * Now initialize software status.
+     *
+     * It's possible that some ports may take a bit longer
+     * to autonegotiate; but we can't wait forever.  They'll
+     * get noticed by mv_phyCheckStatusChange during regular
+     * polling activities.
+     */
+    for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
+        if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
+            continue;
+        }
+
+        if (athrs27_phy_is_link_alive(phyUnit)) {
+            liveLinks++;
+            ATHR_IS_PHY_ALIVE(phyUnit) = TRUE;
+        } else {
+            ATHR_IS_PHY_ALIVE(phyUnit) = FALSE;
+        }
+        DRV_PRINT(DRV_DEBUG_PHYSETUP,
+            ("eth%d: Phy Specific Status=%4.4x\n",
+            ethUnit,
+            s27_rd_phy(ATHR_PHYADDR(phyUnit),ATHR_PHY_SPEC_STATUS)));
+    }
+
+    return (liveLinks > 0);
+}
+
+/******************************************************************************
+*
+* athrs27_phy_is_fdx - Determines whether the phy ports associated with the
+* specified device are FULL or HALF duplex.
+*
+* RETURNS:
+*    1 --> FULL
+*    0 --> HALF
+*/
+int
+athrs27_phy_is_fdx(int ethUnit,int phyUnit)
+{
+    uint32_t  phyBase;
+    uint32_t  phyAddr;
+    uint16_t  phyHwStatus;
+    int       ii = 200;
+
+    if (ethUnit == ENET_UNIT_LAN)
+        return TRUE;
+
+    for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
+        if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
+            continue;
+        }
+
+        if (athrs27_phy_is_link_alive(phyUnit)) {
+
+            phyBase = ATHR_PHYBASE(phyUnit);
+            phyAddr = ATHR_PHYADDR(phyUnit);
+
+            do {
+                phyHwStatus = s27_rd_phy (phyAddr, ATHR_PHY_SPEC_STATUS);
+                        if(phyHwStatus & ATHR_STATUS_RESOVLED)
+                                break;
+                sysMsDelay(10);
+            } while(--ii);
+            if (phyHwStatus & ATHER_STATUS_FULL_DUPLEX) {
+                return TRUE;
+            }
+        }
+    }
+
+    return FALSE;
+}
+/******************************************************************************
+*
+* athrs27_phy_speed - Determines the speed of phy ports associated with the
+* specified device.
+*
+* RETURNS:
+*               ATHR_PHY_SPEED_10T, AG7240_PHY_SPEED_100T;
+*               ATHR_PHY_SPEED_1000T;
+*/
+
+int
+athrs27_phy_speed(int ethUnit,int phyUnit)
+{
+    uint16_t  phyHwStatus;
+    uint32_t  phyBase;
+    uint32_t  phyAddr;
+    int       ii = 200;
+    int       phySpeed;
+    for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
+        if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
+            continue;
+        }
+
+
+        phyBase = ATHR_PHYBASE(phyUnit);
+        phyAddr = ATHR_PHYADDR(phyUnit);
+        phySpeed = _10BASET;
+
+        if (athrs27_phy_is_link_alive(phyUnit)) {
+
+            do {
+                phyHwStatus = s27_rd_phy(phyAddr,
+                                              ATHR_PHY_SPEC_STATUS);
+                        if(phyHwStatus & ATHR_STATUS_RESOVLED)
+                                break;
+                sysMsDelay(10);
+            }while(--ii);
+
+            phyHwStatus = ((phyHwStatus & ATHER_STATUS_LINK_MASK) >>
+                           ATHER_STATUS_LINK_SHIFT);
+
+            switch(phyHwStatus) {
+            case 0:
+                phySpeed = _10BASET;
+               break;
+            case 1:
+                phySpeed = _100BASET;
+               break;
+            case 2:
+                phySpeed = _1000BASET;
+               break;
+            default:
+                printf("Unkown speed read!\n");
+            }
+        }
+
+        phy_reg_write(1,phyAddr, ATHR_DEBUG_PORT_ADDRESS, 0x18);
+
+        if(phySpeed == _100BASET) {
+            phy_reg_write(1,phyAddr, ATHR_DEBUG_PORT_DATA, 0xba8);
+        } else {
+            phy_reg_write(1,phyAddr, ATHR_DEBUG_PORT_DATA, 0x2ea);
+        }
+    }
+
+    if (ethUnit == ENET_UNIT_LAN)
+         phySpeed = _1000BASET;
+
+    return phySpeed;
+}
+
+/*****************************************************************************
+*
+* athr_phy_is_up -- checks for significant changes in PHY state.
+*
+* A "significant change" is:
+*     dropped link (e.g. ethernet cable unplugged) OR
+*     autonegotiation completed + link (e.g. ethernet cable plugged in)
+*
+* When a PHY is plugged in, phyLinkGained is called.
+* When a PHY is unplugged, phyLinkLost is called.
+*/
+
+int
+athrs27_phy_is_up(int ethUnit)
+{
+
+    uint16_t      phyHwStatus, phyHwControl;
+    athrPhyInfo_t *lastStatus;
+    int           linkCount   = 0;
+    int           lostLinks   = 0;
+    int           gainedLinks = 0;
+    uint32_t      phyBase;
+    uint32_t      phyAddr;
+    int           phyUnit;
+
+    for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
+        if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
+            continue;
+        }
+
+        phyBase = ATHR_PHYBASE(phyUnit);
+        phyAddr = ATHR_PHYADDR(phyUnit);
+
+        lastStatus = &athrPhyInfo[phyUnit];
+        if (lastStatus->isPhyAlive) { /* last known link status was ALIVE */
+            phyHwStatus = s27_rd_phy(phyAddr, ATHR_PHY_SPEC_STATUS);
+
+            /* See if we've lost link */
+            if (phyHwStatus & ATHR_STATUS_LINK_PASS) {
+                linkCount++;
+            } else {
+                lostLinks++;
+                DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d down\n",
+                                               ethUnit, phyUnit));
+                printf("enet%d port%d down\n",ethUnit, phyUnit);
+                lastStatus->isPhyAlive = FALSE;
+            }
+        } else { /* last known link status was DEAD */
+            /* Check for reset complete */
+            if(is_emu())
+            {
+                phyHwStatus = s27_rd_phy(phyAddr, ATHR_PHY_STATUS);
+                if(phyAddr%2) {
+                    s27_wr_phy(phyAddr,ATHR_PHY_FUNC_CONTROL,0x820);
+                }
+                else {
+                    s27_wr_phy(phyAddr,ATHR_PHY_FUNC_CONTROL,0x800);
+                }
+
+                if((phyHwStatus & 0x4)==0)
+                {
+                   s27_wr_phy(phyAddr,0x9,0x0);
+                   if(phyAddr !=0x4)
+                       s27_wr_phy(phyAddr,0x4,0x41);
+                   s27_wr_phy(phyAddr,0x0,0x9000);
+                }
+            }
+
+            phyHwStatus = s27_rd_phy(phyAddr, ATHR_PHY_CONTROL);
+            if (!ATHR_RESET_DONE(phyHwStatus))
+                continue;
+
+             phyHwControl = s27_rd_phy(phyAddr, ATHR_PHY_CONTROL);
+             phyHwStatus = s27_rd_phy(phyAddr, ATHR_PHY_STATUS);
+
+            /* Check for AutoNegotiation complete */
+            if ((!(phyHwControl & ATHR_CTRL_AUTONEGOTIATION_ENABLE))
+                 || ATHR_AUTONEG_DONE(phyHwStatus)) {
+                phyHwStatus = s27_rd_phy(phyAddr,
+                                           ATHR_PHY_SPEC_STATUS);
+
+                if (phyHwStatus & ATHR_STATUS_LINK_PASS) {
+                gainedLinks++;
+                linkCount++;
+                printf("enet%d port%d up\n",ethUnit, phyUnit);
+                DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d up\n",
+                                               ethUnit, phyUnit));
+                lastStatus->isPhyAlive = TRUE;
+                }
+            }
+        }
+    }
+    return (linkCount);
+}
+
+unsigned int athrs27_reg_read(unsigned int s27_addr)
+{
+    unsigned int addr_temp;
+    unsigned int s27_rd_csr_low, s27_rd_csr_high, s27_rd_csr;
+    unsigned int data,unit = 0;
+    unsigned int phy_address, reg_address;
+
+    addr_temp = s27_addr >>2;
+    data = addr_temp >> 7;
+
+    phy_address = 0x1f;
+    reg_address = 0x10;
+
+    if (is_ar7240()) {
+        unit = 0;
+    }
+    else if(is_ar7241() || is_ar7242() || is_wasp()) {
+        unit = 1;
+    }
+
+    phy_reg_write(unit,phy_address, reg_address, data);
+
+    phy_address = (0x17 & ((addr_temp >> 4) | 0x10));
+    reg_address = ((addr_temp << 1) & 0x1e);
+    s27_rd_csr_low = (uint32_t) phy_reg_read(unit,phy_address, reg_address);
+
+    reg_address = reg_address | 0x1;
+    s27_rd_csr_high = (uint32_t) phy_reg_read(unit,phy_address, reg_address);
+    s27_rd_csr = (s27_rd_csr_high << 16) | s27_rd_csr_low ;
+       
+    return(s27_rd_csr);
+}
+
+void athrs27_reg_write(unsigned int s27_addr, unsigned int s27_write_data)
+{
+    unsigned int addr_temp;
+    unsigned int data;
+    unsigned int phy_address, reg_address,unit = 0;
+
+    addr_temp = (s27_addr ) >>2;
+    data = addr_temp >> 7;
+
+    phy_address = 0x1f;
+    reg_address = 0x10;
+
+    if (is_ar7240()) {
+        unit = 0;
+    }
+    else if(is_ar7241() || is_ar7242() || is_wasp()) {
+        unit = 1;
+    }
+    phy_reg_write(unit,phy_address, reg_address, data);
+
+    phy_address = (0x17 & ((addr_temp >> 4) | 0x10));
+
+    reg_address = (((addr_temp << 1) & 0x1e) | 0x1);
+    data = (s27_write_data >> 16) & 0xffff;
+    phy_reg_write(unit,phy_address, reg_address, data);
+
+    reg_address = ((addr_temp << 1) & 0x1e);
+    data = s27_write_data  & 0xffff;
+    phy_reg_write(unit,phy_address, reg_address, data);
+
+}
+
+void athrs27_reg_rmw(unsigned int s27_addr, unsigned int s27_write_data)
+{
+    int val = athrs27_reg_read(s27_addr);
+    athrs27_reg_write(s27_addr,(val | s27_write_data));
+}
+
+unsigned int s27_rd_phy(unsigned int phy_addr, unsigned int reg_addr)
+{
+
+     unsigned int rddata, i = 100;
+
+
+    /* MDIO_CMD is set for read */
+
+    rddata = athrs27_reg_read(0x98);
+    rddata = (rddata & 0x0) | (reg_addr<<16)
+              | (phy_addr<<21) | (1<<27)
+              | (1<<30) | (1<<31) ;
+
+    athrs27_reg_write(0x98, rddata);
+
+    rddata = athrs27_reg_read(0x98);
+    rddata = rddata & (1<<31);
+
+    /* Check MDIO_BUSY status */
+    while(rddata && --i){
+        rddata = athrs27_reg_read(0x98);
+        rddata = rddata & (1<<31);
+    }
+
+    if(i <= 0)
+      printf("ERROR:%s failed:phy:%d reg:%X rddata:%X\n",
+                __func__,phy_addr,reg_addr,rddata);
+    /* Read the data from phy */
+
+    rddata = athrs27_reg_read(0x98);
+    rddata = rddata & 0xffff;
+    return(rddata);
+}
+void s27_wr_phy(unsigned int phy_addr, unsigned int reg_addr, unsigned int write_data)
+{
+    unsigned int rddata,i = 100;
+
+    /* MDIO_CMD is set for read */
+
+    rddata = athrs27_reg_read(0x98);
+
+    rddata = (rddata & 0x0) | (write_data & 0xffff)
+               | (reg_addr<<16) | (phy_addr<<21)
+               | (0<<27) | (1<<30) | (1<<31) ;
+
+    athrs27_reg_write(0x98, rddata);
+
+    rddata = athrs27_reg_read(0x98);
+    rddata = rddata & (1<<31);
+
+    /* Check MDIO_BUSY status */
+    while(rddata && --i){
+        rddata = athrs27_reg_read(0x98);
+        rddata = rddata & (1<<31);
+    }
+    if(i <= 0)
+      printf("ERROR:%s failed:phy:%d reg%X\n",__func__,phy_addr,reg_addr);
+
+}
+
+int athrs27_mdc_check()
+{
+    int i;
+
+    for (i=0; i<4000; i++) {
+        if(athrs27_reg_read(0x10c) != 0x18007fff)
+            return -1;
+    }
+    return 0;
+}
+
diff --git a/u-boot/board/ar7240/common/athrs27_phy.h b/u-boot/board/ar7240/common/athrs27_phy.h
new file mode 100755 (executable)
index 0000000..9846a4f
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2008, Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _ATHRS27_PHY_H
+#define _ATHRS27_PHY_H
+
+
+/*****************/
+/* PHY Registers */
+/*****************/
+#define ATHR_PHY_CONTROL                 0
+#define ATHR_PHY_STATUS                  1
+#define ATHR_PHY_ID1                     2
+#define ATHR_PHY_ID2                     3
+#define ATHR_AUTONEG_ADVERT              4
+#define ATHR_LINK_PARTNER_ABILITY        5
+#define ATHR_AUTONEG_EXPANSION           6
+#define ATHR_NEXT_PAGE_TRANSMIT          7
+#define ATHR_LINK_PARTNER_NEXT_PAGE      8
+#define ATHR_1000BASET_CONTROL           9
+#define ATHR_1000BASET_STATUS            10
+#define ATHR_PHY_FUNC_CONTROL            16
+#define ATHR_PHY_SPEC_STATUS             17
+#define ATHR_DEBUG_PORT_ADDRESS          29
+#define ATHR_DEBUG_PORT_DATA             30
+#define ATHR_PHY_INTR_ENABLE             0x12
+#define ATHR_PHY_INTR_STATUS             0x13
+
+/* ATHR_PHY_CONTROL fields */
+#define ATHR_CTRL_SOFTWARE_RESET                    0x8000
+#define ATHR_CTRL_SPEED_LSB                         0x2000
+#define ATHR_CTRL_AUTONEGOTIATION_ENABLE            0x1000
+#define ATHR_CTRL_RESTART_AUTONEGOTIATION           0x0200
+#define ATHR_CTRL_SPEED_FULL_DUPLEX                 0x0100
+#define ATHR_CTRL_SPEED_MSB                         0x0040
+
+#define ATHR_RESET_DONE(phy_control)                   \
+    (((phy_control) & (ATHR_CTRL_SOFTWARE_RESET)) == 0)
+    
+/* Phy status fields */
+#define ATHR_STATUS_AUTO_NEG_DONE                   0x0020
+
+#define ATHR_AUTONEG_DONE(ip_phy_status)                   \
+    (((ip_phy_status) &                                  \
+        (ATHR_STATUS_AUTO_NEG_DONE)) ==                    \
+        (ATHR_STATUS_AUTO_NEG_DONE))
+
+/* Link Partner ability */
+#define ATHR_LINK_100BASETX_FULL_DUPLEX       0x0100
+#define ATHR_LINK_100BASETX                   0x0080
+#define ATHR_LINK_10BASETX_FULL_DUPLEX        0x0040
+#define ATHR_LINK_10BASETX                    0x0020
+
+/* Advertisement register. */
+#define ATHR_ADVERTISE_NEXT_PAGE              0x8000
+#define ATHR_ADVERTISE_ASYM_PAUSE             0x0800
+#define ATHR_ADVERTISE_PAUSE                  0x0400
+#define ATHR_ADVERTISE_100FULL                0x0100
+#define ATHR_ADVERTISE_100HALF                0x0080  
+#define ATHR_ADVERTISE_10FULL                 0x0040  
+#define ATHR_ADVERTISE_10HALF                 0x0020  
+
+#define ATHR_ADVERTISE_ALL (ATHR_ADVERTISE_ASYM_PAUSE | ATHR_ADVERTISE_PAUSE | \
+                            ATHR_ADVERTISE_10HALF | ATHR_ADVERTISE_10FULL | \
+                            ATHR_ADVERTISE_100HALF | ATHR_ADVERTISE_100FULL)
+                       
+/* 1000BASET_CONTROL */
+#define ATHR_ADVERTISE_1000FULL               0x0200
+#define ATHR_ADVERTISE_1000HALF                      0x0100
+
+/* Phy Specific status fields */
+#define ATHER_STATUS_LINK_MASK                0xC000
+#define ATHER_STATUS_LINK_SHIFT               14
+#define ATHER_STATUS_FULL_DUPLEX              0x2000
+#define ATHR_STATUS_LINK_PASS                 0x0400 
+#define ATHR_LATCH_LINK_PASS                  0x0004 
+#define ATHR_STATUS_RESOVLED                  0x0800
+
+/*phy debug port  register */
+#define ATHER_DEBUG_SERDES_REG                5
+
+/* Serdes debug fields */
+#define ATHER_SERDES_BEACON                   0x0100
+
+#define OPERATIONAL_MODE_REG0                0x4
+
+/* S27 CSR Registers */
+
+#define PORT_STATUS_REGISTER0                0x0100 
+#define PORT_STATUS_REGISTER1                0x0200
+#define PORT_STATUS_REGISTER2                0x0300
+#define PORT_STATUS_REGISTER3                0x0400
+#define PORT_STATUS_REGISTER4                0x0500
+#define PORT_STATUS_REGISTER5                0x0600
+
+#define RATE_LIMIT_REGISTER0                 0x010C
+#define RATE_LIMIT_REGISTER1                 0x020C
+#define RATE_LIMIT_REGISTER2                 0x030C
+#define RATE_LIMIT_REGISTER3                 0x040C
+#define RATE_LIMIT_REGISTER4                 0x050C
+#define RATE_LIMIT_REGISTER5                 0x060C
+
+#define PORT_CONTROL_REGISTER0               0x0104
+#define PORT_CONTROL_REGISTER1               0x0204
+#define PORT_CONTROL_REGISTER2               0x0304
+#define PORT_CONTROL_REGISTER3               0x0404
+#define PORT_CONTROL_REGISTER4               0x0504
+#define PORT_CONTROL_REGISTER5               0x0604
+
+#define CPU_PORT_REGISTER                    0x0078
+#define MDIO_CTRL_REGISTER                   0x0098
+
+#define S27_ARL_TBL_FUNC_REG0                0x0050
+#define S27_ARL_TBL_FUNC_REG1                0x0054
+#define S27_ARL_TBL_FUNC_REG2                0x0058
+#define S27_FLD_MASK_REG                     0x002c
+#define S27_ARL_TBL_CTRL_REG                 0x005c
+#define S27_GLOBAL_INTR_REG                  0x10
+#define S27_GLOBAL_INTR_MASK_REG             0x14
+
+
+#define S27_ENABLE_CPU_BROADCAST             (1 << 26)
+#define S27_ENABLE_CPU_BCAST_FWD             (1 << 25)
+
+#define PHY_LINK_CHANGE_REG                 0x4
+#define PHY_LINK_UP                         0x400
+#define PHY_LINK_DOWN                       0x800
+#define PHY_LINK_DUPLEX_CHANGE                      0x2000
+#define PHY_LINK_SPEED_CHANGE               0x4000
+#define PHY_LINK_INTRS                      (PHY_LINK_UP | PHY_LINK_DOWN | PHY_LINK_DUPLEX_CHANGE | PHY_LINK_SPEED_CHANGE)
+
+/* SWITCH QOS REGISTERS */
+
+#define ATHR_QOS_PORT_0                        0x110 /* CPU PORT */
+#define ATHR_QOS_PORT_1                        0x210
+#define ATHR_QOS_PORT_2                        0x310
+#define ATHR_QOS_PORT_3                        0x410
+#define ATHR_QOS_PORT_4                        0x510
+
+#define ATHR_ENABLE_TOS                 (1 << 16)
+
+#define ATHR_QOS_MODE_REGISTER          0x030
+#define ATHR_QOS_FIXED_PRIORITY        ((0 << 31) | (0 << 28))
+#define ATHR_QOS_WEIGHTED              ((1 << 31) | (0 << 28)) /* Fixed weight 8,4,2,1 */
+#define ATHR_QOS_MIXED                 ((1 << 31) | (1 << 28)) /* Q3 for managment; Q2,Q1,Q0 - 4,2,1 */
+
+#ifndef BOOL
+#define BOOL    int
+#endif
+
+#define sysMsDelay(_x) udelay((_x) * 1000)
+#define mdelay(_x)      sysMsDelay(_x)
+
+#undef S27_VER_1_0
+
+/*
+ *  Atheros header defines
+ */
+#ifndef _ATH_HEADER_CONF
+#define _ATH_HEADER_CONF
+
+typedef enum {
+    NORMAL_PACKET,
+    RESERVED0,
+    MIB_1ST,
+    RESERVED1,
+    RESERVED2,
+    READ_WRITE_REG,
+    READ_WRITE_REG_ACK,
+    RESERVED3
+} AT_HEADER_TYPE;
+
+typedef struct {
+    uint16_t    reserved0  :2;
+    uint16_t    priority   :2;
+    uint16_t    type       :4;
+    uint16_t    broadcast  :1;
+    uint16_t    from_cpu   :1;
+    uint16_t    reserved1  :2;
+    uint16_t    port_num   :4;
+}at_header_t;
+
+#define ATHR_HEADER_LEN 2
+
+#endif // _ATH_HEADER_CONF
+
+typedef enum {
+    PORT_EG_UNMODIFIED = 0,  /**<  egress transmit packets unmodified */
+    PORT_EG_UNTAGGED,        /**<  egress transmit packets without vlan tag */
+    PORT_EG_TAGGED,          /**<  egress transmit packets with vlan tag */
+} port_1q_egmode_t;
+
+extern void set_packet_inspection_flag(int flag);
+
+#endif
index 0dc763c0f88b586208b5c73b39e82d4eb9ec2c1b..8f822cae4e02662ae56a011129503f7c3ca596fd 100755 (executable)
@@ -67,6 +67,14 @@ lowlevel_init:
        set_bb_pll(DPLL3_ADDRESS_48, 0x03000000);       // 0x18116248 (AR934X_SRIF_DDR_DPLL3_REG)
        set_bb_pll(DPLL3_ADDRESS_88, 0x03000000);       // 0x18116188 (??)
 
+ref_recognition:
+       li      t5,     KSEG1ADDR(WASP_BOOTSTRAP_REG);
+       li      t6,     WASP_REF_CLK_25
+       lw      t7,     0(t5);
+       and     t6,     t7,     t6
+       beq     zero,   t6,     setup_ref25_val
+       nop
+
 setup_ref40_val:
        li      t5,     CPU_PLL_CONFIG_NINT_VAL_40
        li      t6,     DDR_PLL_CONFIG_NINT_VAL_40
@@ -75,6 +83,12 @@ setup_ref40_val:
        b       1f
        nop
 
+setup_ref25_val:
+       li      t5,     CPU_PLL_CONFIG_NINT_VAL_25
+       li      t6,     DDR_PLL_CONFIG_NINT_VAL_25
+       li      t7,     CPU_PLL_NFRAC_25
+       li      t9,     DDR_PLL_NFRAC_25
+
 1:
        li      t4,     (CPU_PLL_DITHER_DITHER_EN_SET(0) | CPU_PLL_DITHER_NFRAC_STEP_SET(1) | CPU_PLL_DITHER_UPDATE_COUNT_SET(0xf));
        or      t4,     t4,     t7
@@ -117,10 +131,37 @@ init_ahb_pll:
                        CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(1) | \
                        CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(1));
        sw      t8,     0(t7);
-       li      t4,     0x41c00000;
-       li      t5,     0x41680000;
+
+       /* Use built in values, based on ref clock */
+       li      t5,     KSEG1ADDR(WASP_BOOTSTRAP_REG);
+       li      t6,     WASP_REF_CLK_25
+       lw      t7,     0(t5);
+       and     t6,     t7,     t6
+       beq     zero,   t6,     1f
+       nop
+#if !defined(CONFIG_AP123)
+       /*              refdiv          nint            nfrac */
+       li      t4,     ((0x8 << 27) | (112 << 18) | 0);// cpu freq = (40 MHz refclk/refdiv 8) * Nint
+       li      t5,     ((0x8 << 27) | (96 << 18) | 0); // ddr freq = (40 MHz refclk/refdiv 8) * Nint
+       j       2f
+       nop
+1:
+       li      t4,     ((0x5 << 27) | (112 << 18) | 0);// cpu freq = (25 MHz refclk/refdiv 8) * Nint
+       li      t5,     ((0x5 << 27) | (96 << 18) | 0); // ddr freq = (25 MHz refclk/refdiv 8) * Nint
        j       2f
        nop
+#else  /* defined(CONFIG_AP123) */
+       /*              refdiv          nint            nfrac */
+       li      t4,     ((0x8 << 27) | (107 << 18) | 0);// cpu freq = (40 MHz refclk/refdiv 8) * Nint
+       li      t5,     ((0x8 << 27) | (160 << 18) | 0);// ddr freq = (40 MHz refclk/refdiv 8) * Nint
+       j       2f
+       nop
+1:
+       li      t4,     ((0x5 << 27) | (107 << 18) | 0);// cpu freq = (25 MHz refclk/refdiv 8) * Nint
+       li      t5,     ((0x5 << 27) | (160 << 18) | 0);// ddr freq = (25 MHz refclk/refdiv 8) * Nint
+       j       2f
+       nop
+#endif /* !defined(CONFIG_AP123) */
 
 /* CPU */
 2:
@@ -178,11 +219,20 @@ cpu_read_sqsum_dvc:
 
 ddr_pll_is_not_locked:
        inc_loop_count(ATH_DDR_COUNT_LOC)
+#if !defined(CONFIG_AP123)
        set_srif_pll(0xb8116244, (0x4 << 26) | (0x10 << 19) | (0x1e << 7) | (1 << 16));
        set_srif_pll_reg(0xb8116240, t5);
        set_srif_pll(0xb8116244, (0x3 << 30) | (0x4 << 26) | (0x10 << 19) | (0x1e << 7) | (1 << 16));
        set_srif_pll(0xb8116248, (6 << 23));
        set_srif_pll(0xb8116244, (0x3 << 30) | (0x4 << 26) | (0x10 << 19) | (0x1e << 7));
+#else /* defined(CONFIG_AP123) */
+       /* AP123 uses outdiv = 1 for ddr pll */
+       set_srif_pll(0xb8116244, (0x4 << 26) | (0x10 << 19) | (1 << 13) | (0x1e << 7) | (1 << 16));
+       set_srif_pll_reg(0xb8116240, t5);
+       set_srif_pll(0xb8116244, (0x1 << 30) | (0x4 << 26) | (0x10 << 19) | (1 << 13) | (0x1e << 7) | (1 << 16));
+       set_srif_pll(0xb8116248, (6 << 23));
+       set_srif_pll(0xb8116244, (0x1 << 30) | (0x4 << 26) | (0x10 << 19) | (1 << 13) | (0x1e << 7));
+#endif /* !defined(CONFIG_AP123) */
 
 ddr_clear_do_meas1:
        li      t7,     KSEG1ADDR(DDR_DPLL3_ADDRESS)
index c01ba396aa24729039bc64def5d912b07808eb31..dbf98a480d122d1e0da28b7d480361c346087320 100755 (executable)
@@ -2,7 +2,15 @@ include $(TOPDIR)/config.mk
 
 LIB    = lib$(BOARD).a
 
-OBJS   = $(BOARD).o ../common/ar7240_pci.o ../common/ar7240_flash.o ../common/athrs17_phy.o
+OBJS   = $(BOARD).o ../common/ar7240_pci.o ../common/ar7240_flash.o
+
+ifeq ($(ETH_CONFIG), _s17)
+OBJS   += ../common/athrs17_phy.o
+endif
+
+ifeq ($(ETH_CONFIG), _s27)
+OBJS   += ../common/athrs27_phy.o
+endif
 
 SOBJS  = ../common/lowlevel_init_934x.o
 
index 12a0b476f4cbc58a5cf759bb612e5d3cce810780..9e27175347d0c7b41358c309b2c88f37442d7c10 100755 (executable)
@@ -33,7 +33,7 @@ extern void athrs26_reg_init_lan(void);
 extern int athrs26_mdc_check(void);\r
 #endif\r
 \r
-#ifdef  CONFIG_ATHRS17_PHY\r
+#ifdef  CFG_ATHRS17_PHY\r
 extern void athrs17_reg_init(void);\r
 #endif\r
 \r
@@ -145,7 +145,7 @@ void ag7240_mii_setup(ag7240_mac_t *mac){
                ar7240_reg_wr(AR934X_SWITCH_CLOCK_SPARE, 0x570);\r
        }\r
 \r
-#if defined(CONFIG_AR7242_S16_PHY) || defined(CONFIG_ATHRS17_PHY)\r
+#if defined(CONFIG_AR7242_S16_PHY) || defined(CFG_ATHRS17_PHY)\r
        if(is_wasp() && mac->mac_unit == 0){\r
 #ifdef CONFIG_AR7242_S16_PHY\r
                //printf("WASP  ----> S16 PHY *\n");\r
@@ -655,7 +655,7 @@ int ag7240_enet_initialize(bd_t * bis){
                        } else\r
 #endif\r
                        {\r
-#ifdef  CONFIG_ATHRS17_PHY\r
+#ifdef  CFG_ATHRS17_PHY\r
                        athrs17_reg_init();\r
 #endif\r
 \r
index 5ae745da6560ef82ca9b3bf7df7af08987f70b05..c187137a9dbcd134791d9f069bd8cc38ff36b8d9 100755 (executable)
@@ -12,7 +12,7 @@ static inline void ag7240_phy_setup(int unit) {
                athrs16_phy_setup(unit);\r
        } else\r
 #endif\r
-#ifdef CONFIG_ATHRS17_PHY\r
+#ifdef CFG_ATHRS17_PHY\r
     if (unit == 0) {\r
         athrs17_phy_setup(unit);\r
     } else\r
@@ -39,7 +39,7 @@ static inline void ag7240_phy_link(int unit, int *link) {
          *link = athrs16_phy_is_up(unit);\r
     } else\r
 #endif\r
-#ifdef CONFIG_ATHRS17_PHY\r
+#ifdef CFG_ATHRS17_PHY\r
     if (unit == 0) {\r
          *link = athrs17_phy_is_up(unit);\r
     } else\r
@@ -66,7 +66,7 @@ static inline void ag7240_phy_duplex(int unit, int *duplex) {
         *duplex = athrs16_phy_is_fdx(unit);\r
     } else\r
 #endif\r
-#ifdef CONFIG_ATHRS17_PHY\r
+#ifdef CFG_ATHRS17_PHY\r
     if (unit == 0) {\r
         *duplex = athrs17_phy_is_fdx(unit);\r
     } else\r
@@ -93,7 +93,7 @@ static inline void ag7240_phy_speed(int unit, int *speed) {
         *speed = athrs16_phy_speed(unit);\r
     } else\r
 #endif\r
-#ifdef CONFIG_ATHRS17_PHY\r
+#ifdef CFG_ATHRS17_PHY\r
     if (unit == 0) {\r
         *speed = athrs17_phy_speed(unit);\r
     } else\r
index edd3cf87107b127fb90e32d1649722b380eea90b..82d872c2ed2b7f6d012ec579950bfb28e1f4610b 100755 (executable)
@@ -71,6 +71,7 @@
 #define CFG_PLL_566_500_250                    102
 #define CFG_PLL_600_1_2G_400_200       103
 #define CFG_PLL_560_480_240                    104
+#define CFG_PLL_533_400_200                    105
 
 /*-----------------------------------------------------------------------
  * Cache Configuration
index ee1febb9b6f5cb08e7b92c5a3906cbc895469b95..98d6397c42ebaed1d0cfec62808a8df1edaab12c 100755 (executable)
 #undef CFG_HZ\r
 \r
 // CPU-RAM-AHB frequency setting\r
+#if !defined(CONFIG_AP123)\r
 #define CFG_PLL_FREQ                           CFG_PLL_560_480_240\r
 #define CFG_HZ_FALLBACK                                (560000000LU/2)\r
+#else\r
+#define CFG_PLL_FREQ                           CFG_PLL_533_400_200\r
+#define CFG_HZ_FALLBACK                                (535000000LU/2)\r
+#endif\r
+\r
 #define        CFG_HZ                                          bd->bi_cfg_hz\r
 #define AR7240_SPI_CONTROL                     0x43\r
 #define AR7240_SPI_CONTROL_DEFAULT     AR7240_SPI_CONTROL\r