mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2026-03-07 17:57:38 +01:00
Merge "board: arm: devsoc: add QCA8033 ethernet PHY support"
This commit is contained in:
commit
ced5244d01
14 changed files with 1945 additions and 53 deletions
|
|
@ -41,4 +41,14 @@ config IPQ_TINY_SPI_NOR
|
|||
|
||||
config ART_COMPRESSED
|
||||
bool "Enable uncompress support"
|
||||
|
||||
config QCA8033_PHY
|
||||
bool "Enable QCA8033 PHY support"
|
||||
|
||||
config QCA8081_PHY
|
||||
bool "Enable QCA8081 PHY support"
|
||||
|
||||
config QCA8084_PHY
|
||||
depends on QCA8081_PHY
|
||||
bool "Enable QCA8084 PHY support"
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -100,7 +100,11 @@ CONFIG_CMD_SETEXPR=y
|
|||
#
|
||||
# Network PHY
|
||||
#
|
||||
CONFIG_IPQ_QCA_AQUANTIA_PHY=y
|
||||
CONFIG_QCA8033_PHY=y
|
||||
CONFIG_QCA8081_PHY=y
|
||||
CONFIG_QCA8084_PHY=y
|
||||
CONFIG_ATHRS17C_SWITCH=y
|
||||
|
||||
CONFIG_CMD_NET=y
|
||||
# CONFIG_CMD_TFTPPUT is not set
|
||||
|
|
|
|||
|
|
@ -110,3 +110,13 @@ config ZYNQ_GEM
|
|||
This MAC is present in Xilinx Zynq and ZynqMP SoCs.
|
||||
|
||||
endif # NETDEVICES
|
||||
|
||||
config IPQ_QCA_AQUANTIA_PHY
|
||||
bool "Aquantia PHY support"
|
||||
help
|
||||
Enable Aquantia PHY support.
|
||||
|
||||
config ATHRS17C_SWITCH
|
||||
bool "QTI S17C switch support"
|
||||
help
|
||||
Enable QTI S17C switch support.
|
||||
|
|
|
|||
|
|
@ -106,9 +106,11 @@ obj-$(CONFIG_QCA8075_PHY) += ipq_common/ipq_qca8075.o
|
|||
obj-$(CONFIG_QCA8084_PHY) += ipq_common/ipq_qca8084.o
|
||||
obj-$(CONFIG_QCA8084_PHY) += ipq_common/ipq_qca8084_clk.o
|
||||
obj-$(CONFIG_QCA8084_PHY) += ipq_common/ipq_qca8084_interface_ctrl.o
|
||||
obj-$(CONFIG_ATHRS17C_SWITCH) += ipq_common/athrs17_phy.o
|
||||
obj-$(CONFIG_IPQ9574_QCA8075_PHY) += ipq9574/ipq9574_qca8075.o
|
||||
obj-$(CONFIG_QCA8033_PHY) += ipq_common/ipq_qca8033.o
|
||||
obj-$(CONFIG_QCA8081_PHY) += ipq_common/ipq_qca8081.o
|
||||
obj-$(CONFIG_IPQ_QCA_AQUANTIA_PHY) += ipq_common/ipq_aquantia_phy.o
|
||||
obj-$(CONFIG_QCA_AQUANTIA_PHY) += ipq807x/ipq807x_aquantia_phy.o
|
||||
obj-$(CONFIG_IPQ6018_QCA_AQUANTIA_PHY) += ipq6018/ipq6018_aquantia_phy.o
|
||||
obj-$(CONFIG_IPQ9574_QCA_AQUANTIA_PHY) += ipq9574/ipq9574_aquantia_phy.o
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
**************************************************************************
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <net.h>
|
||||
#include <asm-generic/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <malloc.h>
|
||||
|
|
@ -49,9 +48,12 @@ static struct devsoc_eth_dev *devsoc_edma_dev[DEVSOC_EDMA_DEV];
|
|||
|
||||
uchar devsoc_def_enetaddr[6] = {0x00, 0x03, 0x7F, 0xBA, 0xDB, 0xAD};
|
||||
phy_info_t *phy_info[DEVSOC_PHY_MAX] = {0};
|
||||
phy_info_t *swt_info[QCA8084_MAX_PORTS] = {0};
|
||||
int sgmii_mode[2] = {0};
|
||||
|
||||
#ifndef CONFIG_DEVSOC_RUMI
|
||||
extern void ipq_phy_addr_fixup(void);
|
||||
extern void ipq_clock_init(void);
|
||||
extern int ipq_sw_mdio_init(const char *);
|
||||
extern int ipq_mdio_read(int mii_id, int regnum, ushort *data);
|
||||
extern void devsoc_qca8075_phy_map_ops(struct phy_ops **ops);
|
||||
|
|
@ -61,9 +63,27 @@ extern int ipq_qca8033_phy_init(struct phy_ops **ops, u32 phy_id);
|
|||
extern int ipq_qca8081_phy_init(struct phy_ops **ops, u32 phy_id);
|
||||
extern int ipq_qca_aquantia_phy_init(struct phy_ops **ops, u32 phy_id);
|
||||
extern int ipq_board_fw_download(unsigned int phy_addr);
|
||||
extern int ipq_qca8084_hw_init(phy_info_t * phy_info[]);
|
||||
extern int ipq_qca8084_link_update(phy_info_t * phy_info[]);
|
||||
extern void ipq_qca8084_switch_hw_reset(int gpio);
|
||||
|
||||
#ifdef CONFIG_ATHRS17C_SWITCH
|
||||
extern void ppe_uniphy_set_forceMode(uint32_t uniphy_index);
|
||||
|
||||
extern int ipq_qca8337_switch_init(ipq_s17c_swt_cfg_t *s17c_swt_cfg);
|
||||
extern int ipq_qca8337_link_update(ipq_s17c_swt_cfg_t *s17c_swt_cfg);
|
||||
extern void ipq_s17c_switch_reset(int gpio);
|
||||
ipq_s17c_swt_cfg_t s17c_swt_cfg;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int tftp_acl_our_port;
|
||||
#ifndef CONFIG_DEVSOC_RUMI
|
||||
#ifdef CONFIG_QCA8084_PHY
|
||||
static int qca8084_swt_enb = 0;
|
||||
static int qca8084_chip_detect = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* EDMA hardware instance
|
||||
|
|
@ -902,49 +922,70 @@ static int devsoc_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
*/
|
||||
for (i = 0; i < DEVSOC_PHY_MAX; i++) {
|
||||
#ifndef CONFIG_DEVSOC_RUMI
|
||||
if (!priv->ops[i]) {
|
||||
printf("Phy ops not mapped\n");
|
||||
if (phy_info[i]->phy_type == UNUSED_PHY_TYPE)
|
||||
continue;
|
||||
#ifdef CONFIG_QCA8084_PHY
|
||||
else if ((qca8084_swt_enb && qca8084_chip_detect) &&
|
||||
(phy_info[i]->phy_type == QCA8084_PHY_TYPE)) {
|
||||
if (!ipq_qca8084_link_update(swt_info))
|
||||
linkup++;
|
||||
continue;
|
||||
}
|
||||
phy_get_ops = priv->ops[i];
|
||||
|
||||
if (!phy_get_ops->phy_get_link_status ||
|
||||
!phy_get_ops->phy_get_speed ||
|
||||
!phy_get_ops->phy_get_duplex) {
|
||||
printf("Error:Link status/Get speed/Get duplex not mapped\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (phy_node >= 0) {
|
||||
/*
|
||||
* For each ethernet port, one node should be added
|
||||
* inside port_phyinfo with appropriate phy address
|
||||
*/
|
||||
phy_addr = phy_info[i]->phy_address;
|
||||
} else {
|
||||
printf("Error:Phy addresses not configured in DT\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = phy_get_ops->phy_get_link_status(priv->mac_unit, phy_addr);
|
||||
phy_get_ops->phy_get_speed(priv->mac_unit, phy_addr, &curr_speed[i]);
|
||||
phy_get_ops->phy_get_duplex(priv->mac_unit, phy_addr, &duplex);
|
||||
|
||||
if (status == 0) {
|
||||
linkup++;
|
||||
if (old_speed[i] == curr_speed[i]) {
|
||||
printf("eth%d PHY%d %s Speed :%d %s duplex\n",
|
||||
priv->mac_unit, i, lstatus[status], curr_speed[i],
|
||||
dp[duplex]);
|
||||
#endif
|
||||
#ifdef CONFIG_ATHRS17C_SWITCH
|
||||
else if (phy_info[i]->phy_type == ATHRS17C_SWITCH_TYPE) {
|
||||
if (s17c_swt_cfg.chip_detect) {
|
||||
if (!ipq_qca8337_link_update(&s17c_swt_cfg))
|
||||
linkup++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
if (!priv->ops[i]) {
|
||||
printf("Phy ops not mapped\n");
|
||||
continue;
|
||||
}
|
||||
phy_get_ops = priv->ops[i];
|
||||
|
||||
if (!phy_get_ops->phy_get_link_status ||
|
||||
!phy_get_ops->phy_get_speed ||
|
||||
!phy_get_ops->phy_get_duplex) {
|
||||
printf("Error:Link status/Get speed/Get duplex not mapped\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (phy_node >= 0) {
|
||||
/*
|
||||
* For each ethernet port, one node should be added
|
||||
* inside port_phyinfo with appropriate phy address
|
||||
*/
|
||||
phy_addr = phy_info[i]->phy_address;
|
||||
} else {
|
||||
printf("Error:Phy addresses not configured in DT\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = phy_get_ops->phy_get_link_status(priv->mac_unit, phy_addr);
|
||||
phy_get_ops->phy_get_speed(priv->mac_unit, phy_addr, &curr_speed[i]);
|
||||
phy_get_ops->phy_get_duplex(priv->mac_unit, phy_addr, &duplex);
|
||||
|
||||
if (status == 0) {
|
||||
linkup++;
|
||||
if (old_speed[i] == curr_speed[i]) {
|
||||
printf("eth%d PHY%d %s Speed :%d %s duplex\n",
|
||||
priv->mac_unit, i, lstatus[status], curr_speed[i],
|
||||
dp[duplex]);
|
||||
continue;
|
||||
} else {
|
||||
old_speed[i] = curr_speed[i];
|
||||
}
|
||||
} else {
|
||||
printf("eth%d PHY%d %s Speed :%d %s duplex\n",
|
||||
priv->mac_unit, i, lstatus[status], curr_speed[i],
|
||||
dp[duplex]);
|
||||
continue;
|
||||
} else {
|
||||
old_speed[i] = curr_speed[i];
|
||||
}
|
||||
} else {
|
||||
printf("eth%d PHY%d %s Speed :%d %s duplex\n",
|
||||
priv->mac_unit, i, lstatus[status], curr_speed[i],
|
||||
dp[duplex]);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1631,13 +1672,14 @@ int devsoc_edma_hw_init(struct devsoc_edma_hw *ehw)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void get_phy_address(int offset)
|
||||
void get_phy_address(int offset, phy_info_t * phy_info[], int max_phy_ports)
|
||||
{
|
||||
int phy_type;
|
||||
int phy_address;
|
||||
int forced_speed, forced_duplex;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < DEVSOC_PHY_MAX; i++)
|
||||
for (i = 0; i < max_phy_ports; i++)
|
||||
phy_info[i] = devsoc_alloc_mem(sizeof(phy_info_t));
|
||||
i = 0;
|
||||
for (offset = fdt_first_subnode(gd->fdt_blob, offset); offset > 0;
|
||||
|
|
@ -1646,7 +1688,13 @@ void get_phy_address(int offset)
|
|||
offset, "phy_address", 0);
|
||||
phy_type = fdtdec_get_uint(gd->fdt_blob,
|
||||
offset, "phy_type", 0);
|
||||
forced_speed = fdtdec_get_uint(gd->fdt_blob,
|
||||
offset, "forced-speed", 0);
|
||||
forced_duplex = fdtdec_get_uint(gd->fdt_blob,
|
||||
offset, "forced-duplex", 0);
|
||||
phy_info[i]->phy_address = phy_address;
|
||||
phy_info[i]->forced_speed = forced_speed;
|
||||
phy_info[i]->forced_duplex = forced_duplex;
|
||||
phy_info[i++]->phy_type = phy_type;
|
||||
}
|
||||
}
|
||||
|
|
@ -1666,8 +1714,15 @@ int devsoc_edma_init(void *edma_board_cfg)
|
|||
#ifdef CONFIG_DEVSOC_QCA8075_PHY
|
||||
static int sw_init_done = 0;
|
||||
#endif
|
||||
int node, phy_addr, aquantia_port[2] = {-1, -1}, aquantia_port_cnt = -1;
|
||||
int mode, phy_node = -1, res = -1;
|
||||
#ifdef CONFIG_QCA8084_PHY
|
||||
static int qca8084_init_done = 0;
|
||||
int qca8084_gpio, clk[4] = {0};
|
||||
#endif
|
||||
#ifdef CONFIG_ATHRS17C_SWITCH
|
||||
int s17c_swt_enb = 0, s17c_rst_gpio = 0;
|
||||
#endif
|
||||
int node, phy_addr, mode, phy_node = -1, res = -1;
|
||||
int aquantia_port[2] = {-1, -1}, aquantia_port_cnt = -1;
|
||||
|
||||
/*
|
||||
* Init non cache buffer
|
||||
|
|
@ -1687,9 +1742,50 @@ int devsoc_edma_init(void *edma_board_cfg)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_QCA8084_PHY
|
||||
qca8084_swt_enb = fdtdec_get_uint(gd->fdt_blob, node, "qca8084_switch_enable", 0);
|
||||
if (qca8084_swt_enb) {
|
||||
qca8084_gpio = fdtdec_get_uint(gd->fdt_blob, node, "qca808x_gpio", 0);
|
||||
if (qca8084_gpio)
|
||||
ipq_qca8084_switch_hw_reset(qca8084_gpio);
|
||||
}
|
||||
|
||||
phy_node = fdt_path_offset(gd->fdt_blob, "/ess-switch/qca8084_swt_info");
|
||||
if (phy_node >= 0)
|
||||
get_phy_address(phy_node, swt_info, QCA8084_MAX_PORTS);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ATHRS17C_SWITCH
|
||||
s17c_swt_enb = fdtdec_get_uint(gd->fdt_blob, node,
|
||||
"s17c_switch_enable", 0);
|
||||
if (s17c_swt_enb) {
|
||||
s17c_swt_cfg.chip_detect = 0;
|
||||
s17c_rst_gpio = fdtdec_get_uint(gd->fdt_blob, node,
|
||||
"s17c_rst_gpio", 0);
|
||||
|
||||
ipq_s17c_switch_reset(s17c_rst_gpio);
|
||||
|
||||
/*
|
||||
* Set ref clock 25MHZ and enable Force mode
|
||||
*/
|
||||
ppe_uniphy_set_forceMode(PORT0);
|
||||
|
||||
phy_node = fdt_path_offset(gd->fdt_blob,
|
||||
"/ess-switch/s17c_swt_info");
|
||||
s17c_swt_cfg.port_count = fdtdec_get_uint(gd->fdt_blob,
|
||||
phy_node, "s17c_mac_pwr", 0);
|
||||
s17c_swt_cfg.port_count = fdtdec_get_uint(gd->fdt_blob,
|
||||
phy_node, "s17c_port_count", 0);
|
||||
fdtdec_get_int_array(gd->fdt_blob, phy_node,
|
||||
"s17c_port_address",
|
||||
s17c_swt_cfg.port_phy_address,
|
||||
s17c_swt_cfg.port_count);
|
||||
}
|
||||
#endif
|
||||
|
||||
phy_node = fdt_path_offset(gd->fdt_blob, "/ess-switch/port_phyinfo");
|
||||
if (phy_node >= 0)
|
||||
get_phy_address(phy_node);
|
||||
get_phy_address(phy_node, phy_info, DEVSOC_PHY_MAX);
|
||||
|
||||
mode = fdtdec_get_uint(gd->fdt_blob, node, "switch_mac_mode0", -1);
|
||||
if (mode < 0) {
|
||||
|
|
@ -1785,6 +1881,13 @@ int devsoc_edma_init(void *edma_board_cfg)
|
|||
printf("Error:Phy addresses not configured in DT\n");
|
||||
goto init_failed;
|
||||
}
|
||||
#ifdef CONFIG_QCA8084_PHY
|
||||
if (phy_info[phy_id]->phy_type == QCA8084_PHY_TYPE && !qca8084_init_done) {
|
||||
ipq_phy_addr_fixup();
|
||||
ipq_clock_init();
|
||||
qca8084_init_done = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
phy_chip_id1 = ipq_mdio_read(phy_addr, QCA_PHY_ID1, NULL);
|
||||
phy_chip_id2 = ipq_mdio_read(phy_addr, QCA_PHY_ID2, NULL);
|
||||
|
|
@ -1826,7 +1929,18 @@ int devsoc_edma_init(void *edma_board_cfg)
|
|||
ipq_qca8081_phy_init(&devsoc_edma_dev[i]->ops[phy_id], phy_addr);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_DEVSOC_QCA_AQUANTIA_PHY
|
||||
#ifdef CONFIG_QCA8084_PHY
|
||||
case QCA8084_PHY:
|
||||
qca8084_chip_detect = 1;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_ATHRS17C_SWITCH
|
||||
case QCA8337_PHY:
|
||||
if (s17c_swt_enb)
|
||||
s17c_swt_cfg.chip_detect = 1;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_IPQ_QCA_AQUANTIA_PHY
|
||||
case AQUANTIA_PHY_107:
|
||||
case AQUANTIA_PHY_109:
|
||||
case AQUANTIA_PHY_111:
|
||||
|
|
@ -1856,6 +1970,35 @@ int devsoc_edma_init(void *edma_board_cfg)
|
|||
if (ret)
|
||||
goto init_failed;
|
||||
|
||||
#ifndef CONFIG_DEVSOC_RUMI
|
||||
#ifdef CONFIG_QCA8084_PHY
|
||||
/** QCA8084 switch specific configurations */
|
||||
if (qca8084_swt_enb && qca8084_chip_detect) {
|
||||
/** Force speed devsoc 2nd port for QCA8084 switch mode */
|
||||
clk[0] = 0x301;
|
||||
clk[1] = 0x0;
|
||||
clk[2] = 0x401;
|
||||
clk[3] = 0x0;
|
||||
|
||||
pr_debug("Force speed devsoc 2nd PORT for QCA8084 switch mode \n");
|
||||
devsoc_speed_clock_set(PORT1, clk);
|
||||
|
||||
/** Force Link-speed: 1000M
|
||||
* Force Link-status: enable */
|
||||
devsoc_pqsgmii_speed_set(PORT1, 0x2, 0x0);
|
||||
|
||||
ret = ipq_qca8084_hw_init(swt_info);
|
||||
if (ret < 0) {
|
||||
printf("Error: ipq_qca8084_hw_init failed \n");
|
||||
goto init_failed;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_ATHRS17C_SWITCH
|
||||
if (s17c_swt_cfg.chip_detect)
|
||||
ipq_qca8337_switch_init(&s17c_swt_cfg);
|
||||
#endif
|
||||
#endif
|
||||
eth_register(dev[i]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,13 +24,9 @@
|
|||
#include <asm/io.h>
|
||||
#include <malloc.h>
|
||||
#include <phy.h>
|
||||
#include <net.h>
|
||||
#include <miiphy.h>
|
||||
|
||||
|
||||
#define DEVSOC_PPE_BASE_ADDR 0x3a000000
|
||||
#define PORT1 1
|
||||
#define PORT2 2
|
||||
|
||||
#define DEVSOC_PORT5_MUX_PCS_UNIPHY0 0x0
|
||||
#define DEVSOC_PORT5_MUX_PCS_UNIPHY1 0x1
|
||||
|
|
|
|||
|
|
@ -202,10 +202,32 @@ static void ppe_uniphy_qsgmii_mode_set(uint32_t uniphy_index)
|
|||
mdelay(100);
|
||||
}
|
||||
|
||||
void ppe_uniphy_set_forceMode(uint32_t uniphy_index)
|
||||
{
|
||||
uint32_t reg_value;
|
||||
|
||||
reg_value = readl(PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
|
||||
+ UNIPHY_DEC_CHANNEL_0_INPUT_OUTPUT_4);
|
||||
reg_value |= UNIPHY_FORCE_SPEED_25M;
|
||||
|
||||
writel(reg_value, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
|
||||
+ UNIPHY_DEC_CHANNEL_0_INPUT_OUTPUT_4);
|
||||
}
|
||||
|
||||
static void ppe_uniphy_sgmii_mode_set(uint32_t uniphy_index, uint32_t mode)
|
||||
{
|
||||
writel(UNIPHY_MISC2_REG_SGMII_MODE, PPE_UNIPHY_BASE +
|
||||
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_MISC2_REG_OFFSET);
|
||||
if ((uniphy_index == 1) && (mode == EPORT_WRAPPER_SGMII_PLUS)) {
|
||||
writel(UNIPHY_MISC_SRC_PHY_MODE, PPE_UNIPHY_BASE +
|
||||
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_MISC_SOURCE_SELECTION_REG_OFFSET);
|
||||
|
||||
ppe_uniphy_set_forceMode(uniphy_index);
|
||||
|
||||
writel(UNIPHY_MISC2_REG_SGMII_PLUS_MODE, PPE_UNIPHY_BASE +
|
||||
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_MISC2_REG_OFFSET);
|
||||
} else {
|
||||
writel(UNIPHY_MISC2_REG_SGMII_MODE, PPE_UNIPHY_BASE +
|
||||
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_MISC2_REG_OFFSET);
|
||||
}
|
||||
|
||||
writel(UNIPHY_PLL_RESET_REG_VALUE, PPE_UNIPHY_BASE +
|
||||
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET);
|
||||
|
|
@ -238,7 +260,11 @@ static void ppe_uniphy_sgmii_mode_set(uint32_t uniphy_index, uint32_t mode)
|
|||
break;
|
||||
|
||||
case EPORT_WRAPPER_SGMII_PLUS:
|
||||
writel(0x820, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
|
||||
if (uniphy_index == 1)
|
||||
writel(0x20, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
|
||||
+ PPE_UNIPHY_MODE_CONTROL);
|
||||
else
|
||||
writel(0x820, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
|
||||
+ PPE_UNIPHY_MODE_CONTROL);
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,12 @@
|
|||
|
||||
#define UNIPHY_MISC2_REG_VALUE 0x70
|
||||
|
||||
#define UNIPHY_MISC_SOURCE_SELECTION_REG_OFFSET 0x21c
|
||||
#define UNIPHY_MISC_SRC_PHY_MODE 0xa882
|
||||
|
||||
#define UNIPHY_DEC_CHANNEL_0_INPUT_OUTPUT_4 0x480
|
||||
#define UNIPHY_FORCE_SPEED_25M (1 << 3)
|
||||
|
||||
#define UNIPHY_PLL_RESET_REG_OFFSET 0x780
|
||||
#define UNIPHY_PLL_RESET_REG_VALUE 0x02bf
|
||||
#define UNIPHY_PLL_RESET_REG_DEFAULT_VALUE 0x02ff
|
||||
|
|
|
|||
419
drivers/net/ipq_common/athrs17_phy.c
Normal file
419
drivers/net/ipq_common/athrs17_phy.c
Normal file
|
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016, 2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Manage the QTI S17C ethernet PHY.
|
||||
*
|
||||
* All definitions in this file are operating system independent!
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include "athrs17_phy.h"
|
||||
|
||||
/*
|
||||
* Externel Common mdio read, PHY Name : IPQ MDIO1
|
||||
*/
|
||||
|
||||
extern int ipq_mdio_write(int mii_id, int regnum, u16 value);
|
||||
extern int ipq_mdio_read(int mii_id, int regnum, ushort *data);
|
||||
|
||||
/******************************************************************************
|
||||
* FUNCTION DESCRIPTION: Read switch internal register.
|
||||
* Switch internal register is accessed through the
|
||||
* MDIO interface. MDIO access is only 16 bits wide so
|
||||
* it needs the two time access to complete the internal
|
||||
* register access.
|
||||
* INPUT : register address
|
||||
* OUTPUT : Register value
|
||||
*
|
||||
*****************************************************************************/
|
||||
static uint32_t athrs17_reg_read(uint32_t reg_addr)
|
||||
{
|
||||
uint32_t reg_word_addr;
|
||||
uint32_t phy_addr, reg_val;
|
||||
uint16_t phy_val;
|
||||
uint16_t tmp_val;
|
||||
uint8_t phy_reg;
|
||||
|
||||
/* change reg_addr to 16-bit word address, 32-bit aligned */
|
||||
reg_word_addr = (reg_addr & 0xfffffffc) >> 1;
|
||||
|
||||
/* configure register high address */
|
||||
phy_addr = 0x18;
|
||||
phy_reg = 0x0;
|
||||
phy_val = (uint16_t) ((reg_word_addr >> 8) & 0x1ff); /* bit16-8 of reg address */
|
||||
ipq_mdio_write(phy_addr, phy_reg, phy_val);
|
||||
/*
|
||||
* For some registers such as MIBs, since it is read/clear, we should
|
||||
* read the lower 16-bit register then the higher one
|
||||
*/
|
||||
|
||||
/* read register in lower address */
|
||||
phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */
|
||||
phy_reg = (uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */
|
||||
ipq_mdio_read(phy_addr, phy_reg, &phy_val);
|
||||
|
||||
/* read register in higher address */
|
||||
reg_word_addr++;
|
||||
phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */
|
||||
phy_reg = (uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */
|
||||
ipq_mdio_read(phy_addr, phy_reg, &tmp_val);
|
||||
reg_val = (tmp_val << 16 | phy_val);
|
||||
|
||||
return reg_val;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FUNCTION DESCRIPTION: Write switch internal register.
|
||||
* Switch internal register is accessed through the
|
||||
* MDIO interface. MDIO access is only 16 bits wide so
|
||||
* it needs the two time access to complete the internal
|
||||
* register access.
|
||||
* INPUT : register address, value to be written
|
||||
* OUTPUT : NONE
|
||||
*
|
||||
*****************************************************************************/
|
||||
static void athrs17_reg_write(uint32_t reg_addr, uint32_t reg_val)
|
||||
{
|
||||
uint32_t reg_word_addr;
|
||||
uint32_t phy_addr;
|
||||
uint16_t phy_val;
|
||||
uint8_t phy_reg;
|
||||
|
||||
/* change reg_addr to 16-bit word address, 32-bit aligned */
|
||||
reg_word_addr = (reg_addr & 0xfffffffc) >> 1;
|
||||
|
||||
/* configure register high address */
|
||||
phy_addr = 0x18;
|
||||
phy_reg = 0x0;
|
||||
phy_val = (uint16_t) ((reg_word_addr >> 8) & 0x1ff); /* bit16-8 of reg address */
|
||||
ipq_mdio_write(phy_addr, phy_reg, phy_val);
|
||||
|
||||
/*
|
||||
* For some registers such as ARL and VLAN, since they include BUSY bit
|
||||
* in lower address, we should write the higher 16-bit register then the
|
||||
* lower one
|
||||
*/
|
||||
|
||||
/* read register in higher address */
|
||||
reg_word_addr++;
|
||||
phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */
|
||||
phy_reg = (uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */
|
||||
phy_val = (uint16_t) ((reg_val >> 16) & 0xffff);
|
||||
ipq_mdio_write(phy_addr, phy_reg, phy_val);
|
||||
|
||||
/* write register in lower address */
|
||||
reg_word_addr--;
|
||||
phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */
|
||||
phy_reg = (uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */
|
||||
phy_val = (uint16_t) (reg_val & 0xffff);
|
||||
ipq_mdio_write(phy_addr, phy_reg, phy_val);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* FUNCTION DESCRIPTION: V-lan configuration given by Switch team
|
||||
Vlan 1:PHY0,1,2,3 and Mac 6 of s17c
|
||||
Vlan 2:PHY4 and Mac 0 of s17c
|
||||
* INPUT : NONE
|
||||
* OUTPUT: NONE
|
||||
*********************************************************************/
|
||||
void athrs17_vlan_config(void)
|
||||
{
|
||||
athrs17_reg_write(S17_P0LOOKUP_CTRL_REG, 0x00140020);
|
||||
athrs17_reg_write(S17_P0VLAN_CTRL0_REG, 0x20001);
|
||||
|
||||
athrs17_reg_write(S17_P1LOOKUP_CTRL_REG, 0x0014005c);
|
||||
athrs17_reg_write(S17_P1VLAN_CTRL0_REG, 0x10001);
|
||||
|
||||
athrs17_reg_write(S17_P2LOOKUP_CTRL_REG, 0x0014005a);
|
||||
athrs17_reg_write(S17_P2VLAN_CTRL0_REG, 0x10001);
|
||||
|
||||
athrs17_reg_write(S17_P3LOOKUP_CTRL_REG, 0x00140056);
|
||||
athrs17_reg_write(S17_P3VLAN_CTRL0_REG, 0x10001);
|
||||
|
||||
athrs17_reg_write(S17_P4LOOKUP_CTRL_REG, 0x0014004e);
|
||||
athrs17_reg_write(S17_P4VLAN_CTRL0_REG, 0x10001);
|
||||
|
||||
athrs17_reg_write(S17_P5LOOKUP_CTRL_REG, 0x00140001);
|
||||
athrs17_reg_write(S17_P5VLAN_CTRL0_REG, 0x20001);
|
||||
|
||||
athrs17_reg_write(S17_P6LOOKUP_CTRL_REG, 0x0014001e);
|
||||
athrs17_reg_write(S17_P6VLAN_CTRL0_REG, 0x10001);
|
||||
printf("%s ...done\n", __func__);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* FUNCTION DESCRIPTION: Reset S17 register
|
||||
* INPUT: NONE
|
||||
* OUTPUT: NONE
|
||||
*******************************************************************/
|
||||
int athrs17_init_switch(void)
|
||||
{
|
||||
uint32_t data;
|
||||
uint32_t i = 0;
|
||||
|
||||
/* Reset the switch before initialization */
|
||||
athrs17_reg_write(S17_MASK_CTRL_REG, S17_MASK_CTRL_SOFT_RET);
|
||||
do {
|
||||
udelay(10);
|
||||
data = athrs17_reg_read(S17_MASK_CTRL_REG);
|
||||
i++;
|
||||
if (i == 10){
|
||||
printf("QCA_8337: Failed to reset\n");
|
||||
return -1;
|
||||
}
|
||||
} while (data & S17_MASK_CTRL_SOFT_RET);
|
||||
|
||||
i = 0;
|
||||
|
||||
do {
|
||||
udelay(10);
|
||||
data = athrs17_reg_read(S17_GLOBAL_INT0_REG);
|
||||
i++;
|
||||
if (i == 10)
|
||||
return -1;
|
||||
} while ((data & S17_GLOBAL_INITIALIZED_STATUS) != S17_GLOBAL_INITIALIZED_STATUS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* FUNCTION DESCRIPTION: Configure S17 register
|
||||
* INPUT : NONE
|
||||
* OUTPUT: NONE
|
||||
*********************************************************************/
|
||||
void athrs17_reg_init(ipq_s17c_swt_cfg_t *swt_cfg)
|
||||
{
|
||||
athrs17_reg_write(S17_MAC_PWR_REG, swt_cfg->mac_pwr);
|
||||
|
||||
athrs17_reg_write(S17_P0STATUS_REG, (S17_SPEED_1000M |
|
||||
S17_TXMAC_EN |
|
||||
S17_RXMAC_EN |
|
||||
S17_DUPLEX_FULL));
|
||||
|
||||
athrs17_reg_write(S17_GLOFW_CTRL1_REG, (S17_IGMP_JOIN_LEAVE_DPALL |
|
||||
S17_BROAD_DPALL |
|
||||
S17_MULTI_FLOOD_DPALL |
|
||||
S17_UNI_FLOOD_DPALL));
|
||||
|
||||
athrs17_reg_write(S17_P5PAD_MODE_REG, S17_MAC0_RGMII_RXCLK_DELAY);
|
||||
|
||||
athrs17_reg_write(S17_P0PAD_MODE_REG, (S17_MAC0_RGMII_EN |
|
||||
S17_MAC0_RGMII_TXCLK_DELAY |
|
||||
S17_MAC0_RGMII_RXCLK_DELAY |
|
||||
(0x1 << S17_MAC0_RGMII_TXCLK_SHIFT) |
|
||||
(0x2 << S17_MAC0_RGMII_RXCLK_SHIFT)));
|
||||
|
||||
printf("%s: complete\n", __func__);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* FUNCTION DESCRIPTION: Configure S17 register
|
||||
* INPUT : NONE
|
||||
* OUTPUT: NONE
|
||||
*********************************************************************/
|
||||
void athrs17_reg_init_lan(ipq_s17c_swt_cfg_t *swt_cfg)
|
||||
{
|
||||
uint32_t reg_val;
|
||||
|
||||
athrs17_reg_write(S17_P6STATUS_REG, (S17_SPEED_1000M |
|
||||
S17_TXMAC_EN |
|
||||
S17_RXMAC_EN |
|
||||
S17_DUPLEX_FULL));
|
||||
|
||||
athrs17_reg_write(S17_MAC_PWR_REG, swt_cfg->mac_pwr);
|
||||
reg_val = athrs17_reg_read(S17_P6PAD_MODE_REG);
|
||||
athrs17_reg_write(S17_P6PAD_MODE_REG, (reg_val | S17_MAC6_SGMII_EN));
|
||||
|
||||
athrs17_reg_write(S17_PWS_REG, 0x2613a0);
|
||||
|
||||
athrs17_reg_write(S17_SGMII_CTRL_REG,(S17c_SGMII_EN_PLL |
|
||||
S17c_SGMII_EN_RX |
|
||||
S17c_SGMII_EN_TX |
|
||||
S17c_SGMII_EN_SD |
|
||||
S17c_SGMII_BW_HIGH |
|
||||
S17c_SGMII_SEL_CLK125M |
|
||||
S17c_SGMII_TXDR_CTRL_600mV |
|
||||
S17c_SGMII_CDR_BW_8 |
|
||||
S17c_SGMII_DIS_AUTO_LPI_25M |
|
||||
S17c_SGMII_MODE_CTRL_SGMII_PHY |
|
||||
S17c_SGMII_PAUSE_SG_TX_EN_25M |
|
||||
S17c_SGMII_ASYM_PAUSE_25M |
|
||||
S17c_SGMII_PAUSE_25M |
|
||||
S17c_SGMII_HALF_DUPLEX_25M |
|
||||
S17c_SGMII_FULL_DUPLEX_25M));
|
||||
|
||||
athrs17_reg_write(S17_MODULE_EN_REG, S17_MIB_COUNTER_ENABLE);
|
||||
}
|
||||
|
||||
struct athrs17_regmap {
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
};
|
||||
|
||||
struct athrs17_regmap regmap[] = {
|
||||
{ 0x000, 0x0e4 },
|
||||
{ 0x100, 0x168 },
|
||||
{ 0x200, 0x270 },
|
||||
{ 0x400, 0x454 },
|
||||
{ 0x600, 0x718 },
|
||||
{ 0x800, 0xb70 },
|
||||
{ 0xC00, 0xC80 },
|
||||
{ 0x1100, 0x11a7 },
|
||||
{ 0x1200, 0x12a7 },
|
||||
{ 0x1300, 0x13a7 },
|
||||
{ 0x1400, 0x14a7 },
|
||||
{ 0x1600, 0x16a7 },
|
||||
};
|
||||
|
||||
int do_ar8xxx_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regmap); i++) {
|
||||
uint32_t reg;
|
||||
struct athrs17_regmap *section = ®map[i];
|
||||
|
||||
for (reg = section->start; reg <= section->end; reg += sizeof(uint32_t)) {
|
||||
uint32_t val = athrs17_reg_read(reg);
|
||||
printf("%03zx: %08zx\n", reg, val);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
U_BOOT_CMD(
|
||||
ar8xxx_dump, 1, 1, do_ar8xxx_dump,
|
||||
"Dump ar8xxx registers",
|
||||
"\n - print all ar8xxx registers\n"
|
||||
);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* FUNCTION DESCRIPTION: This function invokes RGMII,
|
||||
* SGMII switch init routines.
|
||||
* INPUT : ipq_s17c_swt_cfg_t *
|
||||
* OUTPUT: NONE
|
||||
*
|
||||
**********************************************************************/
|
||||
int ipq_athrs17_init(ipq_s17c_swt_cfg_t *swt_cfg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (swt_cfg == NULL)
|
||||
return -1;
|
||||
|
||||
ret = athrs17_init_switch();
|
||||
if (ret != -1) {
|
||||
athrs17_reg_init(swt_cfg);
|
||||
athrs17_reg_init_lan(swt_cfg);
|
||||
athrs17_vlan_config();
|
||||
printf ("S17c init done\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ipq_qca8337_switch_init(ipq_s17c_swt_cfg_t *s17c_swt_cfg)
|
||||
{
|
||||
int port;
|
||||
for (port = 0; port < s17c_swt_cfg->port_count; ++port) {
|
||||
u32 phy_val;
|
||||
|
||||
/* phy powerdown */
|
||||
ipq_mdio_write(s17c_swt_cfg->port_phy_address[port], 0x0,
|
||||
0x0800);
|
||||
phy_val = ipq_mdio_read(s17c_swt_cfg->port_phy_address[port],
|
||||
0x3d, NULL);
|
||||
phy_val &= ~0x0040;
|
||||
ipq_mdio_write(s17c_swt_cfg->port_phy_address[port], 0x3d,
|
||||
phy_val);
|
||||
|
||||
/*
|
||||
* PHY will stop the tx clock for a while when link is down
|
||||
* en_anychange debug port 0xb bit13 = 0 //speed up link down tx_clk
|
||||
* sel_rst_80us debug port 0xb bit10 = 0 //speed up speed mode change to 2'b10 tx_clk
|
||||
*/
|
||||
phy_val = ipq_mdio_read(s17c_swt_cfg->port_phy_address[port],
|
||||
0xb, NULL);
|
||||
phy_val &= ~0x2400;
|
||||
ipq_mdio_write(s17c_swt_cfg->port_phy_address[port], 0xb,
|
||||
phy_val);
|
||||
mdelay(100);
|
||||
}
|
||||
|
||||
if (ipq_athrs17_init(s17c_swt_cfg) != 0) {
|
||||
printf("QCA_8337 switch init failed \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (port = 0; port < s17c_swt_cfg->port_count; ++port) {
|
||||
ipq_mdio_write(s17c_swt_cfg->port_phy_address[port],
|
||||
MII_ADVERTISE, ADVERTISE_ALL |
|
||||
ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
|
||||
/* phy reg 0x9, b10,1 = Prefer multi-port device (master) */
|
||||
ipq_mdio_write(s17c_swt_cfg->port_phy_address[port],
|
||||
MII_CTRL1000, (0x0400|ADVERTISE_1000FULL));
|
||||
ipq_mdio_write(s17c_swt_cfg->port_phy_address[port],
|
||||
MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
|
||||
mdelay(100);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ipq_qca8337_link_update(ipq_s17c_swt_cfg_t *s17c_swt_cfg)
|
||||
{
|
||||
uint16_t phy_data;
|
||||
int status = 1;
|
||||
|
||||
for(int i = 0; i < s17c_swt_cfg->port_count; ++i){
|
||||
phy_data = ipq_mdio_read(s17c_swt_cfg->port_phy_address[i],
|
||||
0x11, NULL);
|
||||
|
||||
if (phy_data == 0x50)
|
||||
continue;
|
||||
|
||||
/* Atleast one port should be link up*/
|
||||
if (phy_data & LINK_UP)
|
||||
status = 0;
|
||||
|
||||
printf("Port%d %s ", i + 1, LINK(phy_data));
|
||||
|
||||
switch(SPEED(phy_data)){
|
||||
case SPEED_1000M:
|
||||
printf("Speed :1000M ");
|
||||
break;
|
||||
case SPEED_100M:
|
||||
printf("Speed :100M ");
|
||||
break;
|
||||
default:
|
||||
printf("Speed :10M ");
|
||||
}
|
||||
|
||||
printf ("%s \n", DUPLEX(phy_data));
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void ipq_s17c_switch_reset(int gpio)
|
||||
{
|
||||
unsigned int *switch_gpio_base =
|
||||
(unsigned int *)GPIO_CONFIG_ADDR(gpio);
|
||||
|
||||
writel(0x203, switch_gpio_base);
|
||||
writel(0x0, GPIO_IN_OUT_ADDR(gpio));
|
||||
mdelay(500);
|
||||
writel(0x2, GPIO_IN_OUT_ADDR(gpio));
|
||||
}
|
||||
621
drivers/net/ipq_common/athrs17_phy.h
Normal file
621
drivers/net/ipq_common/athrs17_phy.h
Normal file
|
|
@ -0,0 +1,621 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016, 2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _ATHRS17_PHY_H
|
||||
#define _ATHRS17_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_SPEC_CONTROL 16
|
||||
#define ATHR_PHY_SPEC_STATUS 17
|
||||
#define ATHR_DEBUG_PORT_ADDRESS 29
|
||||
#define ATHR_DEBUG_PORT_DATA 30
|
||||
|
||||
/* 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
|
||||
|
||||
/* Phy Specific status fields */
|
||||
#define ATHER_STATUS_LINK_MASK 0xC000
|
||||
#define ATHER_STATUS_LINK_SHIFT 14
|
||||
#define ATHER_STATUS_FULL_DEPLEX 0x2000
|
||||
#define ATHR_STATUS_LINK_PASS 0x0400
|
||||
#define ATHR_STATUS_RESOVLED 0x0800
|
||||
|
||||
/*phy debug port register */
|
||||
#define ATHER_DEBUG_SERDES_REG 5
|
||||
|
||||
/* Serdes debug fields */
|
||||
#define ATHER_SERDES_BEACON 0x0100
|
||||
|
||||
/* S17 CSR Registers */
|
||||
|
||||
#define S17_ENABLE_CPU_BROADCAST (1 << 26)
|
||||
|
||||
#define S17_PHY_LINK_CHANGE_REG 0x4
|
||||
#define S17_PHY_LINK_UP 0x400
|
||||
#define S17_PHY_LINK_DOWN 0x800
|
||||
#define S17_PHY_LINK_DUPLEX_CHANGE 0x2000
|
||||
#define S17_PHY_LINK_SPEED_CHANGE 0x4000
|
||||
#define S17_PHY_LINK_INTRS (PHY_LINK_UP | PHY_LINK_DOWN | PHY_LINK_DUPLEX_CHANGE | PHY_LINK_SPEED_CHANGE)
|
||||
|
||||
#define S17_MASK_CTRL_REG 0x0000
|
||||
#define S17_P0PAD_MODE_REG 0x0004
|
||||
#define S17_P5PAD_MODE_REG 0x0008
|
||||
#define S17_P6PAD_MODE_REG 0x000c
|
||||
#define S17_PWS_REG 0x0010
|
||||
#define S17_GLOBAL_INT0_REG 0x0020
|
||||
#define S17_GLOBAL_INT1_REG 0x0024
|
||||
#define S17_GLOBAL_INTMASK0 0x0028
|
||||
#define S17_GLOBAL_INTMASK1 0x002c
|
||||
#define S17_MODULE_EN_REG 0x0030
|
||||
#define S17_MIB_REG 0x0034
|
||||
#define S17_INTF_HIADDR_REG 0x0038
|
||||
#define S17_MDIO_CTRL_REG 0x003c
|
||||
#define S17_BIST_CTRL_REG 0x0040
|
||||
#define S17_BIST_REC_REG 0x0044
|
||||
#define S17_SERVICE_REG 0x0048
|
||||
#define S17_LED_CTRL0_REG 0x0050
|
||||
#define S17_LED_CTRL1_REG 0x0054
|
||||
#define S17_LED_CTRL2_REG 0x0058
|
||||
#define S17_LED_CTRL3_REG 0x005c
|
||||
#define S17_MACADDR0_REG 0x0060
|
||||
#define S17_MACADDR1_REG 0x0064
|
||||
#define S17_MAX_FRAME_SIZE_REG 0x0078
|
||||
#define S17_P0STATUS_REG 0x007c
|
||||
#define S17_P1STATUS_REG 0x0080
|
||||
#define S17_P2STATUS_REG 0x0084
|
||||
#define S17_P3STATUS_REG 0x0088
|
||||
#define S17_P4STATUS_REG 0x008c
|
||||
#define S17_P5STATUS_REG 0x0090
|
||||
#define S17_P6STATUS_REG 0x0094
|
||||
#define S17_HDRCTRL_REG 0x0098
|
||||
#define S17_P0HDRCTRL_REG 0x009c
|
||||
#define S17_P1HDRCTRL_REG 0x00A0
|
||||
#define S17_P2HDRCTRL_REG 0x00a4
|
||||
#define S17_P3HDRCTRL_REG 0x00a8
|
||||
#define S17_P4HDRCTRL_REG 0x00ac
|
||||
#define S17_P5HDRCTRL_REG 0x00b0
|
||||
#define S17_P6HDRCTRL_REG 0x00b4
|
||||
#define S17_SGMII_CTRL_REG 0x00e0
|
||||
#define S17_MAC_PWR_REG 0x00e4
|
||||
#define S17_EEE_CTRL_REG 0x0100
|
||||
|
||||
/* ACL Registers */
|
||||
#define S17_ACL_FUNC0_REG 0x0400
|
||||
#define S17_ACL_FUNC1_REG 0x0404
|
||||
#define S17_ACL_FUNC2_REG 0x0408
|
||||
#define S17_ACL_FUNC3_REG 0x040c
|
||||
#define S17_ACL_FUNC4_REG 0x0410
|
||||
#define S17_ACL_FUNC5_REG 0x0414
|
||||
#define S17_PRIVATE_IP_REG 0x0418
|
||||
#define S17_P0VLAN_CTRL0_REG 0x0420
|
||||
#define S17_P0VLAN_CTRL1_REG 0x0424
|
||||
#define S17_P1VLAN_CTRL0_REG 0x0428
|
||||
#define S17_P1VLAN_CTRL1_REG 0x042c
|
||||
#define S17_P2VLAN_CTRL0_REG 0x0430
|
||||
#define S17_P2VLAN_CTRL1_REG 0x0434
|
||||
#define S17_P3VLAN_CTRL0_REG 0x0438
|
||||
#define S17_P3VLAN_CTRL1_REG 0x043c
|
||||
#define S17_P4VLAN_CTRL0_REG 0x0440
|
||||
#define S17_P4VLAN_CTRL1_REG 0x0444
|
||||
#define S17_P5VLAN_CTRL0_REG 0x0448
|
||||
#define S17_P5VLAN_CTRL1_REG 0x044c
|
||||
#define S17_P6VLAN_CTRL0_REG 0x0450
|
||||
#define S17_P6VLAN_CTRL1_REG 0x0454
|
||||
|
||||
/* Table Lookup Registers */
|
||||
#define S17_ATU_DATA0_REG 0x0600
|
||||
#define S17_ATU_DATA1_REG 0x0604
|
||||
#define S17_ATU_DATA2_REG 0x0608
|
||||
#define S17_ATU_FUNC_REG 0x060C
|
||||
#define S17_VTU_FUNC0_REG 0x0610
|
||||
#define S17_VTU_FUNC1_REG 0x0614
|
||||
#define S17_ARL_CTRL_REG 0x0618
|
||||
#define S17_GLOFW_CTRL0_REG 0x0620
|
||||
#define S17_GLOFW_CTRL1_REG 0x0624
|
||||
#define S17_GLOLEARN_LIMIT_REG 0x0628
|
||||
#define S17_TOS_PRIMAP_REG0 0x0630
|
||||
#define S17_TOS_PRIMAP_REG1 0x0634
|
||||
#define S17_TOS_PRIMAP_REG2 0x0638
|
||||
#define S17_TOS_PRIMAP_REG3 0x063c
|
||||
#define S17_TOS_PRIMAP_REG4 0x0640
|
||||
#define S17_TOS_PRIMAP_REG5 0x0644
|
||||
#define S17_TOS_PRIMAP_REG6 0x0648
|
||||
#define S17_TOS_PRIMAP_REG7 0x064c
|
||||
#define S17_VLAN_PRIMAP_REG0 0x0650
|
||||
#define S17_LOOP_CHECK_REG 0x0654
|
||||
#define S17_P0LOOKUP_CTRL_REG 0x0660
|
||||
#define S17_P0PRI_CTRL_REG 0x0664
|
||||
#define S17_P0LEARN_LMT_REG 0x0668
|
||||
#define S17_P1LOOKUP_CTRL_REG 0x066c
|
||||
#define S17_P1PRI_CTRL_REG 0x0670
|
||||
#define S17_P1LEARN_LMT_REG 0x0674
|
||||
#define S17_P2LOOKUP_CTRL_REG 0x0678
|
||||
#define S17_P2PRI_CTRL_REG 0x067c
|
||||
#define S17_P2LEARN_LMT_REG 0x0680
|
||||
#define S17_P3LOOKUP_CTRL_REG 0x0684
|
||||
#define S17_P3PRI_CTRL_REG 0x0688
|
||||
#define S17_P3LEARN_LMT_REG 0x068c
|
||||
#define S17_P4LOOKUP_CTRL_REG 0x0690
|
||||
#define S17_P4PRI_CTRL_REG 0x0694
|
||||
#define S17_P4LEARN_LMT_REG 0x0698
|
||||
#define S17_P5LOOKUP_CTRL_REG 0x069c
|
||||
#define S17_P5PRI_CTRL_REG 0x06a0
|
||||
#define S17_P5LEARN_LMT_REG 0x06a4
|
||||
#define S17_P6LOOKUP_CTRL_REG 0x06a8
|
||||
#define S17_P6PRI_CTRL_REG 0x06ac
|
||||
#define S17_P6LEARN_LMT_REG 0x06b0
|
||||
#define S17_GLO_TRUNK_CTRL0_REG 0x0700
|
||||
#define S17_GLO_TRUNK_CTRL1_REG 0x0704
|
||||
#define S17_GLO_TRUNK_CTRL2_REG 0x0708
|
||||
|
||||
/* Queue Management Registers */
|
||||
#define S17_PORT0_HOL_CTRL0 0x0970
|
||||
#define S17_PORT0_HOL_CTRL1 0x0974
|
||||
#define S17_PORT1_HOL_CTRL0 0x0978
|
||||
#define S17_PORT1_HOL_CTRL1 0x097c
|
||||
#define S17_PORT2_HOL_CTRL0 0x0980
|
||||
#define S17_PORT2_HOL_CTRL1 0x0984
|
||||
#define S17_PORT3_HOL_CTRL0 0x0988
|
||||
#define S17_PORT3_HOL_CTRL1 0x098c
|
||||
#define S17_PORT4_HOL_CTRL0 0x0990
|
||||
#define S17_PORT4_HOL_CTRL1 0x0994
|
||||
#define S17_PORT5_HOL_CTRL0 0x0998
|
||||
#define S17_PORT5_HOL_CTRL1 0x099c
|
||||
#define S17_PORT6_HOL_CTRL0 0x09a0
|
||||
#define S17_PORT6_HOL_CTRL1 0x09a4
|
||||
|
||||
/* Port flow control registers */
|
||||
#define S17_P0_FLCTL_REG 0x09b0
|
||||
#define S17_P1_FLCTL_REG 0x09b4
|
||||
#define S17_P2_FLCTL_REG 0x09b8
|
||||
#define S17_P3_FLCTL_REG 0x09bc
|
||||
#define S17_P4_FLCTL_REG 0x09c0
|
||||
#define S17_P5_FLCTL_REG 0x09c4
|
||||
|
||||
/* Packet Edit registers */
|
||||
#define S17_PKT_EDIT_CTRL 0x0c00
|
||||
#define S17_P0Q_REMAP_REG0 0x0c40
|
||||
#define S17_P0Q_REMAP_REG1 0x0c44
|
||||
#define S17_P1Q_REMAP_REG0 0x0c48
|
||||
#define S17_P2Q_REMAP_REG0 0x0c4c
|
||||
#define S17_P3Q_REMAP_REG0 0x0c50
|
||||
#define S17_P4Q_REMAP_REG0 0x0c54
|
||||
#define S17_P5Q_REMAP_REG0 0x0c58
|
||||
#define S17_P5Q_REMAP_REG1 0x0c5c
|
||||
#define S17_P6Q_REMAP_REG0 0x0c60
|
||||
#define S17_P6Q_REMAP_REG1 0x0c64
|
||||
#define S17_ROUTER_VID0 0x0c70
|
||||
#define S17_ROUTER_VID1 0x0c74
|
||||
#define S17_ROUTER_VID2 0x0c78
|
||||
#define S17_ROUTER_VID3 0x0c7c
|
||||
#define S17_ROUTER_EG_VLAN_MODE 0x0c80
|
||||
|
||||
/* L3 Registers */
|
||||
#define S17_HROUTER_CTRL_REG 0x0e00
|
||||
#define S17_HROUTER_PBCTRL0_REG 0x0e04
|
||||
#define S17_HROUTER_PBCTRL1_REG 0x0e08
|
||||
#define S17_HROUTER_PBCTRL2_REG 0x0e0c
|
||||
#define S17_WCMP_HASH_TABLE0_REG 0x0e10
|
||||
#define S17_WCMP_HASH_TABLE1_REG 0x0e14
|
||||
#define S17_WCMP_HASH_TABLE2_REG 0x0e18
|
||||
#define S17_WCMP_HASH_TABLE3_REG 0x0e1c
|
||||
#define S17_WCMP_NHOP_TABLE0_REG 0x0e20
|
||||
#define S17_WCMP_NHOP_TABLE1_REG 0x0e24
|
||||
#define S17_WCMP_NHOP_TABLE2_REG 0x0e28
|
||||
#define S17_WCMP_NHOP_TABLE3_REG 0x0e2c
|
||||
#define S17_ARP_ENTRY_CTRL_REG 0x0e30
|
||||
#define S17_ARP_USECNT_REG 0x0e34
|
||||
#define S17_HNAT_CTRL_REG 0x0e38
|
||||
#define S17_NAPT_ENTRY_CTRL0_REG 0x0e3c
|
||||
#define S17_NAPT_ENTRY_CTRL1_REG 0x0e40
|
||||
#define S17_NAPT_USECNT_REG 0x0e44
|
||||
#define S17_ENTRY_EDIT_DATA0_REG 0x0e48
|
||||
#define S17_ENTRY_EDIT_DATA1_REG 0x0e4c
|
||||
#define S17_ENTRY_EDIT_DATA2_REG 0x0e50
|
||||
#define S17_ENTRY_EDIT_DATA3_REG 0x0e54
|
||||
#define S17_ENTRY_EDIT_CTRL_REG 0x0e58
|
||||
#define S17_HNAT_PRIVATE_IP_REG 0x0e5c
|
||||
|
||||
/* MIB counters */
|
||||
#define S17_MIB_PORT0 0x1000
|
||||
#define S17_MIB_PORT1 0x1100
|
||||
#define S17_MIB_PORT2 0x1200
|
||||
#define S17_MIB_PORT3 0x1300
|
||||
#define S17_MIB_PORT4 0x1400
|
||||
#define S17_MIB_PORT5 0x1500
|
||||
#define S17_MIB_PORT6 0x1600
|
||||
|
||||
#define S17_MIB_COUNTER_ENABLE (1 << 0)
|
||||
#define S17_MIB_NON_CLEAR (1 << 20)
|
||||
|
||||
#define S17_MIB_RXBROAD 0x0
|
||||
#define S17_MIB_RXPAUSE 0x4
|
||||
#define S17_MIB_RXMULTI 0x8
|
||||
#define S17_MIB_RXFCSERR 0xC
|
||||
#define S17_MIB_RXALIGNERR 0x10
|
||||
#define S17_MIB_RXUNDERSIZE 0x14
|
||||
#define S17_MIB_RXFRAG 0x18
|
||||
#define S17_MIB_RX64B 0x1C
|
||||
#define S17_MIB_RX128B 0x20
|
||||
#define S17_MIB_RX256B 0x24
|
||||
#define S17_MIB_RX512B 0x28
|
||||
#define S17_MIB_RX1024B 0x2C
|
||||
#define S17_MIB_RX1518B 0x30
|
||||
#define S17_MIB_RXMAXB 0x34
|
||||
#define S17_MIB_RXTOOLONG 0x38
|
||||
#define S17_MIB_RXBYTE1 0x3C
|
||||
#define S17_MIB_RXBYTE2 0x40
|
||||
#define S17_MIB_RXOVERFLOW 0x4C
|
||||
#define S17_MIB_FILTERED 0x50
|
||||
#define S17_MIB_TXBROAD 0x54
|
||||
#define S17_MIB_TXPAUSE 0x58
|
||||
#define S17_MIB_TXMULTI 0x5C
|
||||
#define S17_MIB_TXUNDERRUN 0x60
|
||||
#define S17_MIB_TX64B 0x64
|
||||
#define S17_MIB_TX128B 0x68
|
||||
#define S17_MIB_TX256B 0x6c
|
||||
#define S17_MIB_TX512B 0x70
|
||||
#define S17_MIB_TX1024B 0x74
|
||||
#define S17_MIB_TX1518B 0x78
|
||||
#define S17_MIB_TXMAXB 0x7C
|
||||
#define S17_MIB_TXOVERSIZE 0x80
|
||||
#define S17_MIB_TXBYTE1 0x84
|
||||
#define S17_MIB_TXBYTE2 0x88
|
||||
#define S17_MIB_TXCOL 0x8C
|
||||
#define S17_MIB_TXABORTCOL 0x90
|
||||
#define S17_MIB_TXMULTICOL 0x94
|
||||
#define S17_MIB_TXSINGLECOL 0x98
|
||||
#define S17_MIB_TXEXCDEFER 0x9C
|
||||
#define S17_MIB_TXDEFER 0xA0
|
||||
#define S17_MIB_TXLATECOL 0xA4
|
||||
|
||||
/* Register fields */
|
||||
#define S17_CHIPID_V1_0 0x1201
|
||||
#define S17_CHIPID_V1_1 0x1202
|
||||
|
||||
#define S17_MASK_CTRL_SOFT_RET (1 << 31)
|
||||
|
||||
#define S17_GLOBAL_INT0_ACL_INI_INT (1<<29)
|
||||
#define S17_GLOBAL_INT0_LOOKUP_INI_INT (1<<28)
|
||||
#define S17_GLOBAL_INT0_QM_INI_INT (1<<27)
|
||||
#define S17_GLOBAL_INT0_MIB_INI_INT (1<<26)
|
||||
#define S17_GLOBAL_INT0_OFFLOAD_INI_INT (1<<25)
|
||||
#define S17_GLOBAL_INT0_HARDWARE_INI_DONE (1<<24)
|
||||
|
||||
#define S17_GLOBAL_INITIALIZED_STATUS \
|
||||
( \
|
||||
S17_GLOBAL_INT0_ACL_INI_INT | \
|
||||
S17_GLOBAL_INT0_LOOKUP_INI_INT | \
|
||||
S17_GLOBAL_INT0_QM_INI_INT | \
|
||||
S17_GLOBAL_INT0_MIB_INI_INT | \
|
||||
S17_GLOBAL_INT0_OFFLOAD_INI_INT | \
|
||||
S17_GLOBAL_INT0_HARDWARE_INI_DONE \
|
||||
)
|
||||
|
||||
#define S17_MAC0_MAC_MII_RXCLK_SEL (1 << 0)
|
||||
#define S17_MAC0_MAC_MII_TXCLK_SEL (1 << 1)
|
||||
#define S17_MAC0_MAC_MII_EN (1 << 2)
|
||||
#define S17_MAC0_MAC_GMII_RXCLK_SEL (1 << 4)
|
||||
#define S17_MAC0_MAC_GMII_TXCLK_SEL (1 << 5)
|
||||
#define S17_MAC0_MAC_GMII_EN (1 << 6)
|
||||
#define S17_MAC0_SGMII_EN (1 << 7)
|
||||
#define S17_MAC0_PHY_MII_RXCLK_SEL (1 << 8)
|
||||
#define S17_MAC0_PHY_MII_TXCLK_SEL (1 << 9)
|
||||
#define S17_MAC0_PHY_MII_EN (1 << 10)
|
||||
#define S17_MAC0_PHY_MII_PIPE_SEL (1 << 11)
|
||||
#define S17_MAC0_PHY_GMII_RXCLK_SEL (1 << 12)
|
||||
#define S17_MAC0_PHY_GMII_TXCLK_SEL (1 << 13)
|
||||
#define S17_MAC0_PHY_GMII_EN (1 << 14)
|
||||
#define S17_MAC0_RGMII_RXCLK_SHIFT 20
|
||||
#define S17_MAC0_RGMII_TXCLK_SHIFT 22
|
||||
#define S17_MAC0_RGMII_RXCLK_DELAY (1 << 24)
|
||||
#define S17_MAC0_RGMII_TXCLK_DELAY (1 << 25)
|
||||
#define S17_MAC0_RGMII_EN (1 << 26)
|
||||
|
||||
#define S17_MAC5_MAC_MII_RXCLK_SEL (1 << 0)
|
||||
#define S17_MAC5_MAC_MII_TXCLK_SEL (1 << 1)
|
||||
#define S17_MAC5_MAC_MII_EN (1 << 2)
|
||||
#define S17_MAC5_PHY_MII_RXCLK_SEL (1 << 8)
|
||||
#define S17_MAC5_PHY_MII_TXCLK_SEL (1 << 9)
|
||||
#define S17_MAC5_PHY_MII_EN (1 << 10)
|
||||
#define S17_MAC5_PHY_MII_PIPE_SEL (1 << 11)
|
||||
#define S17_MAC5_RGMII_RXCLK_SHIFT 20
|
||||
#define S17_MAC5_RGMII_TXCLK_SHIFT 22
|
||||
#define S17_MAC5_RGMII_RXCLK_DELAY (1 << 24)
|
||||
#define S17_MAC5_RGMII_TXCLK_DELAY (1 << 25)
|
||||
#define S17_MAC5_RGMII_EN (1 << 26)
|
||||
|
||||
#define S17_MAC6_MAC_MII_RXCLK_SEL (1 << 0)
|
||||
#define S17_MAC6_MAC_MII_TXCLK_SEL (1 << 1)
|
||||
#define S17_MAC6_MAC_MII_EN (1 << 2)
|
||||
#define S17_MAC6_MAC_GMII_RXCLK_SEL (1 << 4)
|
||||
#define S17_MAC6_MAC_GMII_TXCLK_SEL (1 << 5)
|
||||
#define S17_MAC6_MAC_GMII_EN (1 << 6)
|
||||
#define S17_MAC6_SGMII_EN (1 << 7)
|
||||
#define S17_MAC6_PHY_MII_RXCLK_SEL (1 << 8)
|
||||
#define S17_MAC6_PHY_MII_TXCLK_SEL (1 << 9)
|
||||
#define S17_MAC6_PHY_MII_EN (1 << 10)
|
||||
#define S17_MAC6_PHY_MII_PIPE_SEL (1 << 11)
|
||||
#define S17_MAC6_PHY_GMII_RXCLK_SEL (1 << 12)
|
||||
#define S17_MAC6_PHY_GMII_TXCLK_SEL (1 << 13)
|
||||
#define S17_MAC6_PHY_GMII_EN (1 << 14)
|
||||
#define S17_PHY4_GMII_EN (1 << 16)
|
||||
#define S17_PHY4_RGMII_EN (1 << 17)
|
||||
#define S17_PHY4_MII_EN (1 << 18)
|
||||
#define S17_MAC6_RGMII_RXCLK_SHIFT 20
|
||||
#define S17_MAC6_RGMII_TXCLK_SHIFT 22
|
||||
#define S17_MAC6_RGMII_RXCLK_DELAY (1 << 24)
|
||||
#define S17_MAC6_RGMII_TXCLK_DELAY (1 << 25)
|
||||
#define S17_MAC6_RGMII_EN (1 << 26)
|
||||
|
||||
#define S17_SPEED_10M (0 << 0)
|
||||
#define S17_SPEED_100M (1 << 0)
|
||||
#define S17_SPEED_1000M (2 << 0)
|
||||
#define S17_TXMAC_EN (1 << 2)
|
||||
#define S17_RXMAC_EN (1 << 3)
|
||||
#define S17_TX_FLOW_EN (1 << 4)
|
||||
#define S17_RX_FLOW_EN (1 << 5)
|
||||
#define S17_DUPLEX_FULL (1 << 6)
|
||||
#define S17_DUPLEX_HALF (0 << 6)
|
||||
#define S17_TX_HALF_FLOW_EN (1 << 7)
|
||||
#define S17_LINK_EN (1 << 9)
|
||||
#define S17_FLOW_LINK_EN (1 << 12)
|
||||
#define S17_PORT_STATUS_DEFAULT (S17_SPEED_1000M | S17_TXMAC_EN | \
|
||||
S17_RXMAC_EN | S17_TX_FLOW_EN | \
|
||||
S17_RX_FLOW_EN | S17_DUPLEX_FULL | \
|
||||
S17_TX_HALF_FLOW_EN)
|
||||
|
||||
#define S17_PORT_STATUS_AZ_DEFAULT (S17_SPEED_1000M | S17_TXMAC_EN | \
|
||||
S17_RXMAC_EN | S17_TX_FLOW_EN | \
|
||||
S17_RX_FLOW_EN | S17_DUPLEX_FULL)
|
||||
|
||||
|
||||
#define S17_HDRLENGTH_SEL (1 << 16)
|
||||
#define S17_HDR_VALUE 0xAAAA
|
||||
|
||||
#define S17_TXHDR_MODE_NO 0
|
||||
#define S17_TXHDR_MODE_MGM 1
|
||||
#define S17_TXHDR_MODE_ALL 2
|
||||
#define S17_RXHDR_MODE_NO (0 << 2)
|
||||
#define S17_RXHDR_MODE_MGM (1 << 2)
|
||||
#define S17_RXHDR_MODE_ALL (2 << 2)
|
||||
|
||||
#define S17_CPU_PORT_EN (1 << 10)
|
||||
#define S17_PPPOE_REDIR_EN (1 << 8)
|
||||
#define S17_MIRROR_PORT_SHIFT 4
|
||||
#define S17_IGMP_COPY_EN (1 << 3)
|
||||
#define S17_RIP_COPY_EN (1 << 2)
|
||||
#define S17_EAPOL_REDIR_EN (1 << 0)
|
||||
|
||||
#define S17_IGMP_JOIN_LEAVE_DP_SHIFT 24
|
||||
#define S17_BROAD_DP_SHIFT 16
|
||||
#define S17_MULTI_FLOOD_DP_SHIFT 8
|
||||
#define S17_UNI_FLOOD_DP_SHIFT 0
|
||||
#define S17_IGMP_JOIN_LEAVE_DPALL (0x7f << S17_IGMP_JOIN_LEAVE_DP_SHIFT)
|
||||
#define S17_BROAD_DPALL (0x7f << S17_BROAD_DP_SHIFT)
|
||||
#define S17_MULTI_FLOOD_DPALL (0x7f << S17_MULTI_FLOOD_DP_SHIFT)
|
||||
#define S17_UNI_FLOOD_DPALL (0x7f << S17_UNI_FLOOD_DP_SHIFT)
|
||||
|
||||
#define S17_PWS_CHIP_AR8327 (1 << 30)
|
||||
#define S17c_PWS_SERDES_ANEG_DISABLE (1 << 7)
|
||||
|
||||
/* S17_PHY_CONTROL fields */
|
||||
#define S17_CTRL_SOFTWARE_RESET 0x8000
|
||||
#define S17_CTRL_SPEED_LSB 0x2000
|
||||
#define S17_CTRL_AUTONEGOTIATION_ENABLE 0x1000
|
||||
#define S17_CTRL_RESTART_AUTONEGOTIATION 0x0200
|
||||
#define S17_CTRL_SPEED_FULL_DUPLEX 0x0100
|
||||
#define S17_CTRL_SPEED_MSB 0x0040
|
||||
|
||||
/* For EEE_CTRL_REG */
|
||||
#define S17_LPI_DISABLE_P1 (1 << 4)
|
||||
#define S17_LPI_DISABLE_P2 (1 << 6)
|
||||
#define S17_LPI_DISABLE_P3 (1 << 8)
|
||||
#define S17_LPI_DISABLE_P4 (1 << 10)
|
||||
#define S17_LPI_DISABLE_P5 (1 << 12)
|
||||
#define S17_LPI_DISABLE_ALL 0x1550
|
||||
|
||||
/* For MMD register control */
|
||||
#define S17_MMD_FUNC_ADDR (0 << 14)
|
||||
#define S17_MMD_FUNC_DATA (1 << 14)
|
||||
#define S17_MMD_FUNC_DATA_2 (2 << 14)
|
||||
#define S17_MMD_FUNC_DATA_3 (3 << 14)
|
||||
|
||||
/* For phyInfo_t azFeature */
|
||||
#define S17_8023AZ_PHY_ENABLED (1 << 0)
|
||||
#define S17_8023AZ_PHY_LINKED (1 << 1)
|
||||
|
||||
/* Queue Management registe fields */
|
||||
#define S17_HOL_CTRL0_LAN 0x2a008888 /* egress priority 8, eg_portq = 0x2a */
|
||||
#define S17_HOL_CTRL0_WAN 0x2a666666 /* egress priority 6, eg_portq = 0x2a */
|
||||
#define S17_HOL_CTRL1_DEFAULT 0xc6 /* enable HOL control */
|
||||
|
||||
/* Packet Edit register fields */
|
||||
#define S17_ROUTER_EG_UNMOD 0x0 /* unmodified */
|
||||
#define S17_ROUTER_EG_WOVLAN 0x1 /* without VLAN */
|
||||
#define S17_ROUTER_EG_WVLAN 0x2 /* with VLAN */
|
||||
#define S17_ROUTER_EG_UNTOUCH 0x3 /* untouched */
|
||||
#define S17_ROUTER_EG_MODE_DEFAULT 0x01111111 /* all ports without VLAN */
|
||||
|
||||
#define S17_RESET_DONE(phy_control) \
|
||||
(((phy_control) & (S17_CTRL_SOFTWARE_RESET)) == 0)
|
||||
|
||||
/* Phy status fields */
|
||||
#define S17_STATUS_AUTO_NEG_DONE 0x0020
|
||||
|
||||
#define S17_AUTONEG_DONE(ip_phy_status) \
|
||||
(((ip_phy_status) & \
|
||||
(S17_STATUS_AUTO_NEG_DONE)) == \
|
||||
(S17_STATUS_AUTO_NEG_DONE))
|
||||
|
||||
/* Link Partner ability */
|
||||
#define S17_LINK_100BASETX_FULL_DUPLEX 0x0100
|
||||
#define S17_LINK_100BASETX 0x0080
|
||||
#define S17_LINK_10BASETX_FULL_DUPLEX 0x0040
|
||||
#define S17_LINK_10BASETX 0x0020
|
||||
|
||||
/* Advertisement register. */
|
||||
#define S17_ADVERTISE_NEXT_PAGE 0x8000
|
||||
#define S17_ADVERTISE_ASYM_PAUSE 0x0800
|
||||
#define S17_ADVERTISE_PAUSE 0x0400
|
||||
#define S17_ADVERTISE_100FULL 0x0100
|
||||
#define S17_ADVERTISE_100HALF 0x0080
|
||||
#define S17_ADVERTISE_10FULL 0x0040
|
||||
#define S17_ADVERTISE_10HALF 0x0020
|
||||
|
||||
#define S17_ADVERTISE_ALL (S17_ADVERTISE_ASYM_PAUSE | S17_ADVERTISE_PAUSE | \
|
||||
S17_ADVERTISE_10HALF | S17_ADVERTISE_10FULL | \
|
||||
S17_ADVERTISE_100HALF | S17_ADVERTISE_100FULL)
|
||||
|
||||
/* 1000BASET_CONTROL */
|
||||
#define S17_ADVERTISE_1000FULL 0x0200
|
||||
|
||||
/* Phy Specific status fields */
|
||||
#define S17_STATUS_LINK_MASK 0xC000
|
||||
#define S17_STATUS_LINK_SHIFT 14
|
||||
#define S17_STATUS_FULL_DEPLEX 0x2000
|
||||
#define S17_STATUS_LINK_PASS 0x0400
|
||||
#define S17_STATUS_RESOLVED 0x0800
|
||||
#define S17_STATUS_LINK_10M 0
|
||||
#define S17_STATUS_LINK_100M 1
|
||||
#define S17_STATUS_LINK_1000M 2
|
||||
|
||||
#define S17_GLOBAL_INT_PHYMASK (1 << 15)
|
||||
|
||||
#define S17_PHY_LINK_UP 0x400
|
||||
#define S17_PHY_LINK_DOWN 0x800
|
||||
#define S17_PHY_LINK_DUPLEX_CHANGE 0x2000
|
||||
#define S17_PHY_LINK_SPEED_CHANGE 0x4000
|
||||
|
||||
/* For Port flow control registers */
|
||||
#define S17_PORT_FLCTL_XON_DEFAULT (0x3a << 16)
|
||||
#define S17_PORT_FLCTL_XOFF_DEFAULT (0x4a)
|
||||
|
||||
/* Module enable Register */
|
||||
#define S17_MODULE_L3_EN (1 << 2)
|
||||
#define S17_MODULE_ACL_EN (1 << 1)
|
||||
#define S17_MODULE_MIB_EN (1 << 0)
|
||||
|
||||
/* MIB Function Register 1 */
|
||||
#define S17_MIB_FUNC_ALL (3 << 24)
|
||||
#define S17_MIB_CPU_KEEP (1 << 20)
|
||||
#define S17_MIB_BUSY (1 << 17)
|
||||
#define S17_MIB_AT_HALF_EN (1 << 16)
|
||||
#define S17_MIB_TIMER_DEFAULT 0x100
|
||||
|
||||
#define S17_MAC_MAX 7
|
||||
|
||||
/* MAC power selector bit definitions */
|
||||
#define S17_RGMII0_1_8V (1 << 19)
|
||||
#define S17_RGMII1_1_8V (1 << 18)
|
||||
|
||||
/* SGMII_CTRL bit definitions */
|
||||
#define S17c_SGMII_EN_LCKDT (1 << 0)
|
||||
#define S17c_SGMII_EN_PLL (1 << 1)
|
||||
#define S17c_SGMII_EN_RX (1 << 2)
|
||||
#define S17c_SGMII_EN_TX (1 << 3)
|
||||
#define S17c_SGMII_EN_SD (1 << 4)
|
||||
#define S17c_SGMII_BW_HIGH (1 << 6)
|
||||
#define S17c_SGMII_SEL_CLK125M (1 << 7)
|
||||
#define S17c_SGMII_TXDR_CTRL_600mV (1 << 10)
|
||||
#define S17c_SGMII_CDR_BW_8 (3 << 13)
|
||||
#define S17c_SGMII_DIS_AUTO_LPI_25M (1 << 16)
|
||||
#define S17c_SGMII_MODE_CTRL_SGMII_PHY (1 << 22)
|
||||
#define S17c_SGMII_PAUSE_SG_TX_EN_25M (1 << 24)
|
||||
#define S17c_SGMII_ASYM_PAUSE_25M (1 << 25)
|
||||
#define S17c_SGMII_PAUSE_25M (1 << 26)
|
||||
#define S17c_SGMII_HALF_DUPLEX_25M (1 << 30)
|
||||
#define S17c_SGMII_FULL_DUPLEX_25M (1 << 31)
|
||||
|
||||
#ifndef BOOL
|
||||
#define BOOL int
|
||||
#endif
|
||||
|
||||
/*add feature define here*/
|
||||
|
||||
#ifdef CONFIG_AR7242_S17_PHY
|
||||
#undef HEADER_REG_CONF
|
||||
#undef HEADER_EN
|
||||
#endif
|
||||
|
||||
#define LINK_UP 0x400
|
||||
#define LINK(_data) (_data & LINK_UP)? "Up" : "Down"
|
||||
#define DUPLEX(_data) (_data & 0x2000)?\
|
||||
"Full duplex" : "Half duplex"
|
||||
#define SPEED(_data) ((_data & 0xC000) >> 12)
|
||||
#define SPEED_1000M (1 << 3)
|
||||
#define SPEED_100M (1 << 2)
|
||||
|
||||
#define S17C_MAX_PORT 4
|
||||
typedef struct {
|
||||
u32 mac_pwr;
|
||||
int port_count;
|
||||
int chip_detect;
|
||||
u32 port_phy_address[S17C_MAX_PORT];
|
||||
} ipq_s17c_swt_cfg_t;
|
||||
|
||||
#endif
|
||||
|
||||
597
drivers/net/ipq_common/ipq_aquantia_phy.c
Normal file
597
drivers/net/ipq_common/ipq_aquantia_phy.c
Normal file
|
|
@ -0,0 +1,597 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <net.h>
|
||||
#include <asm-generic/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <malloc.h>
|
||||
#include <phy.h>
|
||||
#include <miiphy.h>
|
||||
#include "ipq_phy.h"
|
||||
#include "ipq_aquantia_phy.h"
|
||||
#include <crc.h>
|
||||
#include <mmc.h>
|
||||
#include <asm/errno.h>
|
||||
#include <nand.h>
|
||||
#include <spi_flash.h>
|
||||
#include <spi.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <fdtdec.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
typedef struct {
|
||||
unsigned int image_type;
|
||||
unsigned int header_vsn_num;
|
||||
unsigned int image_src;
|
||||
unsigned char *image_dest_ptr;
|
||||
unsigned int image_size;
|
||||
unsigned int code_size;
|
||||
unsigned char *signature_ptr;
|
||||
unsigned int signature_size;
|
||||
unsigned char *cert_chain_ptr;
|
||||
unsigned int cert_chain_size;
|
||||
} mbn_header_t;
|
||||
|
||||
mbn_header_t *fwimg_header;
|
||||
static int debug = 0;
|
||||
|
||||
#ifdef CONFIG_QCA_MMC
|
||||
extern qca_mmc mmc_host;
|
||||
static qca_mmc *host = &mmc_host;
|
||||
#endif
|
||||
|
||||
extern int ipq_mdio_write(int mii_id,
|
||||
int regnum, u16 value);
|
||||
extern int ipq_mdio_read(int mii_id,
|
||||
int regnum, ushort *data);
|
||||
|
||||
extern int ipq_sw_mdio_init(const char *);
|
||||
extern void devsoc_eth_initialize(void);
|
||||
static int program_ethphy_fw(unsigned int phy_addr,
|
||||
uint32_t load_addr,uint32_t file_size );
|
||||
static qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
|
||||
|
||||
u16 aq_phy_reg_write(u32 dev_id, u32 phy_id,
|
||||
u32 reg_id, u16 reg_val)
|
||||
{
|
||||
ipq_mdio_write(phy_id, reg_id, reg_val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 aq_phy_reg_read(u32 dev_id, u32 phy_id, u32 reg_id)
|
||||
{
|
||||
return ipq_mdio_read(phy_id, reg_id, NULL);
|
||||
}
|
||||
|
||||
u8 aq_phy_get_link_status(u32 dev_id, u32 phy_id)
|
||||
{
|
||||
u16 phy_data;
|
||||
uint32_t reg;
|
||||
|
||||
reg = AQ_PHY_AUTO_STATUS_REG | AQUANTIA_MII_ADDR_C45;
|
||||
phy_data = aq_phy_reg_read(dev_id, phy_id, reg);
|
||||
phy_data = aq_phy_reg_read(dev_id, phy_id, reg);
|
||||
|
||||
if (((phy_data >> 2) & 0x1) & PORT_LINK_UP)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
u32 aq_phy_get_duplex(u32 dev_id, u32 phy_id, fal_port_duplex_t *duplex)
|
||||
{
|
||||
u16 phy_data;
|
||||
uint32_t reg;
|
||||
|
||||
reg = AQ_PHY_LINK_STATUS_REG | AQUANTIA_MII_ADDR_C45;
|
||||
phy_data = aq_phy_reg_read(dev_id, phy_id, reg);
|
||||
|
||||
/*
|
||||
* Read duplex
|
||||
*/
|
||||
phy_data = phy_data & 0x1;
|
||||
if (phy_data & 0x1)
|
||||
*duplex = FAL_FULL_DUPLEX;
|
||||
else
|
||||
*duplex = FAL_HALF_DUPLEX;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 aq_phy_get_speed(u32 dev_id, u32 phy_id, fal_port_speed_t *speed)
|
||||
{
|
||||
u16 phy_data;
|
||||
uint32_t reg;
|
||||
|
||||
reg = AQ_PHY_LINK_STATUS_REG | AQUANTIA_MII_ADDR_C45;
|
||||
phy_data = aq_phy_reg_read(dev_id, phy_id, reg);
|
||||
|
||||
switch ((phy_data >> 1) & 0x7) {
|
||||
case SPEED_10G:
|
||||
*speed = FAL_SPEED_10000;
|
||||
break;
|
||||
case SPEED_5G:
|
||||
*speed = FAL_SPEED_5000;
|
||||
break;
|
||||
case SPEED_2_5G:
|
||||
*speed = FAL_SPEED_2500;
|
||||
break;
|
||||
case SPEED_1000MBS:
|
||||
*speed = FAL_SPEED_1000;
|
||||
break;
|
||||
case SPEED_100MBS:
|
||||
*speed = FAL_SPEED_100;
|
||||
break;
|
||||
case SPEED_10MBS:
|
||||
*speed = FAL_SPEED_10;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aquantia_phy_restart_autoneg(u32 phy_id)
|
||||
{
|
||||
u16 phy_data;
|
||||
|
||||
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_PHY_XS_REGISTERS,
|
||||
AQUANTIA_PHY_XS_USX_TRANSMIT));
|
||||
if (!(phy_data & AQUANTIA_PHY_USX_AUTONEG_ENABLE))
|
||||
aq_phy_reg_write(0x0, phy_id,AQUANTIA_REG_ADDRESS(
|
||||
AQUANTIA_MMD_PHY_XS_REGISTERS,
|
||||
AQUANTIA_PHY_XS_USX_TRANSMIT),
|
||||
phy_data | AQUANTIA_PHY_USX_AUTONEG_ENABLE);
|
||||
|
||||
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_AUTONEG,
|
||||
AQUANTIA_AUTONEG_STANDARD_CONTROL1));
|
||||
|
||||
phy_data |= AQUANTIA_CTRL_AUTONEGOTIATION_ENABLE;
|
||||
aq_phy_reg_write(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_AUTONEG,
|
||||
AQUANTIA_AUTONEG_STANDARD_CONTROL1),
|
||||
phy_data | AQUANTIA_CTRL_RESTART_AUTONEGOTIATION);
|
||||
}
|
||||
|
||||
int ipq_qca_aquantia_phy_init(struct phy_ops **ops, u32 phy_id)
|
||||
{
|
||||
u16 phy_data;
|
||||
struct phy_ops *aq_phy_ops;
|
||||
aq_phy_ops = (struct phy_ops *)malloc(sizeof(struct phy_ops));
|
||||
if (!aq_phy_ops)
|
||||
return -ENOMEM;
|
||||
aq_phy_ops->phy_get_link_status = aq_phy_get_link_status;
|
||||
aq_phy_ops->phy_get_speed = aq_phy_get_speed;
|
||||
aq_phy_ops->phy_get_duplex = aq_phy_get_duplex;
|
||||
*ops = aq_phy_ops;
|
||||
|
||||
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_PHY_XS_REGISTERS,
|
||||
AQUANTIA_PHY_XS_USX_TRANSMIT));
|
||||
|
||||
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(1, QCA_PHY_ID1));
|
||||
printf ("PHY ID1: 0x%x\n", phy_data);
|
||||
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(1, QCA_PHY_ID2));
|
||||
printf ("PHY ID2: 0x%x\n", phy_data);
|
||||
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_PHY_XS_REGISTERS,
|
||||
AQUANTIA_PHY_XS_USX_TRANSMIT));
|
||||
phy_data |= AQUANTIA_PHY_USX_AUTONEG_ENABLE;
|
||||
aq_phy_reg_write(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_PHY_XS_REGISTERS,
|
||||
AQUANTIA_PHY_XS_USX_TRANSMIT), phy_data);
|
||||
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_AUTONEG,
|
||||
AQUANTIA_AUTONEG_TRANSMIT_VENDOR_INTR_MASK));
|
||||
phy_data |= AQUANTIA_INTR_LINK_STATUS_CHANGE;
|
||||
aq_phy_reg_write(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_AUTONEG,
|
||||
AQUANTIA_AUTONEG_TRANSMIT_VENDOR_INTR_MASK), phy_data);
|
||||
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_GLOABLE_REGISTERS,
|
||||
AQUANTIA_GLOBAL_INTR_STANDARD_MASK));
|
||||
phy_data |= AQUANTIA_ALL_VENDOR_ALARMS_INTERRUPT_MASK;
|
||||
aq_phy_reg_write(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_GLOABLE_REGISTERS,
|
||||
AQUANTIA_GLOBAL_INTR_STANDARD_MASK), phy_data);
|
||||
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_GLOABLE_REGISTERS,
|
||||
AQUANTIA_GLOBAL_INTR_VENDOR_MASK));
|
||||
phy_data |= AQUANTIA_AUTO_AND_ALARMS_INTR_MASK;
|
||||
aq_phy_reg_write(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_GLOABLE_REGISTERS,
|
||||
AQUANTIA_GLOBAL_INTR_VENDOR_MASK), phy_data);
|
||||
|
||||
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_PHY_XS_REGISTERS,
|
||||
AQUANTIA_PHY_XS_USX_TRANSMIT));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_aq_phy_restart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
unsigned int phy_addr = AQU_PHY_ADDR;
|
||||
if (argc > 2)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
if (argc == 2)
|
||||
phy_addr = simple_strtoul(argv[1], NULL, 16);
|
||||
|
||||
aquantia_phy_restart_autoneg(phy_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipq_board_fw_download(unsigned int phy_addr)
|
||||
{
|
||||
char runcmd[256];
|
||||
int ret,i=0;
|
||||
uint32_t start; /* block number */
|
||||
uint32_t size; /* no. of blocks */
|
||||
qca_part_entry_t ethphyfw;
|
||||
unsigned int *ethphyfw_load_addr = NULL;
|
||||
struct { char *name; qca_part_entry_t *part; } entries[] = {
|
||||
{ "0:ETHPHYFW", ðphyfw },
|
||||
};
|
||||
#ifdef CONFIG_QCA_MMC
|
||||
block_dev_desc_t *blk_dev;
|
||||
disk_partition_t disk_info;
|
||||
#endif
|
||||
/* check the smem info to see which flash used for booting */
|
||||
if (sfi->flash_type == SMEM_BOOT_SPI_FLASH) {
|
||||
if (debug) {
|
||||
printf("Using nor device \n");
|
||||
}
|
||||
} else if (sfi->flash_type == SMEM_BOOT_NAND_FLASH) {
|
||||
if (debug) {
|
||||
printf("Using nand device 0\n");
|
||||
}
|
||||
} else if (sfi->flash_type == SMEM_BOOT_MMC_FLASH) {
|
||||
if (debug) {
|
||||
printf("Using MMC device\n");
|
||||
}
|
||||
} else if (sfi->flash_type == SMEM_BOOT_QSPI_NAND_FLASH) {
|
||||
if (debug) {
|
||||
printf("Using qspi nand device 0\n");
|
||||
}
|
||||
} else {
|
||||
printf("Unsupported BOOT flash type\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = smem_getpart(entries[i].name, &start, &size);
|
||||
if (ret < 0) {
|
||||
debug("cdp: get part failed for %s\n", entries[i].name);
|
||||
} else {
|
||||
qca_set_part_entry(entries[i].name, sfi, entries[i].part, start, size);
|
||||
}
|
||||
|
||||
if ((sfi->flash_type == SMEM_BOOT_NAND_FLASH) ||
|
||||
(sfi->flash_type == SMEM_BOOT_QSPI_NAND_FLASH) ||
|
||||
(sfi->flash_type == SMEM_BOOT_SPI_FLASH)) {
|
||||
ethphyfw_load_addr = (uint *)malloc(AQ_ETHPHYFW_IMAGE_SIZE);
|
||||
/* We only need memory equivalent to max size ETHPHYFW
|
||||
* which is currently assumed as 512 KB.
|
||||
*/
|
||||
if (ethphyfw_load_addr == NULL) {
|
||||
printf("ETHPHYFW Loading failed, size = %llu\n",
|
||||
ethphyfw.size);
|
||||
return -1;
|
||||
} else {
|
||||
memset(ethphyfw_load_addr, 0, AQ_ETHPHYFW_IMAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((sfi->flash_type == SMEM_BOOT_NAND_FLASH) ||
|
||||
(sfi->flash_type == SMEM_BOOT_QSPI_NAND_FLASH)) {
|
||||
/*
|
||||
* Kernel is in a separate partition
|
||||
*/
|
||||
snprintf(runcmd, sizeof(runcmd),
|
||||
/* NOR is treated as psuedo NAND */
|
||||
"nand read 0x%p 0x%llx 0x%llx && ",
|
||||
ethphyfw_load_addr, ethphyfw.offset, (long long unsigned int) AQ_ETHPHYFW_IMAGE_SIZE);
|
||||
|
||||
if (debug)
|
||||
printf("%s", runcmd);
|
||||
|
||||
if (run_command(runcmd, 0) != CMD_RET_SUCCESS) {
|
||||
free(ethphyfw_load_addr);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
} else if (sfi->flash_type == SMEM_BOOT_SPI_FLASH) {
|
||||
snprintf(runcmd, sizeof(runcmd),
|
||||
"sf probe && " "sf read 0x%p 0x%llx 0x%llx && ",
|
||||
ethphyfw_load_addr, ethphyfw.offset, (long long unsigned int) AQ_ETHPHYFW_IMAGE_SIZE);
|
||||
|
||||
if (debug)
|
||||
printf("%s", runcmd);
|
||||
|
||||
if (run_command(runcmd, 0) != CMD_RET_SUCCESS) {
|
||||
free(ethphyfw_load_addr);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
#ifdef CONFIG_QCA_MMC
|
||||
} else if (sfi->flash_type == SMEM_BOOT_MMC_FLASH ) {
|
||||
blk_dev = mmc_get_dev(host->dev_num);
|
||||
ret = get_partition_info_efi_by_name(blk_dev,
|
||||
"0:ETHPHYFW", &disk_info);
|
||||
|
||||
ethphyfw_load_addr = (uint *)malloc(((uint)disk_info.size) *
|
||||
((uint)disk_info.blksz));
|
||||
if (ethphyfw_load_addr == NULL) {
|
||||
printf("ETHPHYFW Loading failed, size = %lu\n",
|
||||
((long unsigned int)(uint)disk_info.size) * ((uint)disk_info.blksz));
|
||||
return -1;
|
||||
} else {
|
||||
memset(ethphyfw_load_addr, 0,
|
||||
(((uint)disk_info.size) *
|
||||
((uint)disk_info.blksz)));
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
snprintf(runcmd, sizeof(runcmd),
|
||||
"mmc read 0x%p 0x%X 0x%X",
|
||||
ethphyfw_load_addr,
|
||||
(uint)disk_info.start, (uint)disk_info.size);
|
||||
|
||||
if (run_command(runcmd, 0) != CMD_RET_SUCCESS) {
|
||||
free(ethphyfw_load_addr);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
fwimg_header = (mbn_header_t *)(ethphyfw_load_addr);
|
||||
|
||||
if (fwimg_header->image_type == 0x13 &&
|
||||
fwimg_header->header_vsn_num == 0x3) {
|
||||
program_ethphy_fw(phy_addr,
|
||||
(uint32_t)(((uint32_t)ethphyfw_load_addr)
|
||||
+ sizeof(mbn_header_t)),
|
||||
(uint32_t)(fwimg_header->image_size));
|
||||
} else {
|
||||
printf("bad magic on ETHPHYFW partition\n");
|
||||
free(ethphyfw_load_addr);
|
||||
return -1;
|
||||
}
|
||||
free(ethphyfw_load_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define AQ_PHY_IMAGE_HEADER_CONTENT_OFFSET_HHD 0x300
|
||||
static int program_ethphy_fw(unsigned int phy_addr, uint32_t load_addr, uint32_t file_size)
|
||||
{
|
||||
int i;
|
||||
uint8_t *buf;
|
||||
uint16_t file_crc;
|
||||
uint16_t computed_crc;
|
||||
uint32_t reg1, reg2;
|
||||
uint16_t recorded_ggp8_val;
|
||||
uint16_t daisy_chain_dis;
|
||||
uint32_t primary_header_ptr = 0x00000000;
|
||||
uint32_t primary_iram_ptr = 0x00000000;
|
||||
uint32_t primary_dram_ptr = 0x00000000;
|
||||
uint32_t primary_iram_sz = 0x00000000;
|
||||
uint32_t primary_dram_sz = 0x00000000;
|
||||
uint32_t phy_img_hdr_off;
|
||||
uint32_t byte_sz;
|
||||
uint32_t dword_sz;
|
||||
uint32_t byte_ptr;
|
||||
uint16_t msw = 0;
|
||||
uint16_t lsw = 0;
|
||||
uint8_t msb1;
|
||||
uint8_t msb2;
|
||||
uint8_t lsb1;
|
||||
uint8_t lsb2;
|
||||
uint16_t mailbox_crc;
|
||||
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x300), 0xdead);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x301), 0xbeaf);
|
||||
reg1 = aq_phy_reg_read(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x300));
|
||||
reg2 = aq_phy_reg_read(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x301));
|
||||
|
||||
if(reg1 != 0xdead && reg2 != 0xbeaf) {
|
||||
printf("PHY::Scratchpad Read/Write test fail\n");
|
||||
return 0;
|
||||
}
|
||||
buf = (uint8_t *)load_addr;
|
||||
file_crc = buf[file_size - 2] << 8 | buf[file_size - 1];
|
||||
computed_crc = cyg_crc16(buf, file_size - 2);
|
||||
|
||||
if (file_crc != computed_crc) {
|
||||
printf("CRC check failed on phy fw file\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf("CRC check good on phy fw file (0x%04X)\n",computed_crc);
|
||||
}
|
||||
|
||||
daisy_chain_dis = aq_phy_reg_read(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc452));
|
||||
if (!(daisy_chain_dis & 0x1))
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc452), 0x1);
|
||||
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc471), 0x40);
|
||||
recorded_ggp8_val = aq_phy_reg_read(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc447));
|
||||
if ((recorded_ggp8_val & 0x1f) != phy_addr)
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc447), phy_addr);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc441), 0x4000);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc001), 0x41);
|
||||
primary_header_ptr = (((buf[0x9] & 0x0F) << 8) | buf[0x8]) << 12;
|
||||
phy_img_hdr_off = AQ_PHY_IMAGE_HEADER_CONTENT_OFFSET_HHD;
|
||||
primary_iram_ptr = (buf[primary_header_ptr + phy_img_hdr_off + 0x4 + 2] << 16) |
|
||||
(buf[primary_header_ptr + phy_img_hdr_off + 0x4 + 1] << 8) |
|
||||
buf[primary_header_ptr + phy_img_hdr_off + 0x4];
|
||||
primary_iram_sz = (buf[primary_header_ptr + phy_img_hdr_off + 0x7 + 2] << 16) |
|
||||
(buf[primary_header_ptr + phy_img_hdr_off + 0x7 + 1] << 8) |
|
||||
buf[primary_header_ptr + phy_img_hdr_off + 0x7];
|
||||
primary_dram_ptr = (buf[primary_header_ptr + phy_img_hdr_off + 0xA + 2] << 16) |
|
||||
(buf[primary_header_ptr + phy_img_hdr_off + 0xA + 1] << 8) |
|
||||
buf[primary_header_ptr + phy_img_hdr_off + 0xA];
|
||||
primary_dram_sz = (buf[primary_header_ptr + phy_img_hdr_off + 0xD + 2] << 16) |
|
||||
(buf[primary_header_ptr + phy_img_hdr_off + 0xD + 1] << 8) |
|
||||
buf[primary_header_ptr + phy_img_hdr_off + 0xD];
|
||||
primary_iram_ptr += primary_header_ptr;
|
||||
primary_dram_ptr += primary_header_ptr;
|
||||
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0x1000);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0x0);
|
||||
computed_crc = 0;
|
||||
printf("PHYFW:Loading IRAM...........");
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x202), 0x4000);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x203), 0x0);
|
||||
byte_sz = primary_iram_sz;
|
||||
dword_sz = byte_sz >> 2;
|
||||
byte_ptr = primary_iram_ptr;
|
||||
for (i = 0; i < dword_sz; i++) {
|
||||
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
|
||||
byte_ptr += 2;
|
||||
msw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
|
||||
byte_ptr += 2;
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x204), msw);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x205), lsw);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0xc000);
|
||||
msb1 = msw >> 8;
|
||||
msb2 = msw & 0xFF;
|
||||
lsb1 = lsw >> 8;
|
||||
lsb2 = lsw & 0xFF;
|
||||
computed_crc = cyg_crc16_computed(&msb1, 0x1, computed_crc);
|
||||
computed_crc = cyg_crc16_computed(&msb2, 0x1, computed_crc);
|
||||
computed_crc = cyg_crc16_computed(&lsb1, 0x1, computed_crc);
|
||||
computed_crc = cyg_crc16_computed(&lsb2, 0x1, computed_crc);
|
||||
}
|
||||
|
||||
switch (byte_sz & 0x3) {
|
||||
case 0x1:
|
||||
lsw = buf[byte_ptr++];
|
||||
msw = 0x0000;
|
||||
break;
|
||||
case 0x2:
|
||||
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
|
||||
byte_ptr += 2;
|
||||
msw = 0x0000;
|
||||
break;
|
||||
case 0x3:
|
||||
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
|
||||
byte_ptr += 2;
|
||||
msw = buf[byte_ptr++];
|
||||
break;
|
||||
}
|
||||
|
||||
if (byte_sz & 0x3) {
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x204), msw);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x205), lsw);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0xc000);
|
||||
msb1 = msw >> 8;
|
||||
msb2 = msw & 0xFF;
|
||||
lsb1 = lsw >> 8;
|
||||
lsb2 = lsw & 0xFF;
|
||||
computed_crc = cyg_crc16_computed(&msb1, 0x1, computed_crc);
|
||||
computed_crc = cyg_crc16_computed(&msb2, 0x1, computed_crc);
|
||||
computed_crc = cyg_crc16_computed(&lsb1, 0x1, computed_crc);
|
||||
computed_crc = cyg_crc16_computed(&lsb2, 0x1, computed_crc);
|
||||
}
|
||||
printf("done.\n");
|
||||
printf("PHYFW:Loading DRAM..............");
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x202), 0x3ffe);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x203), 0x0);
|
||||
byte_sz = primary_dram_sz;
|
||||
dword_sz = byte_sz >> 2;
|
||||
byte_ptr = primary_dram_ptr;
|
||||
for (i = 0; i < dword_sz; i++) {
|
||||
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
|
||||
byte_ptr += 2;
|
||||
msw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
|
||||
byte_ptr += 2;
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x204), msw);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x205), lsw);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0xc000);
|
||||
msb1 = msw >> 8;
|
||||
msb2 = msw & 0xFF;
|
||||
lsb1 = lsw >> 8;
|
||||
lsb2 = lsw & 0xFF;
|
||||
computed_crc = cyg_crc16_computed(&msb1, 0x1, computed_crc);
|
||||
computed_crc = cyg_crc16_computed(&msb2, 0x1, computed_crc);
|
||||
computed_crc = cyg_crc16_computed(&lsb1, 0x1, computed_crc);
|
||||
computed_crc = cyg_crc16_computed(&lsb2, 0x1, computed_crc);
|
||||
}
|
||||
|
||||
switch (byte_sz & 0x3) {
|
||||
case 0x1:
|
||||
lsw = buf[byte_ptr++];
|
||||
msw = 0x0000;
|
||||
break;
|
||||
case 0x2:
|
||||
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
|
||||
byte_ptr += 2;
|
||||
msw = 0x0000;
|
||||
break;
|
||||
case 0x3:
|
||||
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
|
||||
byte_ptr += 2;
|
||||
msw = buf[byte_ptr++];
|
||||
break;
|
||||
}
|
||||
|
||||
if (byte_sz & 0x3) {
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x204), msw);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x205), lsw);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0xc000);
|
||||
msb1 = msw >> 8;
|
||||
msb2 = msw & 0xFF;
|
||||
lsb1 = lsw >> 8;
|
||||
lsb2 = lsw & 0xFF;
|
||||
computed_crc = cyg_crc16_computed(&msb1, 0x1, computed_crc);
|
||||
computed_crc = cyg_crc16_computed(&msb2, 0x1, computed_crc);
|
||||
computed_crc = cyg_crc16_computed(&lsb1, 0x1, computed_crc);
|
||||
computed_crc = cyg_crc16_computed(&lsb2, 0x1, computed_crc);
|
||||
}
|
||||
printf("done.\n");
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc441), 0x2010);
|
||||
mailbox_crc = aq_phy_reg_read(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x201));
|
||||
if (mailbox_crc != computed_crc) {
|
||||
printf("phy fw image load CRC-16 (0x%X) does not match calculated CRC-16 (0x%X)\n", mailbox_crc, computed_crc);
|
||||
return 0;
|
||||
} else
|
||||
printf("phy fw image load good CRC-16 matches (0x%X)\n", mailbox_crc);
|
||||
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x0), 0x0);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc001), 0x41);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc001), 0x8041);
|
||||
mdelay(100);
|
||||
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc001), 0x40);
|
||||
mdelay(100);
|
||||
aquantia_phy_restart_autoneg(phy_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_load_fw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
unsigned int phy_addr = AQU_PHY_ADDR;
|
||||
|
||||
if (argc > 2)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
if (argc == 2)
|
||||
phy_addr = simple_strtoul(argv[1], NULL, 16);
|
||||
|
||||
miiphy_init();
|
||||
devsoc_eth_initialize();
|
||||
ipq_sw_mdio_init("IPQ MDIO0");
|
||||
ipq_board_fw_download(phy_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
aq_load_fw, 5, 1, do_load_fw,
|
||||
"LOAD aq-fw-binary",
|
||||
""
|
||||
);
|
||||
|
||||
U_BOOT_CMD(
|
||||
aq_phy_restart, 5, 1, do_aq_phy_restart,
|
||||
"Restart Aquantia phy",
|
||||
""
|
||||
);
|
||||
50
drivers/net/ipq_common/ipq_aquantia_phy.h
Normal file
50
drivers/net/ipq_common/ipq_aquantia_phy.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#define AQ_ETHPHYFW_IMAGE_SIZE 0x80000
|
||||
|
||||
#define AQUANTIA_MII_ADDR_C45 (1<<30)
|
||||
#define AQUANTIA_REG_ADDRESS(dev_ad, reg_num) (AQUANTIA_MII_ADDR_C45 |\
|
||||
((dev_ad & 0x1f) << 16) | (reg_num & 0xFFFF))
|
||||
|
||||
#define AQUANTIA_MMD_PHY_XS_REGISTERS 4
|
||||
#define AQUANTIA_PHY_XS_USX_TRANSMIT 0xc441
|
||||
#define AQUANTIA_PHY_USX_AUTONEG_ENABLE 0x8
|
||||
|
||||
#define AQUANTIA_MMD_AUTONEG 0x7
|
||||
#define AQUANTIA_AUTONEG_TRANSMIT_VENDOR_INTR_MASK 0xD401
|
||||
#define AQUANTIA_INTR_LINK_STATUS_CHANGE 0x0001
|
||||
|
||||
#define AQUANTIA_MMD_GLOABLE_REGISTERS 0x1E
|
||||
#define AQUANTIA_GLOBAL_INTR_STANDARD_MASK 0xff00
|
||||
#define AQUANTIA_ALL_VENDOR_ALARMS_INTERRUPT_MASK 0x0001
|
||||
|
||||
#define AQUANTIA_GLOBAL_INTR_VENDOR_MASK 0xff01
|
||||
#define AQUANTIA_AUTO_AND_ALARMS_INTR_MASK 0x1001
|
||||
|
||||
#define AQUANTIA_AUTONEG_STANDARD_CONTROL1 0
|
||||
#define AQUANTIA_CTRL_AUTONEGOTIATION_ENABLE 0x1000
|
||||
#define AQUANTIA_CTRL_RESTART_AUTONEGOTIATION 0x0200
|
||||
|
||||
#define AQ_PHY_AUTO_STATUS_REG 0x70001
|
||||
|
||||
#define AQ_PHY_LINK_STATUS_REG 0x7c800
|
||||
#define SPEED_5G 5
|
||||
#define SPEED_2_5G 4
|
||||
#define SPEED_10G 3
|
||||
#define SPEED_1000MBS 2
|
||||
#define SPEED_100MBS 1
|
||||
#define SPEED_10MBS 0
|
||||
|
|
@ -16,6 +16,9 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <net.h>
|
||||
#ifdef CONFIG_ATHRS17C_SWITCH
|
||||
#include "athrs17_phy.h"
|
||||
#endif
|
||||
|
||||
#define PHY_MAX 6
|
||||
#define IPQ9574_PHY_MAX 6
|
||||
|
|
@ -40,6 +43,7 @@
|
|||
#define GP_PU_RES(x) (x << 13)
|
||||
#define QCA8075_RST_VAL (GP_PULL_DOWN | GP_OE_EN | \
|
||||
GP_VM_EN | GP_PU_RES(2))
|
||||
#define QCA8337_PHY 0x004DD036
|
||||
#define QCA8075_PHY_V1_0_5P 0x004DD0B0
|
||||
#define QCA8075_PHY_V1_1_5P 0x004DD0B1
|
||||
#define QCA8075_PHY_V1_1_2P 0x004DD0B2
|
||||
|
|
@ -144,6 +148,7 @@ enum phy_mode {
|
|||
QCA8033_PHY_TYPE = 4,
|
||||
SFP_PHY_TYPE = 5,
|
||||
QCA8084_PHY_TYPE = 6,
|
||||
ATHRS17C_SWITCH_TYPE = 7,
|
||||
UNUSED_PHY_TYPE = 0xFF,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -46,5 +46,8 @@
|
|||
#define AQ_PHY_TYPE 0x3
|
||||
#define QCA8033_PHY_TYPE 0x4
|
||||
#define SFP_PHY_TYPE 0x5
|
||||
#define QCA8084_PHY_TYPE 0x6
|
||||
#define ATHRS17C_SWITCH_TYPE 0x7
|
||||
#define UNUSED_PHY_TYPE 0xFF
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue