summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/arch/mips/board/bcm63xx_ram/src/robosw_reg.c
diff options
context:
space:
mode:
Diffstat (limited to 'cfe/cfe/arch/mips/board/bcm63xx_ram/src/robosw_reg.c')
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/robosw_reg.c615
1 files changed, 615 insertions, 0 deletions
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/robosw_reg.c b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/robosw_reg.c
new file mode 100755
index 0000000..15dad53
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/robosw_reg.c
@@ -0,0 +1,615 @@
+/*
+<:copyright-broadcom
+
+ Copyright (c) 2007 Broadcom Corporation
+ All Rights Reserved
+ No portions of this material may be reproduced in any form without the
+ written permission of:
+ Broadcom Corporation
+ 16215 Alton Parkway
+ Irvine, California 92619
+ All information contained in this document is Broadcom Corporation
+ company private, proprietary, and trade secret.
+
+:>
+*/
+
+#include "bcm_map.h"
+#include "lib_types.h"
+#include "lib_malloc.h"
+#include "lib_string.h"
+#include "lib_printf.h"
+#include "mii.h"
+#include "bcmmii.h"
+#include "sbmips.h"
+#include "cfe_iocb.h"
+#include "cfe_timer.h"
+#include "robosw_reg.h"
+#include "dev_bcm63xx_eth.h"
+#include "bcmSpiRes.h"
+
+static uint32 mii_read(uint32 uPhyAddr, uint32 uRegAddr);
+static void mii_write(uint32 uPhyAddr, uint32 uRegAddr, uint32 data);
+
+static int ext_switch_init(void);
+static int ethsw_spi_ss_id(void);
+static void ethsw_spi_select(int page);
+static void ethsw_spi_rreg(int page, int reg, uint8 *data, int len);
+static void ethsw_spi_wreg(int page, int reg, uint8 *data, int len);
+
+void ethsw_rreg_ext(int access_type, int page, int reg, uint8 *data, int len);
+void ethsw_wreg_ext(int access_type, int page, int reg, uint8 *data, int len);
+
+
+static ETHERNET_MAC_INFO EnetInfo[BP_MAX_ENET_MACS];
+static uint16 PortLinkState[BP_MAX_SWITCH_PORTS];
+
+#define MDIO_BUS 0
+#define SPI_BUS 1
+#define TX_BDS 3
+#define RX_BDS 16
+#define CACHE_ALIGN 16
+#define BUF_LENGTH 160
+extern void _cfe_flushcache(int, uint8_t *, uint8_t *);
+#define INVAL_RANGE(s,l) _cfe_flushcache(CFE_CACHE_INVAL_RANGE,((uint8_t *) (s)),((uint8_t *) (s))+(l))
+
+/* read a value from the MII */
+static uint32 mii_read(uint32 uPhyAddr, uint32 uRegAddr)
+{
+ SWITCH->MdioCtrl = 0x0;
+ SWITCH->MdioCtrl = MdioCtrl_Read | (IsExtPhyId(uPhyAddr) ? MdioCtrl_Ext : 0) |
+ ((uPhyAddr << MdioCtrl_ID_Shift) & MdioCtrl_ID_Mask) |
+ (uRegAddr << MdioCtrl_Addr_Shift);
+ cfe_usleep(100);
+ return SWITCH->MdioData;
+}
+
+/* write a value to the MII */
+static void mii_write(uint32 uPhyAddr, uint32 uRegAddr, uint32 data)
+{
+ SWITCH->MdioCtrl = 0x0;
+ SWITCH->MdioCtrl = MdioCtrl_Write | (IsExtPhyId(uPhyAddr) ? MdioCtrl_Ext : 0) |
+ ((uPhyAddr << MdioCtrl_ID_Shift) & MdioCtrl_ID_Mask) |
+ (uRegAddr << MdioCtrl_Addr_Shift) | data;
+ cfe_usleep(100);
+}
+
+static int clkHz = 781000;
+#if !defined(_BCM96328_)
+static int clk781k = 2;
+#endif
+static int ethsw_spi_ss_id()
+{
+ int slave_select;
+
+ switch(EnetInfo[1].usConfigType) {
+ case BP_ENET_CONFIG_SPI_SSB_0:
+ slave_select = 0;
+ break;
+ case BP_ENET_CONFIG_SPI_SSB_1:
+ slave_select = 1;
+ break;
+ case BP_ENET_CONFIG_SPI_SSB_2:
+ slave_select = 2;
+ break;
+ case BP_ENET_CONFIG_SPI_SSB_3:
+ slave_select = 3;
+ break;
+ default:
+ slave_select = 1;
+ xprintf("Invalid SPI_SS in usConfigType, Assuming 1\n");
+ break;
+ }
+ return slave_select;
+}
+
+static void ethsw_spi_select(int page)
+{
+ unsigned char buf[3];
+ int spi_ss, cid = 0;
+
+ spi_ss = ethsw_spi_ss_id();
+ /* Select new chip */
+ buf[0] = BCM5325_SPI_CMD_NORMAL | BCM5325_SPI_CMD_WRITE |
+ ((cid & BCM5325_SPI_CHIPID_MASK) << BCM5325_SPI_CHIPID_SHIFT);
+
+ /* Select new page */
+ buf[1] = PAGE_SELECT;
+ buf[2] = (char)page;
+#if defined(_BCM96328_)
+ BcmSpi_Write(buf, sizeof(buf), HS_SPI_BUS_NUM, spi_ss, clkHz);
+#else
+ BcmSpi_Write(buf, sizeof(buf), LEG_SPI_BUS_NUM, spi_ss, clkHz);
+#endif
+
+}
+
+static void ethsw_spi_rreg(int page, int reg, uint8 *data, int len)
+{
+ unsigned char buf[64];
+ int rc;
+ int i;
+ int max_check_spi_sts;
+ int prependCnt = BCM5325_SPI_PREPENDCNT, spi_ss, cid = 0;
+
+ spi_ss = ethsw_spi_ss_id();
+
+ ethsw_spi_select(page);
+
+ /* write command byte and register address */
+ buf[0] = BCM5325_SPI_CMD_NORMAL | BCM5325_SPI_CMD_READ |
+ ((cid & BCM5325_SPI_CHIPID_MASK) << BCM5325_SPI_CHIPID_SHIFT);
+ buf[1] = (unsigned char)reg;
+#if defined(_BCM96328_)
+ rc = BcmSpi_Read(buf, prependCnt, 1, HS_SPI_BUS_NUM, spi_ss, clkHz);
+#else
+ rc = BcmSpi_Read(buf, prependCnt, 1, LEG_SPI_BUS_NUM, spi_ss, clkHz);
+#endif
+
+ if (rc == SPI_STATUS_OK) {
+ max_check_spi_sts = 0;
+ do {
+ /* write command byte and read spi_sts address */
+ buf[0] = BCM5325_SPI_CMD_NORMAL | BCM5325_SPI_CMD_READ |
+ ((cid & BCM5325_SPI_CHIPID_MASK) << BCM5325_SPI_CHIPID_SHIFT);
+ buf[1] = (unsigned char)BCM5325_SPI_STS;
+#if defined(_BCM96328_)
+ rc = BcmSpi_Read(buf, prependCnt, 1, HS_SPI_BUS_NUM, spi_ss, clkHz);
+#else
+ rc = BcmSpi_Read(buf, prependCnt, 1, LEG_SPI_BUS_NUM, spi_ss, clkHz);
+#endif
+ if (rc == SPI_STATUS_OK) {
+ /* check the bit 0 RACK bit is set */
+ if (buf[0] & BCM5325_SPI_CMD_RACK) {
+ break;
+ }
+ cfe_usleep(10000);
+ } else {
+ break;
+ }
+ } while (max_check_spi_sts++ < 10);
+
+ if (rc == SPI_STATUS_OK) {
+ for (i = 0; i < len; i++) {
+ buf[0] = BCM5325_SPI_CMD_NORMAL | BCM5325_SPI_CMD_READ |
+ ((cid & BCM5325_SPI_CHIPID_MASK) << BCM5325_SPI_CHIPID_SHIFT);
+ buf[1] = (unsigned char)0xf0;
+#if defined(_BCM96328_)
+ rc = BcmSpi_Read(buf, prependCnt, 1, HS_SPI_BUS_NUM, spi_ss, clkHz);
+#else
+ rc = BcmSpi_Read(buf, prependCnt, 1, LEG_SPI_BUS_NUM, spi_ss, clkHz);
+#endif
+ if (rc == SPI_STATUS_OK) {
+ *(data + (len - i - 1)) = buf[0];
+ }
+ }
+ }
+ }
+}
+
+static void ethsw_spi_wreg(int page, int reg, uint8 *data, int len)
+{
+ unsigned char buf[64];
+ int i;
+ int spi_ss, cid = 0;
+
+ ethsw_spi_select(page);
+
+ spi_ss = ethsw_spi_ss_id();
+ buf[0] = BCM5325_SPI_CMD_NORMAL | BCM5325_SPI_CMD_WRITE |
+ ((cid & BCM5325_SPI_CHIPID_MASK) << BCM5325_SPI_CHIPID_SHIFT);
+
+ buf[1] = (char)reg;
+ for (i = 0; i < len; i++) {
+ /* Write the data out in LE format to the switch */
+ buf[BCM5325_SPI_PREPENDCNT+i] = *(data + (len - i - 1));
+ }
+ BcmSpi_Write(buf, len+BCM5325_SPI_PREPENDCNT, LEG_SPI_BUS_NUM, spi_ss, clkHz);
+}
+
+/* External switch register access through MDC/MDIO */
+static void ethsw_mdio_rreg(int page, int reg, uint8 *data, int len)
+{
+ uint32 cmd, res, ret;
+ int max_retry = 0;
+
+ cmd = (page << REG_PPM_REG16_SWITCH_PAGE_NUMBER_SHIFT) | REG_PPM_REG16_MDIO_ENABLE;
+ mii_write(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG16, cmd);
+
+ cmd = (reg << REG_PPM_REG17_REG_NUMBER_SHIFT) | REG_PPM_REG17_OP_READ;
+ mii_write(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17, cmd);
+
+ do {
+ res = mii_read(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17);
+ cfe_usleep(10);
+ } while (((res & (REG_PPM_REG17_OP_WRITE|REG_PPM_REG17_OP_READ)) != REG_PPM_REG17_OP_DONE) &&
+ (max_retry++ < 5));
+
+ ret = 0;
+ ret |= mii_read(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG24) << 0;
+ ret |= mii_read(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG25) << 16;
+ switch (len) {
+ case 1:
+ *data = (uint8)ret;
+ break;
+ case 2:
+ *(uint16 *)data = (uint16)ret;
+ break;
+ case 4:
+ *(uint32 *)data = ret;
+ break;
+ }
+}
+
+static void ethsw_mdio_wreg(int page, int reg, uint8 *data, int len)
+{
+ uint32 cmd, res;
+ uint32 val = 0;
+ int max_retry = 0;
+
+ switch (len) {
+ case 1:
+ val = *data;
+ break;
+ case 2:
+ val = *(uint16 *)data;
+ break;
+ case 4:
+ val = *(uint32 *)data;
+ break;
+ }
+ cmd = (page << REG_PPM_REG16_SWITCH_PAGE_NUMBER_SHIFT) | REG_PPM_REG16_MDIO_ENABLE;
+ mii_write(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG16, cmd);
+
+ cmd = val>>0 & 0xffff;
+ mii_write(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG24, cmd);
+ cmd = val>>16 & 0xffff;
+ mii_write(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG25, cmd);
+ cmd = 0;
+ mii_write(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG26, cmd);
+ cmd = 0;
+ mii_write(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG27, cmd);
+
+ cmd = (reg << REG_PPM_REG17_REG_NUMBER_SHIFT) | REG_PPM_REG17_OP_WRITE;
+ mii_write(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17, cmd);
+
+ do {
+ res = mii_read(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17);
+ cfe_usleep(10);
+ } while (((res & (REG_PPM_REG17_OP_WRITE|REG_PPM_REG17_OP_READ)) != REG_PPM_REG17_OP_DONE) &&
+ (max_retry++ < 5));
+}
+
+void ethsw_rreg_ext(int access_type, int page, int reg, uint8 *data, int len)
+{
+ if (access_type == MDIO_BUS) {
+ ethsw_mdio_rreg(page, reg, data, len);
+
+ } else {
+ ethsw_spi_rreg(page, reg, data, len);
+ }
+}
+
+void ethsw_wreg_ext(int access_type, int page, int reg, uint8 *data, int len)
+{
+ if (access_type == MDIO_BUS) {
+ ethsw_mdio_wreg(page, reg, data, len);
+ } else {
+ ethsw_spi_wreg(page, reg, data, len);
+ }
+}
+
+int ext_switch_init(void)
+{
+ uint8 data8;
+ uint32 data32, access_type;
+#if !defined(_BCM96328_)
+ uint32 clkSave;
+#endif
+
+ switch (EnetInfo[1].usConfigType) {
+ case BP_ENET_CONFIG_SPI_SSB_0:
+ case BP_ENET_CONFIG_SPI_SSB_1:
+ case BP_ENET_CONFIG_SPI_SSB_2:
+ case BP_ENET_CONFIG_SPI_SSB_3:
+ access_type = SPI_BUS;
+#if !defined(_BCM96328_)
+ clkSave = SPI->spiClkCfg & SPI_CLK_MASK;
+ xprintf("spiClkCfg = %x; clkSave = %d \n", SPI->spiClkCfg, clkSave);
+ SPI->spiClkCfg = (SPI->spiClkCfg & ~SPI_CLK_MASK) | clk781k;
+#endif
+ break;
+
+ case BP_ENET_CONFIG_MDIO_PSEUDO_PHY:
+ access_type = MDIO_BUS;
+ break;
+
+ default:
+ xprintf("Unknown PHY configuration type\n");
+ return -1;
+ }
+
+ ethsw_rreg_ext(access_type, PAGE_MANAGEMENT, REG_DEVICE_ID, (uint8 *)&data32, sizeof(data32));
+ xprintf("External switch id = %x \n", data32);
+
+ if (data32 == 0x53115)
+ {
+ /* setup Switch MII1 port state override */
+ data8 = (REG_CONTROL_MPSO_MII_SW_OVERRIDE |
+ REG_CONTROL_MPSO_SPEED1000 |
+ REG_CONTROL_MPSO_FDX |
+ REG_CONTROL_MPSO_LINKPASS);
+ ethsw_wreg_ext(access_type, PAGE_CONTROL,
+ REG_CONTROL_MII1_PORT_STATE_OVERRIDE, &data8, sizeof(data8));
+ /* management mode, enable forwarding */
+ data8 = REG_SWITCH_MODE_FRAME_MANAGE_MODE | REG_SWITCH_MODE_SW_FWDG_EN;
+ ethsw_wreg_ext(access_type, PAGE_CONTROL,
+ REG_SWITCH_MODE, &data8, sizeof(data8));
+ /* Enable IMP Port */
+ data8 = ENABLE_MII_PORT;
+ ethsw_wreg_ext(access_type, PAGE_MANAGEMENT,
+ REG_GLOBAL_CONFIG, &data8, sizeof(data8));
+ /* Disable BRCM Tag for IMP */
+ data8 = ~REG_BRCM_HDR_ENABLE;
+ ethsw_wreg_ext(access_type, PAGE_MANAGEMENT,
+ REG_BRCM_HDR_CTRL, &data8, sizeof(data8));
+ /* enable rx bcast, ucast and mcast of imp port */
+ data8 = (REG_MII_PORT_CONTROL_RX_UCST_EN |
+ REG_MII_PORT_CONTROL_RX_MCST_EN |
+ REG_MII_PORT_CONTROL_RX_BCST_EN);
+ ethsw_wreg_ext(access_type, PAGE_CONTROL, REG_MII_PORT_CONTROL, &data8, sizeof(data8));
+ }
+
+#if !defined(_BCM96328_)
+ if (access_type == SPI_BUS)
+ SPI->spiClkCfg = (SPI->spiClkCfg & ~SPI_CLK_MASK) | clkSave;
+#endif
+ return 0;
+}
+
+
+void robosw_init(void)
+{
+ int port;
+
+ BpGetEthernetMacInfo(EnetInfo, BP_MAX_ENET_MACS);
+
+ // Power up and reset EPHYs
+ GPIO->RoboswEphyCtrl = 0;
+ cfe_usleep(1000);
+
+ // Take EPHYs out of reset
+ GPIO->RoboswEphyCtrl =
+ EPHY_RST_4 |
+ EPHY_RST_3 |
+ EPHY_RST_2 |
+ EPHY_RST_1;
+ cfe_usleep(1000);
+
+#if defined(_BCM96328_) || defined(_BCM96362_)
+ GPIO->RoboswSwitchCtrl |= (RSW_MII_DUMB_FWDG_EN | RSW_HW_FWDG_EN);
+#endif
+#if defined(_BCM96368_) || defined(_BCM96816_)
+ GPIO->RoboswEphyCtrl |= (RSW_MII_DUMB_FWDG_EN | RSW_HW_FWDG_EN);
+#endif
+
+ // Enable Switch clock
+ PERF->blkEnables |= ROBOSW_CLK_EN;
+#if defined(_BCM96368_)
+ PERF->blkEnables |= SWPKT_SAR_CLK_EN | SWPKT_USB_CLK_EN;
+#endif
+#if defined(_BCM96816_)
+ PERF->blkEnables |= SWPKT_GPON_CLK_EN | SWPKT_USB_CLK_EN;
+#endif
+
+ cfe_usleep(1000);
+
+ PERF->softResetB &= ~SOFT_RST_SWITCH;
+ cfe_usleep(1000);
+ PERF->softResetB |= SOFT_RST_SWITCH;
+ cfe_usleep(1000);
+
+ /* Disable Rx and Tx on all Ethernet Ports */
+ for (port = 0; port < EPHY_PORTS; port++) {
+ SWITCH->PortCtrl[port] = 0x03;
+ }
+
+ if (EnetInfo[1].ucPhyType == BP_ENET_EXTERNAL_SWITCH) {
+ ext_switch_init();
+ }
+
+}
+
+void robosw_configure_ports()
+{
+ uint16 data;
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ if ((EnetInfo[0].sw.port_map & (1 << i)) != 0) {
+ if (EnetInfo[0].sw.phy_id[i] == 0xff) {
+#if defined(_BCM96368_)
+ if (i == 4)
+ GPIO->GPIOBaseMode |= (EN_GMII1);
+ if (i == 5)
+ GPIO->GPIOBaseMode |= (EN_GMII2);
+#endif
+ continue;
+ }
+ if (IsWanPort(EnetInfo[0].sw.phy_id[i])) {
+ *(SWITCH_PBVLAN + i) = PBMAP_MIPS;
+ SWITCH->DisableLearn |= (1 << i);
+ }
+ // Reset
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_BMCR, BMCR_RESET);
+ PortLinkState[i] = 0;
+ if (!IsExtPhyId(EnetInfo[0].sw.phy_id[i])) {
+ // Configure PHY link/act LED
+#if defined(_BCM96368_)
+ // Enable status change notification */
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_INTERRUPT, MII_INTR_ENABLE);
+ // Configure LEDs
+ data = mii_read(EnetInfo[0].sw.phy_id[i], MII_RESERVED_1B);
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_RESERVED_1B, data | MII_RESERVED_1B_ACT_LED);
+#elif defined(_BCM96816_)
+ // Configure LEDs
+ mii_write(EnetInfo[0].sw.phy_id[i], 0x1c, 0xa410);
+#elif defined(_BCM96328_) || defined(_BCM96362_)
+ // Configure LEDs
+ // Enable Shadow register 2
+ data = mii_read(EnetInfo[0].sw.phy_id[i], MII_BRCM_TEST);
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_BRCM_TEST, (data | MII_BRCM_TEST_SHADOW2_ENABLE));
+ // Set LED0 to speed. Set LED1 to blinky link
+ mii_write(EnetInfo[0].sw.phy_id[i], 0x15, 0x71);
+ // Disable Shadow register 2
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_BRCM_TEST, (data & ~MII_BRCM_TEST_SHADOW2_ENABLE));
+#endif
+ } else {
+#if defined(_BCM96368_)
+ if (i == 4)
+ GPIO->GPIOBaseMode |= (EN_GMII1);
+ if (i == 5)
+ GPIO->GPIOBaseMode |= (EN_GMII2);
+#endif
+#if defined(_BCM96816_)
+ if (i == 2)
+ GPIO->GPIOBaseMode |= (EN_GMII1);
+ if (i == 3)
+ GPIO->GPIOBaseMode |= (EN_GMII2);
+#endif
+#if defined(_BCM96362_)
+ if (i == 4)
+ GPIO->RoboswSwitchCtrl |= (RSW_MII_SEL_2P5V << RSW_MII_SEL_SHIFT);
+ if (i == 5)
+ GPIO->RoboswSwitchCtrl |= (RSW_MII_2_IFC_EN | (RSW_MII_SEL_2P5V << RSW_MII_2_SEL_SHIFT));
+#endif
+#if defined(_BCM96328_)
+ if (i == 4)
+ MISC->miscPadCtrlHigh |= (MISC_MII_SEL_2P5V << MISC_MII_SEL_SHIFT);
+#endif
+ // Reset
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_BMCR, BMCR_RESET);
+ // Enable auto-negotiation
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_ANAR, ANAR_TXFD | ANAR_TXHD | ANAR_10FD | ANAR_10HD | PSB_802_3);
+
+ // Configure LED for link/activity
+ data = MII_1C_SHADOW_LED_CONTROL << MII_1C_SHADOW_REG_SEL_S;
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C, data);
+ data = mii_read(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C);
+ data |= ACT_LINK_LED_ENABLE;
+ data |= MII_1C_WRITE_ENABLE;
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C, data);
+
+ data = mii_read(EnetInfo[0].sw.phy_id[i], MII_PHYIDR2);
+ if ((data & BCM_PHYID_M) == (BCM54610_PHYID2 & BCM_PHYID_M)) {
+ // Configure RGMII timing for 54610 GPHY
+ data = MII_1C_SHADOW_CLK_ALIGN_CTRL << MII_1C_SHADOW_REG_SEL_S;
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C, data);
+ data = mii_read(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C);
+ data &= (~GTXCLK_DELAY_BYPASS_DISABLE);
+ data |= MII_1C_WRITE_ENABLE;
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C, data);
+
+ // Configure LOM LED Mode
+ data = MII_1C_EXTERNAL_CONTROL_1 << MII_1C_SHADOW_REG_SEL_S;
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C, data);
+ data = mii_read(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C);
+ data |= LOM_LED_MODE;
+ data |= MII_1C_WRITE_ENABLE;
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C, data);
+ }
+ }
+ // Restart auto-negotiation
+ data = mii_read(EnetInfo[0].sw.phy_id[i], MII_BMCR);
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_BMCR, data | BMCR_RESTARTAN);
+ }
+ }
+
+#if defined(_BCM96816_)
+ // Disable SERDES, MoCA, USB and GPON port
+ SWITCH->PortOverride[SERDES_PORT_ID] = PortOverride_Enable;
+ SWITCH->PortOverride[MOCA_PORT_ID] = PortOverride_Enable;
+ SWITCH->PortOverride[USB_PORT_ID] = PortOverride_Enable;
+ SWITCH->PortOverride[GPON_PORT_ID] = PortOverride_Enable;
+#endif
+
+#if defined(_BCM96328_) || defined(_BCM96362_)
+ // Ports 6 and 7 are not used on 6328 and 6362
+ SWITCH->PortOverride[PORT_6_PORT_ID] = PortOverride_Enable;
+ SWITCH->PortOverride[PORT_7_PORT_ID] = PortOverride_Enable;
+#endif
+
+#if defined(_BCM96368_)
+ // Disable SAR and USB port
+ SWITCH->PortOverride[USB_PORT_ID] = PortOverride_Enable;
+ SWITCH->PortOverride[SAR_PORT_ID] = PortOverride_Enable;
+#endif
+
+ // Enable the GMII clocks.
+ SWITCH->ImpRgmiiCtrlP4 |= ImpRgmiiCtrl_GMII_En;
+ /* RGMII Delay Programming. Enable ID mode */
+ SWITCH->ImpRgmiiCtrlP4 |= ImpRgmiiCtrl_Timing_Sel;
+
+#if !defined(_BCM96328_)
+ SWITCH->ImpRgmiiCtrlP5 |= ImpRgmiiCtrl_GMII_En;
+ SWITCH->ImpRgmiiCtrlP5 |= ImpRgmiiCtrl_Timing_Sel;
+#endif
+
+ // Reset MIB counters
+ SWITCH->GlbMgmt = GlbMgmt_ResetMib;
+ cfe_usleep(100);
+ SWITCH->GlbMgmt = 0;
+
+ SWITCH->ImpOverride |= ImpOverride_Force | ImpOverride_Linkup;
+
+}
+
+void robosw_check_ports()
+{
+ uint16 data;
+ uint8 PortOverride;
+ int i;
+
+ for (i = 0; i < EPHY_PORTS; i++) {
+ if ((EnetInfo[0].sw.port_map & (1 << i)) != 0) {
+ if (EnetInfo[0].sw.phy_id[i] == 0xff) {
+ PortOverride = PortOverride_Enable | PortOverride_1000Mbs |
+ PortOverride_Fdx | PortOverride_Linkup;
+ if ((SWITCH->PortOverride[i] & PortOverride) != PortOverride) {
+ SWITCH->PortOverride[i] = PortOverride;
+ SWITCH->PortCtrl[i] = 0;
+ PortLinkState[i] = 1;
+ }
+ continue;
+ }
+ PortOverride = PortOverride_Enable;
+ data = mii_read(EnetInfo[0].sw.phy_id[i], MII_ASR);
+ if (PortLinkState[i] != MII_ASR_LINK(data)) {
+
+ if (MII_ASR_LINK(data))
+ PortOverride |= PortOverride_Linkup;
+
+ if (MII_ASR_DONE(data)) {
+ if (MII_ASR_FDX(data))
+ PortOverride |= PortOverride_Fdx;
+ if (MII_ASR_1000(data))
+ PortOverride |= PortOverride_1000Mbs;
+ else if (MII_ASR_100(data))
+ PortOverride |= PortOverride_100Mbs;
+ else
+ PortOverride |= PortOverride_10Mbs;
+ }
+
+ SWITCH->PortOverride[i] = PortOverride;
+
+ if(PortOverride & PortOverride_Linkup) {
+ /* Enable Rx and Tx */
+ SWITCH->PortCtrl[i] = 0;
+ }
+
+ PortLinkState[i] = MII_ASR_LINK(data);
+ }
+ }
+ }
+}
+