ipq: move qca8075 mdio, phy driver into common directory

ipq40xx, ipq807x hardware share the qca8075 phy. So the qca8075 phy
mdio, driver has been moved to common directory for use by both the
hardware.

Change-Id: Id6e9342438ffbdf8599860df6fbb39bba30429b3
Signed-off-by: Jaiganesh Narayanan <njaigane@codeaurora.org>
This commit is contained in:
Jaiganesh Narayanan 2017-05-23 20:10:28 +05:30 committed by Gerrit - the friendly Code Review server
parent 8b395f5711
commit 428fc1d379
17 changed files with 1594 additions and 88 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2017, The Linux Foundation. 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
@ -305,4 +305,11 @@
};
};
edma_cfg {
unit = <0>;
/* Based on the enum for PSGMII phy interface from include/phy.h */
phy = <13>;
phy_name = "IPQ MDIO0";
};
};

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
* Copyright (c) 2015-2017, The Linux Foundation. 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
@ -326,65 +326,16 @@
#define PATTERN_PART_REG_OFFSET 0x40
#define NETDEV_TX_BUSY 1
#define PHY_MAX 5
#define GCC_ESS_BCR 0x01812008
#define GCC_MDIO_AHB_CBCR 0x1826000
#define MDIO_CTRL_0_REG 0x00090040
#define MDIO_CTRL_0_DIV(x) (x << 0)
#define MDIO_CTRL_0_MODE (1 << 8)
#define MDIO_CTRL_0_RES(x) (x << 9)
#define MDIO_CTRL_0_MDC_MODE (1 << 12)
#define MDIO_CTRL_0_GPHY(x) (x << 13)
#define MDIO_CTRL_0_RES1(x) (x << 17)
#define GP_PULL_DOWN 1
#define GP_OE_EN (1 << 9)
#define GP_VM_EN (1 << 11)
#define GP_PU_RES(x) (x << 13)
#define QCA8075_RST_VAL (GP_PULL_DOWN | GP_OE_EN | \
GP_VM_EN | GP_PU_RES(2))
/* Phy preferred medium type */
typedef enum {
QCA8075_PHY_MEDIUM_COPPER = 0,
QCA8075_PHY_MEDIUM_FIBER = 1, /**< Fiber */
} qca8075_phy_medium_t;
/* Phy pages */
typedef enum {
QCA8075_PHY_SGBX_PAGES = 0, /* sgbx pages */
QCA8075_PHY_COPPER_PAGES = 1 /* copper pages */
} qca8075_phy_reg_pages_t;
typedef enum {
FAL_HALF_DUPLEX = 0,
FAL_FULL_DUPLEX,
FAL_DUPLEX_BUTT = 0xffff
} fal_port_duplex_t;
typedef enum {
FAL_SPEED_10 = 10,
FAL_SPEED_100 = 100,
FAL_SPEED_1000 = 1000,
FAL_SPEED_10000 = 10000,
FAL_SPEED_BUTT = 0xffff,
} fal_port_speed_t;
typedef enum {
FAL_CABLE_STATUS_NORMAL = 0,
FAL_CABLE_STATUS_SHORT = 1,
FAL_CABLE_STATUS_OPENED = 2,
FAL_CABLE_STATUS_INVALID = 3,
FAL_CABLE_STATUS_BUTT = 0xffff,
} fal_cable_status_t;
struct phy_ops {
u8 (*phy_get_link_status) (u32 dev_id, u32 phy_id);
u32 (*phy_get_duplex) (u32 dev_id, u32 phy_id,
fal_port_duplex_t * duplex);
u32 (*phy_get_speed) (u32 dev_id, u32 phy_id,
fal_port_speed_t * speed);
};
#define GCC_ESS_BCR 0x01812008
#define GCC_MDIO_AHB_CBCR 0x1826000
int get_eth_mac_address(uchar *enetaddr, uint no_of_macs);
int ipq40xx_sw_mdio_init(const char *name);
extern int ipq_sw_mdio_init(const char *name);
extern int ipq40xx_ess_sw_init(ipq40xx_edma_board_cfg_t *cfg);
extern void ipq40xx_ess_enable_lookup(void);
extern void ipq40xx_ess_disable_lookup(void);
extern void psgmii_self_test(void);
extern void clear_self_test_config(void);
extern void qca8075_ess_reset(void);
#endif /* _IPQ40XX_EDMA_H */

View file

@ -1,3 +1,4 @@
ccflags-y += -I$(srctree)/board/qca/arm/common/ -I$(srctree)/drivers/net/ipq40xx/
ccflags-y += -I$(srctree)/drivers/net/ipq_common/
obj-y += ipq40xx.o

View file

@ -32,6 +32,7 @@
#include <phy.h>
#include "ipq40xx_edma_eth.h"
#include "qca_common.h"
#include "ipq_phy.h"
DECLARE_GLOBAL_DATA_PTR;
@ -67,11 +68,10 @@ extern int mmc_env_init(void);
extern void mmc_env_relocate_spec(void);
extern int ipq40xx_edma_init(ipq40xx_edma_board_cfg_t *edma_cfg);
extern int ipq40xx_qca8075_phy_init(struct ipq40xx_eth_dev *cfg);
extern int ipq_qca8075_phy_init(struct phy_ops **ops);
extern int ipq40xx_qca8033_phy_init(struct ipq40xx_eth_dev *cfg);
extern void ipq40xx_register_switch(
int (*sw_init)(struct ipq40xx_eth_dev *cfg));
int (*sw_init)(struct phy_ops **ops));
void qca_serial_init(struct ipq_serial_platdata *plat)
{
int node;
@ -148,13 +148,13 @@ int board_eth_init(bd_t *bis)
/* 8075 out of reset */
mdelay(100);
gpio_set_value(62, 1);
ipq40xx_register_switch(ipq40xx_qca8075_phy_init);
ipq40xx_register_switch(ipq_qca8075_phy_init);
break;
case MACH_TYPE_IPQ40XX_AP_DK01_1_C1:
/* 8075 out of reset */
mdelay(100);
gpio_set_value(59, 1);
ipq40xx_register_switch(ipq40xx_qca8075_phy_init);
ipq40xx_register_switch(ipq_qca8075_phy_init);
break;
case MACH_TYPE_IPQ40XX_AP_DK04_1_C4:
case MACH_TYPE_IPQ40XX_AP_DK04_1_C1:
@ -162,25 +162,25 @@ int board_eth_init(bd_t *bis)
/* 8075 out of reset */
mdelay(100);
gpio_set_value(47, 1);
ipq40xx_register_switch(ipq40xx_qca8075_phy_init);
ipq40xx_register_switch(ipq_qca8075_phy_init);
break;
case MACH_TYPE_IPQ40XX_AP_DK04_1_C2:
/* 8075 out of reset */
mdelay(100);
gpio_set_value(67, 1);
ipq40xx_register_switch(ipq40xx_qca8075_phy_init);
ipq40xx_register_switch(ipq_qca8075_phy_init);
break;
case MACH_TYPE_IPQ40XX_AP_DK06_1_C1:
/* 8075 out of reset */
mdelay(100);
gpio_set_value(19, 1);
ipq40xx_register_switch(ipq40xx_qca8075_phy_init);
ipq40xx_register_switch(ipq_qca8075_phy_init);
break;
case MACH_TYPE_IPQ40XX_AP_DK07_1_C1:
/* 8075 out of reset */
mdelay(100);
gpio_set_value(41, 1);
ipq40xx_register_switch(ipq40xx_qca8075_phy_init);
ipq40xx_register_switch(ipq_qca8075_phy_init);
break;
default:
break;

View file

@ -34,6 +34,7 @@ extern loff_t board_env_size;
extern int ipq_spi_init(u16);
extern int ipq807x_edma_init(void *cfg);
extern int ipq_qca8075_phy_init(struct phy_ops **ops);
const char *rsvd_node = "/reserved-memory";
const char *del_node[] = {"uboot",
@ -136,6 +137,11 @@ int board_eth_init(bd_t *bis)
if (ret != 0)
printf("%s: ipq807x_edma_init failed : %d\n", __func__, ret);
/* 8075 out of reset */
mdelay(100);
gpio_set_value(37, 1);
ipq807x_register_switch(ipq_qca8075_phy_init);
return ret;
}

View file

@ -5,7 +5,8 @@
# SPDX-License-Identifier: GPL-2.0+
#
ccflags-y += -I$(srctree)/board/qca/arm/ipq40xx -I$(srctree)/board/qca/arm/common
ccflags-y += -I$(srctree)/board/qca/arm/ipq40xx -I$(srctree)/board/qca/arm/common
ccflags-y += -I$(srctree)/drivers/net/ipq_common
obj-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o
obj-$(CONFIG_ALTERA_TSE) += altera_tse.o
@ -76,11 +77,11 @@ obj-$(CONFIG_FSL_MEMAC) += fm/memac_phy.o
obj-$(CONFIG_VSC9953) += vsc9953.o
obj-$(CONFIG_IPQ40XX_EDMA) += ipq40xx/ipq40xx_edma_eth.o
obj-$(CONFIG_IPQ40XX_ESS) += ipq40xx/ipq40xx_ess_sw.o
obj-$(CONFIG_QCA8075_PHY) += ipq40xx/ipq40xx_qca8075.o
obj-$(CONFIG_QCA8033_PHY) += ipq40xx/ipq40xx_qca8033.o
obj-$(CONFIG_IPQ40XX_MDIO) += ipq40xx/ipq40xx_mdio.o
obj-$(CONFIG_IPQ_SNPS_GMAC) += ipq806x/ipq_gmac_eth.o
obj-$(CONFIG_IPQ_SWITCH_ATHRS17) += ipq806x/athrs17_phy.o
obj-$(CONFIG_IPQ_SWITCH_QCA8511) += ipq806x/qca8511.o
obj-$(CONFIG_IPQ807X_EDMA) += ipq807x/ipq807x_edma.o
obj-$(CONFIG_IPQ807X_EDMA) += ipq807x/ipq807x_ppe.o
obj-$(CONFIG_IPQ_MDIO) += ipq_common/ipq_mdio.o
obj-$(CONFIG_QCA8075_PHY) += ipq_common/ipq_qca8075.o

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
* Copyright (c) 2015-2017, The Linux Foundation. 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
@ -22,6 +22,7 @@
#include <asm/arch-ipq40xx/ess/ipq40xx_edma.h>
#include "ipq40xx_edma_eth.h"
#include "ipq40xx.h"
#include "ipq_phy.h"
#include "qca_common.h"
#ifdef DEBUG
#define debugf(fmt, args...) printf(fmt, ##args);
@ -29,17 +30,11 @@
#define debugf(fmt, args...)
#endif
extern int ipq40xx_ess_sw_init(ipq40xx_edma_board_cfg_t *cfg);
extern void ipq40xx_ess_enable_lookup(void);
extern void ipq40xx_ess_disable_lookup(void);
extern void psgmii_self_test(void);
extern void clear_self_test_config(void);
uchar ipq40xx_def_enetaddr[6] = {0x00, 0x03, 0x7F, 0xBA, 0xDB, 0xAD};
static struct ipq40xx_eth_dev *ipq40xx_edma_dev[IPQ40XX_EDMA_DEV];
static int (*ipq40xx_switch_init)(struct ipq40xx_eth_dev *cfg);
extern void qca8075_ess_reset(void);
static int (*ipq40xx_switch_init)(struct phy_ops **ops);
uchar ipq40xx_def_enetaddr[6] = {0x00, 0x03, 0x7F, 0xBA, 0xDB, 0xAD};
void ipq40xx_register_switch(int(*sw_init)(struct ipq40xx_eth_dev *cfg))
void ipq40xx_register_switch(int(*sw_init)(struct phy_ops **ops))
{
ipq40xx_switch_init = sw_init;
}
@ -930,7 +925,7 @@ int ipq40xx_edma_init(ipq40xx_edma_board_cfg_t *edma_cfg)
c_info[i]->q_cinfo[i].rx_status = 0;
c_info[i]->q_cinfo[i].c_info = c_info[i];
ret = ipq40xx_sw_mdio_init(edma_cfg->phy_name);
ret = ipq_sw_mdio_init(edma_cfg->phy_name);
if (ret)
goto failed;
@ -955,7 +950,7 @@ int ipq40xx_edma_init(ipq40xx_edma_board_cfg_t *edma_cfg)
eth_register(dev[i]);
if (!sw_init_done) {
if (ipq40xx_switch_init(ipq40xx_edma_dev[i]) == 0) {
if (ipq40xx_switch_init(&ipq40xx_edma_dev[i]->ops) == 0) {
sw_init_done = 1;
} else {
printf ("SW inits failed\n");

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
* Copyright (c) 2015-2017, The Linux Foundation. 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
@ -18,6 +18,7 @@
#include <malloc.h>
#include "ipq40xx_edma_eth.h"
#include "ipq40xx_qca8033.h"
#include "ipq_phy.h"
extern int ipq40xx_mdio_write(int mii_id,
int regnum, u16 value);

View file

@ -24,6 +24,7 @@
#include <miiphy.h>
#include <asm/arch-ipq807x/edma_regs.h>
#include "ipq807x_edma.h"
#include "ipq_phy.h"
#ifdef DEBUG
#define pr_debug(fmt, args...) printf(fmt, ##args);
@ -40,6 +41,17 @@ static struct ipq807x_eth_dev *ipq807x_edma_dev[IPQ807X_EDMA_DEV];
uchar ipq807x_def_enetaddr[6] = {0x00, 0x03, 0x7F, 0xBA, 0xDB, 0xAD};
static int (*ipq807x_switch_init)(struct phy_ops **ops);
extern void qca8075_ess_reset(void);
extern void psgmii_self_test(void);
extern void clear_self_test_config(void);
extern int ipq_sw_mdio_init(const char *);
void ipq807x_register_switch(int(*sw_init)(struct phy_ops **ops))
{
ipq807x_switch_init = sw_init;
}
/*
* EDMA hardware instance
*/
@ -1455,6 +1467,7 @@ int ipq807x_edma_init(void *edma_board_cfg)
int i;
int ret = -1;
ipq807x_edma_board_cfg_t ledma_cfg, *edma_cfg;
static int sw_init_done = 0;
memset(c_info, 0, (sizeof(c_info) * IPQ807X_EDMA_DEV));
@ -1531,6 +1544,45 @@ int ipq807x_edma_init(void *edma_board_cfg)
ipq807x_edma_dev[i]->c_info = c_info[i];
ipq807x_edma_hw_addr = IPQ807X_EDMA_CFG_BASE;
ret = ipq_sw_mdio_init(edma_cfg->phy_name);
if (ret)
goto init_failed;
switch (edma_cfg->phy) {
case PHY_INTERFACE_MODE_PSGMII:
writel(PSGMIIPHY_PLL_VCO_VAL,
PSGMIIPHY_PLL_VCO_RELATED_CTRL);
writel(PSGMIIPHY_VCO_VAL,
PSGMIIPHY_VCO_CALIBRATION_CTRL);
/* wait for 10ms */
mdelay(10);
writel(PSGMIIPHY_VCO_RST_VAL, PSGMIIPHY_VCO_CALIBRATION_CTRL);
break;
case PHY_INTERFACE_MODE_RGMII:
writel(0x1, RGMII_TCSR_ESS_CFG);
writel(0x400, ESS_RGMII_CTRL);
break;
default:
printf("unknown MII interface\n");
goto init_failed;
}
if (!sw_init_done) {
if (ipq807x_switch_init(&ipq807x_edma_dev[i]->ops) == 0) {
sw_init_done = 1;
} else {
printf ("SW inits failed\n");
goto init_failed;
}
}
if(edma_cfg->phy == PHY_INTERFACE_MODE_PSGMII) {
qca8075_ess_reset();
mdelay(100);
psgmii_self_test();
mdelay(300);
clear_self_test_config();
}
ret = ipq807x_edma_hw_init(hw[i]);
if (ret)

View file

@ -81,6 +81,15 @@
#define NETDEV_TX_BUSY 1
#define PSGMIIPHY_PLL_VCO_RELATED_CTRL 0x0009878c
#define PSGMIIPHY_PLL_VCO_VAL 0x2803
#define PSGMIIPHY_VCO_CALIBRATION_CTRL 0x0009809c
#define PSGMIIPHY_VCO_VAL 0x4ADA
#define PSGMIIPHY_VCO_RST_VAL 0xADA
#define RGMII_TCSR_ESS_CFG 0x01953000
#define ESS_RGMII_CTRL 0x0C000004
/*
* Tx descriptor
*/

View file

@ -0,0 +1,121 @@
/*
* Copyright (c) 2015-2017, The Linux Foundation. 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 <miiphy.h>
#include <phy.h>
#include <asm/io.h>
#include <errno.h>
#include "ipq_mdio.h"
struct ipq_mdio_data {
struct mii_bus *bus;
int phy_irq[PHY_MAX_ADDR];
};
static int ipq_mdio_wait_busy(void)
{
int i;
u32 busy;
for (i = 0; i < IPQ_MDIO_RETRY; i++) {
udelay(IPQ_MDIO_DELAY);
busy = readl(IPQ_MDIO_BASE +
MDIO_CTRL_4_REG) &
MDIO_CTRL_4_ACCESS_BUSY;
if (!busy)
return 0;
udelay(IPQ_MDIO_DELAY);
}
printf("%s: MDIO operation timed out\n",
__func__);
return -ETIMEDOUT;
}
int ipq_mdio_write(int mii_id, int regnum, u16 value)
{
if (ipq_mdio_wait_busy())
return -ETIMEDOUT;
/* Issue the phy addreass and reg */
writel((mii_id << 8 | regnum),
IPQ_MDIO_BASE + MDIO_CTRL_1_REG);
/* Issue a write data */
writel(value, IPQ_MDIO_BASE + MDIO_CTRL_2_REG);
/* Issue write command */
writel((MDIO_CTRL_4_ACCESS_START |
MDIO_CTRL_4_ACCESS_CODE_WRITE),
(IPQ_MDIO_BASE + MDIO_CTRL_4_REG));
/* Wait for write complete */
if (ipq_mdio_wait_busy())
return -ETIMEDOUT;
return 0;
}
int ipq_mdio_read(int mii_id, int regnum, ushort *data)
{
u32 val;
if (ipq_mdio_wait_busy())
return -ETIMEDOUT;
/* Issue the phy address and reg */
writel((mii_id << 8) | regnum,
IPQ_MDIO_BASE + MDIO_CTRL_1_REG);
/* issue read command */
writel((MDIO_CTRL_4_ACCESS_START |
MDIO_CTRL_4_ACCESS_CODE_READ),
(IPQ_MDIO_BASE + MDIO_CTRL_4_REG));
if (ipq_mdio_wait_busy())
return -ETIMEDOUT;
/* Read data */
val = readl(IPQ_MDIO_BASE + MDIO_CTRL_3_REG);
if (data != NULL)
*data = val;
return val;
}
int ipq_phy_write(struct mii_dev *bus,
int addr, int dev_addr,
int regnum, ushort value)
{
return ipq_mdio_write(addr, regnum, value);
}
int ipq_phy_read(struct mii_dev *bus,
int addr, int dev_addr, int regnum)
{
return ipq_mdio_read(addr, regnum, NULL);
}
int ipq_sw_mdio_init(const char *name)
{
struct mii_dev *bus = mdio_alloc();
if(!bus) {
printf("Failed to allocate IPQ MDIO bus\n");
return -1;
}
bus->read = ipq_phy_read;
bus->write = ipq_phy_write;
bus->reset = NULL;
sprintf(bus->name, name);
return mdio_register(bus);
}

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2015-2017, The Linux Foundation. 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 _IPQ_MDIO_H
#define _IPQ_MDIO_H
#define IPQ_MDIO_BASE 0x90000
#define MDIO_CTRL_0_REG 0x40
#define MDIO_CTRL_1_REG 0x44
#define MDIO_CTRL_2_REG 0x48
#define MDIO_CTRL_3_REG 0x4c
#define MDIO_CTRL_4_REG 0x50
#define MDIO_CTRL_4_ACCESS_BUSY (1 << 16)
#define MDIO_CTRL_4_ACCESS_START (1 << 8)
#define MDIO_CTRL_4_ACCESS_CODE_READ 0
#define MDIO_CTRL_4_ACCESS_CODE_WRITE 1
#define IPQ_MDIO_RETRY 1000
#define IPQ_MDIO_DELAY 5
#endif /* End _IPQ_MDIO_H */

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2015-2017, The Linux Foundation. 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 _IPQ_EDMA_H
#define _IPQ_EDMA_H
#include <common.h>
#include <net.h>
#define PHY_MAX 5
#define MDIO_CTRL_0_REG 0x00090040
#define MDIO_CTRL_0_DIV(x) (x << 0)
#define MDIO_CTRL_0_MODE (1 << 8)
#define MDIO_CTRL_0_RES(x) (x << 9)
#define MDIO_CTRL_0_MDC_MODE (1 << 12)
#define MDIO_CTRL_0_GPHY(x) (x << 13)
#define MDIO_CTRL_0_RES1(x) (x << 17)
#define GP_PULL_DOWN 1
#define GP_OE_EN (1 << 9)
#define GP_VM_EN (1 << 11)
#define GP_PU_RES(x) (x << 13)
#define QCA8075_RST_VAL (GP_PULL_DOWN | GP_OE_EN | \
GP_VM_EN | GP_PU_RES(2))
/* Phy preferred medium type */
typedef enum {
QCA8075_PHY_MEDIUM_COPPER = 0,
QCA8075_PHY_MEDIUM_FIBER = 1, /**< Fiber */
} qca8075_phy_medium_t;
/* Phy pages */
typedef enum {
QCA8075_PHY_SGBX_PAGES = 0, /* sgbx pages */
QCA8075_PHY_COPPER_PAGES = 1 /* copper pages */
} qca8075_phy_reg_pages_t;
typedef enum {
FAL_HALF_DUPLEX = 0,
FAL_FULL_DUPLEX,
FAL_DUPLEX_BUTT = 0xffff
} fal_port_duplex_t;
typedef enum {
FAL_SPEED_10 = 10,
FAL_SPEED_100 = 100,
FAL_SPEED_1000 = 1000,
FAL_SPEED_10000 = 10000,
FAL_SPEED_BUTT = 0xffff,
} fal_port_speed_t;
typedef enum {
FAL_CABLE_STATUS_NORMAL = 0,
FAL_CABLE_STATUS_SHORT = 1,
FAL_CABLE_STATUS_OPENED = 2,
FAL_CABLE_STATUS_INVALID = 3,
FAL_CABLE_STATUS_BUTT = 0xffff,
} fal_cable_status_t;
struct phy_ops {
u8 (*phy_get_link_status) (u32 dev_id, u32 phy_id);
u32 (*phy_get_duplex) (u32 dev_id, u32 phy_id,
fal_port_duplex_t * duplex);
u32 (*phy_get_speed) (u32 dev_id, u32 phy_id,
fal_port_speed_t * speed);
};
#endif /* _IPQ_EDMA_H */

View file

@ -0,0 +1,774 @@
/*
* Copyright (c) 2015-2017, The Linux Foundation. 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 <asm-generic/errno.h>
#include <asm/io.h>
#include <malloc.h>
#include <net.h>
#include <phy.h>
#include <miiphy.h>
#include "ipq_phy.h"
#include "ipq_qca8075.h"
extern int ipq_mdio_write(int mii_id,
int regnum, u16 value);
extern int ipq_mdio_read(int mii_id,
int regnum, ushort *data);
static u32 qca8075_id;
static u16 qca8075_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;
}
static u16 qca8075_phy_reg_read(u32 dev_id, u32 phy_id, u32 reg_id)
{
return ipq_mdio_read(phy_id, reg_id, NULL);
}
/*
* phy4 prfer medium
* get phy4 prefer medum, fiber or copper;
*/
static qca8075_phy_medium_t __phy_prefer_medium_get(u32 dev_id,
u32 phy_id)
{
u16 phy_medium;
phy_medium =
qca8075_phy_reg_read(dev_id, phy_id,
QCA8075_PHY_CHIP_CONFIG);
return ((phy_medium & QCA8075_PHY4_PREFER_FIBER) ?
QCA8075_PHY_MEDIUM_FIBER : QCA8075_PHY_MEDIUM_COPPER);
}
/*
* phy4 activer medium
* get phy4 current active medium, fiber or copper;
*/
static qca8075_phy_medium_t __phy_active_medium_get(u32 dev_id,
u32 phy_id)
{
u16 phy_data = 0;
u32 phy_mode;
phy_mode = qca8075_phy_reg_read(dev_id, phy_id,
QCA8075_PHY_CHIP_CONFIG);
phy_mode &= 0x000f;
if (phy_mode == QCA8075_PHY_PSGMII_AMDET) {
phy_data = qca8075_phy_reg_read(dev_id,
phy_id, QCA8075_PHY_SGMII_STATUS);
if ((phy_data & QCA8075_PHY4_AUTO_COPPER_SELECT)) {
return QCA8075_PHY_MEDIUM_COPPER;
} else if ((phy_data & QCA8075_PHY4_AUTO_BX1000_SELECT)) {
/* PHY_MEDIUM_FIBER_BX1000 */
return QCA8075_PHY_MEDIUM_FIBER;
} else if ((phy_data & QCA8075_PHY4_AUTO_FX100_SELECT)) {
/* PHY_MEDIUM_FIBER_FX100 */
return QCA8075_PHY_MEDIUM_FIBER;
}
/* link down */
return __phy_prefer_medium_get(dev_id, phy_id);
} else if ((phy_mode == QCA8075_PHY_PSGMII_BASET) ||
(phy_mode == QCA8075_PHY_SGMII_BASET)) {
return QCA8075_PHY_MEDIUM_COPPER;
} else if ((phy_mode == QCA8075_PHY_PSGMII_BX1000) ||
(phy_mode == QCA8075_PHY_PSGMII_FX100)) {
return QCA8075_PHY_MEDIUM_FIBER;
} else {
return QCA8075_PHY_MEDIUM_COPPER;
}
}
/*
* phy4 copper page or fiber page select
* set phy4 copper or fiber page
*/
static u8 __phy_reg_pages_sel(u32 dev_id, u32 phy_id,
qca8075_phy_reg_pages_t phy_reg_pages)
{
u16 reg_pages;
reg_pages = qca8075_phy_reg_read(dev_id,
phy_id, QCA8075_PHY_CHIP_CONFIG);
if (phy_reg_pages == QCA8075_PHY_COPPER_PAGES) {
reg_pages |= 0x8000;
} else if (phy_reg_pages == QCA8075_PHY_SGBX_PAGES) {
reg_pages &= ~0x8000;
} else
return -EINVAL;
qca8075_phy_reg_write(dev_id, phy_id,
QCA8075_PHY_CHIP_CONFIG, reg_pages);
return 0;
}
/*
* phy4 reg pages selection by active medium
* phy4 reg pages selection
*/
static u32 __phy_reg_pages_sel_by_active_medium(u32 dev_id,
u32 phy_id)
{
qca8075_phy_medium_t phy_medium;
qca8075_phy_reg_pages_t reg_pages;
phy_medium = __phy_active_medium_get(dev_id, phy_id);
if (phy_medium == QCA8075_PHY_MEDIUM_FIBER) {
reg_pages = QCA8075_PHY_SGBX_PAGES;
} else if (phy_medium == QCA8075_PHY_MEDIUM_COPPER) {
reg_pages = QCA8075_PHY_COPPER_PAGES;
} else {
return -1;
}
return __phy_reg_pages_sel(dev_id, phy_id, reg_pages);
}
static u8 qca8075_phy_get_link_status(u32 dev_id, u32 phy_id)
{
u16 phy_data;
if (phy_id == COMBO_PHY_ID)
__phy_reg_pages_sel_by_active_medium(dev_id, phy_id);
phy_data = qca8075_phy_reg_read(dev_id,
phy_id, QCA8075_PHY_SPEC_STATUS);
if (phy_data & QCA8075_STATUS_LINK_PASS)
return 0;
return 1;
}
static u32 qca8075_phy_get_duplex(u32 dev_id, u32 phy_id,
fal_port_duplex_t * duplex)
{
u16 phy_data;
if (phy_id == COMBO_PHY_ID) {
__phy_reg_pages_sel_by_active_medium(dev_id, phy_id);
}
phy_data = qca8075_phy_reg_read(dev_id, phy_id,
QCA8075_PHY_SPEC_STATUS);
/*
* Read duplex
*/
if (phy_data & QCA8075_STATUS_FULL_DUPLEX)
*duplex = FAL_FULL_DUPLEX;
else
*duplex = FAL_HALF_DUPLEX;
return 0;
}
static u32 qca8075_phy_get_speed(u32 dev_id, u32 phy_id,
fal_port_speed_t * speed)
{
u16 phy_data;
if (phy_id == COMBO_PHY_ID) {
__phy_reg_pages_sel_by_active_medium(dev_id, phy_id);
}
phy_data = qca8075_phy_reg_read(dev_id,
phy_id, QCA8075_PHY_SPEC_STATUS);
switch (phy_data & QCA8075_STATUS_SPEED_MASK) {
case QCA8075_STATUS_SPEED_1000MBS:
*speed = FAL_SPEED_1000;
break;
case QCA8075_STATUS_SPEED_100MBS:
*speed = FAL_SPEED_100;
break;
case QCA8075_STATUS_SPEED_10MBS:
*speed = FAL_SPEED_10;
break;
default:
return -EINVAL;
}
return 0;
}
static u32 qca8075_phy_mmd_write(u32 dev_id, u32 phy_id,
u16 mmd_num, u16 reg_id, u16 reg_val)
{
qca8075_phy_reg_write(dev_id, phy_id,
QCA8075_MMD_CTRL_REG, mmd_num);
qca8075_phy_reg_write(dev_id, phy_id,
QCA8075_MMD_DATA_REG, reg_id);
qca8075_phy_reg_write(dev_id, phy_id,
QCA8075_MMD_CTRL_REG,
0x4000 | mmd_num);
qca8075_phy_reg_write(dev_id, phy_id,
QCA8075_MMD_DATA_REG, reg_val);
return 0;
}
static u16 qca8075_phy_mmd_read(u32 dev_id, u32 phy_id,
u16 mmd_num, u16 reg_id)
{
qca8075_phy_reg_write(dev_id, phy_id,
QCA8075_MMD_CTRL_REG, mmd_num);
qca8075_phy_reg_write(dev_id, phy_id,
QCA8075_MMD_DATA_REG, reg_id);
qca8075_phy_reg_write(dev_id, phy_id,
QCA8075_MMD_CTRL_REG,
0x4000 | mmd_num);
return qca8075_phy_reg_read(dev_id, phy_id,
QCA8075_MMD_DATA_REG);
}
/*
* get phy4 medium is 100fx
*/
static u8 __medium_is_fiber_100fx(u32 dev_id, u32 phy_id)
{
u16 phy_data;
phy_data = qca8075_phy_reg_read(dev_id, phy_id,
QCA8075_PHY_SGMII_STATUS);
if (phy_data & QCA8075_PHY4_AUTO_FX100_SELECT) {
return 1;
}
/* Link down */
if ((!(phy_data & QCA8075_PHY4_AUTO_COPPER_SELECT)) &&
(!(phy_data & QCA8075_PHY4_AUTO_BX1000_SELECT)) &&
(!(phy_data & QCA8075_PHY4_AUTO_SGMII_SELECT))) {
phy_data = qca8075_phy_reg_read(dev_id, phy_id,
QCA8075_PHY_CHIP_CONFIG);
if ((phy_data & QCA8075_PHY4_PREFER_FIBER)
&& (!(phy_data & QCA8075_PHY4_FIBER_MODE_1000BX))) {
return 1;
}
}
return 0;
}
/*
* qca8075_phy_set_hibernate - set hibernate status
* set hibernate status
*/
static u32 qca8075_phy_set_hibernate(u32 dev_id, u32 phy_id, u8 enable)
{
u16 phy_data;
qca8075_phy_reg_write(dev_id, phy_id, QCA8075_DEBUG_PORT_ADDRESS,
QCA8075_DEBUG_PHY_HIBERNATION_CTRL);
phy_data = qca8075_phy_reg_read(dev_id, phy_id,
QCA8075_DEBUG_PORT_DATA);
if (enable) {
phy_data |= 0x8000;
} else {
phy_data &= ~0x8000;
}
qca8075_phy_reg_write(dev_id, phy_id, QCA8075_DEBUG_PORT_DATA, phy_data);
return 0;
}
/*
* qca8075_restart_autoneg - restart the phy autoneg
*/
static u32 qca8075_phy_restart_autoneg(u32 dev_id, u32 phy_id)
{
u16 phy_data;
if (phy_id == COMBO_PHY_ID) {
if (__medium_is_fiber_100fx(dev_id, phy_id))
return -1;
__phy_reg_pages_sel_by_active_medium(dev_id, phy_id);
}
phy_data = qca8075_phy_reg_read(dev_id, phy_id, QCA8075_PHY_CONTROL);
phy_data |= QCA8075_CTRL_AUTONEGOTIATION_ENABLE;
qca8075_phy_reg_write(dev_id, phy_id, QCA8075_PHY_CONTROL,
phy_data | QCA8075_CTRL_RESTART_AUTONEGOTIATION);
return 0;
}
/*
* qca8075_phy_get_8023az status
* get 8023az status
*/
static u32 qca8075_phy_get_8023az(u32 dev_id, u32 phy_id, u8 *enable)
{
u16 phy_data;
if (phy_id == COMBO_PHY_ID) {
if (QCA8075_PHY_MEDIUM_COPPER !=
__phy_active_medium_get(dev_id, phy_id))
return -1;
}
*enable = 0;
phy_data = qca8075_phy_mmd_read(dev_id, phy_id, QCA8075_PHY_MMD7_NUM,
QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL);
if ((phy_data & 0x0004) && (phy_data & 0x0002))
*enable = 1;
return 0;
}
/*
* qca8075_phy_set_powersave - set power saving status
*/
static u32 qca8075_phy_set_powersave(u32 dev_id, u32 phy_id, u8 enable)
{
u16 phy_data;
u8 status = 0;
if (phy_id == COMBO_PHY_ID) {
if (QCA8075_PHY_MEDIUM_COPPER !=
__phy_active_medium_get(dev_id, phy_id))
return -1;
}
if (enable) {
qca8075_phy_get_8023az(dev_id, phy_id, &status);
if (!status) {
phy_data = qca8075_phy_mmd_read(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL);
phy_data &= ~(1 << 14);
qca8075_phy_mmd_write(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL,
phy_data);
}
phy_data = qca8075_phy_mmd_read(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_CLD_CTRL5);
phy_data &= ~(1 << 14);
qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_CLD_CTRL5,
phy_data);
phy_data = qca8075_phy_mmd_read(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_CLD_CTRL3);
phy_data &= ~(1 << 15);
qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_CLD_CTRL3, phy_data);
} else {
phy_data = qca8075_phy_mmd_read(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL);
phy_data |= (1 << 14);
qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL,
phy_data);
phy_data = qca8075_phy_mmd_read(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_CLD_CTRL5);
phy_data |= (1 << 14);
qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_CLD_CTRL5, phy_data);
phy_data = qca8075_phy_mmd_read(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_CLD_CTRL3);
phy_data |= (1 << 15);
qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_CLD_CTRL3, phy_data);
}
qca8075_phy_reg_write(dev_id, phy_id, QCA8075_PHY_CONTROL, 0x9040);
return 0;
}
/*
* qca8075_phy_set_802.3az
*/
static u32 qca8075_phy_set_8023az(u32 dev_id, u32 phy_id, u8 enable)
{
u16 phy_data;
if (phy_id == COMBO_PHY_ID) {
if (QCA8075_PHY_MEDIUM_COPPER !=
__phy_active_medium_get(dev_id, phy_id))
return -1;
}
phy_data = qca8075_phy_mmd_read(dev_id, phy_id, QCA8075_PHY_MMD7_NUM,
QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL);
if (enable) {
phy_data |= 0x0006;
qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD7_NUM,
QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL, phy_data);
if (qca8075_id == QCA8075_PHY_V1_0_5P) {
/*
* Workaround to avoid packet loss and < 10m cable
* 1000M link not stable under az enable
*/
qca8075_phy_mmd_write(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL,
AZ_TIMER_CTRL_ADJUST_VALUE);
qca8075_phy_mmd_write(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_8023AZ_CLD_CTRL,
AZ_CLD_CTRL_ADJUST_VALUE);
}
} else {
phy_data &= ~0x0006;
qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD7_NUM,
QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL, phy_data);
if (qca8075_id == QCA8075_PHY_V1_0_5P) {
qca8075_phy_mmd_write(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL,
AZ_TIMER_CTRL_DEFAULT_VALUE);
}
}
qca8075_phy_restart_autoneg(dev_id, phy_id);
return 0;
}
void ess_reset(void)
{
writel(0x1, 0x1812008);
mdelay(10);
writel(0x0, 0x1812008);
mdelay(100);
}
void qca8075_ess_reset(void)
{
int i;
u32 status;
/*
* Fix phy psgmii RX 20bit
*/
qca8075_phy_reg_write(0, 5, 0x0, 0x005b);
/*
* Reset phy psgmii
*/
qca8075_phy_reg_write(0, 5, 0x0, 0x001b);
/*
* Release reset phy psgmii
*/
qca8075_phy_reg_write(0, 5, 0x0, 0x005b);
for (i = 0; i < QCA8075_MAX_TRIES; i++) {
status = qca8075_phy_mmd_read(0, 5, 1, 0x28);
if(status & 0x1)
break;
mdelay(10);
}
if (i >= QCA8075_MAX_TRIES)
printf("qca8075 PSGMII PLL_VCO_CALIB Not Ready\n");
mdelay(50);
/*
* Check qca8075 psgmii calibration done end.
* Freeze phy psgmii RX CDR
*/
qca8075_phy_reg_write(0, 5, 0x1a, 0x2230);
ess_reset();
/*
* Check ipq psgmii calibration done start
*/
for (i = 0; i < QCA8075_MAX_TRIES; i++) {
status = readl(0x000980A0);
if (status & 0x1)
break;
mdelay(10);
}
if (i >= QCA8075_MAX_TRIES)
printf("PSGMII PLL_VCO_CALIB Not Ready\n");
mdelay(50);
/*
* Check ipq psgmii calibration done end.
* Relesae phy psgmii RX CDR
*/
qca8075_phy_reg_write(0, 5, 0x1a, 0x3230);
/*
* Release phy psgmii RX 20bit
*/
qca8075_phy_reg_write(0, 5, 0x0, 0x005f);
mdelay(200);
}
void psgmii_self_test(void)
{
int i, phy, j;
u32 value;
u32 phy_t_status;
u16 status;
u32 tx_counter_ok, tx_counter_error;
u32 rx_counter_ok, rx_counter_error;
u32 tx_counter_ok_high16;
u32 rx_counter_ok_high16;
u32 tx_ok, rx_ok;
/*
* Switch to access MII reg for copper
*/
qca8075_phy_reg_write(0, 4, 0x1f, 0x8500);
for (phy = 0; phy < 5; phy++) {
/*
* Enable phy mdio broadcast write
*/
qca8075_phy_mmd_write(0, phy, 7, 0x8028, 0x801f);
}
/*
* Force no link by power down
*/
qca8075_phy_reg_write(0, 0x1f, 0x0, 0x1840);
/*
* Packet number
*/
qca8075_phy_mmd_write(0, 0x1f, 7, 0x8021, 0x3000);
qca8075_phy_mmd_write(0, 0x1f, 7, 0x8062, 0x05e0);
/*
* Fix mdi status
*/
qca8075_phy_reg_write(0, 0x1f, 0x10, 0x6800);
for (i = 0; i < 100; i++) {
phy_t_status = 0;
for (phy = 0; phy < 5; phy++) {
value = readl(0xc00066c + (phy * 0xc));
/*
* Enable mac loop back
*/
writel((value | (1 << 21)), (0xc00066c + (phy * 0xc)));
}
/*
* Phy single test
*/
for (phy = 0; phy < 5; phy++) {
/*
* Enable loopback
*/
qca8075_phy_reg_write(0, phy, 0x0, 0x9000);
qca8075_phy_reg_write(0, phy, 0x0, 0x4140);
/*
* Check link
*/
j = 0;
while (j < 100) {
status = qca8075_phy_reg_read(0, phy, 0x11);
if (status & (1 << 10))
break;
mdelay(10);
j++;
}
/*
* Enable check
*/
qca8075_phy_mmd_write(0, phy, 7, 0x8029, 0x0000);
qca8075_phy_mmd_write(0, phy, 7, 0x8029, 0x0003);
/*
* Start traffic
*/
qca8075_phy_mmd_write(0, phy, 7, 0x8020, 0xa000);
mdelay(200);
/*
* check counter
*/
tx_counter_ok = qca8075_phy_mmd_read(0, phy, 7, 0x802e);
tx_counter_ok_high16 = qca8075_phy_mmd_read(0, phy, 7, 0x802d);
tx_counter_error = qca8075_phy_mmd_read(0, phy, 7, 0x802f);
rx_counter_ok = qca8075_phy_mmd_read(0, phy, 7, 0x802b);
rx_counter_ok_high16 = qca8075_phy_mmd_read(0, phy, 7, 0x802a);
rx_counter_error = qca8075_phy_mmd_read(0, phy, 7, 0x802c);
tx_ok = tx_counter_ok + (tx_counter_ok_high16 << 16);
rx_ok = rx_counter_ok + (rx_counter_ok_high16 << 16);
/*
* Success
*/
if((tx_ok == 0x3000) && (tx_counter_error == 0)) {
phy_t_status &= (~(1 << phy));
} else {
phy_t_status |= (1 << phy);
}
/*
* Power down
*/
qca8075_phy_reg_write(0, phy, 0x0, 0x1840);
}
/*
* Reset 5-phy
*/
qca8075_phy_reg_write(0, 0x1f, 0x0, 0x9000);
/*
* Enable 5-phy loopback
*/
qca8075_phy_reg_write(0, 0x1f, 0x0, 0x4140);
/*
* check link
*/
j = 0;
while (j < 100) {
for (phy = 0; phy < 5; phy++) {
status = qca8075_phy_reg_read(0, phy, 0x11);
if (!(status & (1 << 10)))
break;
}
if (phy >= 5)
break;
mdelay(10);
j++;
}
/*
* Enable check
*/
qca8075_phy_mmd_write(0, 0x1f, 7, 0x8029, 0x0000);
qca8075_phy_mmd_write(0, 0x1f, 7, 0x8029, 0x0003);
/*
* Start traffic
*/
qca8075_phy_mmd_write(0, 0x1f, 7, 0x8020, 0xa000);
mdelay(200);
for (phy = 0; phy < 5; phy++) {
/*
* Check counter
*/
tx_counter_ok = qca8075_phy_mmd_read(0, phy, 7, 0x802e);
tx_counter_ok_high16 = qca8075_phy_mmd_read(0, phy, 7, 0x802d);
tx_counter_error = qca8075_phy_mmd_read(0, phy, 7, 0x802f);
rx_counter_ok = qca8075_phy_mmd_read(0, phy, 7, 0x802b);
rx_counter_ok_high16 = qca8075_phy_mmd_read(0, phy, 7, 0x802a);
rx_counter_error = qca8075_phy_mmd_read(0, phy, 7, 0x802c);
tx_ok = tx_counter_ok + (tx_counter_ok_high16 << 16);
rx_ok = rx_counter_ok + (rx_counter_ok_high16 << 16);
debug("rx_ok: %d, tx_ok: %d", rx_ok, tx_ok);
debug("rx_counter_error: %d, tx_counter_error: %d",
rx_counter_error, tx_counter_error);
/*
* Success
*/
if ((tx_ok == 0x3000) && (tx_counter_error == 0)) {
phy_t_status &= (~(1 << (phy + 8)));
} else {
phy_t_status |= (1 << (phy + 8));
}
}
if (phy_t_status) {
qca8075_ess_reset();
} else {
break;
}
}
/*
* Configuration recover
*/
/*
* Packet number
*/
qca8075_phy_mmd_write(0, 0x1f, 7, 0x8021, 0x0);
/*
* Disable check
*/
qca8075_phy_mmd_write(0, 0x1f, 7, 0x8029, 0x0);
/*
* Disable traffic
*/
qca8075_phy_mmd_write(0, 0x1f, 7, 0x8020, 0x0);
}
void clear_self_test_config(void)
{
int phy = 0;
u32 value = 0;
/*
* Disable phy internal loopback
*/
qca8075_phy_reg_write(0, 0x1f, 0x10, 0x6860);
qca8075_phy_reg_write(0, 0x1f, 0x0, 0x9040);
for (phy = 0; phy < 5; phy++) {
value = readl(0xc00066c + (phy * 0xc));
/*
* Disable mac loop back
*/
writel((value&(~(1 << 21))), (0xc00066c + (phy * 0xc)));
/*
* Disable phy mdio broadcast writei
*/
qca8075_phy_mmd_write(0, phy, 7, 0x8028, 0x001f);
}
}
int ipq_qca8075_phy_init(struct phy_ops **ops)
{
u16 phy_data;
u32 phy_id = 0;
struct phy_ops *qca8075_ops;
qca8075_ops = (struct phy_ops *)malloc(sizeof(struct phy_ops));
if (!qca8075_ops)
return -ENOMEM;
qca8075_ops->phy_get_link_status = qca8075_phy_get_link_status;
qca8075_ops->phy_get_speed = qca8075_phy_get_speed;
qca8075_ops->phy_get_duplex = qca8075_phy_get_duplex;
*ops = qca8075_ops;
qca8075_id = phy_data = qca8075_phy_reg_read(0x0, 0x0, QCA8075_PHY_ID1);
printf ("PHY ID1: 0x%x\n", phy_data);
phy_data = qca8075_phy_reg_read(0x0, 0x0, QCA8075_PHY_ID2);
printf ("PHY ID2: 0x%x\n", phy_data);
qca8075_id = (qca8075_id << 16) | phy_data;
if (qca8075_id == QCA8075_PHY_V1_0_5P) {
phy_data = qca8075_phy_mmd_read(0, PSGMII_ID,
QCA8075_PHY_MMD1_NUM, QCA8075_PSGMII_FIFI_CTRL);
phy_data &= 0xbfff;
qca8075_phy_mmd_write(0, PSGMII_ID, QCA8075_PHY_MMD1_NUM,
QCA8075_PSGMII_FIFI_CTRL, phy_data);
}
/*
* Enable AZ transmitting ability
*/
qca8075_phy_mmd_write(0, PSGMII_ID, QCA8075_PHY_MMD1_NUM,
QCA8075_PSGMII_MODE_CTRL,
QCA8075_PHY_PSGMII_MODE_CTRL_ADJUST_VALUE);
/*
* Enable phy power saving function by default
*/
if (qca8075_id == QCA8075_PHY_V1_1_2P)
phy_id = 3;
if ((qca8075_id == QCA8075_PHY_V1_0_5P) ||
(qca8075_id == QCA8075_PHY_V1_1_5P) ||
(qca8075_id == QCA8075_PHY_V1_1_2P)) {
for (; phy_id < 5; phy_id++) {
qca8075_phy_set_8023az(0x0, phy_id, 0x1);
qca8075_phy_set_powersave(0x0, phy_id, 0x1);
qca8075_phy_set_hibernate(0x0, phy_id, 0x1);
}
}
phy_data = qca8075_phy_mmd_read(0, 4, QCA8075_PHY_MMD3_NUM, 0x805a);
phy_data &= (~(1 << 1));
qca8075_phy_mmd_write(0, 4, QCA8075_PHY_MMD3_NUM, 0x805a, phy_data);
return 0;
}

View file

@ -0,0 +1,480 @@
/*
* Copyright (c) 2015-2017, The Linux Foundation. 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 _QCA8075_PHY_H_
#define _QCA8075_PHY_H_
#define QCA8075_PHY_V1_0_5P 0x004DD0B0
#define QCA8075_PHY_V1_1_5P 0x004DD0B1
#define QCA8075_PHY_V1_1_2P 0x004DD0B2
#define QCA8075_PHY_CONTROL 0
#define QCA8075_PHY_STATUS 1
#define QCA8075_PHY_ID1 2
#define QCA8075_PHY_ID2 3
#define QCA8075_AUTONEG_ADVERT 4
#define QCA8075_LINK_PARTNER_ABILITY 5
#define QCA8075_AUTONEG_EXPANSION 6
#define QCA8075_NEXT_PAGE_TRANSMIT 7
#define QCA8075_LINK_PARTNER_NEXT_PAGE 8
#define QCA8075_1000BASET_CONTROL 9
#define QCA8075_1000BASET_STATUS 10
#define QCA8075_MMD_CTRL_REG 13
#define QCA8075_MMD_DATA_REG 14
#define QCA8075_EXTENDED_STATUS 15
#define QCA8075_PHY_SPEC_CONTROL 16
#define QCA8075_PHY_SPEC_STATUS 17
#define QCA8075_PHY_INTR_MASK 18
#define QCA8075_PHY_INTR_STATUS 19
#define QCA8075_PHY_CDT_CONTROL 22
#define QCA8075_PHY_CDT_STATUS 28
#define QCA8075_DEBUG_PORT_ADDRESS 29
#define QCA8075_DEBUG_PORT_DATA 30
#define COMBO_PHY_ID 4
#define PSGMII_ID 5
#define QCA8075_DEBUG_PHY_HIBERNATION_CTRL 0xb
#define QCA8075_DEBUG_PHY_POWER_SAVING_CTRL 0x29
#define QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL 0x3c
#define QCA8075_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL 0x805a
#define QCA8075_PHY_MMD3_WOL_MAGIC_MAC_CTRL1 0x804a
#define QCA8075_PHY_MMD3_WOL_MAGIC_MAC_CTRL2 0x804b
#define QCA8075_PHY_MMD3_WOL_MAGIC_MAC_CTRL3 0x804c
#define QCA8075_PHY_MMD3_WOL_CTRL 0x8012
#define QCA8075_PSGMII_FIFI_CTRL 0x6e
#define QCA8075_PSGMII_CALIB_CTRL 0x27
#define QCA8075_PSGMII_MODE_CTRL 0x6d
#define QCA8075_PHY_PSGMII_MODE_CTRL_ADJUST_VALUE 0x220c
#define QCA8075_PHY_MMD7_NUM 7
#define QCA8075_PHY_MMD3_NUM 3
#define QCA8075_PHY_MMD1_NUM 1
#define QCA8075_PHY_SGMII_STATUS 0x1a /* sgmii_status Register */
#define QCA8075_PHY4_AUTO_SGMII_SELECT 0x40
#define QCA8075_PHY4_AUTO_COPPER_SELECT 0x20
#define QCA8075_PHY4_AUTO_BX1000_SELECT 0x10
#define QCA8075_PHY4_AUTO_FX100_SELECT 0x8
#define QCA8075_PHY_CHIP_CONFIG 0x1f /* Chip Configuration Register */
#define BT_BX_SG_REG_SELECT BIT_15
#define BT_BX_SG_REG_SELECT_OFFSET 15
#define BT_BX_SG_REG_SELECT_LEN 1
#define QCA8075_SG_BX_PAGES 0x0
#define QCA8075_SG_COPPER_PAGES 0x1
#define QCA8075_PHY_PSGMII_BASET 0x0
#define QCA8075_PHY_PSGMII_BX1000 0x1
#define QCA8075_PHY_PSGMII_FX100 0x2
#define QCA8075_PHY_PSGMII_AMDET 0x3
#define QCA8075_PHY_SGMII_BASET 0x4
#define QCA8075_PHY4_PREFER_FIBER 0x400
#define PHY4_PREFER_COPPER 0x0
#define PHY4_PREFER_FIBER 0x1
#define QCA8075_PHY4_FIBER_MODE_1000BX 0x100
#define AUTO_100FX_FIBER 0x0
#define AUTO_1000BX_FIBER 0x1
#define QCA8075_PHY_MDIX 0x0020
#define QCA8075_PHY_MDIX_AUTO 0x0060
#define QCA8075_PHY_MDIX_STATUS 0x0040
#define MODE_CFG_QUAL BIT_4
#define MODE_CFG_QUAL_OFFSET 4
#define MODE_CFG_QUAL_LEN 4
#define MODE_CFG BIT_0
#define MODE_CFG_OFFSET 0
#define MODE_CFG_LEN 4
#define QCA8075_PHY_MMD3_ADDR_8023AZ_CLD_CTRL 0x8007
#define QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL 0x804e
#define QCA8075_PHY_MMD3_ADDR_CLD_CTRL5 0x8005
#define QCA8075_PHY_MMD3_ADDR_CLD_CTRL3 0x8003
#define AZ_TIMER_CTRL_DEFAULT_VALUE 0x3062
#define AZ_CLD_CTRL_DEFAULT_VALUE 0x83f6
#define AZ_TIMER_CTRL_ADJUST_VALUE 0x7062
#define AZ_CLD_CTRL_ADJUST_VALUE 0x8396
/*debug port */
#define QCA8075_DEBUG_PORT_RGMII_MODE 18
#define QCA8075_DEBUG_PORT_RGMII_MODE_EN 0x0008
#define QCA8075_DEBUG_PORT_RX_DELAY 0
#define QCA8075_DEBUG_PORT_RX_DELAY_EN 0x8000
#define QCA8075_DEBUG_PORT_TX_DELAY 5
#define QCA8075_DEBUG_PORT_TX_DELAY_EN 0x0100
/* PHY Registers Field */
/* Control Register fields offset:0 */
/* bits 6,13: 10=1000, 01=100, 00=10 */
#define QCA8075_CTRL_SPEED_MSB 0x0040
/* Collision test enable */
#define QCA8075_CTRL_COLL_TEST_ENABLE 0x0080
/* FDX =1, half duplex =0 */
#define QCA8075_CTRL_FULL_DUPLEX 0x0100
/* Restart auto negotiation */
#define QCA8075_CTRL_RESTART_AUTONEGOTIATION 0x0200
/* Isolate PHY from MII */
#define QCA8075_CTRL_ISOLATE 0x0400
/* Power down */
#define QCA8075_CTRL_POWER_DOWN 0x0800
/* Auto Neg Enable */
#define QCA8075_CTRL_AUTONEGOTIATION_ENABLE 0x1000
/* Local Loopback Enable */
#define QCA8075_LOCAL_LOOPBACK_ENABLE 0x4000
/* bits 6,13: 10=1000, 01=100, 00=10 */
#define QCA8075_CTRL_SPEED_LSB 0x2000
/* 0 = normal, 1 = loopback */
#define QCA8075_CTRL_LOOPBACK 0x4000
#define QCA8075_CTRL_SOFTWARE_RESET 0x8000
#define QCA8075_CTRL_SPEED_MASK 0x2040
#define QCA8075_CTRL_SPEED_1000 0x0040
#define QCA8075_CTRL_SPEED_100 0x2000
#define QCA8075_CTRL_SPEED_10 0x0000
#define QCA8075_RESET_DONE(phy_control) \
(((phy_control) & (QCA8075_CTRL_SOFTWARE_RESET)) == 0)
/* Status Register fields offset:1 */
/* Extended register capabilities */
#define QCA8075_STATUS_EXTENDED_CAPS 0x0001
/* Jabber Detected */
#define QCA8075_STATUS_JABBER_DETECT 0x0002
/* Link Status 1 = link */
#define QCA8075_STATUS_LINK_STATUS_UP 0x0004
/* Auto Neg Capable */
#define QCA8075_STATUS_AUTONEG_CAPS 0x0008
/* Remote Fault Detect */
#define QCA8075_STATUS_REMOTE_FAULT 0x0010
/* Auto Neg Complete */
#define QCA8075_STATUS_AUTO_NEG_DONE 0x0020
/* Preamble may be suppressed */
#define QCA8075_STATUS_PREAMBLE_SUPPRESS 0x0040
/* Ext. status info in Reg 0x0F */
#define QCA8075_STATUS_EXTENDED_STATUS 0x0100
/* 100T2 Half Duplex Capable */
#define QCA8075_STATUS_100T2_HD_CAPS 0x0200
/* 100T2 Full Duplex Capable */
#define QCA8075_STATUS_100T2_FD_CAPS 0x0400
/* 10T Half Duplex Capable */
#define QCA8075_STATUS_10T_HD_CAPS 0x0800
/* 10T Full Duplex Capable */
#define QCA8075_STATUS_10T_FD_CAPS 0x1000
/* 100X Half Duplex Capable */
#define QCA8075_STATUS_100X_HD_CAPS 0x2000
/* 100X Full Duplex Capable */
#define QCA8075_STATUS_100X_FD_CAPS 0x4000
/* 100T4 Capable */
#define QCA8075_STATUS_100T4_CAPS 0x8000
/* extended status register capabilities */
#define QCA8075_STATUS_1000T_HD_CAPS 0x1000
#define QCA8075_STATUS_1000T_FD_CAPS 0x2000
#define QCA8075_STATUS_1000X_HD_CAPS 0x4000
#define QCA8075_STATUS_1000X_FD_CAPS 0x8000
#define QCA8075_AUTONEG_DONE(ip_phy_status) \
(((ip_phy_status) & (QCA8075_STATUS_AUTO_NEG_DONE)) == \
(QCA8075_STATUS_AUTO_NEG_DONE))
/* PHY identifier1 offset:2 */
//Organizationally Unique Identifier bits 3:18
/* PHY identifier2 offset:3 */
//Organizationally Unique Identifier bits 19:24
/* Auto-Negotiation Advertisement register. offset:4 */
/* indicates IEEE 802.3 CSMA/CD */
#define QCA8075_ADVERTISE_SELECTOR_FIELD 0x0001
/* 10T Half Duplex Capable */
#define QCA8075_ADVERTISE_10HALF 0x0020
/* 10T Full Duplex Capable */
#define QCA8075_ADVERTISE_10FULL 0x0040
/* 100TX Half Duplex Capable */
#define QCA8075_ADVERTISE_100HALF 0x0080
/* 100TX Full Duplex Capable */
#define QCA8075_ADVERTISE_100FULL 0x0100
/* 100T4 Capable */
#define QCA8075_ADVERTISE_100T4 0x0200
/* Pause operation desired */
#define QCA8075_ADVERTISE_PAUSE 0x0400
/* Asymmetric Pause Direction bit */
#define QCA8075_ADVERTISE_ASYM_PAUSE 0x0800
/* Remote Fault detected */
#define QCA8075_ADVERTISE_REMOTE_FAULT 0x2000
/* Next Page ability supported */
#define QCA8075_ADVERTISE_NEXT_PAGE 0x8000
/* 100TX Half Duplex Capable */
#define QCA8075_ADVERTISE_1000HALF 0x0100
/* 100TX Full Duplex Capable */
#define QCA8075_ADVERTISE_1000FULL 0x0200
#define QCA8075_ADVERTISE_ALL \
(QCA8075_ADVERTISE_10HALF | QCA8075_ADVERTISE_10FULL | \
QCA8075_ADVERTISE_100HALF | QCA8075_ADVERTISE_100FULL | \
QCA8075_ADVERTISE_1000FULL)
#define QCA8075_ADVERTISE_MEGA_ALL \
(QCA8075_ADVERTISE_10HALF | QCA8075_ADVERTISE_10FULL | \
QCA8075_ADVERTISE_100HALF | QCA8075_ADVERTISE_100FULL)
#define QCA8075_BX_ADVERTISE_1000FULL 0x0020
#define QCA8075_BX_ADVERTISE_1000HALF 0x0040
#define QCA8075_BX_ADVERTISE_PAUSE 0x0080
#define QCA8075_BX_ADVERTISE_ASYM_PAUSE 0x0100
#define QCA8075_BX_ADVERTISE_ALL \
(QCA8075_BX_ADVERTISE_ASYM_PAUSE | QCA8075_BX_ADVERTISE_PAUSE | \
QCA8075_BX_ADVERTISE_1000HALF | QCA8075_BX_ADVERTISE_1000FULL)
/* Link Partner ability offset:5 */
/* Same as advertise selector */
#define QCA8075_LINK_SLCT 0x001f
/* Can do 10mbps half-duplex */
#define QCA8075_LINK_10BASETX_HALF_DUPLEX 0x0020
/* Can do 10mbps full-duplex */
#define QCA8075_LINK_10BASETX_FULL_DUPLEX 0x0040
/* Can do 100mbps half-duplex */
#define QCA8075_LINK_100BASETX_HALF_DUPLEX 0x0080
/* Can do 100mbps full-duplex */
#define QCA8075_LINK_100BASETX_FULL_DUPLEX 0x0100
/* Can do 1000mbps full-duplex */
#define QCA8075_LINK_1000BASETX_FULL_DUPLEX 0x0800
/* Can do 1000mbps half-duplex */
#define QCA8075_LINK_1000BASETX_HALF_DUPLEX 0x0400
/* 100BASE-T4 */
#define QCA8075_LINK_100BASE4 0x0200
/* PAUSE */
#define QCA8075_LINK_PAUSE 0x0400
/* Asymmetrical PAUSE */
#define QCA8075_LINK_ASYPAUSE 0x0800
/* Link partner faulted */
#define QCA8075_LINK_RFAULT 0x2000
/* Link partner acked us */
#define QCA8075_LINK_LPACK 0x4000
/* Next page bit */
#define QCA8075_LINK_NPAGE 0x8000
/* Auto-Negotiation Expansion Register offset:6 */
/* Next Page Transmit Register offset:7 */
/* Link partner Next Page Register offset:8 */
/* 1000BASE-T Control Register offset:9 */
/* Advertise 1000T HD capability */
#define QCA8075_CTL_1000T_HD_CAPS 0x0100
/* Advertise 1000T FD capability */
#define QCA8075_CTL_1000T_FD_CAPS 0x0200
/* 1=Repeater/switch device port 0=DTE device */
#define QCA8075_CTL_1000T_REPEATER_DTE 0x0400
/* 1=Configure PHY as Master 0=Configure PHY as Slave */
#define QCA8075_CTL_1000T_MS_VALUE 0x0800
/* 1=Master/Slave manual config value 0=Automatic Master/Slave config */
#define QCA8075_CTL_1000T_MS_ENABLE 0x1000
/* Normal Operation */
#define QCA8075_CTL_1000T_TEST_MODE_NORMAL 0x0000
/* Transmit Waveform test */
#define QCA8075_CTL_1000T_TEST_MODE_1 0x2000
/* Master Transmit Jitter test */
#define QCA8075_CTL_1000T_TEST_MODE_2 0x4000
/* Slave Transmit Jitter test */
#define QCA8075_CTL_1000T_TEST_MODE_3 0x6000
/* Transmitter Distortion test */
#define QCA8075_CTL_1000T_TEST_MODE_4 0x8000
#define QCA8075_CTL_1000T_SPEED_MASK 0x0300
#define QCA8075_CTL_1000T_DEFAULT_CAP_MASK 0x0300
/* 1000BASE-T Status Register offset:10 */
/* LP is 1000T HD capable */
#define QCA8075_STATUS_1000T_LP_HD_CAPS 0x0400
/* LP is 1000T FD capable */
#define QCA8075_STATUS_1000T_LP_FD_CAPS 0x0800
/* Remote receiver OK */
#define QCA8075_STATUS_1000T_REMOTE_RX_STATUS 0x1000
/* Local receiver OK */
#define QCA8075_STATUS_1000T_LOCAL_RX_STATUS 0x2000
/* 1=Local TX is Master, 0=Slave */
#define QCA8075_STATUS_1000T_MS_CONFIG_RES 0x4000
#define QCA8075_STATUS_1000T_MS_CONFIG_FAULT 0x8000
/* Master/Slave config fault */
#define QCA8075_STATUS_1000T_REMOTE_RX_STATUS_SHIFT 12
#define QCA8075_STATUS_1000T_LOCAL_RX_STATUS_SHIFT 13
/* Phy Specific Control Register offset:16 */
/* 1=Jabber Function disabled */
#define QCA8075_CTL_JABBER_DISABLE 0x0001
/* 1=Polarity Reversal enabled */
#define QCA8075_CTL_POLARITY_REVERSAL 0x0002
/* 1=SQE Test enabled */
#define QCA8075_CTL_SQE_TEST 0x0004
#define QCA8075_CTL_MAC_POWERDOWN 0x0008
/* 1=CLK125 low, 0=CLK125 toggling
#define QCA8075_CTL_CLK125_DISABLE 0x0010
*/
/* MDI Crossover Mode bits 6:5 */
/* Manual MDI configuration */
#define QCA8075_CTL_MDI_MANUAL_MODE 0x0000
/* Manual MDIX configuration */
#define QCA8075_CTL_MDIX_MANUAL_MODE 0x0020
/* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */
#define QCA8075_CTL_AUTO_X_1000T 0x0040
/* Auto crossover enabled all speeds */
#define QCA8075_CTL_AUTO_X_MODE 0x0060
/* 1=Enable Extended 10BASE-T distance
* (Lower 10BASE-T RX Threshold)
* 0=Normal 10BASE-T RX Threshold */
#define QCA8075_CTL_10BT_EXT_DIST_ENABLE 0x0080
/* 1=5-Bit interface in 100BASE-TX
* 0=MII interface in 100BASE-TX */
#define QCA8075_CTL_MII_5BIT_ENABLE 0x0100
/* 1=Scrambler disable */
#define QCA8075_CTL_SCRAMBLER_DISABLE 0x0200
/* 1=Force link good */
#define QCA8075_CTL_FORCE_LINK_GOOD 0x0400
/* 1=Assert CRS on Transmit */
#define QCA8075_CTL_ASSERT_CRS_ON_TX 0x0800
#define QCA8075_CTL_POLARITY_REVERSAL_SHIFT 1
#define QCA8075_CTL_AUTO_X_MODE_SHIFT 5
#define QCA8075_CTL_10BT_EXT_DIST_ENABLE_SHIFT 7
/* Phy Specific status fields offset:17 */
/* 1=Speed & Duplex resolved */
#define QCA8075_STATUS_LINK_PASS 0x0400
#define QCA8075_STATUS_RESOVLED 0x0800
/* 1=Duplex 0=Half Duplex */
#define QCA8075_STATUS_FULL_DUPLEX 0x2000
/* Speed, bits 14:15 */
#define QCA8075_STATUS_SPEED 0xC000
#define QCA8075_STATUS_SPEED_MASK 0xC000
/* 00=10Mbs */
#define QCA8075_STATUS_SPEED_10MBS 0x0000
/* 01=100Mbs */
#define QCA8075_STATUS_SPEED_100MBS 0x4000
/* 10=1000Mbs */
#define QCA8075_STATUS_SPEED_1000MBS 0x8000
#define QCA8075_SPEED_DUPLEX_RESOVLED(phy_status) \
(((phy_status) & \
(QCA8075_STATUS_RESOVLED)) == \
(QCA8075_STATUS_RESOVLED))
/*phy debug port1 register offset:29 */
/*phy debug port2 register offset:30 */
/*QCA8075 interrupt flag */
#define QCA8075_INTR_SPEED_CHANGE 0x4000
#define QCA8075_INTR_DUPLEX_CHANGE 0x2000
#define QCA8075_INTR_STATUS_UP_CHANGE 0x0400
#define QCA8075_INTR_STATUS_DOWN_CHANGE 0x0800
#define QCA8075_INTR_BX_FX_STATUS_DOWN_CHANGE 0x0100
#define QCA8075_INTR_BX_FX_STATUS_UP_CHANGE 0x0080
#define QCA8075_INTR_MEDIA_STATUS_CHANGE 0x1000
#define QCA8075_INTR_WOL 0x0001
#define QCA8075_INTR_POE 0x0002
#define RUN_CDT 0x8000
#define CABLE_LENGTH_UNIT 0x0400
#define QCA8075_MAX_TRIES 100
#endif /* _QCA8075_PHY_H_ */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
* Copyright (c) 2015-2017, The Linux Foundation. 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
@ -202,7 +202,7 @@ typedef struct {
#define CONFIG_IPQ40XX_EDMA 1
#define CONFIG_NET_RETRY_COUNT 5
#define CONFIG_SYS_RX_ETH_BUFFER 16
#define CONFIG_IPQ40XX_MDIO 1
#define CONFIG_IPQ_MDIO 1
#define CONFIG_QCA8075_PHY 1
#define CONFIG_QCA8033_PHY 1
#define CONFIG_MII

View file

@ -263,6 +263,8 @@ extern loff_t board_env_offset;
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_SERVERIP 192.168.10.1
#define CONFIG_CMD_TFTPPUT
#define CONFIG_IPQ_MDIO 1
#define CONFIG_QCA8075_PHY 1
/*
* CRASH DUMP ENABLE