drivers: ethernet: bugfix for Cyclone V Ethernet
bugfix for Cyclone V Ethernet Phy error and timeout overflow. - p->instance was incorrectly assumed to be a reference to the emac device, this is ammended - the volatile uint16_t timeout would often overflow - code cleanup and added more macros for housekeeping Signed-off-by: Benjamin Kyd <benjamin.kyd@intel.com>
This commit is contained in:
parent
c348fb51c9
commit
aad76523e1
|
@ -60,7 +60,7 @@ struct eth_cyclonev_config {
|
|||
uint8_t *base;
|
||||
/** BBRAM size (Unit:bytes) */
|
||||
int size;
|
||||
int inst_num;
|
||||
uint32_t emac_index;
|
||||
void (*irq_config)(void);
|
||||
};
|
||||
|
||||
|
@ -315,6 +315,7 @@ static int eth_cyclonev_set_config(const struct device *dev, enum ethernet_confi
|
|||
const struct ethernet_config *config)
|
||||
{
|
||||
struct eth_cyclonev_priv *p = dev->data;
|
||||
const struct eth_cyclonev_config *cv_config = dev->config;
|
||||
uint32_t reg_val;
|
||||
int ret = 0;
|
||||
|
||||
|
@ -323,7 +324,7 @@ static int eth_cyclonev_set_config(const struct device *dev, enum ethernet_confi
|
|||
switch (type) {
|
||||
case ETHERNET_CONFIG_TYPE_MAC_ADDRESS:
|
||||
memcpy(p->mac_addr, config->mac_address.addr, sizeof(p->mac_addr));
|
||||
eth_cyclonev_set_mac_addr(p->mac_addr, p->instance, 0, p); /* Set MAC address */
|
||||
eth_cyclonev_set_mac_addr(p->mac_addr, cv_config->emac_index, 0, p); /* Set MAC */
|
||||
net_if_set_link_addr(p->iface, p->mac_addr, sizeof(p->mac_addr), NET_LINK_ETHERNET);
|
||||
break;
|
||||
#if defined(CONFIG_NET_PROMISCUOUS_MODE)
|
||||
|
@ -546,6 +547,7 @@ abort:
|
|||
void eth_cyclonev_isr(const struct device *dev)
|
||||
{
|
||||
struct eth_cyclonev_priv *p = dev->data;
|
||||
const struct eth_cyclonev_config *config = dev->config;
|
||||
uint32_t irq_status = 0;
|
||||
uint32_t irq_status_emac = 0;
|
||||
|
||||
|
@ -617,7 +619,7 @@ void eth_cyclonev_isr(const struct device *dev)
|
|||
return;
|
||||
}
|
||||
|
||||
set_mac_conf_status(p->instance, &cfg_reg_set, p);
|
||||
set_mac_conf_status(config->emac_index, &cfg_reg_set, p);
|
||||
sys_write32(cfg_reg_set, GMACGRP_MAC_CONFIG_ADDR(p->base_addr));
|
||||
|
||||
eth_cyclonev_start(dev);
|
||||
|
@ -857,22 +859,21 @@ int eth_cyclonev_probe(const struct device *dev)
|
|||
p->base_addr = (mem_addr_t)config->base;
|
||||
p->running = 0;
|
||||
p->initialised = 0;
|
||||
p->instance = config->inst_num;
|
||||
|
||||
/* EMAC HPS Interface Initialization */
|
||||
|
||||
/* Reset the EMAC */
|
||||
eth_cyclonev_reset(p->instance);
|
||||
eth_cyclonev_reset(config->emac_index);
|
||||
|
||||
/* Reset the PHY */
|
||||
ret = alt_eth_phy_reset(p->instance, p);
|
||||
ret = alt_eth_phy_reset(config->emac_index, p);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("alt_eth_phy_reset failure!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Configure the PHY */
|
||||
ret = alt_eth_phy_config(p->instance, p);
|
||||
ret = alt_eth_phy_config(config->emac_index, p);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("alt_eth_phy_config failure!\n");
|
||||
return ret;
|
||||
|
@ -891,7 +892,7 @@ int eth_cyclonev_probe(const struct device *dev)
|
|||
*operation is completed).
|
||||
*/
|
||||
|
||||
ret = eth_cyclonev_software_reset(p->instance, p);
|
||||
ret = eth_cyclonev_software_reset(config->emac_index, p);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("eth_cyclonev_software_reset failure!\n");
|
||||
return ret;
|
||||
|
@ -993,7 +994,7 @@ int eth_cyclonev_probe(const struct device *dev)
|
|||
/* Enable Transmission to PHY */
|
||||
);
|
||||
|
||||
ret = set_mac_conf_status(p->instance, &mac_config_reg_settings, p);
|
||||
ret = set_mac_conf_status(config->emac_index, &mac_config_reg_settings, p);
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1004,7 +1005,7 @@ int eth_cyclonev_probe(const struct device *dev)
|
|||
*/
|
||||
|
||||
memcpy(p->mac_addr, eth_cyclonev_mac_addr, sizeof(p->mac_addr));
|
||||
eth_cyclonev_set_mac_addr(p->mac_addr, p->instance, 0, p);
|
||||
eth_cyclonev_set_mac_addr(p->mac_addr, config->emac_index, 0, p);
|
||||
|
||||
/* 5. Program the following fields to set the appropriate filters for the
|
||||
* incoming frames in the MAC Frame Filter Register:
|
||||
|
@ -1142,15 +1143,15 @@ const struct ethernet_api eth_cyclonev_api = {.iface_api.init = eth_cyclonev_ifa
|
|||
.stop = eth_cyclonev_stop,
|
||||
.set_config = eth_cyclonev_set_config};
|
||||
|
||||
#define CYCLONEV_ETH_INIT(inst) \
|
||||
#define CYCLONEV_ETH_INIT(inst) \
|
||||
\
|
||||
static struct eth_cyclonev_priv eth_cyclonev_##inst##_data; \
|
||||
static void eth_cyclonev_##inst##_irq_config(void); \
|
||||
\
|
||||
static const struct eth_cyclonev_config eth_cyclonev_##inst##_cfg = { \
|
||||
static const struct eth_cyclonev_config eth_cyclonev_##inst##_cfg = { \
|
||||
.base = (uint8_t *)(DT_INST_REG_ADDR(inst)), \
|
||||
.size = DT_INST_REG_SIZE(inst), \
|
||||
.inst_num = inst, \
|
||||
.emac_index = DT_INST_PROP(inst, emac_index), \
|
||||
.irq_config = eth_cyclonev_##inst##_irq_config, \
|
||||
}; \
|
||||
ETH_NET_DEVICE_DT_INST_DEFINE(inst, eth_cyclonev_probe, NULL, \
|
||||
|
@ -1167,5 +1168,4 @@ const struct ethernet_api eth_cyclonev_api = {.iface_api.init = eth_cyclonev_ifa
|
|||
DEVICE_DT_INST_GET(inst), \
|
||||
0); \
|
||||
irq_enable(DT_INST_IRQN(inst)); \
|
||||
}
|
||||
DT_INST_FOREACH_STATUS_OKAY(CYCLONEV_ETH_INIT)
|
||||
|
|
|
@ -30,7 +30,6 @@ struct eth_cyclonev_dma_desc {
|
|||
|
||||
struct eth_cyclonev_priv {
|
||||
mem_addr_t base_addr; /* Base address */
|
||||
uint32_t instance;
|
||||
uint8_t mac_addr[6];
|
||||
uint32_t interrupt_mask;
|
||||
struct net_if *iface; /* Zephyr net_if Interface Struct (for interface initialisation) */
|
||||
|
|
|
@ -47,8 +47,8 @@
|
|||
#define PHY_RESTART_AUTONEGOTIATION BIT(9)
|
||||
|
||||
/* Basic Status Register */
|
||||
#define PHY_BSR BIT(0)
|
||||
#define PHY_AUTOCAP BIT(30) /* Auto-negotiation capability */
|
||||
#define PHY_BSR (1)
|
||||
#define PHY_AUTOCAP BIT(3) /* Auto-negotiation capability */
|
||||
#define PHY_LINKED_STATUS BIT(2)
|
||||
#define PHY_AUTONEGO_COMPLETE BIT(5)
|
||||
|
||||
|
@ -58,16 +58,20 @@
|
|||
#define PHYANA_10BASETFD BIT(6)
|
||||
#define PHYANA_100BASETX BIT(7)
|
||||
#define PHYANA_100BASETXFD BIT(8)
|
||||
#define PHYSYMETRIC_PAUSE BIT(10)
|
||||
#define PHYASYMETRIC_PAUSE BIT(11)
|
||||
|
||||
/* 1000Base-T Control */
|
||||
#define PHY_1GCTL (9)
|
||||
#define PHYADVERTISE_1000HALF BIT(8)
|
||||
#define PHYADVERTISE_1000FULL BIT(9)
|
||||
#define PHYINDICATE_PORTTYPE BIT(10)
|
||||
#define PHYCONFIG_MASTER BIT(11)
|
||||
#define PHYENABLE_MANUALCONFIG BIT(12)
|
||||
|
||||
/* PHY Control Register */
|
||||
#define PHY_CR (31)
|
||||
#define PHY_DUPLEX_STATUS (0x0008)
|
||||
#define PHYADVERTISE_1000FULL BIT(9)
|
||||
#define PHYADVERTISE_1000HALF BIT(8)
|
||||
#define PHY_DUPLEX_STATUS BIT(3)
|
||||
|
||||
/* Extended registers */
|
||||
#define MII_KSZPHY_CLK_CONTROL_PAD_SKEW 0x104
|
||||
|
@ -92,7 +96,7 @@ int alt_eth_phy_write_register(uint16_t emac_instance, uint16_t phy_reg,
|
|||
uint16_t phy_value, struct eth_cyclonev_priv *p)
|
||||
{
|
||||
uint16_t tmpreg = 0;
|
||||
volatile uint16_t timeout = 0;
|
||||
volatile uint32_t timeout = 0;
|
||||
uint16_t phy_addr;
|
||||
|
||||
if (emac_instance > 1) {
|
||||
|
@ -139,7 +143,7 @@ int alt_eth_phy_read_register(uint16_t emac_instance, uint16_t phy_reg, uint16_t
|
|||
struct eth_cyclonev_priv *p)
|
||||
{
|
||||
uint16_t tmpreg = 0;
|
||||
volatile uint16_t timeout = 0;
|
||||
volatile uint32_t timeout = 0;
|
||||
uint16_t phy_addr;
|
||||
|
||||
if (emac_instance > 1) {
|
||||
|
@ -218,7 +222,8 @@ int alt_eth_phy_config(uint16_t instance, struct eth_cyclonev_priv *p)
|
|||
{
|
||||
|
||||
int rc;
|
||||
uint16_t rdval, timeout;
|
||||
uint16_t rdval;
|
||||
uint32_t timeout;
|
||||
/*-------------------- Configure the PHY skew values ----------------*/
|
||||
|
||||
rc = alt_eth_phy_write_register_extended(instance, MII_KSZPHY_CLK_CONTROL_PAD_SKEW,
|
||||
|
@ -250,7 +255,7 @@ int alt_eth_phy_config(uint16_t instance, struct eth_cyclonev_priv *p)
|
|||
}
|
||||
|
||||
rdval |= (PHYANA_10BASET | PHYANA_10BASETFD | PHYANA_100BASETX | PHYANA_100BASETXFD |
|
||||
PHYASYMETRIC_PAUSE);
|
||||
PHYSYMETRIC_PAUSE);
|
||||
rc = alt_eth_phy_write_register(instance, PHY_AUTON, rdval, p);
|
||||
if (rc == -1) {
|
||||
return rc;
|
||||
|
@ -259,7 +264,9 @@ int alt_eth_phy_config(uint16_t instance, struct eth_cyclonev_priv *p)
|
|||
/* Set Advertise capabilities for 1000 Base-T/1000 Base-T full-duplex */
|
||||
|
||||
rc = alt_eth_phy_write_register(instance, PHY_1GCTL,
|
||||
PHYADVERTISE_1000FULL | PHYADVERTISE_1000HALF, p);
|
||||
PHYADVERTISE_1000FULL | PHYADVERTISE_1000HALF |
|
||||
PHYINDICATE_PORTTYPE | PHYCONFIG_MASTER | PHYENABLE_MANUALCONFIG
|
||||
, p);
|
||||
if (rc == -1) {
|
||||
return rc;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue